]> code.delx.au - gnu-emacs/commitdiff
Merge from emacs--devo--0
authorMiles Bader <miles@gnu.org>
Fri, 26 Jan 2007 06:16:11 +0000 (06:16 +0000)
committerMiles Bader <miles@gnu.org>
Fri, 26 Jan 2007 06:16:11 +0000 (06:16 +0000)
Patches applied:

 * emacs--devo--0  (patch 586-614)

   - Update from CVS
   - Update from erc--emacs--22
   - Merge from gnus--rel--5.10
   - Merge from erc--main--0
   - Make byte compiler correctly write circular constants

 * gnus--rel--5.10  (patch 186-196)

   - Update from CVS
   - Merge from emacs--devo--0

Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-162

220 files changed:
1  2 
configure
configure.in
etc/HELLO
etc/MORE.STUFF
etc/NEWS
etc/PROBLEMS
etc/TODO
leim/CXTERM-DIC/4Corner.tit
leim/CXTERM-DIC/CCDOSPY.tit
leim/CXTERM-DIC/PY-b5.tit
leim/CXTERM-DIC/QJ-b5.tit
leim/CXTERM-DIC/QJ.tit
leim/CXTERM-DIC/README
leim/CXTERM-DIC/SW.tit
leim/CXTERM-DIC/TONEPY.tit
leim/MISC-DIC/README
leim/Makefile.in
leim/quail/cyrillic.el
leim/quail/hangul3.el
leim/quail/indian.el
leim/quail/latin-alt.el
leim/quail/latin-post.el
leim/quail/latin-pre.el
leim/quail/pypunct-b5.el
leim/quail/symbol-ksc.el
leim/quail/thai.el
leim/quail/tibetan.el
leim/quail/uni-input.el
leim/quail/welsh.el
lib-src/makefile.w32-in
lisp/ChangeLog
lisp/ChangeLog.10
lisp/Makefile.in
lisp/arc-mode.el
lisp/bindings.el
lisp/case-table.el
lisp/composite.el
lisp/cus-start.el
lisp/descr-text.el
lisp/desktop.el
lisp/disp-table.el
lisp/dnd.el
lisp/edmacro.el
lisp/emacs-lisp/byte-opt.el
lisp/emacs-lisp/bytecomp.el
lisp/emacs-lisp/cl-macs.el
lisp/emacs-lisp/copyright.el
lisp/emacs-lisp/generic.el
lisp/emacs-lisp/regexp-opt.el
lisp/emulation/keypad.el
lisp/eshell/esh-mode.el
lisp/eshell/esh-opt.el
lisp/faces.el
lisp/font-lock.el
lisp/format.el
lisp/gnus/gnus-start.el
lisp/gnus/mm-bodies.el
lisp/gnus/mm-util.el
lisp/gnus/mml.el
lisp/gnus/rfc2047.el
lisp/gnus/rfc2104.el
lisp/info.el
lisp/international/ccl.el
lisp/international/characters.el
lisp/international/codepage.el
lisp/international/encoded-kb.el
lisp/international/fontset.el
lisp/international/ja-dic-cnv.el
lisp/international/ja-dic-utl.el
lisp/international/mule-cmds.el
lisp/international/mule-conf.el
lisp/international/mule-diag.el
lisp/international/mule-util.el
lisp/international/mule.el
lisp/international/quail.el
lisp/international/titdic-cnv.el
lisp/international/utf-7.el
lisp/isearch.el
lisp/language/china-util.el
lisp/language/chinese.el
lisp/language/cyril-util.el
lisp/language/cyrillic.el
lisp/language/czech.el
lisp/language/devan-util.el
lisp/language/devanagari.el
lisp/language/english.el
lisp/language/ethio-util.el
lisp/language/ethiopic.el
lisp/language/european.el
lisp/language/georgian.el
lisp/language/greek.el
lisp/language/hebrew.el
lisp/language/ind-util.el
lisp/language/indian.el
lisp/language/japanese.el
lisp/language/kannada.el
lisp/language/knd-util.el
lisp/language/korean.el
lisp/language/lao-util.el
lisp/language/lao.el
lisp/language/malayalam.el
lisp/language/misc-lang.el
lisp/language/mlm-util.el
lisp/language/romanian.el
lisp/language/slovak.el
lisp/language/tamil.el
lisp/language/thai-util.el
lisp/language/thai.el
lisp/language/tibet-util.el
lisp/language/tibetan.el
lisp/language/tml-util.el
lisp/language/utf-8-lang.el
lisp/language/viet-util.el
lisp/language/vietnamese.el
lisp/ldefs-boot.el
lisp/loadup.el
lisp/mail/emacsbug.el
lisp/mail/rmail.el
lisp/mail/sendmail.el
lisp/makefile.w32-in
lisp/obsolete/swedish.el
lisp/progmodes/perl-mode.el
lisp/progmodes/sh-script.el
lisp/ps-print.el
lisp/ruler-mode.el
lisp/simple.el
lisp/startup.el
lisp/subr.el
lisp/tar-mode.el
lisp/term.el
lisp/term/mac-win.el
lisp/term/w32-win.el
lisp/term/x-win.el
lisp/textmodes/fill.el
lisp/textmodes/ispell.el
lisp/textmodes/sgml-mode.el
lisp/time-stamp.el
lisp/version.el
lisp/w32-fns.el
lisp/wid-edit.el
make-dist
src/.gdbinit
src/ChangeLog
src/Makefile.in
src/abbrev.c
src/alloc.c
src/buffer.c
src/buffer.h
src/bytecode.c
src/callproc.c
src/casefiddle.c
src/casetab.c
src/category.c
src/category.h
src/ccl.c
src/ccl.h
src/charset.c
src/charset.h
src/cmds.c
src/coding.c
src/coding.h
src/composite.c
src/composite.h
src/config.in
src/data.c
src/dired.c
src/dispextern.h
src/dispnew.c
src/disptab.h
src/doc.c
src/doprnt.c
src/dosfns.c
src/editfns.c
src/emacs.c
src/fileio.c
src/filelock.c
src/fns.c
src/fontset.c
src/fontset.h
src/frame.c
src/frame.h
src/fringe.c
src/indent.c
src/insdel.c
src/intervals.c
src/intervals.h
src/keyboard.c
src/keymap.c
src/lisp.h
src/lread.c
src/macfns.c
src/macgui.h
src/macterm.c
src/makefile.w32-in
src/marker.c
src/minibuf.c
src/msdos.c
src/print.c
src/process.c
src/regex.c
src/regex.h
src/search.c
src/syntax.c
src/syntax.h
src/term.c
src/w16select.c
src/w32bdf.c
src/w32console.c
src/w32fns.c
src/w32select.c
src/w32term.c
src/w32term.h
src/window.c
src/xdisp.c
src/xfaces.c
src/xfns.c
src/xmenu.c
src/xrdb.c
src/xterm.c
src/xterm.h

diff --combined configure
index 3471c72f0decd36ca5f9982346eed97d55a452f2,cbde07567a2ebc37042fda313734a74390dc93a0..92347c927ec027bfbac0f920ec07ad4c9dcdfa27
+++ b/configure
@@@ -689,15 -689,6 +689,15 @@@ SET_MAK
  XMKMF
  GTK_CFLAGS
  GTK_LIBS
 +XFT_CFLAGS
 +XFT_LIBS
 +FREETYPE_CFLAGS
 +FREETYPE_LIBS
 +FONTCONFIG_CFLAGS
 +FONTCONFIG_LIBS
 +HAVE_LIBOTF
 +LIBOTF_CFLAGS
 +LIBOTF_LIBS
  ALLOCA
  liblockfile
  LIBOBJS
@@@ -1323,7 -1314,6 +1323,7 @@@ Optional Features
    --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
    --enable-carbon-app[=DIR]  [DIR=/Application]
                            specify install directory for Emacs.app on Mac OS X
 +  --enable-font-backend   compile code of font-backend support
    --enable-asserts        compile code with asserts enabled
    --enable-maintainer-mode enable make rules and dependencies not useful
                            (and sometimes confusing) to the casual installer
@@@ -1348,8 -1338,6 +1348,8 @@@ Optional Packages
    --with-tiff             use -ltiff for displaying TIFF images
    --with-gif              use -lungif for displaying GIF images
    --with-png              use -lpng for displaying PNG images
 +  --with-freetype         use -lfreetype for local fonts support
 +  --with-xft              use -lXft for anti aliased fonts
    --with-gtk              use GTK (same as --with-x-toolkit=gtk)
    --with-pkg-config-prog  Path to pkg-config to use for finding GTK
    --without-toolkit-scroll-bars
@@@ -1948,18 -1936,6 +1948,18 @@@ if test "${with_png+set}" = set; the
  fi
  
  
 +# Check whether --with-freetype was given.
 +if test "${with_freetype+set}" = set; then
 +  withval=$with_freetype;
 +fi
 +
 +
 +# Check whether --with-xft was given.
 +if test "${with_xft+set}" = set; then
 +  withval=$with_xft;
 +fi
 +
 +
  # Check whether --with-gtk was given.
  if test "${with_gtk+set}" = set; then
    withval=$with_gtk;
@@@ -1995,14 -1971,6 +1995,14 @@@ if test "${enable_carbon_app+set}" = se
  fi
  
  
 +# Check whether --enable-font-backend was given.
 +if test "${enable_font_backend+set}" = set; then
 +  enableval=$enable_font_backend; USE_FONT_BACKEND=$enableval
 +else
 +  USE_FONT_BACKEND=no
 +fi
 +
 +
  # Check whether --enable-asserts was given.
  if test "${enable_asserts+set}" = set; then
    enableval=$enable_asserts; USE_XASSERTS=$enableval
@@@ -2374,6 -2342,24 +2374,24 @@@ _ACEO
      machine=apollo opsys=bsd4-3
    ;;
  
+   ## Apple Darwin / Mac OS X
+   *-apple-darwin* )
+     case "${canonical}" in
+       i[3456]86-* )  machine=intel386 ;;
+       powerpc-* )    machine=powermac ;;
+       * )            unported=yes ;;
+     esac
+     opsys=darwin
+     # Define CPP as follows to make autoconf work correctly.
+     CPP="${CC-cc} -E -no-cpp-precomp"
+     # Use fink packages if available.
+     if test -d /sw/include && test -d /sw/lib; then
+       GCC_TEST_OPTIONS="-I/sw/include -L/sw/lib"
+       CPP="${CPP} ${GCC_TEST_OPTIONS}"
+       NON_GCC_TEST_OPTIONS=${GCC_TEST_OPTIONS}
+     fi
+   ;;
    ## AT&T 3b2, 3b5, 3b15, 3b20
    we32k-att-sysv* )
      machine=att3b opsys=usg5-2-2
      machine=f301 opsys=uxpv
    ;;
  
-   ## Darwin / Mac OS X
-   powerpc-apple-darwin* )
-     machine=powermac opsys=darwin
-     # Define CPP as follows to make autoconf work correctly.
-     CPP="${CC-cc} -E -no-cpp-precomp"
-     # Use fink packages if available.
-     if test -d /sw/include && test -d /sw/lib; then
-       GCC_TEST_OPTIONS="-I/sw/include -L/sw/lib"
-         CPP="${CPP} ${GCC_TEST_OPTIONS}"
-       NON_GCC_TEST_OPTIONS=${GCC_TEST_OPTIONS}
-     fi
-   ;;
    ## AMD x86-64 Linux-based GNU system
    x86_64-*-linux-gnu* )
      machine=amdx86-64 opsys=gnu-linux
  
    fi
    CFLAGS=$late_CFLAGS
 +fi
 +
 +### For font-backend
 +if test "${USE_FONT_BACKEND}" = "yes"; then
 +
 +
 +cat >>confdefs.h <<\_ACEOF
 +#define USE_FONT_BACKEND 1
 +_ACEOF
 +
 +
 +### Use -lXft if available, unless `--with-freetype=no' nor `--with-xft=no'.
 +HAVE_XFT=maybe
 +if test "${HAVE_X11}" = "yes"; then
 +  if test "x${with_freetype}" = "xno"; then
 +    with_xft="no";
 +  fi
 +  if test "x${with_xft}" != "xno"; then
 +
 +        if test "X${with_pkg_config_prog}" != X; then
 +      PKG_CONFIG="${with_pkg_config_prog}"
 +    fi
 +
 +
 +  succeeded=no
 +
 +  if test -z "$PKG_CONFIG"; then
 +    # Extract the first word of "pkg-config", so it can be a program name with args.
 +set dummy pkg-config; ac_word=$2
 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5
 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
 +  echo $ECHO_N "(cached) $ECHO_C" >&6
 +else
 +  case $PKG_CONFIG in
 +  [\\/]* | ?:[\\/]*)
 +  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
 +  ;;
 +  *)
 +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 +for as_dir in $PATH
 +do
 +  IFS=$as_save_IFS
 +  test -z "$as_dir" && as_dir=.
 +  for ac_exec_ext in '' $ac_executable_extensions; do
 +  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
 +    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
 +    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
 +    break 2
 +  fi
 +done
 +done
 +IFS=$as_save_IFS
 +
 +  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
 +  ;;
 +esac
 +fi
 +PKG_CONFIG=$ac_cv_path_PKG_CONFIG
 +if test -n "$PKG_CONFIG"; then
 +  { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
 +echo "${ECHO_T}$PKG_CONFIG" >&6; }
 +else
 +  { echo "$as_me:$LINENO: result: no" >&5
 +echo "${ECHO_T}no" >&6; }
 +fi
 +
 +
 +  fi
 +
 +  if test "$PKG_CONFIG" = "no" ; then
 +     HAVE_XFT=no
 +  else
 +     PKG_CONFIG_MIN_VERSION=0.9.0
 +     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
 +        { echo "$as_me:$LINENO: checking for xft >= 0.13.0" >&5
 +echo $ECHO_N "checking for xft >= 0.13.0... $ECHO_C" >&6; }
 +
 +        if $PKG_CONFIG --exists "xft >= 0.13.0" 2>&5; then
 +            { echo "$as_me:$LINENO: result: yes" >&5
 +echo "${ECHO_T}yes" >&6; }
 +            succeeded=yes
 +
 +            { echo "$as_me:$LINENO: checking XFT_CFLAGS" >&5
 +echo $ECHO_N "checking XFT_CFLAGS... $ECHO_C" >&6; }
 +            XFT_CFLAGS=`$PKG_CONFIG --cflags "xft >= 0.13.0"`
 +            { echo "$as_me:$LINENO: result: $XFT_CFLAGS" >&5
 +echo "${ECHO_T}$XFT_CFLAGS" >&6; }
 +
 +            { echo "$as_me:$LINENO: checking XFT_LIBS" >&5
 +echo $ECHO_N "checking XFT_LIBS... $ECHO_C" >&6; }
 +            XFT_LIBS=`$PKG_CONFIG --libs "xft >= 0.13.0"`
 +            { echo "$as_me:$LINENO: result: $XFT_LIBS" >&5
 +echo "${ECHO_T}$XFT_LIBS" >&6; }
 +        else
 +            { echo "$as_me:$LINENO: result: no" >&5
 +echo "${ECHO_T}no" >&6; }
 +            XFT_CFLAGS=""
 +            XFT_LIBS=""
 +            ## If we have a custom action on failure, don't print errors, but
 +            ## do set a variable so people can do so.
 +            XFT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "xft >= 0.13.0"`
 +
 +        fi
 +
 +
 +
 +     else
 +        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
 +        echo "*** See http://www.freedesktop.org/software/pkgconfig"
 +     fi
 +  fi
 +
 +  if test $succeeded = yes; then
 +     :
 +  else
 +     HAVE_XFT=no
 +  fi
 +
 +    if test "$HAVE_XFT" != no; then
 +      OLD_CPPFLAGS="$CPPFLAGS"
 +      OLD_CFLAGS="$CFLAGS"
 +      OLD_LIBS="$LIBS"
 +      CPPFLAGS="$CPPFLAGS $XFT_CFLAGS"
 +      CFLAGS="$CFLAGS $XFT_CFLAGS"
 +      LIBS="$XFT_LIBS $LIBS"
 +      if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
 +  { echo "$as_me:$LINENO: checking for X11/Xft/Xft.h" >&5
 +echo $ECHO_N "checking for X11/Xft/Xft.h... $ECHO_C" >&6; }
 +if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
 +  echo $ECHO_N "(cached) $ECHO_C" >&6
 +fi
 +{ echo "$as_me:$LINENO: result: $ac_cv_header_X11_Xft_Xft_h" >&5
 +echo "${ECHO_T}$ac_cv_header_X11_Xft_Xft_h" >&6; }
 +else
 +  # Is the header compilable?
 +{ echo "$as_me:$LINENO: checking X11/Xft/Xft.h usability" >&5
 +echo $ECHO_N "checking X11/Xft/Xft.h usability... $ECHO_C" >&6; }
 +cat >conftest.$ac_ext <<_ACEOF
 +/* confdefs.h.  */
 +_ACEOF
 +cat confdefs.h >>conftest.$ac_ext
 +cat >>conftest.$ac_ext <<_ACEOF
 +/* end confdefs.h.  */
 +$ac_includes_default
 +#include <X11/Xft/Xft.h>
 +_ACEOF
 +rm -f conftest.$ac_objext
 +if { (ac_try="$ac_compile"
 +case "(($ac_try" in
 +  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
 +  *) ac_try_echo=$ac_try;;
 +esac
 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
 +  (eval "$ac_compile") 2>conftest.er1
 +  ac_status=$?
 +  grep -v '^ *+' conftest.er1 >conftest.err
 +  rm -f conftest.er1
 +  cat conftest.err >&5
 +  echo "$as_me:$LINENO: \$? = $ac_status" >&5
 +  (exit $ac_status); } && {
 +       test -z "$ac_c_werror_flag" ||
 +       test ! -s conftest.err
 +       } && test -s conftest.$ac_objext; then
 +  ac_header_compiler=yes
 +else
 +  echo "$as_me: failed program was:" >&5
 +sed 's/^/| /' conftest.$ac_ext >&5
 +
 +      ac_header_compiler=no
 +fi
 +
 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
 +echo "${ECHO_T}$ac_header_compiler" >&6; }
 +
 +# Is the header present?
 +{ echo "$as_me:$LINENO: checking X11/Xft/Xft.h presence" >&5
 +echo $ECHO_N "checking X11/Xft/Xft.h presence... $ECHO_C" >&6; }
 +cat >conftest.$ac_ext <<_ACEOF
 +/* confdefs.h.  */
 +_ACEOF
 +cat confdefs.h >>conftest.$ac_ext
 +cat >>conftest.$ac_ext <<_ACEOF
 +/* end confdefs.h.  */
 +#include <X11/Xft/Xft.h>
 +_ACEOF
 +if { (ac_try="$ac_cpp conftest.$ac_ext"
 +case "(($ac_try" in
 +  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
 +  *) ac_try_echo=$ac_try;;
 +esac
 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
 +  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
 +  ac_status=$?
 +  grep -v '^ *+' conftest.er1 >conftest.err
 +  rm -f conftest.er1
 +  cat conftest.err >&5
 +  echo "$as_me:$LINENO: \$? = $ac_status" >&5
 +  (exit $ac_status); } >/dev/null && {
 +       test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
 +       test ! -s conftest.err
 +       }; then
 +  ac_header_preproc=yes
 +else
 +  echo "$as_me: failed program was:" >&5
 +sed 's/^/| /' conftest.$ac_ext >&5
 +
 +  ac_header_preproc=no
 +fi
 +
 +rm -f conftest.err conftest.$ac_ext
 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
 +echo "${ECHO_T}$ac_header_preproc" >&6; }
 +
 +# So?  What about this header?
 +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
 +  yes:no: )
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: accepted by the compiler, rejected by the preprocessor!" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: proceeding with the compiler's result" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h: proceeding with the compiler's result" >&2;}
 +    ac_header_preproc=yes
 +    ;;
 +  no:yes:* )
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: present but cannot be compiled" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h: present but cannot be compiled" >&2;}
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h:     check for missing prerequisite headers?" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h:     check for missing prerequisite headers?" >&2;}
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: see the Autoconf documentation" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h: see the Autoconf documentation" >&2;}
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h:     section \"Present But Cannot Be Compiled\"" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h:     section \"Present But Cannot Be Compiled\"" >&2;}
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: proceeding with the preprocessor's result" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h: proceeding with the preprocessor's result" >&2;}
 +    { echo "$as_me:$LINENO: WARNING: X11/Xft/Xft.h: in the future, the compiler will take precedence" >&5
 +echo "$as_me: WARNING: X11/Xft/Xft.h: in the future, the compiler will take precedence" >&2;}
 +
 +    ;;
 +esac
 +{ echo "$as_me:$LINENO: checking for X11/Xft/Xft.h" >&5
 +echo $ECHO_N "checking for X11/Xft/Xft.h... $ECHO_C" >&6; }
 +if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
 +  echo $ECHO_N "(cached) $ECHO_C" >&6
 +else
 +  ac_cv_header_X11_Xft_Xft_h=$ac_header_preproc
 +fi
 +{ echo "$as_me:$LINENO: result: $ac_cv_header_X11_Xft_Xft_h" >&5
 +echo "${ECHO_T}$ac_cv_header_X11_Xft_Xft_h" >&6; }
 +
 +fi
 +if test $ac_cv_header_X11_Xft_Xft_h = yes; then
 +  { echo "$as_me:$LINENO: checking for XftFontOpen in -lXft" >&5
 +echo $ECHO_N "checking for XftFontOpen in -lXft... $ECHO_C" >&6; }
 +if test "${ac_cv_lib_Xft_XftFontOpen+set}" = set; then
 +  echo $ECHO_N "(cached) $ECHO_C" >&6
 +else
 +  ac_check_lib_save_LIBS=$LIBS
 +LIBS="-lXft $XFT_LIBS $LIBS"
 +cat >conftest.$ac_ext <<_ACEOF
 +/* confdefs.h.  */
 +_ACEOF
 +cat confdefs.h >>conftest.$ac_ext
 +cat >>conftest.$ac_ext <<_ACEOF
 +/* end confdefs.h.  */
 +
 +/* Override any GCC internal prototype to avoid an error.
 +   Use char because int might match the return type of a GCC
 +   builtin and then its argument prototype would still apply.  */
 +#ifdef __cplusplus
 +extern "C"
 +#endif
 +char XftFontOpen ();
 +int
 +main ()
 +{
 +return XftFontOpen ();
 +  ;
 +  return 0;
 +}
 +_ACEOF
 +rm -f conftest.$ac_objext conftest$ac_exeext
 +if { (ac_try="$ac_link"
 +case "(($ac_try" in
 +  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
 +  *) ac_try_echo=$ac_try;;
 +esac
 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
 +  (eval "$ac_link") 2>conftest.er1
 +  ac_status=$?
 +  grep -v '^ *+' conftest.er1 >conftest.err
 +  rm -f conftest.er1
 +  cat conftest.err >&5
 +  echo "$as_me:$LINENO: \$? = $ac_status" >&5
 +  (exit $ac_status); } && {
 +       test -z "$ac_c_werror_flag" ||
 +       test ! -s conftest.err
 +       } && test -s conftest$ac_exeext &&
 +       $as_test_x conftest$ac_exeext; then
 +  ac_cv_lib_Xft_XftFontOpen=yes
 +else
 +  echo "$as_me: failed program was:" >&5
 +sed 's/^/| /' conftest.$ac_ext >&5
 +
 +      ac_cv_lib_Xft_XftFontOpen=no
 +fi
 +
 +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
 +      conftest$ac_exeext conftest.$ac_ext
 +LIBS=$ac_check_lib_save_LIBS
 +fi
 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_Xft_XftFontOpen" >&5
 +echo "${ECHO_T}$ac_cv_lib_Xft_XftFontOpen" >&6; }
 +if test $ac_cv_lib_Xft_XftFontOpen = yes; then
 +  HAVE_XFT=yes
 +fi
 +
 +fi
 +
 +
 +
 +      if test "${HAVE_XFT}" = "yes"; then
 +
 +cat >>confdefs.h <<\_ACEOF
 +#define HAVE_XFT 1
 +_ACEOF
 +
 +
 +        C_SWITCH_X_SITE="$C_SWITCH_X_SITE $XFT_CFLAGS"
 +      else
 +        CFLAGS="$OLD_CPPFLAGS"
 +        CFLAGS="$OLD_CFLAGS"
 +        LIBS="$OLD_LIBS"
 +      fi
 +    fi
 +  fi
 +fi
 +
 +HAVE_FREETYPE=no
 +### Use -lfreetype if available, unless `--with-freetype=no'.
 +if test "${HAVE_XFT}" = "yes"; then
 +      HAVE_FREETYPE=yes
 +elif test "x${with_freetype}" != "xno"; then
 +    if test "X${with_pkg_config_prog}" != X; then
 +    PKG_CONFIG="${with_pkg_config_prog}"
 +  fi
 +
 +
 +  succeeded=no
 +
 +  if test -z "$PKG_CONFIG"; then
 +    # Extract the first word of "pkg-config", so it can be a program name with args.
 +set dummy pkg-config; ac_word=$2
 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5
 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
 +  echo $ECHO_N "(cached) $ECHO_C" >&6
 +else
 +  case $PKG_CONFIG in
 +  [\\/]* | ?:[\\/]*)
 +  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
 +  ;;
 +  *)
 +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 +for as_dir in $PATH
 +do
 +  IFS=$as_save_IFS
 +  test -z "$as_dir" && as_dir=.
 +  for ac_exec_ext in '' $ac_executable_extensions; do
 +  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
 +    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
 +    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
 +    break 2
 +  fi
 +done
 +done
 +IFS=$as_save_IFS
 +
 +  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
 +  ;;
 +esac
 +fi
 +PKG_CONFIG=$ac_cv_path_PKG_CONFIG
 +if test -n "$PKG_CONFIG"; then
 +  { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
 +echo "${ECHO_T}$PKG_CONFIG" >&6; }
 +else
 +  { echo "$as_me:$LINENO: result: no" >&5
 +echo "${ECHO_T}no" >&6; }
 +fi
 +
 +
 +  fi
 +
 +  if test "$PKG_CONFIG" = "no" ; then
 +     HAVE_FREETYPE=no
 +  else
 +     PKG_CONFIG_MIN_VERSION=0.9.0
 +     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
 +        { echo "$as_me:$LINENO: checking for freetype2" >&5
 +echo $ECHO_N "checking for freetype2... $ECHO_C" >&6; }
 +
 +        if $PKG_CONFIG --exists "freetype2" 2>&5; then
 +            { echo "$as_me:$LINENO: result: yes" >&5
 +echo "${ECHO_T}yes" >&6; }
 +            succeeded=yes
 +
 +            { echo "$as_me:$LINENO: checking FREETYPE_CFLAGS" >&5
 +echo $ECHO_N "checking FREETYPE_CFLAGS... $ECHO_C" >&6; }
 +            FREETYPE_CFLAGS=`$PKG_CONFIG --cflags "freetype2"`
 +            { echo "$as_me:$LINENO: result: $FREETYPE_CFLAGS" >&5
 +echo "${ECHO_T}$FREETYPE_CFLAGS" >&6; }
 +
 +            { echo "$as_me:$LINENO: checking FREETYPE_LIBS" >&5
 +echo $ECHO_N "checking FREETYPE_LIBS... $ECHO_C" >&6; }
 +            FREETYPE_LIBS=`$PKG_CONFIG --libs "freetype2"`
 +            { echo "$as_me:$LINENO: result: $FREETYPE_LIBS" >&5
 +echo "${ECHO_T}$FREETYPE_LIBS" >&6; }
 +        else
 +            { echo "$as_me:$LINENO: result: no" >&5
 +echo "${ECHO_T}no" >&6; }
 +            FREETYPE_CFLAGS=""
 +            FREETYPE_LIBS=""
 +            ## If we have a custom action on failure, don't print errors, but
 +            ## do set a variable so people can do so.
 +            FREETYPE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "freetype2"`
 +
 +        fi
 +
 +
 +
 +     else
 +        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
 +        echo "*** See http://www.freedesktop.org/software/pkgconfig"
 +     fi
 +  fi
 +
 +  if test $succeeded = yes; then
 +     HAVE_FREETYPE=yes
 +  else
 +     HAVE_FREETYPE=no
 +  fi
 +
 +  if test "${HAVE_FREETYPE}" = "yes"; then
 +
 +  succeeded=no
 +
 +  if test -z "$PKG_CONFIG"; then
 +    # Extract the first word of "pkg-config", so it can be a program name with args.
 +set dummy pkg-config; ac_word=$2
 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5
 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
 +  echo $ECHO_N "(cached) $ECHO_C" >&6
 +else
 +  case $PKG_CONFIG in
 +  [\\/]* | ?:[\\/]*)
 +  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
 +  ;;
 +  *)
 +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 +for as_dir in $PATH
 +do
 +  IFS=$as_save_IFS
 +  test -z "$as_dir" && as_dir=.
 +  for ac_exec_ext in '' $ac_executable_extensions; do
 +  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
 +    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
 +    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
 +    break 2
 +  fi
 +done
 +done
 +IFS=$as_save_IFS
 +
 +  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
 +  ;;
 +esac
 +fi
 +PKG_CONFIG=$ac_cv_path_PKG_CONFIG
 +if test -n "$PKG_CONFIG"; then
 +  { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
 +echo "${ECHO_T}$PKG_CONFIG" >&6; }
 +else
 +  { echo "$as_me:$LINENO: result: no" >&5
 +echo "${ECHO_T}no" >&6; }
 +fi
 +
 +
 +  fi
 +
 +  if test "$PKG_CONFIG" = "no" ; then
 +     HAVE_FC=no
 +  else
 +     PKG_CONFIG_MIN_VERSION=0.9.0
 +     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
 +        { echo "$as_me:$LINENO: checking for fontconfig" >&5
 +echo $ECHO_N "checking for fontconfig... $ECHO_C" >&6; }
 +
 +        if $PKG_CONFIG --exists "fontconfig" 2>&5; then
 +            { echo "$as_me:$LINENO: result: yes" >&5
 +echo "${ECHO_T}yes" >&6; }
 +            succeeded=yes
 +
 +            { echo "$as_me:$LINENO: checking FONTCONFIG_CFLAGS" >&5
 +echo $ECHO_N "checking FONTCONFIG_CFLAGS... $ECHO_C" >&6; }
 +            FONTCONFIG_CFLAGS=`$PKG_CONFIG --cflags "fontconfig"`
 +            { echo "$as_me:$LINENO: result: $FONTCONFIG_CFLAGS" >&5
 +echo "${ECHO_T}$FONTCONFIG_CFLAGS" >&6; }
 +
 +            { echo "$as_me:$LINENO: checking FONTCONFIG_LIBS" >&5
 +echo $ECHO_N "checking FONTCONFIG_LIBS... $ECHO_C" >&6; }
 +            FONTCONFIG_LIBS=`$PKG_CONFIG --libs "fontconfig"`
 +            { echo "$as_me:$LINENO: result: $FONTCONFIG_LIBS" >&5
 +echo "${ECHO_T}$FONTCONFIG_LIBS" >&6; }
 +        else
 +            { echo "$as_me:$LINENO: result: no" >&5
 +echo "${ECHO_T}no" >&6; }
 +            FONTCONFIG_CFLAGS=""
 +            FONTCONFIG_LIBS=""
 +            ## If we have a custom action on failure, don't print errors, but
 +            ## do set a variable so people can do so.
 +            FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "fontconfig"`
 +
 +        fi
 +
 +
 +
 +     else
 +        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
 +        echo "*** See http://www.freedesktop.org/software/pkgconfig"
 +     fi
 +  fi
 +
 +  if test $succeeded = yes; then
 +     HAVE_FC=yes
 +  else
 +     HAVE_FC=no
 +  fi
 +
 +    if test "${HAVE_FC}" = "no"; then
 +            HAVE_FREETYPE=no
 +    fi
 +  fi
 +fi
 +if test "${HAVE_FREETYPE}" = "yes"; then
 +
 +cat >>confdefs.h <<\_ACEOF
 +#define HAVE_FREETYPE 1
 +_ACEOF
 +
 +  # Extract the first word of "libotf-config", so it can be a program name with args.
 +set dummy libotf-config; ac_word=$2
 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5
 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 +if test "${ac_cv_prog_HAVE_LIBOTF+set}" = set; then
 +  echo $ECHO_N "(cached) $ECHO_C" >&6
 +else
 +  if test -n "$HAVE_LIBOTF"; then
 +  ac_cv_prog_HAVE_LIBOTF="$HAVE_LIBOTF" # Let the user override the test.
 +else
 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 +for as_dir in $PATH
 +do
 +  IFS=$as_save_IFS
 +  test -z "$as_dir" && as_dir=.
 +  for ac_exec_ext in '' $ac_executable_extensions; do
 +  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
 +    ac_cv_prog_HAVE_LIBOTF="yes"
 +    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
 +    break 2
 +  fi
 +done
 +done
 +IFS=$as_save_IFS
 +
 +  test -z "$ac_cv_prog_HAVE_LIBOTF" && ac_cv_prog_HAVE_LIBOTF="no"
 +fi
 +fi
 +HAVE_LIBOTF=$ac_cv_prog_HAVE_LIBOTF
 +if test -n "$HAVE_LIBOTF"; then
 +  { echo "$as_me:$LINENO: result: $HAVE_LIBOTF" >&5
 +echo "${ECHO_T}$HAVE_LIBOTF" >&6; }
 +else
 +  { echo "$as_me:$LINENO: result: no" >&5
 +echo "${ECHO_T}no" >&6; }
 +fi
 +
 +
 +  if test "${HAVE_LIBOTF}" = "yes"; then
 +
 +cat >>confdefs.h <<\_ACEOF
 +#define HAVE_LIBOTF 1
 +_ACEOF
 +
 +    LIBOTF_CFLAGS=`libotf-config --cflags`
 +    LIBOTF_LIBS=`libotf-config --libs`
 +  fi
 +fi
 +
 +
 +
 +
 +
 +
 +
  fi
  
  ### Use -lXpm if available, unless `--with-xpm=no'.
@@@ -24139,15 -23506,6 +24144,15 @@@ SET_MAKE!$SET_MAKE$ac_deli
  XMKMF!$XMKMF$ac_delim
  GTK_CFLAGS!$GTK_CFLAGS$ac_delim
  GTK_LIBS!$GTK_LIBS$ac_delim
 +XFT_CFLAGS!$XFT_CFLAGS$ac_delim
 +XFT_LIBS!$XFT_LIBS$ac_delim
 +FREETYPE_CFLAGS!$FREETYPE_CFLAGS$ac_delim
 +FREETYPE_LIBS!$FREETYPE_LIBS$ac_delim
 +FONTCONFIG_CFLAGS!$FONTCONFIG_CFLAGS$ac_delim
 +FONTCONFIG_LIBS!$FONTCONFIG_LIBS$ac_delim
 +HAVE_LIBOTF!$HAVE_LIBOTF$ac_delim
 +LIBOTF_CFLAGS!$LIBOTF_CFLAGS$ac_delim
 +LIBOTF_LIBS!$LIBOTF_LIBS$ac_delim
  ALLOCA!$ALLOCA$ac_delim
  liblockfile!$liblockfile$ac_delim
  LIBOBJS!$LIBOBJS$ac_delim
@@@ -24164,6 -23522,15 +24169,6 @@@ lispdir!$lispdir$ac_deli
  locallisppath!$locallisppath$ac_delim
  lisppath!$lisppath$ac_delim
  x_default_search_path!$x_default_search_path$ac_delim
 -etcdir!$etcdir$ac_delim
 -archlibdir!$archlibdir$ac_delim
 -bitmapdir!$bitmapdir$ac_delim
 -gamedir!$gamedir$ac_delim
 -gameuser!$gameuser$ac_delim
 -c_switch_system!$c_switch_system$ac_delim
 -c_switch_machine!$c_switch_machine$ac_delim
 -LD_SWITCH_X_SITE!$LD_SWITCH_X_SITE$ac_delim
 -LD_SWITCH_X_SITE_AUX!$LD_SWITCH_X_SITE_AUX$ac_delim
  _ACEOF
  
    if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
  ac_delim='%!_!# '
  for ac_last_try in false false false false false :; do
    cat >conf$$subs.sed <<_ACEOF
 +etcdir!$etcdir$ac_delim
 +archlibdir!$archlibdir$ac_delim
 +bitmapdir!$bitmapdir$ac_delim
 +gamedir!$gamedir$ac_delim
 +gameuser!$gameuser$ac_delim
 +c_switch_system!$c_switch_system$ac_delim
 +c_switch_machine!$c_switch_machine$ac_delim
 +LD_SWITCH_X_SITE!$LD_SWITCH_X_SITE$ac_delim
 +LD_SWITCH_X_SITE_AUX!$LD_SWITCH_X_SITE_AUX$ac_delim
  C_SWITCH_X_SITE!$C_SWITCH_X_SITE$ac_delim
  X_TOOLKIT_TYPE!$X_TOOLKIT_TYPE$ac_delim
  machfile!$machfile$ac_delim
@@@ -24222,7 -23580,7 +24227,7 @@@ carbon_appdir!$carbon_appdir$ac_deli
  LTLIBOBJS!$LTLIBOBJS$ac_delim
  _ACEOF
  
 -  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 6; then
 +  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 15; then
      break
    elif $ac_last_try; then
      { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@@ -24681,9 -24039,6 +24686,9 @@@ echo creating src/Makefil
    sed -e '1,/start of cpp stuff/d'\
        -e 's,/\*\*/#\(.*\)$,/* \1 */,' \
        < Makefile.c > junk.c
 +  if test -f ${srcdir}/admin/unidata/UnicodeData.txt; then
 +    CPPFLAGS="$CPPFLAGS -DHAVE_UNIDATA"
 +  fi
    $CPP $undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
        sed -e 's/^ /   /' -e '/^#/d' -e '/^[   \f]*$/d' > junk2.c
    cat junk1.c junk2.c > Makefile.new
diff --combined configure.in
index e4ebaf0ca7796a40ace65216968333a5ed2e2c52,ceed242cd492b4e11d6bfb6f662b9539edbacbb6..6d1f883c07bfbff2277a602c6ba131a778855043
@@@ -3,7 -3,7 +3,7 @@@ dnl To rebuild the `configure' script f
  dnl   autoconf
  dnl in the directory containing this script.
  dnl
- dnl  Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ dnl  Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  dnl  Free Software Foundation, Inc.
  dnl
  dnl  This file is part of GNU Emacs.
@@@ -109,10 -109,6 +109,10 @@@ AC_ARG_WITH(gif
  [  --with-gif              use -lungif for displaying GIF images])
  AC_ARG_WITH(png,
  [  --with-png              use -lpng for displaying PNG images])
 +AC_ARG_WITH(freetype,
 +[  --with-freetype         use -lfreetype for local fonts support])
 +AC_ARG_WITH(xft,
 +[  --with-xft              use -lXft for anti aliased fonts])
  AC_ARG_WITH(gtk,
  [  --with-gtk              use GTK (same as --with-x-toolkit=gtk)])
  AC_ARG_WITH(pkg-config-prog,
@@@ -129,11 -125,6 +129,11 @@@ AC_ARG_ENABLE(carbon-app
                            specify install directory for Emacs.app on Mac OS X]],
  [ carbon_appdir_x=${enableval}])
  
 +AC_ARG_ENABLE(font-backend,
 +[  --enable-font-backend   compile code of font-backend support],
 +      USE_FONT_BACKEND=$enableval,
 +      USE_FONT_BACKEND=no)
 +
  AC_ARG_ENABLE(asserts,
  [  --enable-asserts        compile code with asserts enabled],
        USE_XASSERTS=$enableval,
@@@ -387,6 -378,24 +387,24 @@@ dnl see the `changequote' comment above
      machine=apollo opsys=bsd4-3
    ;;
  
+   ## Apple Darwin / Mac OS X
+   *-apple-darwin* )
+     case "${canonical}" in
+       i[3456]86-* )  machine=intel386 ;;
+       powerpc-* )    machine=powermac ;;
+       * )            unported=yes ;;
+     esac
+     opsys=darwin
+     # Define CPP as follows to make autoconf work correctly.
+     CPP="${CC-cc} -E -no-cpp-precomp"
+     # Use fink packages if available.
+     if test -d /sw/include && test -d /sw/lib; then
+       GCC_TEST_OPTIONS="-I/sw/include -L/sw/lib"
+       CPP="${CPP} ${GCC_TEST_OPTIONS}"
+       NON_GCC_TEST_OPTIONS=${GCC_TEST_OPTIONS}
+     fi
+   ;;
    ## AT&T 3b2, 3b5, 3b15, 3b20
    we32k-att-sysv* )
      machine=att3b opsys=usg5-2-2
      machine=f301 opsys=uxpv
    ;;
  
-   ## Darwin / Mac OS X
-   powerpc-apple-darwin* )
-     machine=powermac opsys=darwin
-     # Define CPP as follows to make autoconf work correctly.
-     CPP="${CC-cc} -E -no-cpp-precomp"
-     # Use fink packages if available.
-     if test -d /sw/include && test -d /sw/lib; then
-       GCC_TEST_OPTIONS="-I/sw/include -L/sw/lib"
-         CPP="${CPP} ${GCC_TEST_OPTIONS}"
-       NON_GCC_TEST_OPTIONS=${GCC_TEST_OPTIONS}
-     fi
-   ;;
    ## AMD x86-64 Linux-based GNU system
    x86_64-*-linux-gnu* )
      machine=amdx86-64 opsys=gnu-linux
@@@ -2354,90 -2350,6 +2359,90 @@@ either XPointer or XPointer*.])dn
    CFLAGS=$late_CFLAGS
  fi
  
 +### For font-backend
 +if test "${USE_FONT_BACKEND}" = "yes"; then
 +
 +AC_DEFINE(USE_FONT_BACKEND, 1,
 +          [Define to 1 if we should use font-backend.])
 +
 +### Use -lXft if available, unless `--with-freetype=no' nor `--with-xft=no'.
 +HAVE_XFT=maybe
 +if test "${HAVE_X11}" = "yes"; then
 +  if test "x${with_freetype}" = "xno"; then
 +    with_xft="no";
 +  fi
 +  if test "x${with_xft}" != "xno"; then
 +
 +    dnl Check if --with-pkg-config-prog has been given.
 +    if test "X${with_pkg_config_prog}" != X; then
 +      PKG_CONFIG="${with_pkg_config_prog}"
 +    fi
 +
 +    PKG_CHECK_MODULES(XFT, xft >= 0.13.0, , HAVE_XFT=no)
 +    if test "$HAVE_XFT" != no; then
 +      OLD_CPPFLAGS="$CPPFLAGS"
 +      OLD_CFLAGS="$CFLAGS"
 +      OLD_LIBS="$LIBS"
 +      CPPFLAGS="$CPPFLAGS $XFT_CFLAGS"
 +      CFLAGS="$CFLAGS $XFT_CFLAGS"
 +      LIBS="$XFT_LIBS $LIBS"
 +      AC_CHECK_HEADER(X11/Xft/Xft.h,
 +        AC_CHECK_LIB(Xft, XftFontOpen, HAVE_XFT=yes, , $XFT_LIBS))
 +
 +      if test "${HAVE_XFT}" = "yes"; then
 +        AC_DEFINE(HAVE_XFT, 1, [Define to 1 if you have the Xft library.])
 +      AC_SUBST(XFT_LIBS)
 +        C_SWITCH_X_SITE="$C_SWITCH_X_SITE $XFT_CFLAGS"
 +      else
 +        CFLAGS="$OLD_CPPFLAGS"
 +        CFLAGS="$OLD_CFLAGS"
 +        LIBS="$OLD_LIBS"
 +      fi
 +    fi
 +  fi
 +fi
 +
 +HAVE_FREETYPE=no
 +### Use -lfreetype if available, unless `--with-freetype=no'.
 +if test "${HAVE_XFT}" = "yes"; then
 +  dnl As we use Xft, we anyway use freetype.
 +  dnl In this case, there's no need of additional CFLAGS and LIBS.
 +  HAVE_FREETYPE=yes
 +elif test "x${with_freetype}" != "xno"; then
 +  dnl Check if --with-pkg-config-prog has been given.
 +  if test "X${with_pkg_config_prog}" != X; then
 +    PKG_CONFIG="${with_pkg_config_prog}"
 +  fi
 +
 +  PKG_CHECK_MODULES(FREETYPE, freetype2, HAVE_FREETYPE=yes, HAVE_FREETYPE=no)
 +  if test "${HAVE_FREETYPE}" = "yes"; then
 +    PKG_CHECK_MODULES(FONTCONFIG, fontconfig, HAVE_FC=yes, HAVE_FC=no)
 +    if test "${HAVE_FC}" = "no"; then
 +      dnl Witout fontconfig, we can't use freetype at the moment.
 +      HAVE_FREETYPE=no
 +    fi
 +  fi
 +fi
 +if test "${HAVE_FREETYPE}" = "yes"; then
 +  AC_DEFINE(HAVE_FREETYPE, 1,
 +           [Define to 1 if you have freetype and fontconfig libraries.])
 +  AC_CHECK_PROG(HAVE_LIBOTF, libotf-config, yes, no)
 +  if test "${HAVE_LIBOTF}" = "yes"; then
 +    AC_DEFINE(HAVE_LIBOTF, 1,
 +             [Define to 1 if you have libotf library.])
 +    LIBOTF_CFLAGS=`libotf-config --cflags`
 +    LIBOTF_LIBS=`libotf-config --libs`
 +  fi
 +fi
 +AC_SUBST(FREETYPE_CFLAGS)
 +AC_SUBST(FREETYPE_LIBS)
 +AC_SUBST(FONTCONFIG_CFLAGS)
 +AC_SUBST(FONTCONFIG_LIBS)
 +AC_SUBST(LIBOTF_CFLAGS)
 +AC_SUBST(LIBOTF_LIBS)
 +
 +fi
 +
  ### Use -lXpm if available, unless `--with-xpm=no'.
  HAVE_XPM=no
  if test "${HAVE_X11}" = "yes"; then
@@@ -2969,7 -2881,7 +2974,7 @@@ if test "${REL_ALLOC}" = "yes" ; the
  fi
  
  AH_TOP([/* GNU Emacs site configuration template file.
-    Copyright (C) 1988, 1993, 1994, 1999, 2000, 2001, 2002, 2004, 2005, 2006
+    Copyright (C) 1988, 1993, 1994, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
               Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
@@@ -3382,9 -3294,6 +3387,9 @@@ echo creating src/Makefil
    sed -e '1,/start of cpp stuff/d'\
        -e 's,/\*\*/#\(.*\)$,/* \1 */,' \
        < Makefile.c > junk.c
 +  if test -f ${srcdir}/admin/unidata/UnicodeData.txt; then
 +    CPPFLAGS="$CPPFLAGS -DHAVE_UNIDATA"
 +  fi
    $CPP $undefs -I. -I$srcdir/src $CPPFLAGS junk.c | \
        sed -e 's/^ /   /' -e '/^#/d' -e '/^[   \f]*$/d' > junk2.c
    cat junk1.c junk2.c > Makefile.new
diff --combined etc/HELLO
index 821159be4bfc65d0be31646161f9648dc2ce0172,45156f245e9928195fce96c91a94d5d4d93ccc08..d62838ebf09813c82af5de3d9c8f83c2b9c5755e
+++ b/etc/HELLO
@@@ -5,8 -5,8 +5,8 @@@ Non-ASCII examples
            Cze\e,B6f\e(B!, Dobr\e,B}\e(B den, \e,L7T`PRabRcYbU\e(B!, \e,FCei\\e(B \e,Fsar\e(B, \e$,1J2J0J;J0J@JOJ=J1J0\e(B
    Africa: \e$(3!A!,!>\e(B
    Middle/Near East: \e,Hylem\e(B, \e(38R\e(47d\e(3T!JSa\e(4W\e(3W\e(B
 -  South Asia: \e4\e$,4!8v#")\e0\e$,15h\e1\e4\e$,4!hv#")\e0\e$,15n\e1\e4\e$,4!zv#!)v#")v#"D\e0\e$,15x6-5d6'\e1\e(B, \e4\e$,44Kv#4z\e0\e$,1?(\e1\e4\e$,44hv#4zv#4\7f\e0\e$,1?.\e1\e4\e$,44qv#4{v#3Q\e0\e$,1?8?M>u?>\e1\e4\e$,44av#4z\e0\e$,1?0\e1\e(B, \e4\e$,46<\e0\e$,1@H\e1\e4\e$,46A\e0\e$,1@N\e1\e4\e$,46Kv#6Vv#6)v#6M\e0\e$,1@X@m@5@^\e1\e4\e$,46Cv#6W\e0\e$,1@P@"\e1\e(B, \e4\e$,4*U\e0\e$,1<U\e1\e4\e$,4*M\e0\e$,1<C\e1\e4\e$,4*Hv#)b\e0\e$,1<5<m\e1\e4\e$,4*H\e0\e$,1<5\e1\e4\e$,4*Qv#)b\e0\e$,1<N<m\e1\e(B, \e4\e$(7"7\e0"7\e1\e4$P\e0"!#C"Q\e1!;\e4"Er'"S\e0"E"S\e1\e4"G\e0"G\e1!;\e4"7\e0"7\e1\e4"2r'"[\e0"2"[\e1!;\e4"Dr'"[\e0"D"[\e1\e4"#\e0"#\e1\e4"G\e0"G\e1!>\e(B
 -  South East Asia: \e(1JP:R-\e04U\e1\e(B, \e,TJ\e0GQ\e1J\e04U\e1$\e0CQ\e1:\e(B, Ch\e,1`\e(Bo b\e,1U\e(Bn
 +  South Asia: \e$,15h5n5x6-5d6'\e(B, \e$,1?(?.?8?M>u?>?0\e(B, \e$,1@H@N@X@m@5@^@P@"\e(B, \e$,1<U<C<5<m<5<N<m\e(B, \e$(7"7"!#C"Q!;"E"S"G!;"7"2"[!;"D"["#"G!>\e(B
 +  South East Asia: \e(1JP:R-4U\e(B, \e,TJGQJ4U$CQ:\e(B, Ch\e,1`\e(Bo b\e,1U\e(Bn
    East Asia: \e$ADc:C\e(B, \e$(0*/=(\e(B, \e$B$3$s$K$A$O\e(B, \e$(C>H3gGO<<?d\e(B
    Misc: E\e,C6\e(Bo\e,C~\e(Ban\e,Cx\e(Bo \e,Cf\e(Biu\e,C<\e(Ba\e,C}\e(Bde, \e$,2(3(1('('(5\e(B, \e$,1x \e(B p \e$,1x(\e(B world \e$,1s"\e(B hello p  \e$,2!a\e(B
    CJK variety: GB(\e$AT*Fx\e(B,\e$A?*7"\e(B), BIG5(\e$(0&x86\e(B,\e$(0DeBv\e(B), JIS(\e$B855$\e(B,\e$B3+H/\e(B), KSC(\e$(Cj*Q(\e(B,\e$(CKR[!\e(B)
  
  LANGUAGE (NATIVE NAME)        HELLO
  ----------------------        -----
 -Amharic (\e$(3"c!<!N"^\e(B)     \e$(3!A!,!>\e(B
 -Arabic        \e(38R\e(47d\e(3T!JSa\e(4W\e(3W\e(B
 +Amharic (\e$,1O M[MmN{\e(B)     \e$,1M`MKM]\e(B
 +Arabic (\e,GIqjHQYdG\e(B)       \e,GecjdY\e(B \e,GeGdqSdG\e(B
  Braille       \e$,2(3(1('('(5\e(B
 -Bulgarian (\e,LQj[SP`aZX\e(B)   \e,L7T`PRUYbU\e(B
  C     printf ("Hello, world!\n");
 -Czech (\e,Bh\e(Be\e,B9\e(Btina)   Dobr\e,B}\e(B den
 +Czech (\e,Bh\e(Be\e,B9\e(Btina)   Dobr\e,A}\e(B den
  Danish (dansk)        Hej, Goddag, Hall\e,Ax\e(Bj
 +Dutch (Nederlands)    Hallo, Dag
  Emacs emacs --no-splash -f view-hello-file
 -English [\e,0p U\e(B-\e,0EZ L\e(B]        Hello
 +English [\e$(O+S\e(Bi\e,D?\e(B-gli\e$(O*h\e(B]      Hello
  Esperanto     Saluton (E\e,C6\e(Bo\e,C~\e(Ban\e,Cx\e(Bo \e,Cf\e(Biu\e,C<\e(Ba\e,C}\e(Bde)
 -Estonian (eesti)      Tere p\e,Ad\e(Bevast, Tere \e,Au\e(Bhtust
 -Finnish (suomi)       Hei, Hyv\e,Add\e(B p\e,Ad\e(Biv\e,Add\e(B
 +Estonian (eesti keel) Tere p\e,Ad\e(Bevast, Tere \e,Au\e(Bhtust
 +Finnish (Suomi)       Hei, Hyv\e,Add\e(B p\e,Ad\e(Biv\e,Add\e(B
  French (fran\e,Ag\e(Bais)       Bonjour, Salut
  Georgian (\e$,1JEJ0J@J7J5J4J:J8\e(B)    \e$,1J2J0J;J0J@JOJ=J1J0\e(B
  German (Deutsch)      Guten Tag, Gr\e,A|_\e(B Gott
  Greek (\e,Fekkgmij\\e(B)        \e,FCei\\e(B \e,Fsar\e(B
 -Hebrew (\e,Hraxiz\e(B)  \e,Hylem\e(B
 +Hebrew (\e,Hzixar\e(B)  \e,Hylem\e(B
  Hungarian (magyar)    Sz\e,Bi\e(Bp j\e,Bs\e(B napot!
 -Hindi (\e4\e$,4!}t%"+\e0\e$,15y5\7f5B\e1\e4\e$,4!.v#"Yv#"2\e0\e$,15f6 \e1\e(B)     \e4\e$,4!8v#")\e0\e$,15h\e1\e4\e$,4!hv#")\e0\e$,15n\e1\e4\e$,4!zv#!)v#")v#"D\e0\e$,15x6-5d6'\e1\e(B, \e4\e$,4!8v#")\e0\e$,15h\e1\e4\e$,4!hv#")\e0\e$,15n\e1\e4\e$,4!zv# ev#"Rv#")\e0\e$,15x6-5U5~\e1\e4\e$,4!nv#"W\e0\e$,15p\e1\e(B \e4\e$,4 J\e0\e$,16D\e1\e(B
 +Hindi (\e$,15y5\7f5B5f6 \e(B)     \e$,15h5n5x6-5d6'\e(B, \e$,15h5n5x6-5U5~5p\e(B \e$,16D\e(B
  Italian (italiano)    Ciao, Buon giorno
  Javanese (Jawa)       System.out.println("Halo, selamat sore!");
 -Kannada (\e4\e$,43Ov#4z\e0\e$,1>u\e1\e4\e$,44Kv#4zv#4M\e0\e$,1?(?M?(\e1\e4\e$,43sv#4z\e0\e$,1?!\e1\e(B)       \e4\e$,44Kv#4z\e0\e$,1?(\e1\e4\e$,44hv#4zv#4\7f\e0\e$,1?.\e1\e4\e$,44qv#4{v#3Q\e0\e$,1?8?M>u?>\e1\e4\e$,44av#4z\e0\e$,1?0\e1\e(B
 -Lao (\e(1>RJRERG\e(B)   \e(1JP:R-\e04U\e1\e(B, \e0\e(1"m\e1c\e0Ki\e1b*!\e04U\e1\e(B
 -Malayalam (\e4\e$,46A\e0\e$,1@N\e1\e4\e$,46E\e0\e$,1@R\e1\e4\e$,46Bv#6M\e0\e$,1@O@^\e1\e4\e$,46Fv#6W\e0\e$,1@S@"\e1\e(B)   \e4\e$,46<\e0\e$,1@H\e1\e4\e$,46A\e0\e$,1@N\e1\e4\e$,46Kv#6Vv#6)v#6M\e0\e$,1@X@m@5@^\e1\e4\e$,46Cv#6W\e0\e$,1@P@"\e1\e(B
 +Kannada (\e$,1>u?(?M?(?!\e(B)   \e$,1?(?.?8?M>u?>?0\e(B
 +Lao (\e(1>RJRERG\e(B)   \e(1JP:R-4U\e(B, \e(1"mcKib*!4U\e(B
 +Malayalam (\e$,1@N@R@O@^@S@"\e(B)       \e$,1@H@N@X@m@5@^@P@"\e(B
  Maltese (il-Malti)    Bon\e,Cu\e(Bu, Sa\e,C11\e(Ba
 -Mathematics   \e$,1x \e(B p \e$,1x(\e(B world \e$,1s"\e(B hello p  \e$,2!a\e(B
 +Mathematics   \e$B"O\e(B p \e$A!J\e(B world \e$(O#@\e(B hello p  \e$A!u\e(B
  Nederlands, Vlaams    Hallo, Dag
  Norwegian (norsk)     Hei, God dag
 -Polish (polski)       Dzie\e,Bq\e(B dobry! Cze\e,B6f\e(B!
 +Polish  (j\e,Bj\e(Bzyk polski)  Dzie\e,Bq\e(B dobry! Cze\e,B6f\e(B!
  Russian (\e,L`caaZXY\e(B)       \e,L7T`PRabRcYbU\e(B!
 -Slovak (sloven\e,Bh\e(Bina)     Dobr\e,B}\e(B de\e,Br\e(B
 +Slovak (sloven\e,Bh\e(Bina)     Dobr\e,A}\e(B de\e,Br\e(B
  Slovenian (sloven\e,B9h\e(Bina) Pozdravljeni!
  Spanish (espa\e,Aq\e(Bol)       \e,A!\e(BHola!
 -Swedish (svenska)     Hej, Goddag, Hall\e,Ae\e(B
 -Tamil (\e4\e$,4*N\e0\e$,1<D\e1\e4\e$,4(i\e0\e$,1<N<_\e1\e4\e$,4*Vv#)b\e0\e$,1<T<m\e1\e(B)     \e4\e$,4*U\e0\e$,1<U\e1\e4\e$,4*M\e0\e$,1<C\e1\e4\e$,4*Hv#)b\e0\e$,1<5<m\e1\e4\e$,4*H\e0\e$,1<5\e1\e4\e$,4*Qv#)b\e0\e$,1<N<m\e1\e(B
 -Thai (\e,T@RIRd7B\e(B)  \e,TJ\e0GQ\e1J\e04U\e1$\e0CQ\e1:\e(B, \e,TJ\e0GQ\e1J\e04U\e1\e0$h\e1P\e(B
 -Tibetan (\e4\e$(7"7r'"]\e0"7"]\e1\e4"2\e0"2\e1!;\e4%P\e0"G#!"Q\e1\e4"2\e0"2\e1!;\e(B)       \e4\e$(7"7\e0"7\e1\e4$P\e0"!#C"Q\e1!;\e4"Er'"S\e0"E"S\e1\e4"G\e0"G\e1!;\e4"7\e0"7\e1\e4"2r'"[\e0"2"[\e1!;\e4"Dr'"[\e0"D"[\e1\e4"#\e0"#\e1\e4"G\e0"G\e1!>\e(B
 -Tigrigna (\e$(3"8#r!N"^\e(B)    \e$(3!Q!,!<"8\e(B
 -Turkish (T\e,M|\e(Brk\e,Mg\e(Be)  Merhaba
 +Swedish (p\e,Ae\e(B svenska)    Hej, Goddag, Hall\e,Ae\e(B
 +Tamil (\e$,1<D<N<_<T<m\e(B)     \e$,1<U<C<5<m<5<N<m\e(B
 +Thai (\e,T@RIRd7B\e(B)  \e,TJGQJ4U$CQ:\e(B, \e,TJGQJ4U$hP\e(B
 +Tibetan (\e$(7"7"]"2!;"G#!"Q"2!;\e(B)   \e$(7"7"!#C"Q!;"E"S"G!;"7"2"[!;"D"["#"G!>\e(B
 +Tigrigna (\e$,1NUP-MmN{\e(B)    \e$,1MpMKM[NU\e(B
 +Turkish (T\e,A|\e(Brk\e,Ag\e(Be)  Merhaba
  Ukrainian (\e,LcZ`Pw]alZP\e(B)  \e,L2vbPn\e(B
 -Vietnamese (Ti\e,1*\e(Bng Vi\e,1.\e(Bt)   Ch\e,1`\e(Bo b\e,1U\e(Bn
 +Vietnamese (ti\e,1*\e(Bng Vi\e,1.\e(Bt)   Ch\e,A`\e(Bo b\e,1U\e(Bn
  
  Japanese (\e$BF|K\8l\e(B)       \e$B$3$s$K$A$O\e(B, \e(I:]FAJ\e(B
  Chinese (\e$AVPND\e(B,\e$AFUM(;0\e(B,\e$A::So\e(B)  \e$ADc:C\e(B
 -Cantonese (\e$(0GnM$\e(B,\e$(0N]0*Hd\e(B) \e$(0*/=(\e(B, \e$(0+$)p\e(B
 +Cantonese (\e$(0GnM$\e(B,\e$(Gl]\e$(00*Hd\e(B)     \e$(0*/=(\e(B, \e$(0+$)p\e(B
  Korean (\e$(CGQ1[\e(B)  \e$(C>H3gGO<<?d\e(B, \e$(C>H3gGO=J4O1n\e(B
  
  \f
  
- Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006
- Free software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
  
  COPYING PERMISSIONS:
  
diff --combined etc/MORE.STUFF
index b3ccc33dda6d6fa668a91a7b4b4ae7fb03f18093,d835b1f03adb0a596857bb94262768f232ce1b5f..8935baa1adb75136cd66c9f50f4f96ba70dec56f
@@@ -1,6 -1,6 +1,6 @@@
  More Neat Stuff for your Emacs
- Copyright (c) 1993, 1999, 2003, 2004, 2005, 2006 
- Free software Foundation, Inc.
+ Copyright (C) 1993, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
  See the end of the file for copying permissions.
  
  This file describes GNU Emacs programs and resources that are
@@@ -199,6 -199,13 +199,6 @@@ Several are for Debian GNU/Linux in par
   * JDEE: <URL:http://jdee.sunsite.dk/>
     Provides a Java development environment for Emacs.
  
 - * Mule-UCS: Universal enCoding System:
 -   <URL:ftp://ftp.m17n.org/pub/mule/Mule-UCS/>
 -   Extended coding systems for Mule, specifically for reading and
 -   writing UTF-8 encoded Unicode.  This probably doesn't have much
 -   advantage over the built-in `mule-utf-8' coding system with
 -   `utf-translate-cjk' turned on.
 -
   * Mailcrypt:
     <URL:http://mailcrypt.sourceforge.net/>
     PGP and GPG support.  PGP isn't free software, but GPG, the GNU
diff --combined etc/NEWS
index dec33c9b4e0db197367d85f57f5054c87d07ac91,ed1e34ce4e47ff912173bbd6d5d84b4ca3311ad7..2ca4c07555056b350be58a229258f62bde7e824c
+++ b/etc/NEWS
@@@ -1,5 -1,5 +1,5 @@@
  GNU Emacs NEWS -- history of user-visible changes.  2006-06-04
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
            Free Software Foundation, Inc.
  See the end for copying conditions.
  
@@@ -20,81 -20,6 +20,81 @@@ Temporary note
  When you add a new item, please add it without either +++ or ---
  so we will look at it and add it to the manual.
  
 +Fixme: The notes about Emacs 23 are quite incomplete.
 +
 +\f
 +* Changes in Emacs 23.1
 +
 +** The Emacs character set is now a superset of Unicode.  
 +(It has about four times the code space, which should be plenty).
 +
 +The internal encoding used for buffers and strings is now
 +Unicode-based and called `utf-8-emacs'.  utf-8-emacs is backwards
 +compatible with the UTF-8 encoding of Unicode.  The `emacs-mule'
 +coding system can still read and write data in the old internal
 +encoding.
 +
 +There are still charsets which contain disjoint sets of characters
 +where this is necessary or useful, especially for various Far Eastern
 +sets which are problematic with Unicode.
 +
 +Since the internal encoding is also used by default for byte-compiled
 +files -- i.e. the normal coding system for byte-compiled Lisp files is
 +now utf-8-Emacs -- Lisp containing non-ASCII characters which is
 +compiled by Emacs 23 can't be read by earlier versions of Emacs.  Files
 +compiled by Emacs 20, 21, or 22 are loaded correctly as emacs-mule
 +(whether or not they contain multibyte characters), which makes loading
 +them somewhat slower than Emacs 23-compiled files.  Thus it may be worth
 +recompiling existing .elc files which don't need to be shared with older
 +Emacsen.
 +
 +** There are assorted new coding systems/aliases -- see
 +M-x list-coding-systems.
 +
 +** New charset implementation with many new charsets.
 +See M-x list-character-sets.  New charsets can be defined conveniently
 +as tables of unicodes.
 +
 +The dimension of a charset is now 0, 1, 2, or 3, and the size of each
 +dimension is no longer limited to 94 or 96.
 +
 +Generic characters no longer exist.  
 +
 +A dynamic charset priority list is used to infer the charset of
 +unicodes for display &c.
 +
 +** The following facilities are obsolete:
 +
 +Minor modes: unify-8859-on-encoding-mode, unify-8859-on-decoding-mode
 +
 +\f
 +* Lisp changes in Emacs 23.1
 +
 +map-char-table's behaviour has changed.
 +
 +New functions: characterp, max-char, map-charset-chars,
 +define-charset-alias, primary-charset, set-primary-charset,
 +unify-charset, clear-charset-maps, charset-priority-list,
 +set-charset-priority, define-coding-system,
 +define-coding-system-alias, coding-system-aliases, langinfo,
 +string-to-multibyte.
 +
 +Changed functions: copy-sequence, decode-char, encode-char,
 +set-fontset-font, new-fontset, modify-syntax-entry, define-charset,
 +modify-category-entry
 +
 +Obsoleted: char-bytes, chars-in-region, set-coding-priority,
 +char-valid-p
 +
 +\f
 +* Incompatible Lisp changes
 +
 +Deleted functions: make-coding-system, register-char-codings,
 +coding-system-spec
 +
 +** The character codes for characters from the
 +eight-bit-control/eight-bit-graphic charsets aren't now in the range
 +128-255.
  \f
  * Installation Changes in Emacs 22.1
  
@@@ -587,7 -512,7 +587,7 @@@ hyperlinks for variables without variab
  preceded by one of the words `variable' or `option'.  It now makes
  hyperlinks to Info anchors (or nodes) if the anchor (or node) name is
  enclosed in single quotes and preceded by `info anchor' or `Info
- anchor' (in addition to earlier `info node' and `Info node'). In
+ anchor' (in addition to earlier `info node' and `Info node').  In
  addition, it now makes hyperlinks to URLs as well if the URL is
  enclosed in single quotes and preceded by `URL'.
  
@@@ -853,7 -778,7 +853,7 @@@ parts less visible than normal, so tha
  parts is, by contrast, slightly highlighted.
  
  Above fontification is always done when listing completions is
- triggered at minibuffer. If you want to fontify completions whose
+ triggered at minibuffer.  If you want to fontify completions whose
  listing is triggered at the other normal buffer, you have to pass
  the common prefix of completions to `display-completion-list' as
  its second argument.
@@@ -1741,8 -1666,8 +1741,8 @@@ on the mode line, header line and displ
  
  ---
  *** Improved key bindings support when running in an xterm.
- When emacs is running in an xterm more key bindings are available. The
- following should work:
+ When emacs is running in an xterm more key bindings are available.
The following should work:
  {C,S,C-S,A}-{right,left,up,down,prior,next,delete,insert,F1-12}.
  These key bindings work on xterm from X.org 6.8, they might not work on
  some older versions of xterm, or on some proprietary versions.
@@@ -2107,7 -2032,7 +2107,7 @@@ boundaries during scrolling
  +++
  ** The file t-mouse.el is now part of Emacs and provides access to mouse
  events from the console.  It still requires gpm to work but has been updated
- for Emacs 22. In particular, the mode-line is now position sensitive.
+ for Emacs 22.  In particular, the mode-line is now position sensitive.
  \f
  * Changes in Specialized Modes and Packages in Emacs 22.1:
  
@@@ -2122,7 -2047,7 +2122,7 @@@ is similar to the way sequential outpu
  +++
  *** Bindings for Tumme added
  Several new keybindings, all starting with the C-t prefix, have been
- added to Dired. They are all bound to commands in Tumme. As a starting
+ added to Dired.  They are all bound to commands in Tumme.  As a starting
  point, mark some image files in a dired buffer and do C-t d to display
  thumbnails of them in a separate buffer.
  
@@@ -2771,7 -2696,7 +2771,7 @@@ C-c C-i b, and so on
  ** Fortran mode changes:
  
  ---
- *** Fortran mode does more font-locking by default. Use level 3
+ *** Fortran mode does more font-locking by default.  Use level 3
  highlighting for the old default.
  
  +++
@@@ -2965,7 -2890,7 +2965,7 @@@ extracting the content of a BibTeX fiel
  *** The variables `bibtex-autokey-name-case-convert' and
  `bibtex-autokey-titleword-case-convert' have been renamed to
  `bibtex-autokey-name-case-convert-function' and
- `bibtex-autokey-titleword-case-convert-function'. The old names are
+ `bibtex-autokey-titleword-case-convert-function'.  The old names are
  still available as aliases.
  
  ** In Artist mode the variable `artist-text-renderer' has been
@@@ -3179,13 -3104,13 +3179,13 @@@ feature
  +++
  ***  When comparing directories.
  Typing D brings up a buffer that lists the differences between the contents of
- directories. Now it is possible to use this buffer to copy the missing files
+ directories.  Now it is possible to use this buffer to copy the missing files
  from one directory to another.
  
  +++
  *** When comparing files or buffers.
  Typing the = key now offers to perform the word-by-word comparison of the
- currently highlighted regions in an inferior Ediff session. If you answer 'n'
+ currently highlighted regions in an inferior Ediff session.  If you answer 'n'
  then it reverts to the old behavior and asks the user to select regions for
  comparison.
  
@@@ -3286,6 -3211,10 +3286,10 @@@ be used (only once) in place of a file 
  reads from standard input and marks the produced tags as belonging to
  the file FILE.
  
+ ** Ctags changes.
+ *** Ctags now allows duplicate tags
  ** VC Changes
  
  +++
@@@ -3419,7 -3348,7 +3423,7 @@@ appointments, paydays or anything else 
  
  +++
  *** The new function `calendar-goto-day-of-year' (g D) prompts for a
- year and day number, and moves to that date. Negative day numbers
+ year and day number, and moves to that date.  Negative day numbers
  count backward from the end of the year.
  
  +++
@@@ -3434,7 -3363,7 +3438,7 @@@ window generated by the function `gener
  ---
  *** The functions `holiday-easter-etc' and `holiday-advent' now take
  optional arguments, in order to only report on the specified holiday
- rather than all. This makes customization of variables such as
+ rather than all.  This makes customization of variables such as
  `christian-holidays' simpler.
  
  ---
@@@ -3794,7 -3723,7 +3798,7 @@@ See the Emacs 21.1 NEWS entry for toolt
  ---
  ** Images are now supported on MS Windows.
  
- PBM and XBM images are supported out of the box. Other image formats
+ PBM and XBM images are supported out of the box.  Other image formats
  depend on external libraries.  All of these libraries have been ported
  to Windows, and can be found in both source and binary form at
  http://gnuwin32.sourceforge.net/.  Note that libpng also depends on
@@@ -3836,7 -3765,7 +3840,7 @@@ you wish to use them in other faces
  ** On MS Windows NT/W2K/XP, Emacs uses Unicode for clipboard operations.
  
  Those systems use Unicode internally, so this allows Emacs to share
- multilingual text with other applications. On other versions of
+ multilingual text with other applications.  On other versions of
  MS Windows, Emacs now uses the appropriate locale coding-system, so
  the clipboard should work correctly for your local language without
  any customizations.
  
  Previous versions of Emacs erred on the side of having a usable Emacs
  through telnet, even though that was inconvenient if you use Emacs in
- a local console window with a scrollback buffer. The default value of
+ a local console window with a scrollback buffer.  The default value of
  w32-use-full-screen-buffer is now nil, which favors local console
- windows. Recent versions of Windows telnet also work well with this
- setting. If you are using an older telnet server then Emacs detects
+ windows.  Recent versions of Windows telnet also work well with this
+ setting.  If you are using an older telnet server then Emacs detects
  that the console window dimensions that are reported are not sane, and
- defaults to 80x25. If you use such a telnet server regularly at a size
+ defaults to 80x25.  If you use such a telnet server regularly at a size
  other than 80x25, you can still manually set
  w32-use-full-screen-buffer to t.
  
@@@ -6046,7 -5975,7 +6050,7 @@@ an error if the argument actually retur
  ----------------------------------------------------------------------
  Copyright information:
  
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
          Free Software Foundation, Inc.
  
     Permission is granted to anyone to make or distribute verbatim copies
diff --combined etc/PROBLEMS
index ffad920d7ec9f7750d177b7d6300dccee80e5548,aede0f7c1d2c6e4903351b3b94a665078a1c0757..a30f4b94a63a1ff081e6d55ce90e2fa0c791ee51
@@@ -2,10 -2,6 +2,10 @@@ This file describes various problems th
  in compiling, installing and running GNU Emacs.  Try doing Ctl-C Ctl-t
  and browsing through the outline headers.
  
 +* Mule-UCS doesn't work in Emacs 23.
 +
 +It's completely redundant now, as far as we know.
 +
  * Emacs startup failures
  
  ** Emacs fails to start, complaining about missing fonts.
@@@ -2359,6 -2355,16 +2359,16 @@@ This results from a bug in a VERY old v
  the problem, install the current version of GNU Sed, then rerun
  Emacs's configure script.
  
+ *** Building a 32-bit executable on a 64-bit GNU/Linux architecture.
+ First ensure that the necessary 32-bit system libraries and include
+ files are installed. Then use:
+   env CC="gcc -m32" ./configure --build=i386-linux-gnu \
+     --x-libraries=/usr/X11R6/lib
+ (using the location of the 32-bit X libraries on your system).
  *** Building the Cygwin port for MS-Windows can fail with some GCC version
  
  Building Emacs 22 with Cygwin builds of GCC 3.4.4-1 and 3.4.4-2 is
@@@ -3690,8 -3696,8 +3700,8 @@@ This problem will not happen if the m-.
  of machine defines NO_UNION_TYPE.
  
  \f
- Copyright 1987, 1988, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-    2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+    2001, 2002, 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  Copying and redistribution of this file with or without modification
  are permitted without royalty provided this notice is preserved.
diff --combined etc/TODO
index 2f5cb9a029329e576ae4e5bcf4599f1f91679aaa,1ebc75929480bb021778a402c87dcfc70449024e..7c91aa43db66f06168623c1e7da125b467e04188
+++ b/etc/TODO
@@@ -1,7 -1,7 +1,7 @@@
  Emacs TODO List                                                   -*-outline-*-
  
- Copyright (c) 2003, 2004, 2005, 2006
- Free software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
  See the end of the file for copying permissions.
  
  If you are ready to start working on any of these TODO items, we
@@@ -79,6 -79,8 +79,8 @@@ current buffer
  
  ** The toolbar should show keyboard equivalents in its tooltips.
  
+ ** Add function to redraw the tool bar.
  ** Modify allout.el to use overlays, like outline.el.
  
  ** M-! M-n should fetch the buffer-file-name as the default.
@@@ -194,6 -196,8 +196,8 @@@ typically due to pilot errors and shoul
    has advice] (x y) The overlay could also be a button that you could
    use to view the advice.
  
+ ** Add a function to get the insertion-type of the markers in an overlay.
  ** ange-ftp
  *** understand sftp
     This is hard to make work because sftp doesn't print status
  ** Allow unknown image types to be rendered via an external program
    converting them to, say, PBM (in the same way as PostScript?).
  
+ ** Display images with alpha channels, such as png, with the current
+ background color of whatever frame it is displayed in.  Currently, we
+ use the default background color if specified in the png file, or, if
+ that is unspecified, the background color of the frame in which the
+ image was first created.  Ideally, the image should display the
+ background color of whichever frame it is being displayed in.  The
+ main complication is that this will require the loading of a new image
+ object for each different background color.
  ** Allow displaying an X window from an external program in a buffer,
    e.g. to render graphics from Java applets.  [gerd and/or wmperry
    thought this was feasible.]
    (with ASCIIfied fallback via latin1-disp).  Examples include
    box-drawing graphics in Custom buffers, W3 rules and tables, and
    tree displays generally, mode-line mail indicator.  [See work done
 -  already for Emacs 22 and consult fx.]
 +  already for Emacs 23 and consult fx.]
  
  ** Do something to make rms happy with fx's dynamic loading, and use it
    to implement things like auto-loaded buffer parsers and database
index 8b52b531d64578da13a5bbca1601c755859d071d,18417a0dabceefd98fe870e301e9261e4d89960b..c73d9e389e9accda2104ebf34651b029ca3b12b9
@@@ -1,9 -1,11 +1,11 @@@
 -# $Id: 4Corner.tit,v 1.2 1994/06/06 01:54:03 ygz Exp $
++# $Id: 4Corner.tit,v 1.5 2007/01/24 06:35:08 handa Exp $
  # HANZI input table for cxterm
  # To be used by cxterm, convert me to .cit format first
  # .cit version 2
  ENCODE:       BIG5
+ AUTOSELECT:   NO
  PROMPT:       Â¥|¨¤¸¹½X::\040
- AUTOSELECT:   NEVER
+ #
  COMMENT 
  COMMENT Copyright (c) 2001 Christian Wittern <chris@ccbs.ntu.edu.tw>
  COMMENT 
@@@ -14,11 -16,10 +16,10 @@@ COMMEN
  COMMENT       Authors: Dr. Urs App, Christian Wittern (Kyoto Univ, Japan)
  COMMENT
  COMMENT Input:  Â¥|¨¤¸¹½X (¤Î¤@ªþ¥[½X)
- # input key definitions
+ # define keys
  VALIDINPUTKEY:        0123456789
  WILDCARDKEY:  *
  WILDCHARKEY:  ?
- # choice list keys
  SELECTKEY:    1\040
  SELECTKEY:    2
  SELECTKEY:    3
@@@ -29,17 -30,11 +30,11 @@@ SELECTKEY: 
  SELECTKEY:    8
  SELECTKEY:    9
  SELECTKEY:    0
+ BACKSPACE:    \010\177
+ DELETEALL:    \015\025
  MOVERIGHT:    .>
  MOVELEFT:     ,<
- # pre-editing keys
- BACKSPACE:    \010\177                # ctrl-H,  DEL
- DELETEALL:    \015\025                # RETURN,  ctrl-U
- CURSOR-BEGIN: \001                    # ctrl-A
- CURSOR-END:   \005                    # ctrl-E
- CURSOR-FORW:  \006                    # ctrl-F
- CURSOR-BACK:  \002                    # ctrl-B
- CURSOR-ERASE: \004                    # ctrl-D
- REPEATKEY:    \020\022                # ctrl-P,  ctrl-R
+ REPEATKEY:    \020\022
  # the following line must not be removed
  BEGINDICTIONARY
  #
index 5b135288de10cf4fc478e0d9b781810ccd8c698a,3f64c408cbb3e33e1903d772e0f3f6a75003bb01..cca16b62d09c83fb4642862372e7f8ef2fde4d97
@@@ -1,9 -1,10 +1,10 @@@
 -# $Id: CCDOSPY.tit,v 1.2 1994/06/06 01:51:50 ygz Exp $
++# $Id: CCDOSPY.tit,v 1.4 2007/01/24 06:35:08 handa Exp $
  # HANZI input table for cxterm
  # To be used by cxterm, convert me to .cit format first
- # .cit version 1
+ # .cit version 2
  ENCODE:       GB
- MULTICHOICE:  YES
- PROMPT:       ÂºÂºÃ—ÖÊäÈë¡ËËõôƴÒô¡Ë£ 
+ AUTOSELECT:   NO
+ PROMPT:       ÂºÂºÃ—ÖÊäÈë¡ËËõôƴÒô¡Ë\040
  #
  COMMENT Ã‹ÃµÃ´Æ´Òô·½°¸ (Ô´ÓÚ CCDOS)
  COMMENT
@@@ -15,6 -16,8 +16,8 @@@ COMMENT       Ã†Â´Ã’ô¡Ã   a    guo   zhon
  COMMENT       Â¼Ã¼ÃˆÃ«Â¡Ãƒ   a1   guo4   as1   wf4  guh1  yu..6 qvj6
  # define keys
  VALIDINPUTKEY:        abcdefghijklmnopqrstuvwxyz
+ WILDCARDKEY:  *
+ WILDCHARKEY:  ?
  SELECTKEY:    1\040
  SELECTKEY:    2
  SELECTKEY:    3
index 5ef45b854666a10b5a7662ce31fbaefc704ec2ba,22039a06d04ecbecfdbbd0116b781b52490badd5..ae330dbc906b3694aa010389fcc26a3853929b7b
@@@ -1,14 -1,11 +1,11 @@@
 -# $Id: PY.tit,v 1.2 1994/06/06 01:54:03 ygz Exp $
++# $Id: PY-b5.tit,v 1.3 2007/01/24 06:35:08 handa Exp $
  # HANZI input table for cxterm
- # Generated from PY-b5.cit by cit2tit
  # To be used by cxterm, convert me to .cit format first
- # .cit version 1
+ # .cit version 2
  ENCODE:       BIG5
- MULTICHOICE:  YES
- PROMPT:       Â¤Â¤Â¤Ã¥Â¿Ã©Â¤J¡i«÷­µ¡j
+ AUTOSELECT:   NO
+ PROMPT:       Âº~¦r¿é¤J::«÷­µ::\040
  #
- COMMENT last modified by cyl@ifcss.org 1994 March 9
- COMMENT Modify by Wei-Chung Hwang, OCT 15, 1992.
- COMMENT
  COMMENT       Âº~»y«÷­µ¿é¤J¤è®×¤¶²à  (ª`­µ²Å¸¹¹ï·Ó)
  COMMENT       
  COMMENT                               Ãn¥À (CONSONANT)
@@@ -44,6 -41,8 +41,8 @@@ COMMENT       j+ -> Â¸Ã²Ãn¥À j,q,x Â«Ã·ÂªÂºÂ®Ã‰Â­Ã”,   
  COMMENT
  # define keys
  VALIDINPUTKEY:        12345:abcdefghijklmnopqrstuvwxyz
+ WILDCARDKEY:  *
+ WILDCHARKEY:  ?
  SELECTKEY:    1\040
  SELECTKEY:    2
  SELECTKEY:    3
@@@ -163,7 -162,7 +162,7 @@@ bing
  bing3 Â»Ã¦Â¤Ã¾Â¸[¬`ªÃ¬±ÎôÃÔÌ}ï@»Ã×®ÃÃœÃ~Ò÷«Ìε
  bing4 Â¨ÃƒÂ¯f¨Ö¦}´¬ØÖïxÔR
  bing5 
- bo1   Â¬Ã¼·­éµÔ²ÚågÒÜÞë×·ðÔø[ÔqÃYóQÃŒi
+ bo1   Âªi¬Ã¼·­éµÔ²ÚågÒÜÞë×·ðÔø[ÔqÃYóQÃŒi
  bo2   Â§B³Õ¬fªy«k·i´ñ»éá²ä©­²íºä²ò½³»K¹Yèù`õÎñÃçôÒJöJäc
  bo2   Ã±Wìaàûñ®õfÕÅî¬ÀÃì`ÃcѴުߴèwïÌðcò¡ùRÓöù{ò®
  bo3   Â¶_ðװ
@@@ -993,7 -992,7 +992,7 @@@ leng
  li1   Â­Ã¹
  li2   Ã‚÷¼þ¾¤±ùÆXÂç¼ù¿©»©Æz²pºvöè¯WòÔ¸ÄÄùùÃáuîqõ¶Õ¼åúíÃëI
  li2   Ã¥Ã¸Ãù÷ðÜƳííÌñNùÎ÷ÑöÛößöxá}åËðÛóÑóîöàÄRÛzøMøuÓNւ
- li3   Â§ÃµÂ¨Â½Â¸ÃŒÂ²z§ùØ­ù¯@ÃU®[«Z¿CÃ…ÃÄ¿Äùø×¾YßUàTÃŽ~øô
+ li3   Â§ÃµÂ¨Â½Â¸ÃŒÂ²z§­ù¯@ÃU®[«Z¿CÃ…ÃÄ¿Äùø×¾YßUàTÃŽ~øô
  li4   Â¤O¥ß§QÄR¾úÃc¨Ò¾ä²ú¼FÀyÄr²É»YÆEÃwÄ×ÃõÄt¦O¯ï®ß·X«Wµg
  li4   Ã‚~²Ã©Ñ°æÅ°²|Ûàñò·ÌÄ÷ôUÃBõæòR÷eòtïgÒªôsê¼ÃkÑEÉv÷`°z
  li4   Â°Â¬Ã´qÒõâÔøHÃŒlÉñÅÃô¡Ã²ì¤ÃíïòÒÚÕ`שØdßSãtãïðVòHòrô¾öF
index eb5a558bfb7c932b78e0d565cd9daf574b992c10,3492ae95315296dc191a4071a9a2264f038785aa..9b18b52486c0fbb4d795af98d521c509789f1b1b
@@@ -1,21 -1,17 +1,17 @@@
 -# $Id: QJ.tit,v 1.2 1994/06/06 01:54:03 ygz Exp $
++# $Id: QJ-b5.tit,v 1.3 2007/01/24 06:35:08 handa Exp $
  # HANZI input table for cxterm
- # Generated from QJ-b5.cit by cit2tit
  # To be used by cxterm, convert me to .cit format first
- # .cit version 1
+ # .cit version 2
  ENCODE:       BIG5
- MULTICHOICE:  NO
- PROMPT:       Â¤Â¤Â¤Ã¥Â¿Ã©Â¤J¡i¥þ§Î¡j
+ AUTOSELECT:   YES
+ PROMPT:       Âº~¦r¿é¤J::¥þ¨¤::
  #
  COMMENT Copyright 1991 by Yongguang Zhang.      (ygz@cs.purdue.edu)
  COMMENT Permission to use/modify/copy for any purpose is hereby granted.
  COMMENT Absolutely no warranties.
- COMMENT Modify by Wei-Chung Hwang, OCT 15, 1992.
  # define keys
  VALIDINPUTKEY:        \040!"\043$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN
  VALIDINPUTKEY:        OPQRSTUVWXYZ[\134]^_`abcdefghijklmnopqrstuvwxyz{|}~
- BACKSPACE:    \010\177
- DELETEALL:    \015\025
- REPEATKEY:    \020\022
  # the following line must not be removed
  BEGINDICTIONARY
  #
diff --combined leim/CXTERM-DIC/QJ.tit
index b591f1326af53e93c9e7e3fcab18f5aedb2acf0c,cad66ffe474ec6d649243d31f9c03a1c8ef777fc..06c677080727d1e2e9add49fc17f2ba924f6244d
@@@ -1,9 -1,10 +1,10 @@@
 -# $Id: QJ.tit,v 1.2 1994/06/06 01:53:09 ygz Exp $
++# $Id: QJ.tit,v 1.4 2007/01/24 06:35:08 handa Exp $
  # HANZI input table for cxterm
  # To be used by cxterm, convert me to .cit format first
- # .cit version 1
+ # .cit version 2
  ENCODE:       GB
- MULTICHOICE:  NO
- PROMPT:       ÂºÂºÃ—ÖÊäÈë¡ËÈ«½Ç¡Ë£ 
+ AUTOSELECT:   YES
+ PROMPT:       ÂºÂºÃ—ÖÊäÈë¡ËÈ«½Ç¡Ë
  #
  COMMENT Copyright 1991 by Yongguang Zhang.      (ygz@cs.purdue.edu)
  COMMENT Permission to use/modify/copy for any purpose is hereby granted.
diff --combined leim/CXTERM-DIC/README
index 0000000000000000000000000000000000000000,43f397dff3ea59724ecd61ea757fc4e6de23725d..bda7055a2b56ddd140b8970741452059c8e57ef9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,58 +1,58 @@@
 -contains a license notice.
+ All *.tit files in this directory are dictionary files to use with
+ the program cxterm.  Their source and copyright status are categorised
+ into these four.
+ (1) QJ-b5.tit (renamed from .../cxterm/dict/big5/QJ.tit)
+     QJ.tit (copied from .../cxterm/dict/gb/QJ.tit)
+ These are verbatim copies of what included in the directory
+ contrib/clients/cxterm of the distribution of X11R6.  Each file
 -themselves don't contain license notices, the section 6 of the file
++contains a copyright notice.
+ (2) CCDOSPY.tit (copied from .../cxterm/dict/gb/CCDOSPY.tit)
+     PY-b5.tit (renamed from .../cxterm/dict/big5/PY.tit)
+     SW.tit (copied from .../cxterm/dict/gb/SW.tit)
+     TONEPY.tit (copied from .../cxterm/dict/gb/TONEPY.tit)
+ These are verbatim copies of what included in the directory
+ contrib/clients/cxterm of the distribution of X11R6.  As those files
 -contains a license notice.
++themselves don't contain copyright notices, the section 6 of the file
+ .../cxterm/README should cover them.
+ ============================================================
+ 6. COPYRIGHTS AND TERMS
+ This copyright and permission notice outlines the rights and
+ restrictions covering most parts of this distribution of cxterm.
+ Cxterm is modified from xterm, which is copyrighted by MIT.
+ Some individual files are covered by other copyrights.  Utils
+ parts are redistributed software covered by their own copyrights
+ and terms.  Please see individual file's copyright notices.
+ X11R6 CXTERM (C) 1994 BY YONGGUANG ZHANG.
+ X11R5 CXTERM (C) 1991 BY YONGGUANG ZHANG AND MAN-CHI PONG.
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose is hereby granted without fee,
+ provided that this entire copyright and permission notice appear
+ in all such copies, and that the name of the authors may not be
+ used to endorse or promote products derived from this material
+ without specific prior written permission.  The authors make no
+ representations about the suitability of this software for any
+ purpose.  It is provided "as is" without express or implied warranty.
+ ============================================================
+ (3) 4Corner.tit
+     ARRAY30.tit
+     ETZY.tit
+     ZOZY.tit
+ These are the versions modified by the original authors from what
+ distributed with X11R5 to include proper copyright notices.  Each file
 -ftp://ftp.ifcss.org/pub/software/.  Each file contains a license
++contains a copyright notice.
+ (4) ECDICT.tit, Punct-b5.tit, Punct.tit
+ These are verbatim copies of what distributed at
++ftp://ftp.ifcss.org/pub/software/.  Each file contains a copyright
+ notice.
diff --combined leim/CXTERM-DIC/SW.tit
index fed48d62e671f15674ae8292a4e03322d10a7b99,a0a5a442323d53842aa8c49be1f91a8653589d07..b32c73762d44c686a88cc3c64b407afc27a94485
@@@ -1,15 -1,18 +1,18 @@@
 -# $Id: SW.tit,v 1.2 1994/06/06 01:53:09 ygz Exp $
++# $Id: SW.tit,v 1.4 2007/01/24 06:35:08 handa Exp $
  # HANZI input table for cxterm
  # To be used by cxterm, convert me to .cit format first
- # .cit version 1
+ # .cit version 2
  ENCODE:       GB
- MULTICHOICE:  YES
- PROMPT:       ÂºÂºÃ—ÖÊäÈë¡ËÊ×β¡Ë£ 
+ AUTOSELECT:   NO
+ PROMPT:       ÂºÂºÃ—ÖÊäÈë¡ËÊ×β¡Ë\040
  #
  COMMENT       (Ô´ÓÚ CCDOS)
  COMMENT       ÃŠÃ©Ã´¸Ãºº×ÖʱµÄ¡¸Êױʡ¹¼°¡¸Î²±Ê¡¹¡£ÀýÈ磬¡¾ÂÀ¡¿Ê×β±Ê½ÔΪ¡¸¿Ú¡¹£¬¹ÊÔÚ
  COMMENT Â¡Â¸ÃŠÃ—β¡¹Ä£Ê½ÖÃÓàff0 ÃˆÃ½Â¼Ã¼ÃŠÃ¤ÃˆÃ«Â¡Â£Â£Â¨ f Â¼Ã¼Ã”Ú¡¸Ê×β¡¹Ä£Ê½Öñíʾ¡¸¿Ú¡¹£©
  # define keys
  VALIDINPUTKEY:        abcdefghijklmnopqrstuvwxyz
+ WILDCARDKEY:  *
+ WILDCHARKEY:  ?
  SELECTKEY:    1\040
  SELECTKEY:    2
  SELECTKEY:    3
index a93bf9dcb6467b7d3b651219b0987b2215d2c3b1,501ebfd52d02bf755e938cf2b13e6c22fdd69aef..46b8df61bbe8bad17dc31b9bb0c2d704999c4dab
@@@ -1,9 -1,10 +1,10 @@@
 -# $Id: TONEPY.tit,v 1.2 1994/06/06 01:53:09 ygz Exp $
++# $Id: TONEPY.tit,v 1.4 2007/01/24 06:35:08 handa Exp $
  # HANZI input table for cxterm
  # To be used by cxterm, convert me to .cit format first
- # .cit version 1
+ # .cit version 2
  ENCODE:       GB
- MULTICHOICE:  YES
- PROMPT:       ÂºÂºÃ—ÖÊäÈë¡Ë´øµ÷Æ´Òô¡Ë£ 
+ AUTOSELECT:   NO
+ PROMPT:       ÂºÂºÃ—ÖÊäÈë¡Ë´øµ÷Æ´Òô¡Ë\040
  #
  COMMENT       Â´Ã¸ÂµÃ·Ã†Â´Ã’ô·½°¸
  COMMENT
@@@ -11,6 -12,8 +12,8 @@@ COMMENT Ã¡Ã´Ó¢ÎÄ×Öĸ´ú±í¡¸Æ´Òô¡¹·ûºÅ£¬ 
  COMMENT Ã’ôµ÷ÓÃÊý×Ö±íʾ£¬ 12345 Â·Ã–±ð´ú±íÒõƽ¡¢Ñôƽ¡¢ÉÃÉù¡¢ÃÂÉù¼°ÇáÉù
  # define keys
  VALIDINPUTKEY:        12345:abcdefghijklmnopqrstuvwxyz
+ WILDCARDKEY:  *
+ WILDCHARKEY:  ?
  SELECTKEY:    1\040
  SELECTKEY:    2
  SELECTKEY:    3
diff --combined leim/MISC-DIC/README
index 0000000000000000000000000000000000000000,a8d7c0578aa390bd90070f593631235ca180b998..fbc061801aa8b32b0a47d790306867509560c3dd
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,46 +1,46 @@@
 -Wittern himself.  Each file contains a license notice.
+ The source and copyright status of dictionary files in this directory
+ are categorised into these three.
+ (1) cangjie-table.b5
+     cangjie-table.cns
+ These are verbatim copies of what distributed by the author Christian
 -<umunhum.stanford.edu/~lee/chicomp/> Each file contains a license
++Wittern himself.  Each file contains a copyright notice.
+ (2) CTLau.html
+     CTLau-b5.html
+ These are verbatim copies of what distributed at the authors home page
 -As those files themselves don't contain license notices, the
 -copyright/license notice of the package itself should cover them.
++<umunhum.stanford.edu/~lee/chicomp/> Each file contains a copyright
+ notice.
+ (3) pinyin.map
+     ziranma.cin
+ These are verbatim copies of what distributed with a free packaged
+ called CCE at:
+       http://ftp.debian.org/debian/dists/potato/main
+               /source/utils/cce_0.36.orig.tar.gz
++As those files themselves don't contain copyright notices, the
++copyright notice of the package itself should cover them.
+ ============================================================
+             Copyright (C) 1999, Rui He, herui@cs.duke.edu
+                  CCE(Console Chinese Environment) 0.32
+ CCE is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 1, or (at your option) any later version.
+ CCE 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 General Public License for more
+ details.
+ You should have received a copy of the GNU General Public License along with
+ CCE; see the file COPYING.  If not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.")
+ ============================================================
diff --combined leim/Makefile.in
index 9fdc0a30ad6ea98ce6080c72866547ba3320a95d,4c5d9b68751eec7fd55009c3e6a7e2f44568a08b..99441ab15ff081d3ed1b0a29f5d533bc2d54448f
@@@ -1,7 -1,7 +1,7 @@@
  # Makefile for leim subdirectory in GNU Emacs.
- # Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ # Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  #   Free Software Foundation, Inc.
- # Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ # Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  #   National Institute of Advanced Industrial Science and Technology (AIST)
  #   Registration Number H14PRO021
  
@@@ -48,7 -48,7 +48,7 @@@ BUILT-EMACS = ${dot}${dot}/src/emac
  buildlisppath=${srcdir}/${dot}${dot}/lisp
  
  # How to run Emacs.
 -RUN-EMACS = EMACSLOADPATH=$(buildlisppath) LC_ALL=C\
 +RUN-EMACS = EMACSLOADPATH=$(buildlisppath) LC_ALL=C \
        ${BUILT-EMACS} -batch --no-init-file --no-site-file --multibyte
  
  # Subdirectories to be made if ${srcdir} is different from the current
diff --combined leim/quail/cyrillic.el
index 771858e51e14f5cfc6f5c008f3f0304b8263a0be,df58b811907a6571f39d0ad332960ca40d4a5711..4cc37e5325515b3170d069144bcab18adf355eee
@@@ -1,8 -1,9 +1,9 @@@
  ;;; cyrillic.el --- Quail package for inputting Cyrillic characters
  
- ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  ;; least the top row is different.
  (quail-define-package
   "cyrillic-macedonian" "Cyrillic" "\e,L6\e(BM" nil
 - "\e,L)*5@B7\e(B-\e,L#,\e(B keyboard layout based on JUS.I.K1.004 (ISO 8859-5 encoding)"
 + "\e,L)*5@B7\e(B-\e,L#,\e(B keyboard layout based on JUS.I.K1.004"
   nil t t t t nil nil nil nil nil t)
  
  ;;  1! 2" 3# 4$ 5% 6& 7' 8( 9) 0= /? +* <>
  
  (quail-define-package
   "cyrillic-serbian" "Cyrillic" "\e,L6\e(BS" nil
 - "\e,L)*5@B7\e(B-\e,L"+\e(B keyboard layout based on JUS.I.K1.005 (ISO 8859-5 encoding)"
 + "\e,L)*5@B7\e(B-\e,L"+\e(B keyboard layout based on JUS.I.K1.005"
   nil t t t t nil nil nil nil nil t)
  
  ;;  1! 2" 3# 4$ 5% 6& 7' 8( 9) 0= /? +* <>
  ;; Fixme: add GHE_WITH_UPTURN.
  (quail-define-package
   "cyrillic-ukrainian" "Ukrainian" "\e,L6\e(BU" nil
 - "\e,L$'5@B7\e(B-\e,L&.\e(B UKRAINIAN (ISO 8859-5 encoding)
 + "\e,L$'5@B7\e(B-\e,L&.\e(B UKRAINIAN
  
  Sorry, but 'ghe with upturn' is not included in ISO 8859-5."
   nil t t t t nil nil nil nil nil t)
  ;; (mostly Russian) from time to time.
  (quail-define-package
   "cyrillic-yawerty" "Cyrillic" "\e,L6O\e(B" nil
 - "\e,LO25@BK\e(B Roman transcription (ISO 8859-5 encoding)
 + "\e,LO25@BK\e(B Roman transcription
  
  This layout is based on Roman transcription by phonemic resemblance.
  When preceded by a '/', the second and the third rows (number key row) change
diff --combined leim/quail/hangul3.el
index 129701981338f2bda2d85021df4192f0a99ee322,b554f019827318aac2fe8b4af696d26506699db6..673e2c6778841ed863702719f3554b3bb12950e0
@@@ -1,7 -1,9 +1,9 @@@
  ;;; hangul3.el --- Quail package for inputting Korean Hangul characters  -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 1997, 1998, 2001, 2002, 2006  Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
@@@ -53,7 -55,7 +55,7 @@@
     (?1 . "\e$(C$>\e(B")
     ;; other bindings
     (?G . "/")  (?T . ";")   (?H . "'")   (?B . "!")  (?Y . "<")
 -   (?P . ">")  (?\[ . "\e$(C!8\e(B") (?\[ . "\e$(C!9\e(B") (?{ . "\e$(C!:\e(B") (?{ . "\e$(C!;\e(B")
 +   (?P . ">")  (?\[ . "[") (?\[ . "]") (?{ . "{") (?{ . "}")
     (?N . "0")  (?M . "1")   (?< . "2")   (?> . "3")  (?J . "4")
     (?K . "5")  (?L . "6")   (?U . "7")   (?I . "8")  (?O . "9"))
   "\e$(CGQ1[\e(B 3\e$(C9z=D\e(B: Hangul input method
   ("B" ?!)
   ("Y" ?<)
   ("P" ?>)
 - ("\[" ?\e$(C!8\e(B)
 - ("\]" ?\e$(C!9\e(B)
 - ("{" ?\e$(C!:\e(B)
 - ("}" ?\e$(C!;\e(B)
 + ("\[" ?[)
 + ("\]" ?])
 + ("{" ?{)
 + ("}" ?})
   ("N" ?0)
   ("M" ?1)
   ("<" ?2)
  
  ;;; arch-tag: 20ea2223-ab47-414f-8e28-d03dc83617b7
  ;;; hangul3.el ends here
 +
diff --combined leim/quail/indian.el
index 06e8dd23d2b9f8748e369900adbb0c311875e823,973c5ff12bbf0df6d063f8aee22abde8a3262335..367aa059adc485c1b6754a79f17b28d9cd63e947
@@@ -1,6 -1,7 +1,7 @@@
  ;;; indian.el --- Quail packages for inputting Indian
  
- ;; Copyright (C) 2000, 2001, 2002, 2003, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
  
  ;; Author: KAWABATA, Taichi <kawabata@m17n.org>
  
  ;;; Code:
  
  (require 'quail)
 -(require 'devan-util)
  (require 'ind-util)
 -
 -(defun quail-indian-preceding-char-position (position)
 -  "Return the position of preceding composite character."
 -  (let (prec-composed)
 -    (if (char-valid-p (char-before position)) ;; range o.k.
 -        (if (setq prec-composed (find-composition (1- position)))
 -            (car prec-composed)
 -          (1- position))
 -      nil)))
 -
 -(defvar quail-indian-update-preceding-char nil)
 -(make-variable-frame-local 'quail-indian-update-preceding-char)
 -
 -;; Input value ::
 -;;   CONTROL-FLAG is integer `n'
 -;;     quail-current-key :: keyboard input.
 -;;                          Only first `n' can be translated.
 -;;     quail-current-str :: corresonding string. 
 -;;     jobs :: (1) put last (len-n) char to unrread-command-event.
 -;;             (2) put translated string to  quail-current-str.
 -;;
 -;;   CONTROL-FLAG is t (terminate) or nil (proceed the translation)
 -;;     quail-current-key :: keyboard input.
 -;;     quail-current-str :: corresponding string.
 -;;     jobs :: (1) put modified translated string to quail-current-str.
 -;;
 -;; When non-nil value is returned from quail-translation-update-function, 
 -;; the quail-current-str is split to characters and put into event queue, 
 -;; with `compose-last-char' event with composition info at the end.
 -
 -(defun quail-indian-update-translation (control-flag)
 -  ;; make quail-current-str string when possible.
 -  (if (char-valid-p quail-current-str)
 -      (setq quail-current-str (char-to-string quail-current-str)))
 -  ;(message "\n input control-flag=%s, str=%s, key=%s q-ind-upd-prec-char=%s"
 -  ;         control-flag quail-current-str quail-current-key
 -  ;         quail-indian-update-preceding-char)
 -  ;; reset quail-indian-update-preceding-char if it's initial.
 -  (if (= (overlay-start quail-overlay) (overlay-end quail-overlay))
 -      (setq quail-indian-update-preceding-char nil))
 -  ;; Check the preceding character of the quail region.  If the
 -  ;; preceding character can be composed with quail-current-str, then
 -  ;; grab that preceding character into the quail-current-str and
 -  ;; remove that char from the region.  
 -  (let* (prec-char-position composition-regexp
 -         prec-char-str candidate-str match-pos match-end)
 -    (when (and quail-current-str
 -               (null quail-indian-update-preceding-char)
 -               (null input-method-use-echo-area)
 -               (null input-method-exit-on-first-char)
 -               (setq prec-char-position
 -                     (quail-indian-preceding-char-position
 -                      (overlay-start quail-overlay)))
 -               (setq composition-regexp
 -                     (if prec-char-position
 -                         (caar (elt composition-function-table
 -                                    (char-after prec-char-position)))))
 -               (setq prec-char-str
 -                     (buffer-substring prec-char-position
 -                                       (overlay-start quail-overlay))
 -                     candidate-str (concat prec-char-str quail-current-str)
 -                     match-pos (string-match composition-regexp candidate-str)
 -                     match-end (match-end 0))
 -               (> match-end (length prec-char-str)))
 -      (setq quail-indian-update-preceding-char prec-char-str)
 -      (delete-region prec-char-position
 -                     (overlay-start quail-overlay))))
 -  (setq quail-current-str 
 -        (indian-compose-string
 -         (concat quail-indian-update-preceding-char 
 -                 quail-current-str)))
 -  (if (numberp control-flag)
 -      (setq unread-command-events
 -            (string-to-list
 -             (substring quail-current-key control-flag))))
 -  (when control-flag
 -    (setq quail-indian-update-preceding-char nil))
 -  ;(message "output control-flag=%s, str=%s, key=%s q-ind-upd-prec-char=%s"
 -  ;         control-flag quail-current-str quail-current-key
 -  ;         quail-indian-update-preceding-char)
 -  control-flag)
 +(require 'devan-util)
  
  ;;;
  ;;; Input by transliteration
  (defun quail-define-indian-trans-package (hashtbls pkgname
                                                   lang title doc)
    (funcall 'quail-define-package pkgname lang title t doc
 -         nil nil nil nil nil nil t nil
 -         'quail-indian-update-translation)
 +         nil nil nil nil nil nil t nil)
    (maphash
     (lambda (key val)
       (quail-defrule key (if (= (length val) 1)
  ;;; Input by Inscript
  ;;;
  
 -(defun quail-indian-flatten-list (lst)
 -  "Flatten the nested LIST so that there would be no innner list."
 -  (if (listp lst)
 -      (apply 'append (mapcar 'quail-indian-flatten-list lst))
 -    (list lst)))
 -
 -(defun quail-define-inscript-package (char-table key-table pkgname lang title
 -                                               docstring)
 -  (setq char-table (quail-indian-flatten-list char-table))
 -  (setq key-table (quail-indian-flatten-list key-table))
 +(defun quail-define-inscript-package (char-tables key-tables pkgname lang
 +                                                  title docstring)
    (funcall 'quail-define-package pkgname lang title nil docstring
 -         nil nil nil nil nil nil nil nil
 -         'quail-indian-update-translation)
 -  (dolist (key key-table)
 -    (let ((val (pop char-table)))
 -      (if (and key val)
 -        (quail-defrule
 -          (if (char-valid-p key) (char-to-string key) key)
 -          (if (stringp val) (vector val) val))))))
 +         nil nil nil nil nil nil nil nil)
 +  (let (char-table key-table char key)
 +    (while (and char-tables key-tables)
 +      (setq char-table  (car char-tables)
 +            char-tables (cdr char-tables)
 +            key-table   (car key-tables)
 +            key-tables  (cdr key-tables))
 +      (while (and char-table key-table)
 +        (setq char       (car char-table)
 +              char-table (cdr char-table)
 +              key        (car key-table)
 +              key-table  (cdr key-table))
 +        (if (and (consp char) (consp key))
 +            (setq char-table (append char char-table)
 +                  key-table  (append key  key-table))
 +          (if (and key char)
 +              (quail-defrule
 +               (if (characterp key) (char-to-string key) key)
 +               (if (stringp char)   (vector char) char))))))))
  
  ;;
  
      (;; Inscripts
       ?# ?$ ?^ ?* ?\])))
  
 +(defvar inscript-tml-keytable
 +  '(
 +    (;; VOWELS  (18)
 +     (?D nil) (?E ?e) (?F ?f) (?R ?r) (?G ?g) (?T ?t)
 +     nil nil nil (?S ?s) (?Z ?z) (?W ?w)
 +     nil (?A ?a) (?~ ?`) (?Q ?q) nil nil)
 +    (;; CONSONANTS (42)
 +     ?k ?K ?i ?I ?U                ;; GRUTTALS
 +     ?\; ?: ?p ?P ?}               ;; PALATALS
 +     ?' ?\" ?\[ ?{ ?C              ;; CEREBRALS
 +     ?l ?L ?o ?O ?v ?V             ;; DENTALS
 +     ?h ?H ?y ?Y ?c                ;; LABIALS
 +     ?/ ?j ?J ?n ?N "N]" ?b        ;; SEMIVOWELS
 +     ?M ?< ?m ?u                   ;; SIBILANTS
 +     "k]" "K]" "i]" "p]" "[]" "{]" "H]" "/]" ;; NUKTAS
 +     ?% ?&)
 +    (;; Misc Symbols (7)
 +     ?X ?x ?_ ">]" ?d "X]" ?>)
 +    (;; Digits
 +     ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)
 +    (;; Inscripts
 +     ?# ?$ ?^ ?* ?\])))
 +
  (if nil
      (quail-define-package "devanagari-inscript" "Devanagari" "DevIS" t "Devanagari keyboard Inscript"))
  (quail-define-inscript-package
  (if nil
      (quail-define-package "tamil-inscript" "Tamil" "TmlIS" t "Tamil keyboard Inscript"))
  (quail-define-inscript-package
 - indian-tml-base-table inscript-dev-keytable
 + indian-tml-base-table inscript-tml-keytable
   "tamil-inscript" "Tamil" "TmlIS"
   "Tamil keyboard Inscript.")
  
diff --combined leim/quail/latin-alt.el
index d573d4a0e13abacdc7c213c599235b3433a05ead,54160808cc0f09843101bf0af5e7b8b98e8b9f00..d913e80856378b3526efe24f874abfb95554587d
@@@ -1,7 -1,8 +1,8 @@@
 -;;; latin-alt.el --- Quail package for inputting various European characters -*-coding: iso-2022-7bit;-*-
 +;;; latin-alt.el --- Quail package for inputting various European characters -*-coding: utf-8;-*-
  
- ;; Copyright (C) 1997, 1998, 2001, 2002, 2006  Free Software Foundation, Inc.
- ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
+ ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Aa\e(B
 -  grave      |    `    | a` -> \e,A`\e(B
 -  circumflex |    ^    | a^ -> \e,Ab\e(B
 -  diaeresis  |    \"    | a\" -> \e,Ad\e(B
 -  tilde      |    ~    | a~ -> \e,Ac\e(B
 -  cedilla    |    /    | c/ -> \e,Ag\e(B
 -  nordic     |    /    | d/ -> \e,Ap\e(B   t/ -> \e,A~\e(B   a/ -> \e,Ae\e(B   e/ -> \e,Af\e(B   o/ -> \e,Ax\e(B
 -  others     |   /<>   | s/ -> \e,A_\e(B   ?/ -> \e,A?\e(B   !/ -> \e,A!\e(B
 -             | various | << -> \e,A+\e(B   >> -> \e,A;\e(B   o_ -> \e,A:\e(B   a_ -> \e,A*\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  tilde      |    ~    | a~ -> Ã£
 +  cedilla    |    /    | c/ -> Ã§
 +  nordic     |    /    | d/ -> Ã°   t/ -> Ã¾   a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |   /<>   | s/ -> ÃŸ   ?/ -> Â¿   !/ -> Â¡
 +             | various | << -> Â«   >> -> Â»   o_ -> Âº   a_ -> Âª
  
  It would be natural to use comma for cedillas, but that would be
  inconvenient in practice because commas are needed very often after a
@@@ -56,74 -57,74 +57,74 @@@ Doubling the postfix separates the lett
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,A@\e(B)
 - ("A'" ?\e,AA\e(B)
 - ("A^" ?\e,AB\e(B)
 - ("A~" ?\e,AC\e(B)
 - ("A\"" ?\e,AD\e(B)
 - ("A/" ?\e,AE\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("a^" ?\e,Ab\e(B)
 - ("a~" ?\e,Ac\e(B)
 - ("a\"" ?\e,Ad\e(B)
 - ("a/" ?\e,Ae\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("E^" ?\e,AJ\e(B)
 - ("E\"" ?\e,AK\e(B)
 - ("E/" ?\e,AF\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("e^" ?\e,Aj\e(B)
 - ("e\"" ?\e,Ak\e(B)
 - ("e/" ?\e,Af\e(B)
 - ("I`" ?\e,AL\e(B)
 - ("i`" ?\e,Al\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("I^" ?\e,AN\e(B)
 - ("i^" ?\e,An\e(B)
 - ("I\"" ?\e,AO\e(B)
 - ("i\"" ?\e,Ao\e(B)
 - ("O`" ?\e,AR\e(B)
 - ("o`" ?\e,Ar\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("o'" ?\e,As\e(B)
 - ("O^" ?\e,AT\e(B)
 - ("o^" ?\e,At\e(B)
 - ("O~" ?\e,AU\e(B)
 - ("o~" ?\e,Au\e(B)
 - ("O\"" ?\e,AV\e(B)
 - ("o\"" ?\e,Av\e(B)
 - ("O/" ?\e,AX\e(B)
 - ("o/" ?\e,Ax\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("U^" ?\e,A[\e(B)
 - ("u^" ?\e,A{\e(B)
 - ("U\"" ?\e,A\\e(B)
 - ("u\"" ?\e,A|\e(B)
 - ("Y'" ?\e,A]\e(B)
 - ("y'" ?\e,A}\e(B)
 - ("y\"" ?\e,A\7f\e(B)
 - ("D/" ?\e,AP\e(B)
 - ("d/" ?\e,Ap\e(B)
 - ("T/" ?\e,A^\e(B)
 - ("t/" ?\e,A~\e(B)
 - ("s/" ?\e,A_\e(B)
 - ("C/" ?\e,AG\e(B)
 - ("c/" ?\e,Ag\e(B)
 - ("N~" ?\e,AQ\e(B)
 - ("n~" ?\e,Aq\e(B)
 - ("?/" ?\e,A?\e(B)
 - ("!/" ?\e,A!\e(B)
 - ("<<" ?\e,A+\e(B)
 - (">>" ?\e,A;\e(B)
 - ("o_" ?\e,A:\e(B)
 - ("a_" ?\e,A*\e(B)
 + ("A`" ?À)
 + ("A'" ?Ã)
 + ("A^" ?Â)
 + ("A~" ?Ã)
 + ("A\"" ?Ä)
 + ("A/" ?Ã…)
 + ("a`" ?à)
 + ("a'" ?á)
 + ("a^" ?â)
 + ("a~" ?ã)
 + ("a\"" ?ä)
 + ("a/" ?Ã¥)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("E^" ?Ê)
 + ("E\"" ?Ë)
 + ("E/" ?Æ)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("e^" ?ê)
 + ("e\"" ?ë)
 + ("e/" ?æ)
 + ("I`" ?ÃŒ)
 + ("i`" ?ì)
 + ("I'" ?Ã)
 + ("i'" ?í)
 + ("I^" ?ÃŽ)
 + ("i^" ?î)
 + ("I\"" ?Ã)
 + ("i\"" ?ï)
 + ("O`" ?Ã’)
 + ("o`" ?ò)
 + ("O'" ?Ó)
 + ("o'" ?ó)
 + ("O^" ?Ô)
 + ("o^" ?ô)
 + ("O~" ?Õ)
 + ("o~" ?õ)
 + ("O\"" ?Ö)
 + ("o\"" ?ö)
 + ("O/" ?Ø)
 + ("o/" ?ø)
 + ("U`" ?Ù)
 + ("u`" ?ù)
 + ("U'" ?Ú)
 + ("u'" ?ú)
 + ("U^" ?Û)
 + ("u^" ?û)
 + ("U\"" ?Ãœ)
 + ("u\"" ?ü)
 + ("Y'" ?Ã)
 + ("y'" ?ý)
 + ("y\"" ?ÿ)
 + ("D/" ?Ã)
 + ("d/" ?ð)
 + ("T/" ?Þ)
 + ("t/" ?þ)
 + ("s/" ?ß)
 + ("C/" ?Ç)
 + ("c/" ?ç)
 + ("N~" ?Ñ)
 + ("n~" ?ñ)
 + ("?/" ?¿)
 + ("!/" ?¡)
 + ("<<" ?«)
 + (">>" ?»)
 + ("o_" ?º)
 + ("a_" ?ª)
  
   ("A``" ["A`"])
   ("A''" ["A'"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Ba\e(B
 -  ogonek     |    `    | a` -> \e,B1\e(B
 -  diaeresis  |    \"    | a\" -> \e,Bd\e(B
 -  circumflex |    ^    | a^ -> \e,Bb\e(B
 -  breve      |    ~    | a~ -> \e,Bc\e(B
 -  cedilla    |    `    | c` -> \e,Bg\e(B
 -  caron      |    ~    | c~ -> \e,Bh\e(B
 -  dbl. acute |    :    | o: -> \e,Bu\e(B
 -  ring       |    `    | u` -> \e,By\e(B
 -  dot        |    `    | z` -> \e,B?\e(B
 -  stroke     |    /    | d/ -> \e,Bp\e(B
 -  others     |    /    | s/ -> \e,B_\e(B
 +  acute      |    '    | a' -> Ã¡
 +  ogonek     |    `    | a` -> Ä…
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  circumflex |    ^    | a^ -> Ã¢
 +  breve      |    ~    | a~ -> Äƒ
 +  cedilla    |    `    | c` -> Ã§
 +  caron      |    ~    | c~ -> Ä
 +  dbl. acute |    :    | o: -> Å‘
 +  ring       |    `    | u` -> Å¯
 +  dot        |    `    | z` -> Å¼
 +  stroke     |    /    | d/ -> Ä‘
 +  others     |    /    | s/ -> ÃŸ
  
  It would be natural to use period and comma for dots/rings and
  cedillas/ogoneks, but that would inconvenient in practice, because
@@@ -222,87 -223,87 +223,87 @@@ Doubling the postfix separates the lett
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,BA\e(B)
 - ("A`" ?\e,B!\e(B)
 - ("A\"" ?\e,BD\e(B)
 - ("A^" ?\e,BB\e(B)
 - ("A~" ?\e,BC\e(B)
 - ("C'" ?\e,BF\e(B)
 - ("C`" ?\e,BG\e(B)
 - ("C~" ?\e,BH\e(B)
 - ("D/" ?\e,BP\e(B)
 - ("D~" ?\e,BO\e(B)
 - ("E'" ?\e,BI\e(B)
 - ("E`" ?\e,BJ\e(B)
 - ("E\"" ?\e,BK\e(B)
 - ("E~" ?\e,BL\e(B)
 - ("I'" ?\e,BM\e(B)
 - ("I^" ?\e,BN\e(B)
 - ("L'" ?\e,BE\e(B)
 - ("L/" ?\e,B#\e(B)
 - ("L~" ?\e,B%\e(B)
 - ("N'" ?\e,BQ\e(B)
 - ("N~" ?\e,BR\e(B)
 - ("O'" ?\e,BS\e(B)
 - ("O:" ?\e,BU\e(B)
 - ("O\"" ?\e,BV\e(B)
 - ("O^" ?\e,BT\e(B)
 - ("R'" ?\e,B@\e(B)
 - ("R~" ?\e,BX\e(B)
 - ("S'" ?\e,B&\e(B)
 - ("S`" ?\e,B*\e(B)
 - ("S~" ?\e,B)\e(B)
 - ("T`" ?\e,B^\e(B)
 - ("T~" ?\e,B+\e(B)
 - ("U'" ?\e,BZ\e(B)
 - ("U:" ?\e,B[\e(B)
 - ("U\"" ?\e,B\\e(B)
 - ("U`" ?\e,BY\e(B)
 - ("Y'" ?\e,B]\e(B)
 - ("Z'" ?\e,B,\e(B)
 - ("Z`" ?\e,B/\e(B)
 - ("Z~" ?\e,B.\e(B)
 - ("a'" ?\e,Ba\e(B)
 - ("a`" ?\e,B1\e(B)
 - ("a\"" ?\e,Bd\e(B)
 - ("a^" ?\e,Bb\e(B)
 - ("a~" ?\e,Bc\e(B)
 - ("c'" ?\e,Bf\e(B)
 - ("c`" ?\e,Bg\e(B)
 - ("c~" ?\e,Bh\e(B)
 - ("d/" ?\e,Bp\e(B)
 - ("d~" ?\e,Bo\e(B)
 - ("e'" ?\e,Bi\e(B)
 - ("e`" ?\e,Bj\e(B)
 - ("e\"" ?\e,Bk\e(B)
 - ("e~" ?\e,Bl\e(B)
 - ("i'" ?\e,Bm\e(B)
 - ("i^" ?\e,Bn\e(B)
 - ("l'" ?\e,Be\e(B)
 - ("l/" ?\e,B3\e(B)
 - ("l~" ?\e,B5\e(B)
 - ("n'" ?\e,Bq\e(B)
 - ("n~" ?\e,Br\e(B)
 - ("o'" ?\e,Bs\e(B)
 - ("o:" ?\e,Bu\e(B)
 - ("o\"" ?\e,Bv\e(B)
 - ("o^" ?\e,Bt\e(B)
 - ("r'" ?\e,B`\e(B)
 - ("r~" ?\e,Bx\e(B)
 - ("s'" ?\e,B6\e(B)
 - ("s`" ?\e,B:\e(B)
 - ("s/" ?\e,B_\e(B)
 - ("s~" ?\e,B9\e(B)
 - ("t`" ?\e,B~\e(B)
 - ("t~" ?\e,B;\e(B)
 - ("u'" ?\e,Bz\e(B)
 - ("u:" ?\e,B{\e(B)
 - ("u\"" ?\e,B|\e(B)
 - ("u`" ?\e,By\e(B)
 - ("y'" ?\e,B}\e(B)
 - ("z'" ?\e,B<\e(B)
 - ("z`" ?\e,B?\e(B)
 - ("z~" ?\e,B>\e(B)
 + ("A'" ?Ã)
 + ("A`" ?Ä„)
 + ("A\"" ?Ä)
 + ("A^" ?Â)
 + ("A~" ?Ä‚)
 + ("C'" ?Ć)
 + ("C`" ?Ç)
 + ("C~" ?ÄŒ)
 + ("D/" ?Ä)
 + ("D~" ?ÄŽ)
 + ("E'" ?É)
 + ("E`" ?Ę)
 + ("E\"" ?Ë)
 + ("E~" ?Äš)
 + ("I'" ?Ã)
 + ("I^" ?ÃŽ)
 + ("L'" ?Ĺ)
 + ("L/" ?Å)
 + ("L~" ?Ľ)
 + ("N'" ?Ń)
 + ("N~" ?Ň)
 + ("O'" ?Ó)
 + ("O:" ?Å)
 + ("O\"" ?Ö)
 + ("O^" ?Ô)
 + ("R'" ?Å”)
 + ("R~" ?Ř)
 + ("S'" ?Åš)
 + ("S`" ?Åž)
 + ("S~" ?Å )
 + ("T`" ?Å¢)
 + ("T~" ?Ť)
 + ("U'" ?Ú)
 + ("U:" ?Å°)
 + ("U\"" ?Ãœ)
 + ("U`" ?Å®)
 + ("Y'" ?Ã)
 + ("Z'" ?Ź)
 + ("Z`" ?Å»)
 + ("Z~" ?Ž)
 + ("a'" ?á)
 + ("a`" ?Ä…)
 + ("a\"" ?ä)
 + ("a^" ?â)
 + ("a~" ?ă)
 + ("c'" ?ć)
 + ("c`" ?ç)
 + ("c~" ?Ä)
 + ("d/" ?Ä‘)
 + ("d~" ?Ä)
 + ("e'" ?é)
 + ("e`" ?Ä™)
 + ("e\"" ?ë)
 + ("e~" ?Ä›)
 + ("i'" ?í)
 + ("i^" ?î)
 + ("l'" ?ĺ)
 + ("l/" ?Å‚)
 + ("l~" ?ľ)
 + ("n'" ?Å„)
 + ("n~" ?ň)
 + ("o'" ?ó)
 + ("o:" ?Å‘)
 + ("o\"" ?ö)
 + ("o^" ?ô)
 + ("r'" ?Å•)
 + ("r~" ?Å™)
 + ("s'" ?Å›)
 + ("s`" ?ÅŸ)
 + ("s/" ?ß)
 + ("s~" ?Å¡)
 + ("t`" ?Å£)
 + ("t~" ?Å¥)
 + ("u'" ?ú)
 + ("u:" ?ű)
 + ("u\"" ?ü)
 + ("u`" ?ů)
 + ("y'" ?ý)
 + ("z'" ?ź)
 + ("z`" ?ż)
 + ("z~" ?ž)
  
   ("A''" ["A'"])
   ("A``" ["A`"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Ca\e(B
 -  grave      |    `    | a` -> \e,C`\e(B
 -  circumflex |    ^    | a^ -> \e,Cb\e(B
 -  diaeresis  |    \"    | a\" -> \e,Cd\e(B
 -  dot        |    /    | c/ -> \e,Ce\e(B   i/ -> \e,C9\e(B   I/ -> \e,C)\e(B
 -  cedilla    |    `    | c` -> \e,Cg\e(B
 -  breve      |    ~    | g~ -> \e,C;\e(B
 -  tilde      |    ~    | n~ -> \e,Cq\e(B
 -  stroke     |    /    | h/ -> \e,C1\e(B
 -  others     |    /    | s/ -> \e,C_\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  dot        |    /    | c/ -> Ä‹   i/ -> Ä±   I/ -> Ä°
 +  cedilla    |    `    | c` -> Ã§
 +  breve      |    ~    | g~ -> ÄŸ
 +  tilde      |    ~    | n~ -> Ã±
 +  stroke     |    /    | h/ -> Ä§
 +  others     |    /    | s/ -> ÃŸ
  
  It would be natural to use period and comma for dots and cedillas, but
  that would inconvenient in practice, because periods and commas are
@@@ -412,77 -413,77 +413,77 @@@ Doubling the postfix separates the lett
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,C@\e(B)
 - ("A'" ?\e,CA\e(B)
 - ("A^" ?\e,CB\e(B)
 - ("A\"" ?\e,CD\e(B)
 - ("C/" ?\e,CE\e(B)
 - ("C^" ?\e,CF\e(B)
 - ("C`" ?\e,CG\e(B)
 - ("E`" ?\e,CH\e(B)
 - ("E'" ?\e,CI\e(B)
 - ("E^" ?\e,CJ\e(B)
 - ("E\"" ?\e,CK\e(B)
 - ("G~" ?\e,C+\e(B)
 - ("G/" ?\e,CU\e(B)
 - ("G^" ?\e,CX\e(B)
 - ("H/" ?\e,C!\e(B)
 - ("H^" ?\e,C&\e(B)
 - ("I/" ?\e,C)\e(B)
 - ("I`" ?\e,CL\e(B)
 - ("I'" ?\e,CM\e(B)
 - ("I^" ?\e,CN\e(B)
 - ("I\"" ?\e,CO\e(B)
 - ("J^" ?\e,C,\e(B)
 - ("N~" ?\e,CQ\e(B)
 - ("O`" ?\e,CR\e(B)
 - ("O'" ?\e,CS\e(B)
 - ("O^" ?\e,CT\e(B)
 - ("O\"" ?\e,CV\e(B)
 - ("S`" ?\e,C*\e(B)
 - ("S^" ?\e,C^\e(B)
 - ("U`" ?\e,CY\e(B)
 - ("U'" ?\e,CZ\e(B)
 - ("U^" ?\e,C[\e(B)
 - ("U\"" ?\e,C\\e(B)
 - ("U~" ?\e,C]\e(B)
 - ("Z/" ?\e,C/\e(B)
 - ("a`" ?\e,C`\e(B)
 - ("a'" ?\e,Ca\e(B)
 - ("a^" ?\e,Cb\e(B)
 - ("a\"" ?\e,Cd\e(B)
 - ("c/" ?\e,Ce\e(B)
 - ("c^" ?\e,Cf\e(B)
 - ("c`" ?\e,Cg\e(B)
 - ("e`" ?\e,Ch\e(B)
 - ("e'" ?\e,Ci\e(B)
 - ("e^" ?\e,Cj\e(B)
 - ("e\"" ?\e,Ck\e(B)
 - ("g~" ?\e,C;\e(B)
 - ("g/" ?\e,Cu\e(B)
 - ("g^" ?\e,Cx\e(B)
 - ("h/" ?\e,C1\e(B)
 - ("h^" ?\e,C6\e(B)
 - ("i/" ?\e,C9\e(B)
 - ("i`" ?\e,Cl\e(B)
 - ("i'" ?\e,Cm\e(B)
 - ("i^" ?\e,Cn\e(B)
 - ("i\"" ?\e,Co\e(B)
 - ("j^" ?\e,C<\e(B)
 - ("n~" ?\e,Cq\e(B)
 - ("o`" ?\e,Cr\e(B)
 - ("o'" ?\e,Cs\e(B)
 - ("o^" ?\e,Ct\e(B)
 - ("o\"" ?\e,Cv\e(B)
 - ("s`" ?\e,C:\e(B)
 - ("s/" ?\e,C_\e(B)
 - ("s^" ?\e,C~\e(B)
 - ("u`" ?\e,Cy\e(B)
 - ("u'" ?\e,Cz\e(B)
 - ("u^" ?\e,C{\e(B)
 - ("u\"" ?\e,C|\e(B)
 - ("u~" ?\e,C}\e(B)
 - ("z/" ?\e,C?\e(B)
 + ("A`" ?À)
 + ("A'" ?Ã)
 + ("A^" ?Â)
 + ("A\"" ?Ä)
 + ("C/" ?ÄŠ)
 + ("C^" ?Ĉ)
 + ("C`" ?Ç)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("E^" ?Ê)
 + ("E\"" ?Ë)
 + ("G~" ?Äž)
 + ("G/" ?Ä )
 + ("G^" ?Äœ)
 + ("H/" ?Ħ)
 + ("H^" ?Ĥ)
 + ("I/" ?Ä°)
 + ("I`" ?ÃŒ)
 + ("I'" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I\"" ?Ã)
 + ("J^" ?Ä´)
 + ("N~" ?Ñ)
 + ("O`" ?Ã’)
 + ("O'" ?Ó)
 + ("O^" ?Ô)
 + ("O\"" ?Ö)
 + ("S`" ?Åž)
 + ("S^" ?Åœ)
 + ("U`" ?Ù)
 + ("U'" ?Ú)
 + ("U^" ?Û)
 + ("U\"" ?Ãœ)
 + ("U~" ?Ŭ)
 + ("Z/" ?Å»)
 + ("a`" ?à)
 + ("a'" ?á)
 + ("a^" ?â)
 + ("a\"" ?ä)
 + ("c/" ?Ä‹)
 + ("c^" ?ĉ)
 + ("c`" ?ç)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("e^" ?ê)
 + ("e\"" ?ë)
 + ("g~" ?ÄŸ)
 + ("g/" ?Ä¡)
 + ("g^" ?Ä)
 + ("h/" ?ħ)
 + ("h^" ?Ä¥)
 + ("i/" ?ı)
 + ("i`" ?ì)
 + ("i'" ?í)
 + ("i^" ?î)
 + ("i\"" ?ï)
 + ("j^" ?ĵ)
 + ("n~" ?ñ)
 + ("o`" ?ò)
 + ("o'" ?ó)
 + ("o^" ?ô)
 + ("o\"" ?ö)
 + ("s`" ?ÅŸ)
 + ("s/" ?ß)
 + ("s^" ?Å)
 + ("u`" ?ù)
 + ("u'" ?ú)
 + ("u^" ?û)
 + ("u\"" ?ü)
 + ("u~" ?Å­)
 + ("z/" ?ż)
  
   ("A``" ["A`"])
   ("A''" ["A'"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Da\e(B
 -  circumflex |    ^    | a^ -> \e,Db\e(B
 -  diaeresis  |    \"    | a\" -> \e,Dd\e(B
 -  ogonek     |    `    | a` -> \e,D1\e(B
 -  macron     |    -    | a- -> \e,D`\e(B
 -  tilde      |    ~    | a~ -> \e,Dc\e(B
 -  caron      |    ~    | c~ -> \e,Dh\e(B
 -  dot        |    ~    | e~ -> \e,Dl\e(B
 -  cedilla    |    `    | k` -> \e,Ds\e(B   g` -> \e,D;\e(B
 -  stroke     |    /    | d/ -> \e,Dp\e(B
 -  nordic     |    /    | a/ -> \e,De\e(B   e/ -> \e,Df\e(B   o/ -> \e,Dx\e(B
 -  others     |    /    | s/ -> \e,D_\e(B   n/ -> \e,D?\e(B   k/ -> \e,D"\e(B
 +  acute      |    '    | a' -> Ã¡
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  ogonek     |    `    | a` -> Ä…
 +  macron     |    -    | a- -> Ä
 +  tilde      |    ~    | a~ -> Ã£
 +  caron      |    ~    | c~ -> Ä
 +  dot        |    ~    | e~ -> Ä—
 +  cedilla    |    `    | k` -> Ä·   g` -> Ä£
 +  stroke     |    /    | d/ -> Ä‘
 +  nordic     |    /    | a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |    /    | s/ -> ÃŸ   n/ -> Å‹   k/ -> Ä¸
  
  It would be natural to use period and comma for dots and
  cedillas/ogoneks, but that would inconvenient in practice, because
@@@ -584,88 -585,88 +585,88 @@@ Doubling the postfix separates the lett
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,D!\e(B)
 - ("A-" ?\e,D@\e(B)
 - ("A'" ?\e,DA\e(B)
 - ("A^" ?\e,DB\e(B)
 - ("A~" ?\e,DC\e(B)
 - ("A\"" ?\e,DD\e(B)
 - ("A/" ?\e,DE\e(B)
 - ("C~" ?\e,DH\e(B)
 - ("D/" ?\e,DP\e(B)
 - ("E/" ?\e,DF\e(B)
 - ("E-" ?\e,D*\e(B)
 - ("E'" ?\e,DI\e(B)
 - ("E`" ?\e,DJ\e(B)
 - ("E\"" ?\e,DK\e(B)
 - ("E~" ?\e,DL\e(B)
 - ("G`" ?\e,D+\e(B)
 - ("I~" ?\e,D%\e(B)
 - ("I`" ?\e,DG\e(B)
 - ("I'" ?\e,DM\e(B)
 - ("I^" ?\e,DN\e(B)
 - ("I-" ?\e,DO\e(B)
 - ("K`" ?\e,DS\e(B)
 - ("L`" ?\e,D&\e(B)
 - ("N/" ?\e,D=\e(B)
 - ("N`" ?\e,DQ\e(B)
 - ("O-" ?\e,DR\e(B)
 - ("O^" ?\e,DT\e(B)
 - ("O~" ?\e,DU\e(B)
 - ("O\"" ?\e,DV\e(B)
 - ("O/" ?\e,DX\e(B)
 - ("R`" ?\e,D#\e(B)
 - ("S~" ?\e,D)\e(B)
 - ("T/" ?\e,D,\e(B)
 - ("U`" ?\e,DY\e(B)
 - ("U'" ?\e,DZ\e(B)
 - ("U^" ?\e,D[\e(B)
 - ("U\"" ?\e,D\\e(B)
 - ("U~" ?\e,D]\e(B)
 - ("U-" ?\e,D^\e(B)
 - ("Z~" ?\e,D.\e(B)
 - ("a`" ?\e,D1\e(B)
 - ("a-" ?\e,D`\e(B)
 - ("a'" ?\e,Da\e(B)
 - ("a^" ?\e,Db\e(B)
 - ("a~" ?\e,Dc\e(B)
 - ("a\"" ?\e,Dd\e(B)
 - ("a/" ?\e,De\e(B)
 - ("c~" ?\e,Dh\e(B)
 - ("d/" ?\e,Dp\e(B)
 - ("e/" ?\e,Df\e(B)
 - ("e-" ?\e,D:\e(B)
 - ("e'" ?\e,Di\e(B)
 - ("e`" ?\e,Dj\e(B)
 - ("e\"" ?\e,Dk\e(B)
 - ("e~" ?\e,Dl\e(B)
 - ("g`" ?\e,D;\e(B)
 - ("i~" ?\e,D5\e(B)
 - ("i`" ?\e,Dg\e(B)
 - ("i'" ?\e,Dm\e(B)
 - ("i^" ?\e,Dn\e(B)
 - ("i-" ?\e,Do\e(B)
 - ("k/" ?\e,D"\e(B)
 - ("k`" ?\e,Ds\e(B)
 - ("l`" ?\e,D6\e(B)
 - ("n/" ?\e,D?\e(B)
 - ("n`" ?\e,Dq\e(B)
 - ("o-" ?\e,Dr\e(B)
 - ("o^" ?\e,Dt\e(B)
 - ("o~" ?\e,Du\e(B)
 - ("o\"" ?\e,Dv\e(B)
 - ("o/" ?\e,Dx\e(B)
 - ("r`" ?\e,D3\e(B)
 - ("s/" ?\e,D_\e(B)
 - ("s~" ?\e,D9\e(B)
 - ("t/" ?\e,D<\e(B)
 - ("u`" ?\e,Dy\e(B)
 - ("u'" ?\e,Dz\e(B)
 - ("u^" ?\e,D{\e(B)
 - ("u\"" ?\e,D|\e(B)
 - ("u~" ?\e,D}\e(B)
 - ("u-" ?\e,D~\e(B)
 - ("z~" ?\e,D>\e(B)
 + ("A`" ?Ä„)
 + ("A-" ?Ä€)
 + ("A'" ?Ã)
 + ("A^" ?Â)
 + ("A~" ?Ã)
 + ("A\"" ?Ä)
 + ("A/" ?Ã…)
 + ("C~" ?ÄŒ)
 + ("D/" ?Ä)
 + ("E/" ?Æ)
 + ("E-" ?Ä’)
 + ("E'" ?É)
 + ("E`" ?Ę)
 + ("E\"" ?Ë)
 + ("E~" ?Ä–)
 + ("G`" ?Ä¢)
 + ("I~" ?Ĩ)
 + ("I`" ?Ä®)
 + ("I'" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I-" ?Ī)
 + ("K`" ?Ķ)
 + ("L`" ?Ä»)
 + ("N/" ?ÅŠ)
 + ("N`" ?Å…)
 + ("O-" ?ÅŒ)
 + ("O^" ?Ô)
 + ("O~" ?Õ)
 + ("O\"" ?Ö)
 + ("O/" ?Ø)
 + ("R`" ?Å–)
 + ("S~" ?Å )
 + ("T/" ?Ŧ)
 + ("U`" ?Ų)
 + ("U'" ?Ú)
 + ("U^" ?Û)
 + ("U\"" ?Ãœ)
 + ("U~" ?Ũ)
 + ("U-" ?Ū)
 + ("Z~" ?Ž)
 + ("a`" ?Ä…)
 + ("a-" ?Ä)
 + ("a'" ?á)
 + ("a^" ?â)
 + ("a~" ?ã)
 + ("a\"" ?ä)
 + ("a/" ?Ã¥)
 + ("c~" ?Ä)
 + ("d/" ?Ä‘)
 + ("e/" ?æ)
 + ("e-" ?Ä“)
 + ("e'" ?é)
 + ("e`" ?Ä™)
 + ("e\"" ?ë)
 + ("e~" ?Ä—)
 + ("g`" ?Ä£)
 + ("i~" ?Ä©)
 + ("i`" ?į)
 + ("i'" ?í)
 + ("i^" ?î)
 + ("i-" ?Ä«)
 + ("k/" ?ĸ)
 + ("k`" ?Ä·)
 + ("l`" ?ļ)
 + ("n/" ?Å‹)
 + ("n`" ?ņ)
 + ("o-" ?Å)
 + ("o^" ?ô)
 + ("o~" ?õ)
 + ("o\"" ?ö)
 + ("o/" ?ø)
 + ("r`" ?Å—)
 + ("s/" ?ß)
 + ("s~" ?Å¡)
 + ("t/" ?ŧ)
 + ("u`" ?ų)
 + ("u'" ?ú)
 + ("u^" ?û)
 + ("u\"" ?ü)
 + ("u~" ?Å©)
 + ("u-" ?Å«)
 + ("z~" ?ž)
  
   ("A``" ["A`"])
   ("A--" ["A-"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Ma\e(B
 -  grave      |    `    | a` -> \e,M`\e(B
 -  circumflex |    ^    | a^ -> \e,Mb\e(B
 -  diaeresis  |    \"    | a\" -> \e,Md\e(B
 -  tilde      |    ~    | a~ -> \e,Mc\e(B
 -  breve      |    ~    | g~ -> \e,Mp\e(B
 -  cedilla    |    `    | c` -> \e,Mg\e(B
 -  dot        |    /    | i/ -> \e,M}\e(B   I/ -> \e,M]\e(B
 -  nordic     |    /    | a/ -> \e,Me\e(B   e/ -> \e,Mf\e(B   o/ -> \e,Mx\e(B
 -  others     |    /    | s/ -> \e,M_\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  tilde      |    ~    | a~ -> Ã£
 +  breve      |    ~    | g~ -> ÄŸ
 +  cedilla    |    `    | c` -> Ã§
 +  dot        |    /    | i/ -> Ä±   I/ -> Ä°
 +  nordic     |    /    | a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |    /    | s/ -> ÃŸ
  
  It would be natural to use period and comma for dots and cedillas, but
  that would inconvenient in practice, because periods and commas are
@@@ -776,68 -777,68 +777,68 @@@ Doubling the postfix separates the lett
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,MA\e(B)
 - ("A/" ?\e,ME\e(B)
 - ("A\"" ?\e,MD\e(B)
 - ("A^" ?\e,MB\e(B)
 - ("A`" ?\e,M@\e(B)
 - ("A~" ?\e,MC\e(B)
 - ("C`" ?\e,MG\e(B)
 - ("E'" ?\e,MI\e(B)
 - ("E/" ?\e,MF\e(B)
 - ("E\"" ?\e,MK\e(B)
 - ("E^" ?\e,MJ\e(B)
 - ("E`" ?\e,MH\e(B)
 - ("G~" ?\e,MP\e(B)
 - ("I'" ?\e,MM\e(B)
 - ("I/" ?\e,M]\e(B)
 - ("I\"" ?\e,MO\e(B)
 - ("I^" ?\e,MN\e(B)
 - ("I`" ?\e,ML\e(B)
 - ("N~" ?\e,MQ\e(B)
 - ("O'" ?\e,MS\e(B)
 - ("O/" ?\e,MX\e(B)
 - ("O\"" ?\e,MV\e(B)
 - ("O^" ?\e,MT\e(B)
 - ("O`" ?\e,MR\e(B)
 - ("O~" ?\e,MU\e(B)
 - ("S`" ?\e,M^\e(B)
 - ("U'" ?\e,MZ\e(B)
 - ("U\"" ?\e,M\\e(B)
 - ("U^" ?\e,M[\e(B)
 - ("U`" ?\e,MY\e(B)
 - ("a'" ?\e,Ma\e(B)
 - ("a/" ?\e,Me\e(B)
 - ("a\"" ?\e,Md\e(B)
 - ("a^" ?\e,Mb\e(B)
 - ("a`" ?\e,M`\e(B)
 - ("a~" ?\e,Mc\e(B)
 - ("c`" ?\e,Mg\e(B)
 - ("e'" ?\e,Mi\e(B)
 - ("e/" ?\e,Mf\e(B)
 - ("e\"" ?\e,Mk\e(B)
 - ("e^" ?\e,Mj\e(B)
 - ("e`" ?\e,Mh\e(B)
 - ("g~" ?\e,Mp\e(B)
 - ("i'" ?\e,Mm\e(B)
 - ("i/" ?\e,M}\e(B)
 - ("i\"" ?\e,Mo\e(B)
 - ("i^" ?\e,Mn\e(B)
 - ("i`" ?\e,Ml\e(B)
 - ("n~" ?\e,Mq\e(B)
 - ("o'" ?\e,Ms\e(B)
 - ("o/" ?\e,Mx\e(B)
 - ("o\"" ?\e,Mv\e(B)
 - ("o^" ?\e,Mt\e(B)
 - ("o`" ?\e,Mr\e(B)
 - ("o~" ?\e,Mu\e(B)
 - ("s`" ?\e,M~\e(B)
 - ("s/" ?\e,M_\e(B)
 - ("u'" ?\e,Mz\e(B)
 - ("u\"" ?\e,M|\e(B)
 - ("u^" ?\e,M{\e(B)
 - ("u`" ?\e,My\e(B)
 - ("y\"" ?\e,M\7f\e(B)
 + ("A'" ?Ã)
 + ("A/" ?Ã…)
 + ("A\"" ?Ä)
 + ("A^" ?Â)
 + ("A`" ?À)
 + ("A~" ?Ã)
 + ("C`" ?Ç)
 + ("E'" ?É)
 + ("E/" ?Æ)
 + ("E\"" ?Ë)
 + ("E^" ?Ê)
 + ("E`" ?È)
 + ("G~" ?Äž)
 + ("I'" ?Ã)
 + ("I/" ?Ä°)
 + ("I\"" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I`" ?ÃŒ)
 + ("N~" ?Ñ)
 + ("O'" ?Ó)
 + ("O/" ?Ø)
 + ("O\"" ?Ö)
 + ("O^" ?Ô)
 + ("O`" ?Ã’)
 + ("O~" ?Õ)
 + ("S`" ?Åž)
 + ("U'" ?Ú)
 + ("U\"" ?Ãœ)
 + ("U^" ?Û)
 + ("U`" ?Ù)
 + ("a'" ?á)
 + ("a/" ?Ã¥)
 + ("a\"" ?ä)
 + ("a^" ?â)
 + ("a`" ?à)
 + ("a~" ?ã)
 + ("c`" ?ç)
 + ("e'" ?é)
 + ("e/" ?æ)
 + ("e\"" ?ë)
 + ("e^" ?ê)
 + ("e`" ?è)
 + ("g~" ?ÄŸ)
 + ("i'" ?í)
 + ("i/" ?ı)
 + ("i\"" ?ï)
 + ("i^" ?î)
 + ("i`" ?ì)
 + ("n~" ?ñ)
 + ("o'" ?ó)
 + ("o/" ?ø)
 + ("o\"" ?ö)
 + ("o^" ?ô)
 + ("o`" ?ò)
 + ("o~" ?õ)
 + ("s`" ?ÅŸ)
 + ("s/" ?ß)
 + ("u'" ?ú)
 + ("u\"" ?ü)
 + ("u^" ?û)
 + ("u`" ?ù)
 + ("y\"" ?ÿ)
  
   ("A''" ["A'"])
   ("A//" ["A/"])
  
  (quail-define-package
   "danish-alt-postfix" "Latin-1" "DA<" t
 - "Danish input method (rule: AE -> \e,AF\e(B, OE -> \e,AX\e(B, AA -> \e,AE\e(B, E' -> \e,AI\e(B)
 + "Danish input method (rule: AE -> Ã†, OE -> Ã˜, AA -> Ã…, E' -> Ã‰)
  
  Doubling the postfix separates the letter and postfix: e.g. aee -> ae
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AX\e(B)
 - ("oe" ?\e,Ax\e(B)
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ø)
 + ("oe" ?ø)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
   "Esperanto input method with postfix modifiers
  
  A following ^ or x will produce an accented character,
 -e.g. c^ -> \e,Cf\e(B   gx -> \e,Cx\e(B   u^ -> \e,C}\e(B.
 +e.g. c^ -> Ä‰   gx -> Ä   u^ -> Å­.
  
  Doubling the postfix separates the letter and postfix,
  e.g. a'' -> a'.
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("Cx" ?\e,CF\e(B)
 - ("C^" ?\e,CF\e(B)
 - ("cx" ?\e,Cf\e(B)
 - ("c^" ?\e,Cf\e(B)
 - ("Gx" ?\e,CX\e(B)
 - ("G^" ?\e,CX\e(B)
 - ("gx" ?\e,Cx\e(B)
 - ("g^" ?\e,Cx\e(B)
 - ("Hx" ?\e,C&\e(B)
 - ("H^" ?\e,C&\e(B)
 - ("hx" ?\e,C6\e(B)
 - ("h^" ?\e,C6\e(B)
 - ("Jx" ?\e,C,\e(B)
 - ("J^" ?\e,C,\e(B)
 - ("jx" ?\e,C<\e(B)
 - ("j^" ?\e,C<\e(B)
 - ("Sx" ?\e,C^\e(B)
 - ("S^" ?\e,C^\e(B)
 - ("sx" ?\e,C~\e(B)
 - ("s^" ?\e,C~\e(B)
 - ("Ux" ?\e,C]\e(B)
 - ("U^" ?\e,C]\e(B)
 - ("ux" ?\e,C}\e(B)
 - ("u^" ?\e,C}\e(B)
 + ("Cx" ?Ĉ)
 + ("C^" ?Ĉ)
 + ("cx" ?ĉ)
 + ("c^" ?ĉ)
 + ("Gx" ?Äœ)
 + ("G^" ?Äœ)
 + ("gx" ?Ä)
 + ("g^" ?Ä)
 + ("Hx" ?Ĥ)
 + ("H^" ?Ĥ)
 + ("hx" ?Ä¥)
 + ("h^" ?Ä¥)
 + ("Jx" ?Ä´)
 + ("J^" ?Ä´)
 + ("jx" ?ĵ)
 + ("j^" ?ĵ)
 + ("Sx" ?Åœ)
 + ("S^" ?Åœ)
 + ("sx" ?Å)
 + ("s^" ?Å)
 + ("Ux" ?Ŭ)
 + ("U^" ?Ŭ)
 + ("ux" ?Å­)
 + ("u^" ?Å­)
  
   ("Cxx" ["Cx"])
   ("C^^" ["C^"])
   "finnish-alt-postfix" "Latin-1" "FI<" t
   "Finnish (Suomi) input method
  
 -AE  -> \e,AD\e(B
 +AE  -> Ã„
  AEE -> AE
 -OE  -> \e,AV\e(B
 +OE  -> Ã–
  OEE -> OE
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AD\e(B)
 - ("ae" ?\e,Ad\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 + ("AE" ?Ä)
 + ("ae" ?ä)
 + ("OE" ?Ö)
 + ("oe" ?ö)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
  
  (quail-define-package
   "french-alt-postfix" "French" "FR<" t
 - "French (Fran\e,Ag\e(Bais) input method with postfix modifiers
 + "French (Français) input method with postfix modifiers
  
 -` pour grave, ' pour aigu, ^ pour circonflexe, et \" pour tr\e,Ai\e(Bma.
 -Par exemple: a` -> \e,A`\e(B   e' -> \e,Ai\e(B.
 +` pour grave, ' pour aigu, ^ pour circonflexe, et \" pour tréma.
 +Par exemple: a` -> Ã    e' -> Ã©.
  
 -\e,AG\e(B, \e,A+\e(B, et \e,A;\e(B sont produits par C/, <<, et >>.
 +Ç, Â«, et Â» sont produits par C/, <<, et >>.
  
  En doublant la frappe des diacritiques, ils s'isoleront de la lettre.
  Par exemple: e'' -> e'
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,A@\e(B)
 - ("A^" ?\e,AB\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("a^" ?\e,Ab\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("E^" ?\e,AJ\e(B)
 - ("E\"" ?\e,AK\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("e^" ?\e,Aj\e(B)
 - ("e\"" ?\e,Ak\e(B)
 - ("I^" ?\e,AN\e(B)
 - ("I\"" ?\e,AO\e(B)
 - ("i^" ?\e,An\e(B)
 - ("i\"" ?\e,Ao\e(B)
 - ("O^" ?\e,AT\e(B)
 - ("o^" ?\e,At\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("U^" ?\e,A[\e(B)
 - ("U\"" ?\e,A\\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("u^" ?\e,A{\e(B)
 - ("u\"" ?\e,A|\e(B)
 - ("C/" ?\e,AG\e(B)
 - ("c/" ?\e,Ag\e(B)
 - ("<<" ?\e,A+\e(B)
 - (">>" ?\e,A;\e(B)
 + ("A`" ?À)
 + ("A^" ?Â)
 + ("a`" ?à)
 + ("a^" ?â)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("E^" ?Ê)
 + ("E\"" ?Ë)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("e^" ?ê)
 + ("e\"" ?ë)
 + ("I^" ?ÃŽ)
 + ("I\"" ?Ã)
 + ("i^" ?î)
 + ("i\"" ?ï)
 + ("O^" ?Ô)
 + ("o^" ?ô)
 + ("U`" ?Ù)
 + ("U^" ?Û)
 + ("U\"" ?Ãœ)
 + ("u`" ?ù)
 + ("u^" ?û)
 + ("u\"" ?ü)
 + ("C/" ?Ç)
 + ("c/" ?ç)
 + ("<<" ?«)
 + (">>" ?»)
  
   ("A``" ["A`"])
   ("A^^" ["A^"])
   "german-alt-postfix" "German" "DE<" t
   "German (Deutsch) input method
  
 -ae  -> \e,Ad\e(B
 +ae  -> Ã¤
  aee -> ae
 -oe  -> \e,Av\e(B
 +oe  -> Ã¶
  oee -> oe
 -ue  -> \e,A|\e(B
 +ue  -> Ã¼
  uee -> ue
 -sz  -> \e,A_\e(B
 +sz  -> ÃŸ
  szz -> sz
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AD\e(B)
 - ("ae" ?\e,Ad\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 - ("UE" ?\e,A\\e(B)
 - ("ue" ?\e,A|\e(B)
 - ("sz" ?\e,A_\e(B)
 + ("AE" ?Ä)
 + ("ae" ?ä)
 + ("OE" ?Ö)
 + ("oe" ?ö)
 + ("UE" ?Ãœ)
 + ("ue" ?ü)
 + ("sz" ?ß)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
  
  (quail-define-package
   "icelandic-alt-postfix" "Latin-1" "IS<" t
 - "Icelandic (\e,AM\e(Bslenska) input method with postfix modifiers
 -
 -A' -> \e,AA\e(B
 -E' -> \e,AI\e(B
 -I' -> \e,AM\e(B
 -O' -> \e,AS\e(B
 -U' -> \e,AZ\e(B
 -Y' -> \e,A]\e(B
 -AE -> \e,AF\e(B
 -OE -> \e,AV\e(B
 -D/ -> \e,AP\e(B (eth)
 -T/ -> \e,A^\e(B (thorn)
 + "Icelandic (Ãslenska) input method with postfix modifiers
 +
 +A' -> Ã
 +E' -> Ã‰
 +I' -> Ã
 +O' -> Ã“
 +U' -> Ãš
 +Y' -> Ã
 +AE -> Ã†
 +OE -> Ã–
 +D/ -> Ã (eth)
 +T/ -> Ãž (thorn)
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,AA\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("o'" ?\e,As\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("Y'" ?\e,A]\e(B)
 - ("y'" ?\e,A}\e(B)
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 - ("D/" ?\e,AP\e(B)
 - ("d/" ?\e,Ap\e(B)
 - ("T/" ?\e,A^\e(B)
 - ("t/" ?\e,A~\e(B)
 + ("A'" ?Ã)
 + ("a'" ?á)
 + ("E'" ?É)
 + ("e'" ?é)
 + ("I'" ?Ã)
 + ("i'" ?í)
 + ("O'" ?Ó)
 + ("o'" ?ó)
 + ("U'" ?Ú)
 + ("u'" ?ú)
 + ("Y'" ?Ã)
 + ("y'" ?ý)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ö)
 + ("oe" ?ö)
 + ("D/" ?Ã)
 + ("d/" ?ð)
 + ("T/" ?Þ)
 + ("t/" ?þ)
  
   ("A''" ["A'"])
   ("a''" ["a'"])
   "italian-alt-postfix" "Latin-1" "IT<" t
   "Italian (Italiano) input method with postfix modifiers
  
 -a' -> \e,Aa\e(B    A' -> \e,AA\e(B    a` -> \e,A`\e(B    A` -> \e,A@\e(B    i^ -> \e,An\e(B    << -> \e,A+\e(B
 -e' -> \e,Ai\e(B    E' -> \e,AI\e(B    e` -> \e,Ah\e(B    E` -> \e,AH\e(B    I^ -> \e,AN\e(B    >> -> \e,A;\e(B
 -i' -> \e,Am\e(B    I' -> \e,AM\e(B    i` -> \e,Al\e(B    I` -> \e,AL\e(B               o_ -> \e,A:\e(B
 -o' -> \e,As\e(B    O' -> \e,AS\e(B    o` -> \e,Ar\e(B    O` -> \e,AR\e(B               a_ -> \e,A*\e(B
 -u' -> \e,Az\e(B    U' -> \e,AZ\e(B    u` -> \e,Ay\e(B    U` -> \e,AY\e(B
 +a' -> Ã¡    A' -> Ã    a` -> Ã     A` -> Ã€    i^ -> Ã®    << -> Â«
 +e' -> Ã©    E' -> Ã‰    e` -> Ã¨    E` -> Ãˆ    I^ -> ÃŽ    >> -> Â»
 +i' -> Ã­    I' -> Ã    i` -> Ã¬    I` -> ÃŒ               o_ -> Âº
 +o' -> Ã³    O' -> Ã“    o` -> Ã²    O` -> Ã’               a_ -> Âª
 +u' -> Ãº    U' -> Ãš    u` -> Ã¹    U` -> Ã™
  
  This method is for purists who like accents the old way.
  
@@@ -1203,32 -1204,32 +1204,32 @@@ Doubling the postfix separates the lett
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,A@\e(B)
 - ("A'" ?\e,AA\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("I`" ?\e,AL\e(B)
 - ("i`" ?\e,Al\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("I^" ?\e,AN\e(B)
 - ("i^" ?\e,An\e(B)
 - ("O`" ?\e,AR\e(B)
 - ("o`" ?\e,Ar\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("o'" ?\e,As\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("<<" ?\e,A+\e(B)
 - (">>" ?\e,A;\e(B)
 - ("o_" ?\e,A:\e(B)
 - ("a_" ?\e,A*\e(B)
 + ("A`" ?À)
 + ("A'" ?Ã)
 + ("a`" ?à)
 + ("a'" ?á)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("I`" ?ÃŒ)
 + ("i`" ?ì)
 + ("I'" ?Ã)
 + ("i'" ?í)
 + ("I^" ?ÃŽ)
 + ("i^" ?î)
 + ("O`" ?Ã’)
 + ("o`" ?ò)
 + ("O'" ?Ó)
 + ("o'" ?ó)
 + ("U`" ?Ù)
 + ("u`" ?ù)
 + ("U'" ?Ú)
 + ("u'" ?ú)
 + ("<<" ?«)
 + (">>" ?»)
 + ("o_" ?º)
 + ("a_" ?ª)
  
   ("A``" ["A`"])
   ("A''" ["A'"])
  
  (quail-define-package
   "norwegian-alt-postfix" "Latin-1" "NO<" t
 - "Norwegian (Norsk) input method (rule: AE->\e,AF\e(B, OE->\e,AX\e(B, AA->\e,AE\e(B, E'->\e,AI\e(B)
 + "Norwegian (Norsk) input method (rule: AE->Æ, OE->Ø, AA->Ã…, E'->É)
  
  Doubling the postfix separates the letter and postfix: e.g. aee -> ae
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AX\e(B)
 - ("oe" ?\e,Ax\e(B)
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ø)
 + ("oe" ?ø)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
   "Scandinavian input method with postfix modifiers
  Supported languages are Swedish, Norwegian, Danish, and Finnish.
  
 -ae -> \e,Af\e(B
 -oe -> \e,Ax\e(B
 -aa -> \e,Ae\e(B
 -a\" -> \e,Ad\e(B
 -o\" -> \e,Av\e(B
 -e' -> \e,Ai\e(B
 +ae -> Ã¦
 +oe -> Ã¸
 +aa -> Ã¥
 +a\" -> Ã¤
 +o\" -> Ã¶
 +e' -> Ã©
  
  Doubling the postfix separates the letter and postfix:
  aee -> ae   o\"\" -> o\"   etc.
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AX\e(B)
 - ("oe" ?\e,Ax\e(B)
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("A\"" ?\e,AD\e(B)
 - ("a\"" ?\e,Ad\e(B)
 - ("O\"" ?\e,AV\e(B)
 - ("o\"" ?\e,Av\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ø)
 + ("oe" ?ø)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("A\"" ?Ä)
 + ("a\"" ?ä)
 + ("O\"" ?Ö)
 + ("o\"" ?ö)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
  
  (quail-define-package
   "spanish-alt-postfix" "Spanish" "ES<" t
 - "Spanish (Espa\e,Aq\e(Bol) input method with postfix modifiers
 + "Spanish (Español) input method with postfix modifiers
  
 -A' -> \e,AA\e(B
 -E' -> \e,AI\e(B
 -I' -> \e,AM\e(B
 -O' -> \e,AS\e(B
 -U' -> \e,AZ\e(B
 -N~ -> \e,AQ\e(B
 -!/ -> \e,A!\e(B
 -?/ -> \e,A?\e(B
 +A' -> Ã
 +E' -> Ã‰
 +I' -> Ã
 +O' -> Ã“
 +U' -> Ãš
 +N~ -> Ã‘
 +!/ -> Â¡
 +?/ -> Â¿
  
  Doubling the postfix separates the letter and postfix:
  a'' -> a'   n~~ -> n~, etc.
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,AA\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("o'" ?\e,As\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("N~" ?\e,AQ\e(B)
 - ("n~" ?\e,Aq\e(B)
 - ("?/" ?\e,A?\e(B)
 - ("!/" ?\e,A!\e(B)
 + ("A'" ?Ã)
 + ("a'" ?á)
 + ("E'" ?É)
 + ("e'" ?é)
 + ("I'" ?Ã)
 + ("i'" ?í)
 + ("O'" ?Ó)
 + ("o'" ?ó)
 + ("U'" ?Ú)
 + ("u'" ?ú)
 + ("N~" ?Ñ)
 + ("n~" ?ñ)
 + ("?/" ?¿)
 + ("!/" ?¡)
  
   ("A''" ["A'"])
   ("a''" ["a'"])
  
  (quail-define-package
   "swedish-alt-postfix" "Latin-1" "SV<" t
 - "Swedish (Svenska) input method (rule: AA -> \e,AE\e(B, AE -> \e,AD\e(B, OE -> \e,AV\e(B, E' -> \e,AI\e(B)
 + "Swedish (Svenska) input method (rule: AA -> Ã…, AE -> Ã„, OE -> Ã–, E' -> Ã‰)
  
  Doubling the postfix separates the letter and postfix: e.g. aee -> ae
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("AE" ?\e,AD\e(B)
 - ("ae" ?\e,Ad\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("AE" ?Ä)
 + ("ae" ?ä)
 + ("OE" ?Ö)
 + ("oe" ?ö)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AAA" ["AA"])
   ("aaa" ["aa"])
   )
  
  (quail-define-package
 - "turkish-latin-3-alt-postfix" "Turkish" "TR3<<" t
 - "Turkish (T\e,A|\e(Brk\e,Ag\e(Be) input method with postfix modifiers.
 + "turkish-alt-postfix" "Turkish" "TR«" t
 + "Turkish (Türkçe) input method with postfix modifiers.
  
 -This is for those who use Latin-3 (ISO-8859-3) for Turkish.  If you
 -use Latin-5 (ISO-8859-9), you should use \"turkish-alt-postfix\" instead.
 +turkish-latin-3-alt-postfix is an obsolete alias for turkish-alt-postfix.
  
 -Note for I, \e,C9\e(B, \e,C)\e(B, i.
 +Note for I, Ä±, Ä°, i.
  
 -A^ -> \e,CB\e(B
 -C` -> \e,CG\e(B
 -G^ -> \e,C+\e(B
 +A^ -> Ã‚
 +C` -> Ã‡
 +G^ -> Äž
  I  -> I
 -i  -> \e,C9\e(B
 -I/ -> \e,C)\e(B
 +i  -> Ä±
 +I/ -> Ä°
  i/ -> i
 -O\" -> \e,CV\e(B
 -S` -> \e,C*\e(B
 -U\" -> \e,C\\e(B
 -U^ -> \e,C[\e(B
 +O\" -> Ã–
 +S` -> Åž
 +U\" -> Ãœ
 +U^ -> Ã›
  
  Doubling the postfix separates the letter and postfix: e.g. a^^ -> a^
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A^" ?\e,CB\e(B)
 - ("a^" ?\e,Cb\e(B)
 - ("C`" ?\e,CG\e(B)
 - ("c`" ?\e,Cg\e(B)
 - ("G^" ?\e,C+\e(B)
 - ("g^" ?\e,C;\e(B)
 - ("I/" ?\e,C)\e(B)
 - ("i" ?\e,C9\e(B)
 + ("A^" ?Â)
 + ("a^" ?â)
 + ("C`" ?Ç)
 + ("c`" ?ç)
 + ("G^" ?Äž)
 + ("g^" ?ÄŸ)
 + ("I/" ?Ä°)
 + ("i" ?ı)
   ("i/" ?i)
 - ("O\"" ?\e,CV\e(B)
 - ("o\"" ?\e,Cv\e(B)
 - ("S`" ?\e,C*\e(B)
 - ("s`" ?\e,C:\e(B)
 - ("U\"" ?\e,C\\e(B)
 - ("u\"" ?\e,C|\e(B)
 - ("U^" ?\e,C[\e(B)
 - ("u^" ?\e,C{\e(B)
 + ("O\"" ?Ö)
 + ("o\"" ?ö)
 + ("S`" ?Åž)
 + ("s`" ?ÅŸ)
 + ("U\"" ?Ãœ)
 + ("u\"" ?ü)
 + ("U^" ?Û)
 + ("u^" ?û)
  
   ("A^^" ["A^"])
   ("a^^" ["a^"])
   ("u^^" ["u^"])
   )
  
 -(quail-define-package
 - "turkish-alt-postfix" "Turkish" "TR\e,A+\e(B" t
 - "Turkish (T\e,A|\e(Brk\e,Ag\e(Be) input method with postfix modifiers.
 -
 -This is for those who use Latin-5 (ISO-8859-9) for Turkish.  If you
 -use Latin-3 (ISO-8859-3), you should use
 -\"turkish-latin-3-alt-postfix\" instead.
 -
 -Note for I, \e,M}\e(B, \e,M]\e(B, i.
 -
 -A^ -> \e,MB\e(B
 -C` -> \e,MG\e(B
 -G^ -> \e,MP\e(B
 -I  -> I
 -i  -> \e,M}\e(B
 -I/ -> \e,M]\e(B
 -i/ -> i
 -O\" -> \e,MV\e(B
 -S` -> \e,M^\e(B
 -U\" -> \e,M\\e(B
 -U^ -> \e,M[\e(B
 -
 -Doubling the postfix separates the letter and postfix: e.g. a^^ -> a^
 -" nil t nil nil nil nil nil nil nil nil t)
 -
 -(quail-define-rules
 - ("A^" ?\e,MB\e(B)
 - ("a^" ?\e,Mb\e(B)
 - ("C`" ?\e,MG\e(B)
 - ("c`" ?\e,Mg\e(B)
 - ("G^" ?\e,MP\e(B)
 - ("g^" ?\e,Mp\e(B)
 - ("I/" ?\e,M]\e(B)
 - ("i" ?\e,M}\e(B)
 - ("i/" ?i)
 - ("O\"" ?\e,MV\e(B)
 - ("o\"" ?\e,Cv\e(B)
 - ("S`" ?\e,M^\e(B)
 - ("s`" ?\e,M~\e(B)
 - ("U\"" ?\e,M\\e(B)
 - ("u\"" ?\e,M|\e(B)
 - ("U^" ?\e,M[\e(B)
 - ("u^" ?\e,M{\e(B)
 -
 - ("A^^" ["A^"])
 - ("a^^" ["a^"])
 - ("C``" ["C`"])
 - ("c``" ["c`"])
 - ("G^^" ["G^"])
 - ("g^^" ["g^"])
 - ("I//" ["I/"])
 - ("i" ["i"])
 - ("i//" ["i/"])
 - ("O\"\"" ["O\""])
 - ("o\"\"" ["o\""])
 - ("S``" ["S`"])
 - ("s``" ["s`"])
 - ("U\"\"" ["U\""])
 - ("u\"\"" ["u\""])
 - ("U^^" ["U^"])
 - ("u^^" ["u^"])
 - )
 +;; Backwards compatibility.
 +(push (cons "turkish-latin-3-alt-postfix"
 +          (cdr (assoc "turkish-alt-postfix" quail-package-alist)))
 +      quail-package-alist)
  
  ;; Dutch Quail input method derived from the one in Yudit by Roman
  ;; Czyborra.
  (quail-define-package
   "dutch" "Dutch" "NL" t
   "Dutch character mixfix input method.
 -Uses the `mule-unicode-0100-24ff' charset to supplement Latin-1.
 +Caters for French and Turkish as well as Dutch.
  
               |         | examples
   ------------+---------+----------
 -  others     |         | fl. -> \e$,1!R\e(B  eur. -> \e$,1tL\e(B  ij -> \e$,1 S\e(B  IJ -> \e$,1 R\e(B
 +  others     |         | fl. -> Æ’  eur. -> â‚¬  ij -> Ä³  IJ -> Ä²
   ------------+---------+----------
               | postfix |
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Aa\e(B
 -  grave      |    `    | a` -> \e,A`\e(B
 -  circumflex |    ^    | a^ -> \e,Ab\e(B
 -  Turkish    | various | i/ -> \e$,1 Q\e(B  s, -> \e$,1 \7f\e(B  g^ -> \e$,1 ?\e(B   I/ -> \e$,1 P\e(B
 -             |         |  S, -> \e$,1 ~\e(B  G^ -> \e$,1 >\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  Turkish    | various | i/ -> Ä±  s, -> ÅŸ  g^ -> ÄŸ   I/ -> Ä°
 +             |         |  S, -> Åž  G^ -> Äž
   ------------+---------+----------
               | prefix  |
   ------------+---------+----------
 -  diaeresis  |    \"    | \"a -> \e,Ad\e(B
 +  diaeresis  |    \"    | \"a -> Ã¤
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("fl." ?\e$,1!R\e(B) ;; LATIN SMALL LETTER F WITH HOOK (florin currency symbol)
 - ("eur." ?\e$,1tL\e(B) ;; EURO SIGN
 - ;; \e$,1r|\e(BThe 25th letter of the Dutch alphabet.\e$,1r}\e(B
 - ("ij" ?\e$,1 S\e(B) ;; LATIN SMALL LIGATURE IJ
 - ("IJ" ?\e$,1 R\e(B) ;; LATIN CAPITAL LIGATURE IJ
 - ;; \e$,1r|\e(BTrema on the second letter of vowel pair.\e$,1r}\e(B  Yudit uses `:', not `"'.
 - ("\"a" ?\e,Ad\e(B) ;; LATIN SMALL LETTER A WITH DIAERESIS
 - ("\"e" ?\e,Ak\e(B) ;; LATIN SMALL LETTER E WITH DIAERESIS
 - ("\"i" ?\e,Ao\e(B) ;; LATIN SMALL LETTER I WITH DIAERESIS
 - ("\"o" ?\e,Av\e(B) ;; LATIN SMALL LETTER O WITH DIAERESIS
 - ("\"u" ?\e,A|\e(B) ;; LATIN SMALL LETTER U WITH DIAERESIS
 - ("\"A" ?\e,AD\e(B) ;; LATIN CAPITAL LETTER A WITH DIAERESIS
 - ("\"E" ?\e,AK\e(B) ;; LATIN CAPITAL LETTER E WITH DIAERESIS
 - ("\"I" ?\e,AO\e(B) ;; LATIN CAPITAL LETTER I WITH DIAERESIS
 - ("\"O" ?\e,AV\e(B) ;; LATIN CAPITAL LETTER O WITH DIAERESIS
 - ("\"U" ?\e,A\\e(B) ;; LATIN CAPITAL LETTER U WITH DIAERESIS
 - ;; \e$,1r|\e(BAcute, marking emphasis on long vowels\e$,1r}\e(B:
 - ("a'" ?\e,Aa\e(B) ;; LATIN SMALL LETTER A WITH ACUTE
 - ("e'" ?\e,Ai\e(B) ;; LATIN SMALL LETTER E WITH ACUTE
 - ("i'" ?\e,Am\e(B) ;; LATIN SMALL LETTER I WITH ACUTE
 - ("o'" ?\e,As\e(B) ;; LATIN SMALL LETTER O WITH ACUTE
 - ("u'" ?\e,Az\e(B) ;; LATIN SMALL LETTER U WITH ACUTE
 - ("A'" ?\e,AA\e(B) ;; LATIN CAPITAL LETTER A WITH ACUTE
 - ("E'" ?\e,AI\e(B) ;; LATIN CAPITAL LETTER E WITH ACUTE
 - ("I'" ?\e,AM\e(B) ;; LATIN CAPITAL LETTER I WITH ACUTE
 - ("O'" ?\e,AS\e(B) ;; LATIN CAPITAL LETTER O WITH ACUTE
 - ("U'" ?\e,AZ\e(B) ;; LATIN CAPITAL LETTER U WITH ACUTE
 - ;; \e$,1r|\e(BGrave, marking emphasis on short vowels\e$,1r}\e(B:
 - ("a`" ?\e,A`\e(B) ;; LATIN SMALL LETTER A WITH GRAVE
 - ("e`" ?\e,Ah\e(B) ;; LATIN SMALL LETTER E WITH GRAVE
 - ("i`" ?\e,Al\e(B) ;; LATIN SMALL LETTER I WITH GRAVE
 - ("o`" ?\e,Ar\e(B) ;; LATIN SMALL LETTER O WITH GRAVE
 - ("u`" ?\e,Ay\e(B) ;; LATIN SMALL LETTER U WITH GRAVE
 - ("A`" ?\e,A@\e(B) ;; LATIN CAPITAL LETTER A WITH GRAVE
 - ("E`" ?\e,AH\e(B) ;; LATIN CAPITAL LETTER E WITH GRAVE
 - ("I`" ?\e,AL\e(B) ;; LATIN CAPITAL LETTER I WITH GRAVE
 - ("O`" ?\e,AR\e(B) ;; LATIN CAPITAL LETTER O WITH GRAVE
 - ("U`" ?\e,AY\e(B) ;; LATIN CAPITAL LETTER U WITH GRAVE
 - ;; \e$,1r|\e(BCater for the use of many French words and use of the circumflex
 - ;; in Frisian.\e$,1r}\e(B  Yudit used `;' for cedilla.
 - ("c," ?\e,Ag\e(B) ;; LATIN SMALL LETTER C WITH CEDILLA
 - ("C," ?\e,AG\e(B) ;; LATIN CAPITAL LETTER C WITH CEDILLA
 - ("a^" ?\e,Ab\e(B) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX
 - ("e^" ?\e,Aj\e(B) ;; LATIN SMALL LETTER E WITH CIRCUMFLEX
 - ("i^" ?\e,An\e(B) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX
 - ("o^" ?\e,At\e(B) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX
 - ("u^" ?\e,A{\e(B) ;; LATIN SMALL LETTER U WITH CIRCUMFLEX
 - ("A^" ?\e,AB\e(B) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX
 - ("E^" ?\e,AJ\e(B) ;; LATIN CAPITAL LETTER E WITH CIRCUMFLEX
 - ("I^" ?\e,AN\e(B) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX
 - ("O^" ?\e,AT\e(B) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
 - ("U^" ?\e,A[\e(B) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX
 - ;; \e$,1r|\e(BFollow the example of the Dutch POSIX locale, using ISO-8859-9 to
 - ;; cater to the many Turks in Dutch society.\e$,1r}\e(B  Perhaps German methods
 + ("fl." ?Æ’) ;; LATIN SMALL LETTER F WITH HOOK (florin currency symbol)
 + ("eur." ?€) ;; EURO SIGN
 + ;; â€œThe 25th letter of the Dutch alphabet.â€
 + ("ij" ?ij) ;; LATIN SMALL LIGATURE IJ
 + ("IJ" ?IJ) ;; LATIN CAPITAL LIGATURE IJ
 + ;; â€œTrema on the second letter of vowel pair.† Yudit uses `:', not `"'.
 + ("\"a" ?ä) ;; LATIN SMALL LETTER A WITH DIAERESIS 
 + ("\"e" ?ë) ;; LATIN SMALL LETTER E WITH DIAERESIS 
 + ("\"i" ?ï) ;; LATIN SMALL LETTER I WITH DIAERESIS 
 + ("\"o" ?ö) ;; LATIN SMALL LETTER O WITH DIAERESIS 
 + ("\"u" ?ü) ;; LATIN SMALL LETTER U WITH DIAERESIS 
 + ("\"A" ?Ä) ;; LATIN CAPITAL LETTER A WITH DIAERESIS 
 + ("\"E" ?Ë) ;; LATIN CAPITAL LETTER E WITH DIAERESIS 
 + ("\"I" ?Ã) ;; LATIN CAPITAL LETTER I WITH DIAERESIS 
 + ("\"O" ?Ö) ;; LATIN CAPITAL LETTER O WITH DIAERESIS 
 + ("\"U" ?Ãœ) ;; LATIN CAPITAL LETTER U WITH DIAERESIS 
 + ;; â€œAcute, marking emphasis on long vowelsâ€:
 + ("a'" ?á) ;; LATIN SMALL LETTER A WITH ACUTE 
 + ("e'" ?é) ;; LATIN SMALL LETTER E WITH ACUTE 
 + ("i'" ?í) ;; LATIN SMALL LETTER I WITH ACUTE 
 + ("o'" ?ó) ;; LATIN SMALL LETTER O WITH ACUTE 
 + ("u'" ?ú) ;; LATIN SMALL LETTER U WITH ACUTE 
 + ("A'" ?Ã) ;; LATIN CAPITAL LETTER A WITH ACUTE 
 + ("E'" ?É) ;; LATIN CAPITAL LETTER E WITH ACUTE 
 + ("I'" ?Ã) ;; LATIN CAPITAL LETTER I WITH ACUTE 
 + ("O'" ?Ó) ;; LATIN CAPITAL LETTER O WITH ACUTE 
 + ("U'" ?Ú) ;; LATIN CAPITAL LETTER U WITH ACUTE 
 + ;; â€œGrave, marking emphasis on short vowelsâ€:
 + ("a`" ?à) ;; LATIN SMALL LETTER A WITH GRAVE
 + ("e`" ?è) ;; LATIN SMALL LETTER E WITH GRAVE 
 + ("i`" ?ì) ;; LATIN SMALL LETTER I WITH GRAVE 
 + ("o`" ?ò) ;; LATIN SMALL LETTER O WITH GRAVE 
 + ("u`" ?ù) ;; LATIN SMALL LETTER U WITH GRAVE 
 + ("A`" ?À) ;; LATIN CAPITAL LETTER A WITH GRAVE 
 + ("E`" ?È) ;; LATIN CAPITAL LETTER E WITH GRAVE 
 + ("I`" ?ÃŒ) ;; LATIN CAPITAL LETTER I WITH GRAVE 
 + ("O`" ?Ã’) ;; LATIN CAPITAL LETTER O WITH GRAVE 
 + ("U`" ?Ù) ;; LATIN CAPITAL LETTER U WITH GRAVE
 + ;; â€œCater for the use of many French words and use of the circumflex
 + ;; in Frisian.† Yudit used `;' for cedilla.
 + ("c," ?ç) ;; LATIN SMALL LETTER C WITH CEDILLA 
 + ("C," ?Ç) ;; LATIN CAPITAL LETTER C WITH CEDILLA 
 + ("a^" ?â) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX 
 + ("e^" ?ê) ;; LATIN SMALL LETTER E WITH CIRCUMFLEX 
 + ("i^" ?î) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX 
 + ("o^" ?ô) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX 
 + ("u^" ?û) ;; LATIN SMALL LETTER U WITH CIRCUMFLEX 
 + ("A^" ?Â) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX 
 + ("E^" ?Ê) ;; LATIN CAPITAL LETTER E WITH CIRCUMFLEX 
 + ("I^" ?ÃŽ) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX 
 + ("O^" ?Ô) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX 
 + ("U^" ?Û) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX
 + ;; â€œFollow the example of the Dutch POSIX locale, using ISO-8859-9 to
 + ;; cater to the many Turks in Dutch society.† Perhaps German methods
   ;; should do so too.  Follow turkish-alt-postfix here.
 - ("i/" ?\e$,1 Q\e(B) ;; LATIN SMALL LETTER I WITH NO DOT
 - ("s," ?\e$,1 \7f\e(B) ;; LATIN SMALL LETTER S WITH CEDILLA
 - ("g^" ?\e$,1 ?\e(B) ;; LATIN SMALL LETTER G WITH BREVE
 - ("I/" ?\e$,1 P\e(B) ;; LATIN CAPITAL LETTER I WITH DOT ABOVE
 - ("S," ?\e$,1 ~\e(B) ;; LATIN CAPITAL LETTER S WITH CEDILLA
 - ("G^" ?\e$,1 >\e(B) ;; LATIN CAPITAL LETTER G WITH BREVE
 + ("i/" ?ı) ;; LATIN SMALL LETTER I WITH NO DOT
 + ("s," ?ÅŸ) ;; LATIN SMALL LETTER S WITH CEDILLA 
 + ("g^" ?ÄŸ) ;; LATIN SMALL LETTER G WITH BREVE 
 + ("I/" ?Ä°) ;; LATIN CAPITAL LETTER I WITH DOT ABOVE
 + ("S," ?Åž) ;; LATIN CAPITAL LETTER S WITH CEDILLA 
 + ("G^" ?Äž) ;; LATIN CAPITAL LETTER G WITH BREVE 
   )
  
  ;; Originally from Yudit, discussed with Albertas Agejevas
  " nil t t t t nil nil nil nil nil t)
  
  (quail-define-rules
 - ("1" ?\e$,1 %\e(B)
 - ("2" ?\e$,1 -\e(B)
 - ("3" ?\e$,1 9\e(B)
 - ("4" ?\e$,1 7\e(B)
 - ("5" ?\e$,1 O\e(B)
 - ("6" ?\e$,1!!\e(B)
 - ("7" ?\e$,1!3\e(B)
 - ("8" ?\e$,1!+\e(B)
 - ("9" ?\e$,1r~\e(B)
 - ("0" ?\e$,1r|\e(B)
 - ("=" ?\e$,1!>\e(B)
 - ("!" ?\e$,1 $\e(B)
 - ("@" ?\e$,1 ,\e(B)
 - ("#" ?\e$,1 8\e(B)
 - ("$" ?\e$,1 6\e(B)
 - ("%" ?\e$,1 N\e(B)
 - ("^" ?\e$,1! \e(B)
 - ("&" ?\e$,1!2\e(B)
 - ("*" ?\e$,1!*\e(B)
 - ("+" ?\e$,1!=\e(B))
 + ("1" ?Ä…)
 + ("2" ?Ä)
 + ("3" ?Ä™)
 + ("4" ?Ä—)
 + ("5" ?į)
 + ("6" ?Å¡)
 + ("7" ?ų)
 + ("8" ?Å«)
 + ("9" ?„)
 + ("0" ?“)
 + ("=" ?ž)
 + ("!" ?Ä„)
 + ("@" ?ÄŒ)
 + ("#" ?Ę)
 + ("$" ?Ä–)
 + ("%" ?Ä®)
 + ("^" ?Å )
 + ("&" ?Ų)
 + ("*" ?Ū)
 + ("+" ?Ž))
  
  ;; From XFree 4.1 /usr/X11R6/lib/X11/xkb/symbols/lt, suggested by
  ;; Albertas Agejevas <alga@uosis.mif.vu.lt>
  " nil t t t t nil nil nil nil nil t)
  
  (quail-define-rules
 - ("1" ?\e$,1 %\e(B)
 - ("!" ?\e$,1 $\e(B)
 - ("2" ?\e$,1 -\e(B)
 - ("@" ?\e$,1 ,\e(B)
 - ("#" ?\e$,1 8\e(B)
 - ("4" ?\e$,1 7\e(B)
 - ("$" ?\e$,1 6\e(B)
 - ("5" ?\e$,1 O\e(B)
 - ("%" ?\e$,1 N\e(B)
 - ("6" ?\e$,1!!\e(B)
 - ("^" ?\e$,1! \e(B)
 - ("7" ?\e$,1!3\e(B)
 - ("&" ?\e$,1!2\e(B)
 - ("9" ?\e$,1r~\e(B)
 - ("0" ?\e$,1r|\e(B)
 - ("=" ?\e$,1!>\e(B)
 - ("+" ?\e$,1!=\e(B))
 + ("1" ?Ä…)
 + ("!" ?Ä„)
 + ("2" ?Ä)
 + ("@" ?ÄŒ)
 + ("#" ?Ę)
 + ("4" ?Ä—)
 + ("$" ?Ä–)
 + ("5" ?į)
 + ("%" ?Ä®)
 + ("6" ?Å¡)
 + ("^" ?Å )
 + ("7" ?ų)
 + ("&" ?Ų)
 + ("9" ?„)
 + ("0" ?“)
 + ("=" ?ž)
 + ("+" ?Ž))
  
  ;; From XFree 4.1 /usr/X11R6/lib/X11/xkb/symbols/lv
  (quail-define-package
  " nil t t t t nil nil nil nil nil t)
  
  (quail-define-rules
 - ("4" ?\e$,1tL\e(B)
 - ("$" ?\e,A"\e(B)
 - ("e" ?\e$,1 3\e(B)
 - ("E" ?\e$,1 2\e(B)
 - ("r" ?\e$,1 w\e(B)
 - ("R" ?\e$,1 v\e(B)
 - ("u" ?\e$,1!+\e(B)
 - ("U" ?\e$,1!*\e(B)
 - ("i" ?\e$,1 K\e(B)
 - ("I" ?\e$,1 J\e(B)
 - ("o" ?\e$,1 m\e(B)
 - ("O" ?\e$,1 l\e(B)
 - ("a" ?\e$,1 !\e(B)
 - ("A" ?\e$,1  \e(B)
 - ("s" ?\e$,1!!\e(B)
 - ("S" ?\e$,1! \e(B)
 - ("g" ?\e$,1 C\e(B)
 - ("G" ?\e$,1 B\e(B)
 - ("k" ?\e$,1 W\e(B)
 - ("K" ?\e$,1 V\e(B)
 - ("l" ?\e$,1 \\e(B)
 - ("L" ?\e$,1 [\e(B)
 - ("\'" ?\e$,1r|\e(B)
 - ("\"" ?\e$,1r~\e(B)
 - ("z" ?\e$,1!>\e(B)
 - ("Z" ?\e$,1!=\e(B)
 - ("c" ?\e$,1 -\e(B)
 - ("C" ?\e$,1 ,\e(B)
 - ("n" ?\e$,1 f\e(B)
 - ("N" ?\e$,1 e\e(B))
 + ("4" ?€)
 + ("$" ?¢)
 + ("e" ?Ä“)
 + ("E" ?Ä’)
 + ("r" ?Å—)
 + ("R" ?Å–)
 + ("u" ?Å«)
 + ("U" ?Ū)
 + ("i" ?Ä«)
 + ("I" ?Ī)
 + ("o" ?Å)
 + ("O" ?ÅŒ)
 + ("a" ?Ä)
 + ("A" ?Ä€)
 + ("s" ?Å¡)
 + ("S" ?Å )
 + ("g" ?Ä£)
 + ("G" ?Ä¢)
 + ("k" ?Ä·)
 + ("K" ?Ķ)
 + ("l" ?ļ)
 + ("L" ?Ä»)
 + ("\'" ?“)
 + ("\"" ?„)
 + ("z" ?ž)
 + ("Z" ?Ž)
 + ("c" ?Ä)
 + ("C" ?ÄŒ)
 + ("n" ?ņ)
 + ("N" ?Å…))
  
  (quail-define-package
   "latin-alt-postfix" "Latin" "L<" t
@@@ -1663,22 -1723,22 +1664,22 @@@ of characters from a single Latin-N cha
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Aa\e(B
 -  grave      |    `    | a` -> \e,A`\e(B
 -  circumflex |    ^    | a^ -> \e,Ab\e(B
 -  diaeresis  |    \"    | a\" -> \e,Ad\e(B
 -  tilde      |    ~    | a~ -> \e,Ac\e(B
 -  cedilla    |    /`   | c/ -> \e,Ag\e(B   c` -> \e,Ag\e(B
 -  ogonek     |    `    | a` -> \e$,1 %\e(B
 -  breve      |    ~    | a~ -> \e$,1 #\e(B
 -  caron      |    ~    | c~ -> \e$,1 -\e(B
 -  dbl. acute |    :    | o: -> \e$,1 q\e(B
 -  ring       |    `    | u` -> \e$,1!/\e(B
 -  dot        |    `    | z` -> \e$,1!<\e(B
 -  stroke     |    /    | d/ -> \e$,1 1\e(B
 -  nordic     |    /    | d/ -> \e,Ap\e(B   t/ -> \e,A~\e(B   a/ -> \e,Ae\e(B   e/ -> \e,Af\e(B   o/ -> \e,Ax\e(B
 -  others     |   /<>   | s/ -> \e,A_\e(B   ?/ -> \e,A?\e(B   !/ -> \e,A!\e(B
 -             | various | << -> \e,A+\e(B   >> -> \e,A;\e(B   o_ -> \e,A:\e(B   a_ -> \e,A*\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  tilde      |    ~    | a~ -> Ã£
 +  cedilla    |    /`   | c/ -> Ã§   c` -> Ã§
 +  ogonek     |    `    | a` -> Ä…
 +  breve      |    ~    | a~ -> Äƒ
 +  caron      |    ~    | c~ -> Ä
 +  dbl. acute |    :    | o: -> Å‘
 +  ring       |    `    | u` -> Å¯
 +  dot        |    `    | z` -> Å¼
 +  stroke     |    /    | d/ -> Ä‘
 +  nordic     |    /    | d/ -> Ã°   t/ -> Ã¾   a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |   /<>   | s/ -> ÃŸ   ?/ -> Â¿   !/ -> Â¡
 +             | various | << -> Â«   >> -> Â»   o_ -> Âº   a_ -> Âª
  
  It would be natural to use comma for cedillas, but that would be
  inconvenient in practice because commas are needed very often after a
@@@ -1687,197 -1747,197 +1688,197 @@@ letter
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
 -;; Fixme: \e,A&\e(B \e,A'\e(B \e,A(\e(B \e,A)\e(B \e,A,\e(B \e,A-\e(B \e,A.\e(B \e,A/\e(B \e,A0\e(B \e,A1\e(B \e,A2\e(B \e,A3\e(B \e,A4\e(B \e,A5\e(B \e,A6\e(B \e,A7\e(B \e,A8\e(B \e,A9\e(B \e,A<\e(B \e,A=\e(B \e,A>\e(B \e,AW\e(B \e,Aw\e(B
 +;; Fixme: Â¦ Â§ Â¨ Â© Â¬ Â­ Â® Â¯ Â° Â± Â² Â³ Â´ Âµ Â¶ Â· Â¸ Â¹ Â¼ Â½ Â¾ Ã— Ã·
  (quail-define-rules
 - (" _" ?\e,A \e(B)
 - ("!/" ?\e,A!\e(B)
 - ("//" ?\e,A0\e(B)
 - ("<<" ?\e,A+\e(B)
 - (">>" ?\e,A;\e(B)
 - ("?/" ?\e,A?\e(B)
 - ("$/" ?\e,A#\e(B)
 - ("$/" ?\e,A$\e(B)
 - ("A'" ?\e,AA\e(B)
 - ("A-" ?\e$,1  \e(B)
 - ("A/" ?\e,AE\e(B)
 - ("A\"" ?\e,AD\e(B)
 - ("A^" ?\e,AB\e(B)
 - ("A`" ?\e,A@\e(B)
 - ("A`" ?\e$,1 $\e(B)
 - ("A~" ?\e,AC\e(B)
 - ("A~" ?\e$,1 "\e(B)
 - ("C'" ?\e$,1 &\e(B)
 - ("C/" ?\e,AG\e(B)
 - ("C/" ?\e$,1 *\e(B)
 - ("C^" ?\e$,1 (\e(B)
 - ("C`" ?\e,AG\e(B)
 - ("C~" ?\e$,1 ,\e(B)
 - ("D/" ?\e,AP\e(B)
 - ("D/" ?\e$,1 0\e(B)
 - ("D~" ?\e$,1 .\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("E-" ?\e$,1 2\e(B)
 - ("E/" ?\e,AF\e(B)
 - ("E\"" ?\e,AK\e(B)
 - ("E^" ?\e,AJ\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E`" ?\e$,1 8\e(B)
 - ("E~" ?\e$,1 6\e(B)
 - ("E~" ?\e$,1 :\e(B)
 - ("G/" ?\e$,1 @\e(B)
 - ("G^" ?\e$,1 <\e(B)
 - ("G`" ?\e$,1 B\e(B)
 - ("G~" ?\e$,1 >\e(B)
 - ("H/" ?\e$,1 F\e(B)
 - ("H^" ?\e$,1 D\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("I-" ?\e$,1 J\e(B)
 - ("I/" ?\e$,1 P\e(B)
 - ("I\"" ?\e,AO\e(B)
 - ("I^" ?\e,AN\e(B)
 - ("I`" ?\e,AL\e(B)
 - ("I`" ?\e$,1 N\e(B)
 - ("I~" ?\e$,1 H\e(B)
 - ("J^" ?\e$,1 T\e(B)
 - ("K`" ?\e$,1 V\e(B)
 - ("L'" ?\e$,1 Y\e(B)
 - ("L/" ?\e$,1 a\e(B)
 - ("L`" ?\e$,1 [\e(B)
 - ("L~" ?\e$,1 ]\e(B)
 - ("N'" ?\e$,1 c\e(B)
 - ("N/" ?\e$,1 j\e(B)
 - ("N`" ?\e$,1 e\e(B)
 - ("N~" ?\e,AQ\e(B)
 - ("N~" ?\e$,1 g\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("O-" ?\e$,1 l\e(B)
 - ("O/" ?\e,AX\e(B)
 - ("O:" ?\e$,1 p\e(B)
 - ("O\"" ?\e,AV\e(B)
 - ("O^" ?\e,AT\e(B)
 - ("O`" ?\e,AR\e(B)
 - ("O~" ?\e,AU\e(B)
 - ("R'" ?\e$,1 t\e(B)
 - ("R`" ?\e$,1 v\e(B)
 - ("R~" ?\e$,1 x\e(B)
 - ("S'" ?\e$,1 z\e(B)
 - ("S^" ?\e$,1 |\e(B)
 - ("S`" ?\e$,1 ~\e(B)
 - ("S~" ?\e$,1! \e(B)
 - ("T/" ?\e,A^\e(B)
 - ("T/" ?\e$,1!&\e(B)
 - ("T`" ?\e$,1!"\e(B)
 - ("T~" ?\e$,1!$\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("U-" ?\e$,1!*\e(B)
 - ("U:" ?\e$,1!0\e(B)
 - ("U\"" ?\e,A\\e(B)
 - ("U^" ?\e,A[\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("U`" ?\e$,1!.\e(B)
 - ("U`" ?\e$,1!2\e(B)
 - ("U~" ?\e$,1!(\e(B)
 - ("U~" ?\e$,1!,\e(B)
 - ("Y'" ?\e,A]\e(B)
 - ("Y\"" ?\e$,1!8\e(B)
 - ("Y=" ?\e,A%\e(B)
 - ("Z'" ?\e$,1!9\e(B)
 - ("Z/" ?\e$,1!;\e(B)
 - ("Z`" ?\e$,1!;\e(B)
 - ("Z~" ?\e$,1!=\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("a-" ?\e$,1 !\e(B)
 - ("a/" ?\e,Ae\e(B)
 - ("a\"" ?\e,Ad\e(B)
 - ("a^" ?\e,Ab\e(B)
 - ("a_" ?\e,A*\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("a`" ?\e$,1 %\e(B)
 - ("a~" ?\e,Ac\e(B)
 - ("a~" ?\e$,1 #\e(B)
 - ("c'" ?\e$,1 '\e(B)
 - ("c/" ?\e,Ag\e(B)
 - ("c/" ?\e$,1 +\e(B)
 - ("c/" ?\e,A"\e(B)
 - ("c^" ?\e$,1 )\e(B)
 - ("c`" ?\e,Ag\e(B)
 - ("c~" ?\e$,1 -\e(B)
 - ("d/" ?\e,Ap\e(B)
 - ("d/" ?\e$,1 1\e(B)
 - ("d~" ?\e$,1 /\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("e-" ?\e$,1 3\e(B)
 - ("e/" ?\e,Af\e(B)
 - ("e\"" ?\e,Ak\e(B)
 - ("e^" ?\e,Aj\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e`" ?\e$,1 9\e(B)
 - ("e~" ?\e$,1 7\e(B)
 - ("e~" ?\e$,1 ;\e(B)
 - ("e=" ?\e$,1tL\e(B)
 - ("g/" ?\e$,1 A\e(B)
 - ("g^" ?\e$,1 =\e(B)
 - ("g`" ?\e$,1 C\e(B)
 - ("g~" ?\e$,1 ?\e(B)
 - ("h/" ?\e$,1 G\e(B)
 - ("h^" ?\e$,1 E\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("i-" ?\e$,1 K\e(B)
 - ("i/" ?\e$,1 Q\e(B)
 - ("i\"" ?\e,Ao\e(B)
 - ("i^" ?\e,An\e(B)
 - ("i`" ?\e,Al\e(B)
 - ("i`" ?\e$,1 O\e(B)
 - ("i~" ?\e$,1 I\e(B)
 - ("j^" ?\e$,1 U\e(B)
 - ("k/" ?\e$,1 X\e(B)
 - ("k`" ?\e$,1 W\e(B)
 - ("l'" ?\e$,1 Z\e(B)
 - ("l/" ?\e$,1 b\e(B)
 - ("l`" ?\e$,1 \\e(B)
 - ("l~" ?\e$,1 ^\e(B)
 - ("n'" ?\e$,1 d\e(B)
 - ("n/" ?\e$,1 k\e(B)
 - ("n`" ?\e$,1 f\e(B)
 - ("n~" ?\e,Aq\e(B)
 - ("n~" ?\e$,1 h\e(B)
 - ("o'" ?\e,As\e(B)
 - ("o-" ?\e$,1 m\e(B)
 - ("o/" ?\e,Ax\e(B)
 - ("o:" ?\e$,1 q\e(B)
 - ("o\"" ?\e,Av\e(B)
 - ("o^" ?\e,At\e(B)
 - ("o_" ?\e,A:\e(B)
 - ("o`" ?\e,Ar\e(B)
 - ("o~" ?\e,Au\e(B)
 - ("r'" ?\e$,1 u\e(B)
 - ("r`" ?\e$,1 w\e(B)
 - ("r~" ?\e$,1 y\e(B)
 - ("s'" ?\e$,1 {\e(B)
 - ("s/" ?\e,A_\e(B)
 - ("s^" ?\e$,1 }\e(B)
 - ("s`" ?\e$,1 \7f\e(B)
 - ("s~" ?\e$,1!!\e(B)
 - ("t/" ?\e,A~\e(B)
 - ("t/" ?\e$,1!'\e(B)
 - ("t`" ?\e$,1!#\e(B)
 - ("t~" ?\e$,1!%\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("u-" ?\e$,1!+\e(B)
 - ("u:" ?\e$,1!1\e(B)
 - ("u\"" ?\e,A|\e(B)
 - ("u^" ?\e,A{\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("u`" ?\e$,1!/\e(B)
 - ("u`" ?\e$,1!3\e(B)
 - ("u~" ?\e$,1!)\e(B)
 - ("u~" ?\e$,1!-\e(B)
 - ("y'" ?\e,A}\e(B)
 - ("y\"" ?\e,A\7f\e(B)
 - ("z'" ?\e$,1!:\e(B)
 - ("z/" ?\e$,1!<\e(B)
 - ("z`" ?\e$,1!<\e(B)
 - ("z~" ?\e$,1!>\e(B)
 + (" _" ? )
 + ("!/" ?¡)
 + ("//" ?°)
 + ("<<" ?«)
 + (">>" ?»)
 + ("?/" ?¿)
 + ("$/" ?£)
 + ("$/" ?¤)
 + ("A'" ?Ã)
 + ("A-" ?Ä€)
 + ("A/" ?Ã…)
 + ("A\"" ?Ä)
 + ("A^" ?Â)
 + ("A`" ?À)
 + ("A`" ?Ä„)
 + ("A~" ?Ã)
 + ("A~" ?Ä‚)
 + ("C'" ?Ć)
 + ("C/" ?Ç)
 + ("C/" ?ÄŠ)
 + ("C^" ?Ĉ)
 + ("C`" ?Ç)
 + ("C~" ?ÄŒ)
 + ("D/" ?Ã)
 + ("D/" ?Ä)
 + ("D~" ?ÄŽ)
 + ("E'" ?É)
 + ("E-" ?Ä’)
 + ("E/" ?Æ)
 + ("E\"" ?Ë)
 + ("E^" ?Ê)
 + ("E`" ?È)
 + ("E`" ?Ę)
 + ("E~" ?Ä–)
 + ("E~" ?Äš)
 + ("G/" ?Ä )
 + ("G^" ?Äœ)
 + ("G`" ?Ä¢)
 + ("G~" ?Äž)
 + ("H/" ?Ħ)
 + ("H^" ?Ĥ)
 + ("I'" ?Ã)
 + ("I-" ?Ī)
 + ("I/" ?Ä°)
 + ("I\"" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I`" ?ÃŒ)
 + ("I`" ?Ä®)
 + ("I~" ?Ĩ)
 + ("J^" ?Ä´)
 + ("K`" ?Ķ)
 + ("L'" ?Ĺ)
 + ("L/" ?Å)
 + ("L`" ?Ä»)
 + ("L~" ?Ľ)
 + ("N'" ?Ń)
 + ("N/" ?ÅŠ)
 + ("N`" ?Å…)
 + ("N~" ?Ñ)
 + ("N~" ?Ň)
 + ("O'" ?Ó)
 + ("O-" ?ÅŒ)
 + ("O/" ?Ø)
 + ("O:" ?Å)
 + ("O\"" ?Ö)
 + ("O^" ?Ô)
 + ("O`" ?Ã’)
 + ("O~" ?Õ)
 + ("R'" ?Å”)
 + ("R`" ?Å–)
 + ("R~" ?Ř)
 + ("S'" ?Åš)
 + ("S^" ?Åœ)
 + ("S`" ?Åž)
 + ("S~" ?Å )
 + ("T/" ?Þ)
 + ("T/" ?Ŧ)
 + ("T`" ?Å¢)
 + ("T~" ?Ť)
 + ("U'" ?Ú)
 + ("U-" ?Ū)
 + ("U:" ?Å°)
 + ("U\"" ?Ãœ)
 + ("U^" ?Û)
 + ("U`" ?Ù)
 + ("U`" ?Å®)
 + ("U`" ?Ų)
 + ("U~" ?Ũ)
 + ("U~" ?Ŭ)
 + ("Y'" ?Ã)
 + ("Y\"" ?Ÿ)
 + ("Y=" ?Â¥)
 + ("Z'" ?Ź)
 + ("Z/" ?Å»)
 + ("Z`" ?Å»)
 + ("Z~" ?Ž)
 + ("a'" ?á)
 + ("a-" ?Ä)
 + ("a/" ?Ã¥)
 + ("a\"" ?ä)
 + ("a^" ?â)
 + ("a_" ?ª)
 + ("a`" ?à)
 + ("a`" ?Ä…)
 + ("a~" ?ã)
 + ("a~" ?ă)
 + ("c'" ?ć)
 + ("c/" ?ç)
 + ("c/" ?Ä‹)
 + ("c/" ?¢)
 + ("c^" ?ĉ)
 + ("c`" ?ç)
 + ("c~" ?Ä)
 + ("d/" ?ð)
 + ("d/" ?Ä‘)
 + ("d~" ?Ä)
 + ("e'" ?é)
 + ("e-" ?Ä“)
 + ("e/" ?æ)
 + ("e\"" ?ë)
 + ("e^" ?ê)
 + ("e`" ?è)
 + ("e`" ?Ä™)
 + ("e~" ?Ä—)
 + ("e~" ?Ä›)
 + ("e=" ?€)
 + ("g/" ?Ä¡)
 + ("g^" ?Ä)
 + ("g`" ?Ä£)
 + ("g~" ?ÄŸ)
 + ("h/" ?ħ)
 + ("h^" ?Ä¥)
 + ("i'" ?í)
 + ("i-" ?Ä«)
 + ("i/" ?ı)
 + ("i\"" ?ï)
 + ("i^" ?î)
 + ("i`" ?ì)
 + ("i`" ?į)
 + ("i~" ?Ä©)
 + ("j^" ?ĵ)
 + ("k/" ?ĸ)
 + ("k`" ?Ä·)
 + ("l'" ?ĺ)
 + ("l/" ?Å‚)
 + ("l`" ?ļ)
 + ("l~" ?ľ)
 + ("n'" ?Å„)
 + ("n/" ?Å‹)
 + ("n`" ?ņ)
 + ("n~" ?ñ)
 + ("n~" ?ň)
 + ("o'" ?ó)
 + ("o-" ?Å)
 + ("o/" ?ø)
 + ("o:" ?Å‘)
 + ("o\"" ?ö)
 + ("o^" ?ô)
 + ("o_" ?º)
 + ("o`" ?ò)
 + ("o~" ?õ)
 + ("r'" ?Å•)
 + ("r`" ?Å—)
 + ("r~" ?Å™)
 + ("s'" ?Å›)
 + ("s/" ?ß)
 + ("s^" ?Å)
 + ("s`" ?ÅŸ)
 + ("s~" ?Å¡)
 + ("t/" ?þ)
 + ("t/" ?ŧ)
 + ("t`" ?Å£)
 + ("t~" ?Å¥)
 + ("u'" ?ú)
 + ("u-" ?Å«)
 + ("u:" ?ű)
 + ("u\"" ?ü)
 + ("u^" ?û)
 + ("u`" ?ù)
 + ("u`" ?ů)
 + ("u`" ?ų)
 + ("u~" ?Å©)
 + ("u~" ?Å­)
 + ("y'" ?ý)
 + ("y\"" ?ÿ)
 + ("z'" ?ź)
 + ("z/" ?ż)
 + ("z`" ?ż)
 + ("z~" ?ž)
  
   (" __" [" _"])
   ("!//" ["!/"])
diff --combined leim/quail/latin-post.el
index 7fdf3e7f9808ec65c0b6e7ea3195f1835677e770,5140348e7cc462d222bbc7ea02d1931b187047b9..1d958183d2f41a3c60a0080c74229358622e2e29
@@@ -1,14 -1,13 +1,16 @@@
 -;;; latin-post.el --- Quail packages for inputting various European characters  -*-coding: iso-2022-7bit;-*-
 +;;; latin-post.el --- Quail packages for inputting various European characters  -*-coding: utf-8;-*-
  
- ;; Copyright (C) 1997, 1998, 2001, 2002, 2006 Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
 -;; Keywords: multilingual, input method, latin
 +;; Keywords: multilingual, input method, latin, i18n
  
  ;; This file is part of GNU Emacs.
  
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Aa\e(B
 -  grave      |    `    | a` -> \e,A`\e(B
 -  circumflex |    ^    | a^ -> \e,Ab\e(B
 -  diaeresis  |    \"    | a\" -> \e,Ad\e(B
 -  tilde      |    ~    | a~ -> \e,Ac\e(B
 -  cedilla    |    ,    | c, -> \e,Ag\e(B
 -  nordic     |    /    | d/ -> \e,Ap\e(B   t/ -> \e,A~\e(B   a/ -> \e,Ae\e(B   e/ -> \e,Af\e(B   o/ -> \e,Ax\e(B
 -  others     |    /    | s/ -> \e,A_\e(B   ?/ -> \e,A?\e(B   !/ -> \e,A!\e(B   // -> \e,A0\e(B
 -             | various | << -> \e,A+\e(B   >> -> \e,A;\e(B   o_ -> \e,A:\e(B   a_ -> \e,A*\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  tilde      |    ~    | a~ -> Ã£
 +  cedilla    |    ,    | c, -> Ã§
 +  nordic     |    /    | d/ -> Ã°   t/ -> Ã¾   a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |    /    | s/ -> ÃŸ   ?/ -> Â¿   !/ -> Â¡   // -> Â°
 +             | various | << -> Â«   >> -> Â»   o_ -> Âº   a_ -> Âª
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,A@\e(B)
 - ("A'" ?\e,AA\e(B)
 - ("A^" ?\e,AB\e(B)
 - ("A~" ?\e,AC\e(B)
 - ("A\"" ?\e,AD\e(B)
 - ("A/" ?\e,AE\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("a^" ?\e,Ab\e(B)
 - ("a~" ?\e,Ac\e(B)
 - ("a\"" ?\e,Ad\e(B)
 - ("a/" ?\e,Ae\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("E^" ?\e,AJ\e(B)
 - ("E\"" ?\e,AK\e(B)
 - ("E/" ?\e,AF\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("e^" ?\e,Aj\e(B)
 - ("e\"" ?\e,Ak\e(B)
 - ("e/" ?\e,Af\e(B)
 - ("I`" ?\e,AL\e(B)
 - ("i`" ?\e,Al\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("I^" ?\e,AN\e(B)
 - ("i^" ?\e,An\e(B)
 - ("I\"" ?\e,AO\e(B)
 - ("i\"" ?\e,Ao\e(B)
 - ("O`" ?\e,AR\e(B)
 - ("o`" ?\e,Ar\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("o'" ?\e,As\e(B)
 - ("O^" ?\e,AT\e(B)
 - ("o^" ?\e,At\e(B)
 - ("O~" ?\e,AU\e(B)
 - ("o~" ?\e,Au\e(B)
 - ("O\"" ?\e,AV\e(B)
 - ("o\"" ?\e,Av\e(B)
 - ("O/" ?\e,AX\e(B)
 - ("o/" ?\e,Ax\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("U^" ?\e,A[\e(B)
 - ("u^" ?\e,A{\e(B)
 - ("U\"" ?\e,A\\e(B)
 - ("u\"" ?\e,A|\e(B)
 - ("Y'" ?\e,A]\e(B)
 - ("y'" ?\e,A}\e(B)
 - ("y\"" ?\e,A\7f\e(B)
 - ("D/" ?\e,AP\e(B)
 - ("d/" ?\e,Ap\e(B)
 - ("T/" ?\e,A^\e(B)
 - ("t/" ?\e,A~\e(B)
 - ("s/" ?\e,A_\e(B)
 - ("C," ?\e,AG\e(B)
 - ("c," ?\e,Ag\e(B)
 - ("N~" ?\e,AQ\e(B)
 - ("n~" ?\e,Aq\e(B)
 - ("?/" ?\e,A?\e(B)
 - ("!/" ?\e,A!\e(B)
 - ("<<" ?\e,A+\e(B)
 - (">>" ?\e,A;\e(B)
 - ("o_" ?\e,A:\e(B)
 - ("a_" ?\e,A*\e(B)
 - ("//" ?\e,A0\e(B)
 + ("A`" ?À)
 + ("A'" ?Ã)
 + ("A^" ?Â)
 + ("A~" ?Ã)
 + ("A\"" ?Ä)
 + ("A/" ?Ã…)
 + ("a`" ?à)
 + ("a'" ?á)
 + ("a^" ?â)
 + ("a~" ?ã)
 + ("a\"" ?ä)
 + ("a/" ?Ã¥)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("E^" ?Ê)
 + ("E\"" ?Ë)
 + ("E/" ?Æ)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("e^" ?ê)
 + ("e\"" ?ë)
 + ("e/" ?æ)
 + ("I`" ?ÃŒ)
 + ("i`" ?ì)
 + ("I'" ?Ã)
 + ("i'" ?í)
 + ("I^" ?ÃŽ)
 + ("i^" ?î)
 + ("I\"" ?Ã)
 + ("i\"" ?ï)
 + ("O`" ?Ã’)
 + ("o`" ?ò)
 + ("O'" ?Ó)
 + ("o'" ?ó)
 + ("O^" ?Ô)
 + ("o^" ?ô)
 + ("O~" ?Õ)
 + ("o~" ?õ)
 + ("O\"" ?Ö)
 + ("o\"" ?ö)
 + ("O/" ?Ø)
 + ("o/" ?ø)
 + ("U`" ?Ù)
 + ("u`" ?ù)
 + ("U'" ?Ú)
 + ("u'" ?ú)
 + ("U^" ?Û)
 + ("u^" ?û)
 + ("U\"" ?Ãœ)
 + ("u\"" ?ü)
 + ("Y'" ?Ã)
 + ("y'" ?ý)
 + ("y\"" ?ÿ)
 + ("D/" ?Ã)
 + ("d/" ?ð)
 + ("T/" ?Þ)
 + ("t/" ?þ)
 + ("s/" ?ß)
 + ("C," ?Ç)
 + ("c," ?ç)
 + ("N~" ?Ñ)
 + ("n~" ?ñ)
 + ("?/" ?¿)
 + ("!/" ?¡)
 + ("<<" ?«)
 + (">>" ?»)
 + ("o_" ?º)
 + ("a_" ?ª)
 + ("//" ?°)
  
   ("A``" ["A`"])
   ("A''" ["A'"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Ba\e(B
 -  ogonek     |    ,    | a, -> \e,B1\e(B
 -  diaeresis  |    \"    | a\" -> \e,Bd\e(B
 -  circumflex |    ^    | a^ -> \e,Bb\e(B
 -  breve      |    ~    | a~ -> \e,Bc\e(B
 -  cedilla    |    ,    | c, -> \e,Bg\e(B
 -  caron      |    ~    | c~ -> \e,Bh\e(B
 -  dbl. acute |    :    | o: -> \e,Bu\e(B
 -  ring       |    .    | u. -> \e,By\e(B
 -  dot        |    .    | z. -> \e,B?\e(B
 -  stroke     |    /    | d/ -> \e,Bp\e(B
 -  others     |    /    | s/ -> \e,B_\e(B
 +  acute      |    '    | a' -> Ã¡
 +  ogonek     |    ,    | a, -> Ä…
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  circumflex |    ^    | a^ -> Ã¢
 +  breve      |    ~    | a~ -> Äƒ
 +  cedilla    |    ,    | c, -> Ã§
 +  caron      |    ~    | c~ -> Ä
 +  dbl. acute |    :    | o: -> Å‘
 +  ring       |    .    | u. -> Å¯
 +  dot        |    .    | z. -> Å¼
 +  stroke     |    /    | d/ -> Ä‘
 +  others     |    /    | s/ -> ÃŸ
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,BA\e(B)
 - ("A," ?\e,B!\e(B)
 - ("A\"" ?\e,BD\e(B)
 - ("A^" ?\e,BB\e(B)
 - ("A~" ?\e,BC\e(B)
 - ("C'" ?\e,BF\e(B)
 - ("C," ?\e,BG\e(B)
 - ("C~" ?\e,BH\e(B)
 - ("D/" ?\e,BP\e(B)
 - ("D~" ?\e,BO\e(B)
 - ("E'" ?\e,BI\e(B)
 - ("E," ?\e,BJ\e(B)
 - ("E\"" ?\e,BK\e(B)
 - ("E~" ?\e,BL\e(B)
 - ("I'" ?\e,BM\e(B)
 - ("I^" ?\e,BN\e(B)
 - ("L'" ?\e,BE\e(B)
 - ("L/" ?\e,B#\e(B)
 - ("L~" ?\e,B%\e(B)
 - ("N'" ?\e,BQ\e(B)
 - ("N~" ?\e,BR\e(B)
 - ("O'" ?\e,BS\e(B)
 - ("O:" ?\e,BU\e(B)
 - ("O\"" ?\e,BV\e(B)
 - ("O^" ?\e,BT\e(B)
 - ("R'" ?\e,B@\e(B)
 - ("R~" ?\e,BX\e(B)
 - ("S'" ?\e,B&\e(B)
 - ("S," ?\e,B*\e(B)
 - ("S~" ?\e,B)\e(B)
 - ("T," ?\e,B^\e(B)
 - ("T~" ?\e,B+\e(B)
 - ("U'" ?\e,BZ\e(B)
 - ("U:" ?\e,B[\e(B)
 - ("U\"" ?\e,B\\e(B)
 - ("U." ?\e,BY\e(B)
 - ("Y'" ?\e,B]\e(B)
 - ("Z'" ?\e,B,\e(B)
 - ("Z." ?\e,B/\e(B)
 - ("Z~" ?\e,B.\e(B)
 - ("a'" ?\e,Ba\e(B)
 - ("a," ?\e,B1\e(B)
 - ("a\"" ?\e,Bd\e(B)
 - ("a^" ?\e,Bb\e(B)
 - ("a~" ?\e,Bc\e(B)
 - ("c'" ?\e,Bf\e(B)
 - ("c," ?\e,Bg\e(B)
 - ("c~" ?\e,Bh\e(B)
 - ("d/" ?\e,Bp\e(B)
 - ("d~" ?\e,Bo\e(B)
 - ("e'" ?\e,Bi\e(B)
 - ("e," ?\e,Bj\e(B)
 - ("e\"" ?\e,Bk\e(B)
 - ("e~" ?\e,Bl\e(B)
 - ("i'" ?\e,Bm\e(B)
 - ("i^" ?\e,Bn\e(B)
 - ("l'" ?\e,Be\e(B)
 - ("l/" ?\e,B3\e(B)
 - ("l~" ?\e,B5\e(B)
 - ("n'" ?\e,Bq\e(B)
 - ("n~" ?\e,Br\e(B)
 - ("o'" ?\e,Bs\e(B)
 - ("o:" ?\e,Bu\e(B)
 - ("o\"" ?\e,Bv\e(B)
 - ("o^" ?\e,Bt\e(B)
 - ("r'" ?\e,B`\e(B)
 - ("r~" ?\e,Bx\e(B)
 - ("s'" ?\e,B6\e(B)
 - ("s," ?\e,B:\e(B)
 - ("s/" ?\e,B_\e(B)
 - ("s~" ?\e,B9\e(B)
 - ("t," ?\e,B~\e(B)
 - ("t~" ?\e,B;\e(B)
 - ("u'" ?\e,Bz\e(B)
 - ("u:" ?\e,B{\e(B)
 - ("u\"" ?\e,B|\e(B)
 - ("u." ?\e,By\e(B)
 - ("y'" ?\e,B}\e(B)
 - ("z'" ?\e,B<\e(B)
 - ("z." ?\e,B?\e(B)
 - ("z~" ?\e,B>\e(B)
 + ("A'" ?Ã)
 + ("A," ?Ä„)
 + ("A\"" ?Ä)
 + ("A^" ?Â)
 + ("A~" ?Ä‚)
 + ("C'" ?Ć)
 + ("C," ?Ç)
 + ("C~" ?ÄŒ)
 + ("D/" ?Ä)
 + ("D~" ?ÄŽ)
 + ("E'" ?É)
 + ("E," ?Ę)
 + ("E\"" ?Ë)
 + ("E~" ?Äš)
 + ("I'" ?Ã)
 + ("I^" ?ÃŽ)
 + ("L'" ?Ĺ)
 + ("L/" ?Å)
 + ("L~" ?Ľ)
 + ("N'" ?Ń)
 + ("N~" ?Ň)
 + ("O'" ?Ó)
 + ("O:" ?Å)
 + ("O\"" ?Ö)
 + ("O^" ?Ô)
 + ("R'" ?Å”)
 + ("R~" ?Ř)
 + ("S'" ?Åš)
 + ("S," ?Åž)
 + ("S~" ?Å )
 + ("T," ?Å¢)
 + ("T~" ?Ť)
 + ("U'" ?Ú)
 + ("U:" ?Å°)
 + ("U\"" ?Ãœ)
 + ("U." ?Å®)
 + ("Y'" ?Ã)
 + ("Z'" ?Ź)
 + ("Z." ?Å»)
 + ("Z~" ?Ž)
 + ("a'" ?á)
 + ("a," ?Ä…)
 + ("a\"" ?ä)
 + ("a^" ?â)
 + ("a~" ?ă)
 + ("c'" ?ć)
 + ("c," ?ç)
 + ("c~" ?Ä)
 + ("d/" ?Ä‘)
 + ("d~" ?Ä)
 + ("e'" ?é)
 + ("e," ?Ä™)
 + ("e\"" ?ë)
 + ("e~" ?Ä›)
 + ("i'" ?í)
 + ("i^" ?î)
 + ("l'" ?ĺ)
 + ("l/" ?Å‚)
 + ("l~" ?ľ)
 + ("n'" ?Å„)
 + ("n~" ?ň)
 + ("o'" ?ó)
 + ("o:" ?Å‘)
 + ("o\"" ?ö)
 + ("o^" ?ô)
 + ("r'" ?Å•)
 + ("r~" ?Å™)
 + ("s'" ?Å›)
 + ("s," ?ÅŸ)
 + ("s/" ?ß)
 + ("s~" ?Å¡)
 + ("t," ?Å£)
 + ("t~" ?Å¥)
 + ("u'" ?ú)
 + ("u:" ?ű)
 + ("u\"" ?ü)
 + ("u." ?ů)
 + ("y'" ?ý)
 + ("z'" ?ź)
 + ("z." ?ż)
 + ("z~" ?ž)
  
   ("A''" ["A'"])
   ("A,," ["A,"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Ca\e(B
 -  grave      |    `    | a` -> \e,C`\e(B
 -  circumflex |    ^    | a^ -> \e,Cb\e(B
 -  diaeresis  |    \"    | a\" -> \e,Cd\e(B
 -  dot        |    .    | c. -> \e,Ce\e(B   i. -> \e,C9\e(B   I. -> \e,C)\e(B
 -  cedilla    |    ,    | c, -> \e,Cg\e(B
 -  breve      |    ~    | g~ -> \e,C;\e(B
 -  tilde      |    ~    | n~ -> \e,Cq\e(B
 -  stroke     |    /    | h/ -> \e,C1\e(B
 -  others     |    /    | s/ -> \e,C_\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  dot        |    .    | c. -> Ä‹   i. -> Ä±   I. -> Ä°
 +  cedilla    |    ,    | c, -> Ã§
 +  breve      |    ~    | g~ -> ÄŸ
 +  tilde      |    ~    | n~ -> Ã±
 +  stroke     |    /    | h/ -> Ä§
 +  others     |    /    | s/ -> ÃŸ
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,C@\e(B)
 - ("A'" ?\e,CA\e(B)
 - ("A^" ?\e,CB\e(B)
 - ("A\"" ?\e,CD\e(B)
 - ("C." ?\e,CE\e(B)
 - ("C^" ?\e,CF\e(B)
 - ("C," ?\e,CG\e(B)
 - ("E`" ?\e,CH\e(B)
 - ("E'" ?\e,CI\e(B)
 - ("E^" ?\e,CJ\e(B)
 - ("E\"" ?\e,CK\e(B)
 - ("G~" ?\e,C+\e(B)
 - ("G." ?\e,CU\e(B)
 - ("G^" ?\e,CX\e(B)
 - ("H/" ?\e,C!\e(B)
 - ("H^" ?\e,C&\e(B)
 - ("I." ?\e,C)\e(B)
 - ("I`" ?\e,CL\e(B)
 - ("I'" ?\e,CM\e(B)
 - ("I^" ?\e,CN\e(B)
 - ("I\"" ?\e,CO\e(B)
 - ("J^" ?\e,C,\e(B)
 - ("N~" ?\e,CQ\e(B)
 - ("O`" ?\e,CR\e(B)
 - ("O'" ?\e,CS\e(B)
 - ("O^" ?\e,CT\e(B)
 - ("O\"" ?\e,CV\e(B)
 - ("S," ?\e,C*\e(B)
 - ("S^" ?\e,C^\e(B)
 - ("U`" ?\e,CY\e(B)
 - ("U'" ?\e,CZ\e(B)
 - ("U^" ?\e,C[\e(B)
 - ("U\"" ?\e,C\\e(B)
 - ("U~" ?\e,C]\e(B)
 - ("Z." ?\e,C/\e(B)
 - ("a`" ?\e,C`\e(B)
 - ("a'" ?\e,Ca\e(B)
 - ("a^" ?\e,Cb\e(B)
 - ("a\"" ?\e,Cd\e(B)
 - ("c." ?\e,Ce\e(B)
 - ("c^" ?\e,Cf\e(B)
 - ("c," ?\e,Cg\e(B)
 - ("e`" ?\e,Ch\e(B)
 - ("e'" ?\e,Ci\e(B)
 - ("e^" ?\e,Cj\e(B)
 - ("e\"" ?\e,Ck\e(B)
 - ("g~" ?\e,C;\e(B)
 - ("g." ?\e,Cu\e(B)
 - ("g^" ?\e,Cx\e(B)
 - ("h/" ?\e,C1\e(B)
 - ("h^" ?\e,C6\e(B)
 - ("i." ?\e,C9\e(B)
 - ("i`" ?\e,Cl\e(B)
 - ("i'" ?\e,Cm\e(B)
 - ("i^" ?\e,Cn\e(B)
 - ("i\"" ?\e,Co\e(B)
 - ("j^" ?\e,C<\e(B)
 - ("n~" ?\e,Cq\e(B)
 - ("o`" ?\e,Cr\e(B)
 - ("o'" ?\e,Cs\e(B)
 - ("o^" ?\e,Ct\e(B)
 - ("o\"" ?\e,Cv\e(B)
 - ("s," ?\e,C:\e(B)
 - ("s/" ?\e,C_\e(B)
 - ("s^" ?\e,C~\e(B)
 - ("u`" ?\e,Cy\e(B)
 - ("u'" ?\e,Cz\e(B)
 - ("u^" ?\e,C{\e(B)
 - ("u\"" ?\e,C|\e(B)
 - ("u~" ?\e,C}\e(B)
 - ("z." ?\e,C?\e(B)
 + ("A`" ?À)
 + ("A'" ?Ã)
 + ("A^" ?Â)
 + ("A\"" ?Ä)
 + ("C." ?ÄŠ)
 + ("C^" ?Ĉ)
 + ("C," ?Ç)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("E^" ?Ê)
 + ("E\"" ?Ë)
 + ("G~" ?Äž)
 + ("G." ?Ä )
 + ("G^" ?Äœ)
 + ("H/" ?Ħ)
 + ("H^" ?Ĥ)
 + ("I." ?Ä°)
 + ("I`" ?ÃŒ)
 + ("I'" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I\"" ?Ã)
 + ("J^" ?Ä´)
 + ("N~" ?Ñ)
 + ("O`" ?Ã’)
 + ("O'" ?Ó)
 + ("O^" ?Ô)
 + ("O\"" ?Ö)
 + ("S," ?Åž)
 + ("S^" ?Åœ)
 + ("U`" ?Ù)
 + ("U'" ?Ú)
 + ("U^" ?Û)
 + ("U\"" ?Ãœ)
 + ("U~" ?Ŭ)
 + ("Z." ?Å»)
 + ("a`" ?à)
 + ("a'" ?á)
 + ("a^" ?â)
 + ("a\"" ?ä)
 + ("c." ?Ä‹)
 + ("c^" ?ĉ)
 + ("c," ?ç)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("e^" ?ê)
 + ("e\"" ?ë)
 + ("g~" ?ÄŸ)
 + ("g." ?Ä¡)
 + ("g^" ?Ä)
 + ("h/" ?ħ)
 + ("h^" ?Ä¥)
 + ("i." ?ı)
 + ("i`" ?ì)
 + ("i'" ?í)
 + ("i^" ?î)
 + ("i\"" ?ï)
 + ("j^" ?ĵ)
 + ("n~" ?ñ)
 + ("o`" ?ò)
 + ("o'" ?ó)
 + ("o^" ?ô)
 + ("o\"" ?ö)
 + ("s," ?ÅŸ)
 + ("s/" ?ß)
 + ("s^" ?Å)
 + ("u`" ?ù)
 + ("u'" ?ú)
 + ("u^" ?û)
 + ("u\"" ?ü)
 + ("u~" ?Å­)
 + ("z." ?ż)
  
   ("A``" ["A`"])
   ("A''" ["A'"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Da\e(B
 -  circumflex |    ^    | a^ -> \e,Db\e(B
 -  diaeresis  |    \"    | a\" -> \e,Dd\e(B
 -  ogonek     |    ,    | a, -> \e,D1\e(B
 -  macron     |    -    | a- -> \e,D`\e(B
 -  tilde      |    ~    | a~ -> \e,Dc\e(B
 -  caron      |    ~    | c~ -> \e,Dh\e(B
 -  dot        |    .    | e. -> \e,Dl\e(B
 -  cedilla    |    ,    | k, -> \e,Ds\e(B   g, -> \e,D;\e(B
 -  stroke     |    /    | d/ -> \e,Dp\e(B
 -  nordic     |    /    | a/ -> \e,De\e(B   e/ -> \e,Df\e(B   o/ -> \e,Dx\e(B
 -  others     |    /    | s/ -> \e,D_\e(B   n/ -> \e,D?\e(B   k/ -> \e,D"\e(B
 +  acute      |    '    | a' -> Ã¡
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  ogonek     |    ,    | a, -> Ä…
 +  macron     |    -    | a- -> Ä
 +  tilde      |    ~    | a~ -> Ã£
 +  caron      |    ~    | c~ -> Ä
 +  dot        |    .    | e. -> Ä—
 +  cedilla    |    ,    | k, -> Ä·   g, -> Ä£
 +  stroke     |    /    | d/ -> Ä‘
 +  nordic     |    /    | a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |    /    | s/ -> ÃŸ   n/ -> Å‹   k/ -> Ä¸
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A," ?\e,D!\e(B)
 - ("A-" ?\e,D@\e(B)
 - ("A'" ?\e,DA\e(B)
 - ("A^" ?\e,DB\e(B)
 - ("A~" ?\e,DC\e(B)
 - ("A\"" ?\e,DD\e(B)
 - ("A/" ?\e,DE\e(B)
 - ("C~" ?\e,DH\e(B)
 - ("D/" ?\e,DP\e(B)
 - ("E/" ?\e,DF\e(B)
 - ("E-" ?\e,D*\e(B)
 - ("E'" ?\e,DI\e(B)
 - ("E," ?\e,DJ\e(B)
 - ("E\"" ?\e,DK\e(B)
 - ("E." ?\e,DL\e(B)
 - ("G," ?\e,D+\e(B)
 - ("I~" ?\e,D%\e(B)
 - ("I," ?\e,DG\e(B)
 - ("I'" ?\e,DM\e(B)
 - ("I^" ?\e,DN\e(B)
 - ("I-" ?\e,DO\e(B)
 - ("K," ?\e,DS\e(B)
 - ("L," ?\e,D&\e(B)
 - ("N/" ?\e,D=\e(B)
 - ("N," ?\e,DQ\e(B)
 - ("O-" ?\e,DR\e(B)
 - ("O^" ?\e,DT\e(B)
 - ("O~" ?\e,DU\e(B)
 - ("O\"" ?\e,DV\e(B)
 - ("O/" ?\e,DX\e(B)
 - ("R," ?\e,D#\e(B)
 - ("S~" ?\e,D)\e(B)
 - ("T/" ?\e,D,\e(B)
 - ("U," ?\e,DY\e(B)
 - ("U'" ?\e,DZ\e(B)
 - ("U^" ?\e,D[\e(B)
 - ("U\"" ?\e,D\\e(B)
 - ("U~" ?\e,D]\e(B)
 - ("U-" ?\e,D^\e(B)
 - ("Z~" ?\e,D.\e(B)
 - ("a," ?\e,D1\e(B)
 - ("a-" ?\e,D`\e(B)
 - ("a'" ?\e,Da\e(B)
 - ("a^" ?\e,Db\e(B)
 - ("a~" ?\e,Dc\e(B)
 - ("a\"" ?\e,Dd\e(B)
 - ("a/" ?\e,De\e(B)
 - ("c~" ?\e,Dh\e(B)
 - ("d/" ?\e,Dp\e(B)
 - ("e/" ?\e,Df\e(B)
 - ("e-" ?\e,D:\e(B)
 - ("e'" ?\e,Di\e(B)
 - ("e," ?\e,Dj\e(B)
 - ("e\"" ?\e,Dk\e(B)
 - ("e." ?\e,Dl\e(B)
 - ("g," ?\e,D;\e(B)
 - ("i~" ?\e,D5\e(B)
 - ("i," ?\e,Dg\e(B)
 - ("i'" ?\e,Dm\e(B)
 - ("i^" ?\e,Dn\e(B)
 - ("i-" ?\e,Do\e(B)
 - ("k/" ?\e,D"\e(B)
 - ("k," ?\e,Ds\e(B)
 - ("l," ?\e,D6\e(B)
 - ("n/" ?\e,D?\e(B)
 - ("n," ?\e,Dq\e(B)
 - ("o-" ?\e,Dr\e(B)
 - ("o^" ?\e,Dt\e(B)
 - ("o~" ?\e,Du\e(B)
 - ("o\"" ?\e,Dv\e(B)
 - ("o/" ?\e,Dx\e(B)
 - ("r," ?\e,D3\e(B)
 - ("s/" ?\e,D_\e(B)
 - ("s~" ?\e,D9\e(B)
 - ("t/" ?\e,D<\e(B)
 - ("u," ?\e,Dy\e(B)
 - ("u'" ?\e,Dz\e(B)
 - ("u^" ?\e,D{\e(B)
 - ("u\"" ?\e,D|\e(B)
 - ("u~" ?\e,D}\e(B)
 - ("u-" ?\e,D~\e(B)
 - ("z~" ?\e,D>\e(B)
 + ("A," ?Ä„)
 + ("A-" ?Ä€)
 + ("A'" ?Ã)
 + ("A^" ?Â)
 + ("A~" ?Ã)
 + ("A\"" ?Ä)
 + ("A/" ?Ã…)
 + ("C~" ?ÄŒ)
 + ("D/" ?Ä)
 + ("E/" ?Æ)
 + ("E-" ?Ä’)
 + ("E'" ?É)
 + ("E," ?Ę)
 + ("E\"" ?Ë)
 + ("E." ?Ä–)
 + ("G," ?Ä¢)
 + ("I~" ?Ĩ)
 + ("I," ?Ä®)
 + ("I'" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I-" ?Ī)
 + ("K," ?Ķ)
 + ("L," ?Ä»)
 + ("N/" ?ÅŠ)
 + ("N," ?Å…)
 + ("O-" ?ÅŒ)
 + ("O^" ?Ô)
 + ("O~" ?Õ)
 + ("O\"" ?Ö)
 + ("O/" ?Ø)
 + ("R," ?Å–)
 + ("S~" ?Å )
 + ("T/" ?Ŧ)
 + ("U," ?Ų)
 + ("U'" ?Ú)
 + ("U^" ?Û)
 + ("U\"" ?Ãœ)
 + ("U~" ?Ũ)
 + ("U-" ?Ū)
 + ("Z~" ?Ž)
 + ("a," ?Ä…)
 + ("a-" ?Ä)
 + ("a'" ?á)
 + ("a^" ?â)
 + ("a~" ?ã)
 + ("a\"" ?ä)
 + ("a/" ?Ã¥)
 + ("c~" ?Ä)
 + ("d/" ?Ä‘)
 + ("e/" ?æ)
 + ("e-" ?Ä“)
 + ("e'" ?é)
 + ("e," ?Ä™)
 + ("e\"" ?ë)
 + ("e." ?Ä—)
 + ("g," ?Ä£)
 + ("i~" ?Ä©)
 + ("i," ?į)
 + ("i'" ?í)
 + ("i^" ?î)
 + ("i-" ?Ä«)
 + ("k/" ?ĸ)
 + ("k," ?Ä·)
 + ("l," ?ļ)
 + ("n/" ?Å‹)
 + ("n," ?ņ)
 + ("o-" ?Å)
 + ("o^" ?ô)
 + ("o~" ?õ)
 + ("o\"" ?ö)
 + ("o/" ?ø)
 + ("r," ?Å—)
 + ("s/" ?ß)
 + ("s~" ?Å¡)
 + ("t/" ?ŧ)
 + ("u," ?ų)
 + ("u'" ?ú)
 + ("u^" ?û)
 + ("u\"" ?ü)
 + ("u~" ?Å©)
 + ("u-" ?Å«)
 + ("z~" ?ž)
  
   ("A,," ["A,"])
   ("A--" ["A-"])
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Ma\e(B
 -  grave      |    `    | a` -> \e,M`\e(B
 -  circumflex |    ^    | a^ -> \e,Mb\e(B
 -  diaeresis  |    \"    | a\" -> \e,Md\e(B
 -  tilde      |    ~    | a~ -> \e,Mc\e(B
 -  breve      |    ~    | g~ -> \e,Mp\e(B
 -  cedilla    |    ,    | c, -> \e,Mg\e(B
 -  dot        |    .    | i. -> \e,M}\e(B   I. -> \e,M]\e(B
 -  nordic     |    /    | a/ -> \e,Me\e(B   e/ -> \e,Mf\e(B   o/ -> \e,Mx\e(B
 -  others     |    /    | s/ -> \e,M_\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  tilde      |    ~    | a~ -> Ã£
 +  breve      |    ~    | g~ -> ÄŸ
 +  cedilla    |    ,    | c, -> Ã§
 +  dot        |    .    | i. -> Ä±   I. -> Ä°
 +  nordic     |    /    | a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |    /    | s/ -> ÃŸ
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,MA\e(B)
 - ("A/" ?\e,ME\e(B)
 - ("A\"" ?\e,MD\e(B)
 - ("A^" ?\e,MB\e(B)
 - ("A`" ?\e,M@\e(B)
 - ("A~" ?\e,MC\e(B)
 - ("C," ?\e,MG\e(B)
 - ("E'" ?\e,MI\e(B)
 - ("E/" ?\e,MF\e(B)
 - ("E\"" ?\e,MK\e(B)
 - ("E^" ?\e,MJ\e(B)
 - ("E`" ?\e,MH\e(B)
 - ("G~" ?\e,MP\e(B)
 - ("I'" ?\e,MM\e(B)
 - ("I." ?\e,M]\e(B)
 - ("I\"" ?\e,MO\e(B)
 - ("I^" ?\e,MN\e(B)
 - ("I`" ?\e,ML\e(B)
 - ("N~" ?\e,MQ\e(B)
 - ("O'" ?\e,MS\e(B)
 - ("O/" ?\e,MX\e(B)
 - ("O\"" ?\e,MV\e(B)
 - ("O^" ?\e,MT\e(B)
 - ("O`" ?\e,MR\e(B)
 - ("O~" ?\e,MU\e(B)
 - ("S," ?\e,M^\e(B)
 - ("U'" ?\e,MZ\e(B)
 - ("U\"" ?\e,M\\e(B)
 - ("U^" ?\e,M[\e(B)
 - ("U`" ?\e,MY\e(B)
 - ("a'" ?\e,Ma\e(B)
 - ("a/" ?\e,Me\e(B)
 - ("a\"" ?\e,Md\e(B)
 - ("a^" ?\e,Mb\e(B)
 - ("a`" ?\e,M`\e(B)
 - ("a~" ?\e,Mc\e(B)
 - ("c," ?\e,Mg\e(B)
 - ("e'" ?\e,Mi\e(B)
 - ("e/" ?\e,Mf\e(B)
 - ("e\"" ?\e,Mk\e(B)
 - ("e^" ?\e,Mj\e(B)
 - ("e`" ?\e,Mh\e(B)
 - ("g~" ?\e,Mp\e(B)
 - ("i'" ?\e,Mm\e(B)
 - ("i." ?\e,M}\e(B)
 - ("i\"" ?\e,Mo\e(B)
 - ("i^" ?\e,Mn\e(B)
 - ("i`" ?\e,Ml\e(B)
 - ("n~" ?\e,Mq\e(B)
 - ("o'" ?\e,Ms\e(B)
 - ("o/" ?\e,Mx\e(B)
 - ("o\"" ?\e,Mv\e(B)
 - ("o^" ?\e,Mt\e(B)
 - ("o`" ?\e,Mr\e(B)
 - ("o~" ?\e,Mu\e(B)
 - ("s," ?\e,M~\e(B)
 - ("s/" ?\e,M_\e(B)
 - ("u'" ?\e,Mz\e(B)
 - ("u\"" ?\e,M|\e(B)
 - ("u^" ?\e,M{\e(B)
 - ("u`" ?\e,My\e(B)
 - ("y\"" ?\e,M\7f\e(B)
 + ("A'" ?Ã)
 + ("A/" ?Ã…)
 + ("A\"" ?Ä)
 + ("A^" ?Â)
 + ("A`" ?À)
 + ("A~" ?Ã)
 + ("C," ?Ç)
 + ("E'" ?É)
 + ("E/" ?Æ)
 + ("E\"" ?Ë)
 + ("E^" ?Ê)
 + ("E`" ?È)
 + ("G~" ?Äž)
 + ("I'" ?Ã)
 + ("I." ?Ä°)
 + ("I\"" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I`" ?ÃŒ)
 + ("N~" ?Ñ)
 + ("O'" ?Ó)
 + ("O/" ?Ø)
 + ("O\"" ?Ö)
 + ("O^" ?Ô)
 + ("O`" ?Ã’)
 + ("O~" ?Õ)
 + ("S," ?Åž)
 + ("U'" ?Ú)
 + ("U\"" ?Ãœ)
 + ("U^" ?Û)
 + ("U`" ?Ù)
 + ("a'" ?á)
 + ("a/" ?Ã¥)
 + ("a\"" ?ä)
 + ("a^" ?â)
 + ("a`" ?à)
 + ("a~" ?ã)
 + ("c," ?ç)
 + ("e'" ?é)
 + ("e/" ?æ)
 + ("e\"" ?ë)
 + ("e^" ?ê)
 + ("e`" ?è)
 + ("g~" ?ÄŸ)
 + ("i'" ?í)
 + ("i." ?ı)
 + ("i\"" ?ï)
 + ("i^" ?î)
 + ("i`" ?ì)
 + ("n~" ?ñ)
 + ("o'" ?ó)
 + ("o/" ?ø)
 + ("o\"" ?ö)
 + ("o^" ?ô)
 + ("o`" ?ò)
 + ("o~" ?õ)
 + ("s," ?ÅŸ)
 + ("s/" ?ß)
 + ("u'" ?ú)
 + ("u\"" ?ü)
 + ("u^" ?û)
 + ("u`" ?ù)
 + ("y\"" ?ÿ)
  
   ("A''" ["A'"])
   ("A//" ["A/"])
  
  (quail-define-package
   "danish-postfix" "Latin-1" "DA<" t
 - "Danish input method (rule: AE -> \e,AF\e(B, OE -> \e,AX\e(B, AA -> \e,AE\e(B, E' -> \e,AI\e(B)
 + "Danish input method (rule: AE -> Ã†, OE -> Ã˜, AA -> Ã…, E' -> Ã‰)
  
  Doubling the postfix separates the letter and postfix: e.g. aee -> ae
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AX\e(B)
 - ("oe" ?\e,Ax\e(B)
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ø)
 + ("oe" ?ø)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
   "Esperanto input method with postfix modifiers
  
  A following ^ or x will produce an accented character,
 -e.g. c^ -> \e,Cf\e(B   gx -> \e,Cx\e(B   u^ -> \e,C}\e(B.
 +e.g. c^ -> Ä‰   gx -> Ä   u^ -> Å­.
  
  Doubling the postfix separates the letter and postfix,
  e.g. a'' -> a'.
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("Cx" ?\e,CF\e(B)
 - ("C^" ?\e,CF\e(B)
 - ("cx" ?\e,Cf\e(B)
 - ("c^" ?\e,Cf\e(B)
 - ("Gx" ?\e,CX\e(B)
 - ("G^" ?\e,CX\e(B)
 - ("gx" ?\e,Cx\e(B)
 - ("g^" ?\e,Cx\e(B)
 - ("Hx" ?\e,C&\e(B)
 - ("H^" ?\e,C&\e(B)
 - ("hx" ?\e,C6\e(B)
 - ("h^" ?\e,C6\e(B)
 - ("Jx" ?\e,C,\e(B)
 - ("J^" ?\e,C,\e(B)
 - ("jx" ?\e,C<\e(B)
 - ("j^" ?\e,C<\e(B)
 - ("Sx" ?\e,C^\e(B)
 - ("S^" ?\e,C^\e(B)
 - ("sx" ?\e,C~\e(B)
 - ("s^" ?\e,C~\e(B)
 - ("Ux" ?\e,C]\e(B)
 - ("U^" ?\e,C]\e(B)
 - ("ux" ?\e,C}\e(B)
 - ("u^" ?\e,C}\e(B)
 + ("Cx" ?Ĉ)
 + ("C^" ?Ĉ)
 + ("cx" ?ĉ)
 + ("c^" ?ĉ)
 + ("Gx" ?Äœ)
 + ("G^" ?Äœ)
 + ("gx" ?Ä)
 + ("g^" ?Ä)
 + ("Hx" ?Ĥ)
 + ("H^" ?Ĥ)
 + ("hx" ?Ä¥)
 + ("h^" ?Ä¥)
 + ("Jx" ?Ä´)
 + ("J^" ?Ä´)
 + ("jx" ?ĵ)
 + ("j^" ?ĵ)
 + ("Sx" ?Åœ)
 + ("S^" ?Åœ)
 + ("sx" ?Å)
 + ("s^" ?Å)
 + ("Ux" ?Ŭ)
 + ("U^" ?Ŭ)
 + ("ux" ?Å­)
 + ("u^" ?Å­)
  
   ("Cxx" ["Cx"])
   ("C^^" ["C^"])
   "finnish-postfix" "Latin-1" "FI<" t
   "Finnish (Suomi) input method
  
 -AE  -> \e,AD\e(B
 +AE  -> Ã„
  AEE -> AE
 -OE  -> \e,AV\e(B
 +OE  -> Ã–
  OEE -> OE
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AD\e(B)
 - ("ae" ?\e,Ad\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 + ("AE" ?Ä)
 + ("ae" ?ä)
 + ("OE" ?Ö)
 + ("oe" ?ö)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
  
  (quail-define-package
   "french-postfix" "French" "FR<" t
 - "French (Fran\e,Ag\e(Bais) input method with postfix modifiers
 + "French (Français) input method with postfix modifiers
  
 -` pour grave, ' pour aigu, ^ pour circonflexe, et \" pour tr\e,Ai\e(Bma.
 -Par exemple: a` -> \e,A`\e(B   e' -> \e,Ai\e(B.
 +` pour grave, ' pour aigu, ^ pour circonflexe, et \" pour tréma.
 +Par exemple: a` -> Ã    e' -> Ã©.
  
 -\e,AG\e(B, \e,A+\e(B, et \e,A;\e(B sont produits par C,, <<, et >>.
 +Ç, Â«, et Â» sont produits par C,, <<, et >>.
  
  En doublant la frappe des diacritiques, ils s'isoleront de la lettre.
  Par exemple: e'' -> e'
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,A@\e(B)
 - ("A^" ?\e,AB\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("a^" ?\e,Ab\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("E^" ?\e,AJ\e(B)
 - ("E\"" ?\e,AK\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("e^" ?\e,Aj\e(B)
 - ("e\"" ?\e,Ak\e(B)
 - ("I^" ?\e,AN\e(B)
 - ("I\"" ?\e,AO\e(B)
 - ("i^" ?\e,An\e(B)
 - ("i\"" ?\e,Ao\e(B)
 - ("O^" ?\e,AT\e(B)
 - ("o^" ?\e,At\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("U^" ?\e,A[\e(B)
 - ("U\"" ?\e,A\\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("u^" ?\e,A{\e(B)
 - ("u\"" ?\e,A|\e(B)
 - ("C," ?\e,AG\e(B)
 - ("c," ?\e,Ag\e(B)
 - ("<<" ?\e,A+\e(B)
 - (">>" ?\e,A;\e(B)
 + ("A`" ?À)
 + ("A^" ?Â)
 + ("a`" ?à)
 + ("a^" ?â)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("E^" ?Ê)
 + ("E\"" ?Ë)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("e^" ?ê)
 + ("e\"" ?ë)
 + ("I^" ?ÃŽ)
 + ("I\"" ?Ã)
 + ("i^" ?î)
 + ("i\"" ?ï)
 + ("O^" ?Ô)
 + ("o^" ?ô)
 + ("U`" ?Ù)
 + ("U^" ?Û)
 + ("U\"" ?Ãœ)
 + ("u`" ?ù)
 + ("u^" ?û)
 + ("u\"" ?ü)
 + ("C," ?Ç)
 + ("c," ?ç)
 + ("<<" ?«)
 + (">>" ?»)
  
   ("A``" ["A`"])
   ("A^^" ["A^"])
   "german-postfix" "German" "DE<" t
   "German (Deutsch) input method
  
 -ae  -> \e,Ad\e(B
 +ae  -> Ã¤
  aee -> ae
 -oe  -> \e,Av\e(B
 +oe  -> Ã¶
  oee -> oe
 -ue  -> \e,A|\e(B
 +ue  -> Ã¼
  uee -> ue
 -sz  -> \e,A_\e(B
 +sz  -> ÃŸ
  szz -> sz
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AD\e(B)
 - ("ae" ?\e,Ad\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 - ("UE" ?\e,A\\e(B)
 - ("ue" ?\e,A|\e(B)
 - ("sz" ?\e,A_\e(B)
 + ("AE" ?Ä)
 + ("ae" ?ä)
 + ("OE" ?Ö)
 + ("oe" ?ö)
 + ("UE" ?Ãœ)
 + ("ue" ?ü)
 + ("sz" ?ß)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
  
  (quail-define-package
   "icelandic-postfix" "Latin-1" "IS<" t
 - "Icelandic (\e,AM\e(Bslenska) input method with postfix modifiers
 -
 -A' -> \e,AA\e(B
 -E' -> \e,AI\e(B
 -I' -> \e,AM\e(B
 -O' -> \e,AS\e(B
 -U' -> \e,AZ\e(B
 -Y' -> \e,A]\e(B
 -AE -> \e,AF\e(B
 -OE -> \e,AV\e(B
 -D/ -> \e,AP\e(B (eth)
 -T/ -> \e,A^\e(B (thorn)
 + "Icelandic (Ãslenska) input method with postfix modifiers
 +
 +A' -> Ã
 +E' -> Ã‰
 +I' -> Ã
 +O' -> Ã“
 +U' -> Ãš
 +Y' -> Ã
 +AE -> Ã†
 +OE -> Ã–
 +D/ -> Ã (eth)
 +T/ -> Ãž (thorn)
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,AA\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("o'" ?\e,As\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("Y'" ?\e,A]\e(B)
 - ("y'" ?\e,A}\e(B)
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 - ("D/" ?\e,AP\e(B)
 - ("d/" ?\e,Ap\e(B)
 - ("T/" ?\e,A^\e(B)
 - ("t/" ?\e,A~\e(B)
 + ("A'" ?Ã)
 + ("a'" ?á)
 + ("E'" ?É)
 + ("e'" ?é)
 + ("I'" ?Ã)
 + ("i'" ?í)
 + ("O'" ?Ó)
 + ("o'" ?ó)
 + ("U'" ?Ú)
 + ("u'" ?ú)
 + ("Y'" ?Ã)
 + ("y'" ?ý)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ö)
 + ("oe" ?ö)
 + ("D/" ?Ã)
 + ("d/" ?ð)
 + ("T/" ?Þ)
 + ("t/" ?þ)
  
   ("A''" ["A'"])
   ("a''" ["a'"])
   "italian-postfix" "Latin-1" "IT<" t
   "Italian (Italiano) input method with postfix modifiers
  
 -a` -> \e,A`\e(B    A` -> \e,A@\e(B    e' -> \e,Ai\e(B    << -> \e,A+\e(B
 -e` -> \e,Ah\e(B    E` -> \e,AH\e(B    E' -> \e,AI\e(B    >> -> \e,A;\e(B
 -i` -> \e,Al\e(B    I` -> \e,AL\e(B               o_ -> \e,A:\e(B
 -o` -> \e,Ar\e(B    O` -> \e,AR\e(B               a_ -> \e,A*\e(B
 -u` -> \e,Ay\e(B    U` -> \e,AY\e(B
 +a` -> Ã     A` -> Ã€    e' -> Ã©    << -> Â«
 +e` -> Ã¨    E` -> Ãˆ    E' -> Ã‰    >> -> Â»
 +i` -> Ã¬    I` -> ÃŒ               o_ -> Âº
 +o` -> Ã²    O` -> Ã’               a_ -> Âª
 +u` -> Ã¹    U` -> Ã™
  
  Typewriter-style italian characters.
  
@@@ -1188,22 -1187,22 +1190,22 @@@ Doubling the postfix separates the lett
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A`" ?\e,A@\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("I`" ?\e,AL\e(B)
 - ("i`" ?\e,Al\e(B)
 - ("O`" ?\e,AR\e(B)
 - ("o`" ?\e,Ar\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("<<" ?\e,A+\e(B)
 - (">>" ?\e,A;\e(B)
 - ("o_" ?\e,A:\e(B)
 - ("a_" ?\e,A*\e(B)
 + ("A`" ?À)
 + ("a`" ?à)
 + ("E`" ?È)
 + ("E'" ?É)
 + ("e`" ?è)
 + ("e'" ?é)
 + ("I`" ?ÃŒ)
 + ("i`" ?ì)
 + ("O`" ?Ã’)
 + ("o`" ?ò)
 + ("U`" ?Ù)
 + ("u`" ?ù)
 + ("<<" ?«)
 + (">>" ?»)
 + ("o_" ?º)
 + ("a_" ?ª)
  
   ("A``" ["A`"])
   ("a``" ["a`"])
  
  (quail-define-package
   "norwegian-postfix" "Latin-1" "NO<" t
 - "Norwegian (Norsk) input method (rule: AE->\e,AF\e(B   OE->\e,AX\e(B   AA->\e,AE\e(B   E'->\e,AI\e(B)
 + "Norwegian (Norsk) input method (rule: AE->Æ   OE->Ø   AA->Ã…   E'->É)
  
  Doubling the postfix separates the letter and postfix: e.g. aee -> ae
  "
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AX\e(B)
 - ("oe" ?\e,Ax\e(B)
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ø)
 + ("oe" ?ø)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
   "Scandinavian input method with postfix modifiers
  Supported languages are Swidish, Norwegian, Danish, and Finnish.
  
 -ae -> \e,Af\e(B
 -oe -> \e,Ax\e(B
 -aa -> \e,Ae\e(B
 -a\" -> \e,Ad\e(B
 -o\" -> \e,Av\e(B
 -e' -> \e,Ai\e(B
 +ae -> Ã¦
 +oe -> Ã¸
 +aa -> Ã¥
 +a\" -> Ã¤
 +o\" -> Ã¶
 +e' -> Ã©
  
  Doubling the postfix separates the letter and postfix:
  aee -> ae   o\"\" -> o\"   etc.
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AE" ?\e,AF\e(B)
 - ("ae" ?\e,Af\e(B)
 - ("OE" ?\e,AX\e(B)
 - ("oe" ?\e,Ax\e(B)
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("A\"" ?\e,AD\e(B)
 - ("a\"" ?\e,Ad\e(B)
 - ("O\"" ?\e,AV\e(B)
 - ("o\"" ?\e,Av\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AE" ?Æ)
 + ("ae" ?æ)
 + ("OE" ?Ø)
 + ("oe" ?ø)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("A\"" ?Ä)
 + ("a\"" ?ä)
 + ("O\"" ?Ö)
 + ("o\"" ?ö)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AEE" ["AE"])
   ("aee" ["ae"])
  
  (quail-define-package
   "spanish-postfix" "Spanish" "ES<" t
 - "Spanish (Espa\e,Aq\e(Bol) input method with postfix modifiers
 + "Spanish (Español) input method with postfix modifiers
  
 -A' -> \e,AA\e(B
 -E' -> \e,AI\e(B
 -I' -> \e,AM\e(B
 -O' -> \e,AS\e(B
 -U' -> \e,AZ\e(B
 -N~ -> \e,AQ\e(B
 -!/ -> \e,A!\e(B
 -?/ -> \e,A?\e(B
 +A' -> Ã
 +E' -> Ã‰
 +I' -> Ã
 +O' -> Ã“
 +U' -> Ãš
 +N~ -> Ã‘
 +!/ -> Â¡
 +?/ -> Â¿
  
  Doubling the postfix separates the letter and postfix:
  a'' -> a'   n~~ -> n~, etc.
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A'" ?\e,AA\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("o'" ?\e,As\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("U\"" ?\e,C\\e(B)
 - ("u\"" ?\e,C|\e(B)
 - ("N~" ?\e,AQ\e(B)
 - ("n~" ?\e,Aq\e(B)
 - ("?/" ?\e,A?\e(B)
 - ("!/" ?\e,A!\e(B)
 + ("A'" ?Ã)
 + ("a'" ?á)
 + ("E'" ?É)
 + ("e'" ?é)
 + ("I'" ?Ã)
 + ("i'" ?í)
 + ("O'" ?Ó)
 + ("o'" ?ó)
 + ("U'" ?Ú)
 + ("u'" ?ú)
 + ("U\"" ?Ãœ)
 + ("u\"" ?ü)
 + ("N~" ?Ñ)
 + ("n~" ?ñ)
 + ("?/" ?¿)
 + ("!/" ?¡)
  
   ("A''" ["A'"])
   ("a''" ["a'"])
  
  (quail-define-package
   "swedish-postfix" "Latin-1" "SV<" t
 - "Swedish (Svenska) input method (rule: AA -> \e,AE\e(B   AE -> \e,AD\e(B   OE -> \e,AV\e(B   E' -> \e,AI\e(B)
 + "Swedish (Svenska) input method (rule: AA -> Ã…   AE -> Ã„   OE -> Ã–   E' -> Ã‰)
  
  Doubling the postfix separates the letter and postfix: e.g. aee -> ae
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("AA" ?\e,AE\e(B)
 - ("aa" ?\e,Ae\e(B)
 - ("AE" ?\e,AD\e(B)
 - ("ae" ?\e,Ad\e(B)
 - ("OE" ?\e,AV\e(B)
 - ("oe" ?\e,Av\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("e'" ?\e,Ai\e(B)
 + ("AA" ?Ã…)
 + ("aa" ?Ã¥)
 + ("AE" ?Ä)
 + ("ae" ?ä)
 + ("OE" ?Ö)
 + ("oe" ?ö)
 + ("E'" ?É)
 + ("e'" ?é)
  
   ("AAA" ["AA"])
   ("aaa" ["aa"])
   ("e''" ["e'"])
   )
  
 -(quail-define-package
 - "turkish-latin-3-postfix" "Turkish" "TR3<" t
 - "Turkish (T\e,C|\e(Brk\e,Cg\e(Be) input method with postfix modifiers.
 -
 -This is for those who use Latin-3 (ISO-8859-3) for Turkish.  If you
 -use Latin-5 (ISO-8859-9), you should use \"turkish-postfix\" instead.
 -
 -Note for I, \e,C9\e(B, \e,C)\e(B, i.
 -
 -A^ -> \e,CB\e(B
 -C, -> \e,CG\e(B
 -G^ -> \e,C+\e(B
 -I  -> I
 -i  -> \e,C9\e(B
 -I. -> \e,C)\e(B
 -i. -> i
 -O\" -> \e,CV\e(B
 -S, -> \e,C*\e(B
 -U\" -> \e,C\\e(B
 -U^ -> \e,C[\e(B
 -
 -Doubling the postfix separates the letter and postfix: e.g. a^^ -> a^
 -" nil t nil nil nil nil nil nil nil nil t)
 -
 -(quail-define-rules
 - ("A^" ?\e,CB\e(B)
 - ("a^" ?\e,Cb\e(B)
 - ("C," ?\e,CG\e(B)
 - ("c," ?\e,Cg\e(B)
 - ("G^" ?\e,C+\e(B)
 - ("g^" ?\e,C;\e(B)
 - ("I." ?\e,C)\e(B)
 - ("i" ?\e,C9\e(B)
 - ("i." ?i)
 - ("O\"" ?\e,CV\e(B)
 - ("o\"" ?\e,Cv\e(B)
 - ("S," ?\e,C*\e(B)
 - ("s," ?\e,C:\e(B)
 - ("U\"" ?\e,C\\e(B)
 - ("u\"" ?\e,C|\e(B)
 - ("U^" ?\e,C[\e(B)
 - ("u^" ?\e,C{\e(B)
 -
 - ("A^^" ["A^"])
 - ("a^^" ["a^"])
 - ("C,," ["C,"])
 - ("c,," ["c,"])
 - ("G^^" ["G^"])
 - ("g^^" ["g^"])
 - ("I.." ["I."])
 - ("i" ["i"])
 - ("i.." ["i."])
 - ("O\"\"" ["O\""])
 - ("o\"\"" ["o\""])
 - ("S,," ["S,"])
 - ("s,," ["s,"])
 - ("U\"\"" ["U\""])
 - ("u\"\"" ["u\""])
 - ("U^^" ["U^"])
 - ("u^^" ["u^"])
 - )
 -
  (quail-define-package
   "turkish-postfix" "Turkish" "TR<" t
 - "Turkish (T\e,M|\e(Brk\e,Mg\e(Be) input method with postfix modifiers.
 + "Turkish (Türkçe) input method with postfix modifiers.
 +turkish-latin-3-postfix is an obsolete alias for turkish-postfix.
  
 -This is for those who use Latin-5 (ISO-8859-9) for Turkish.  If you
 -use Latin-3 (ISO-8859-3), you should use \"turkish-latin-3-postfix\"
 -instead.
 +Note for I, Ä±, Ä°, i.
  
 -Note for I, \e,M}\e(B, \e,M]\e(B, i.
 -
 -A^ -> \e,MB\e(B
 -C, -> \e,MG\e(B
 -G^ -> \e,MP\e(B
 +A^ -> Ã‚
 +C, -> Ã‡
 +G^ -> Äž
  I  -> I
 -i  -> \e,M}\e(B
 -I. -> \e,M]\e(B
 +i  -> Ä±
 +I. -> Ä°
  i. -> i
 -O\" -> \e,MV\e(B
 -S, -> \e,M^\e(B
 -U\" -> \e,M\\e(B
 -U^ -> \e,M[\e(B
 +O\" -> Ã–
 +S, -> Åž
 +U\" -> Ãœ
 +U^ -> Ã›
  
  Doubling the postfix separates the letter and postfix: e.g. a^^ -> a^
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("A^" ?\e,MB\e(B)
 - ("a^" ?\e,Mb\e(B)
 - ("C," ?\e,MG\e(B)
 - ("c," ?\e,Mg\e(B)
 - ("G^" ?\e,MP\e(B)
 - ("g^" ?\e,Mp\e(B)
 - ("I." ?\e,M]\e(B)
 - ("i" ?\e,M}\e(B)
 + ("A^" ?Â)
 + ("a^" ?â)
 + ("C," ?Ç)
 + ("c," ?ç)
 + ("G^" ?Äž)
 + ("g^" ?ÄŸ)
 + ("I." ?Ä°)
 + ("i" ?ı)
   ("i." ?i)
 - ("O\"" ?\e,MV\e(B)
 - ("o\"" ?\e,Mv\e(B)
 - ("S," ?\e,M^\e(B)
 - ("s," ?\e,M~\e(B)
 - ("U\"" ?\e,M\\e(B)
 - ("u\"" ?\e,M|\e(B)
 - ("U^" ?\e,M[\e(B)
 - ("u^" ?\e,M{\e(B)
 + ("O\"" ?Ö)
 + ("o\"" ?ö)
 + ("S," ?Åž)
 + ("s," ?ÅŸ)
 + ("U\"" ?Ãœ)
 + ("u\"" ?ü)
 + ("U^" ?Û)
 + ("u^" ?û)
  
   ("A^^" ["A^"])
   ("a^^" ["a^"])
   ("u^^" ["u^"])
   )
  
 +;; Backwards compatibility.
 +(push (cons "turkish-latin-3-postfix"
 +          (cdr (assoc "turkish-postfix" quail-package-alist)))
 +      quail-package-alist)
 +
  (quail-define-package
 - "british" "Latin-1" "\e,A#\e(B@" t
 - "British English input method with Latin-1 character \e,A#\e(B (# -> \e,A#\e(B)"
 + "british" "Latin-1" "£@" t
 + "British English input method with Latin-1 character Â£ (# -> Â£)"
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("#" [?\e,A#\e(B ?#])
 + ("#" [?£ ?#])
   )
  
  ;; The following are various quail packages for those who think
 -;; the aboves are too awkward.  Supported languages and their
 +;; the above are too awkward.  Supported languages and their
  ;; package name are:
  ;;
  ;; French     (frnch, azerty)
  ;;
  (quail-define-package
   "french-keyboard" "French" "FR@" t
 - "French (Fran\e,Ag\e(Bais) input method simulating some French keyboard
 + "French (Français) input method simulating some French keyboard
  <e dans l'o> n'est pas disponible." nil t t t t nil nil nil nil nil t)
  
 -;; \e,Aj\e(B1  \e,Ai\e(B2  \e,Ah\e(B3  \e,At\e(B4  \e,An\e(B5  \e,Ao\e(B6  \e,Ab\e(B7  \e,A{\e(B8  \e,Ay\e(B9  \e,A`\e(B0  -_  \e,Ak\e(B+  `~
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,AgG\e(B  \e,A|\e(B&
 +;; Ãª1  Ã©2  Ã¨3  Ã´4  Ã®5  Ã¯6  Ã¢7  Ã»8  Ã¹9  Ã 0  -_  Ã«+  `~
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã§Ã‡  Ã¼&
  ;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  ;:  '"  \|
  ;;    zZ  xX  cC  vV  bB  nN  mM  ,(  .)  !?
  
  (quail-define-rules
 - ("1" ?\e,Aj\e(B)
 - ("2" ?\e,Ai\e(B)
 - ("3" ?\e,Ah\e(B)
 - ("4" ?\e,At\e(B)
 - ("5" ?\e,An\e(B)
 - ("6" ?\e,Ao\e(B)
 - ("7" ?\e,Ab\e(B)
 - ("8" ?\e,A{\e(B)
 - ("9" ?\e,Ay\e(B)
 - ("0" ?\e,A`\e(B)
 - ("=" ?\e,Ak\e(B)
 - ("[" ?\e,Ag\e(B)
 - ("]" ?\e,A|\e(B)
 + ("1" ?ê)
 + ("2" ?é)
 + ("3" ?è)
 + ("4" ?ô)
 + ("5" ?î)
 + ("6" ?ï)
 + ("7" ?â)
 + ("8" ?û)
 + ("9" ?ù)
 + ("0" ?à)
 + ("=" ?ë)
 + ("[" ?ç)
 + ("]" ?ü)
  
   ("!" ?1)
   ("@" ?2)
   ("*" ?8)
   ("(" ?9)
   (")" ?0)
 - ("{" ?\e,AG\e(B)
 + ("{" ?Ç)
   ("}" ?&)
   ("<" ?\()
   (">" ?\))
  ;;
  (quail-define-package
   "french-azerty" "French" "AZ@" t
 - "French (Fran\e,Ag\e(Bais) input method simulating Azerty keyboard
 + "French (Français) input method simulating Azerty keyboard
  
 -Similaire au clavier fran\e,Ag\e(Bais de SUN.
 -pr\e,Ai\e(Bfixes:  ^ pour circonflexe,  \e,A(\e(B pour tr\e,Ai\e(Bma.
 +Similaire au clavier français de SUN.
 +préfixes:  ^ pour circonflexe,  Â¨ pour tréma.
  <e dans l'o> n'est pas disponible." nil t t t t nil nil nil nil nil t)
  
 -;; &1  \e,Ai\e(B2  "3  '4  (5  \e,A'\e(B6  \e,Ah\e(B7  !8  \e,Ag\e(B9  \e,A`\e(B0  )\e,A0\e(B -_  @~
 -;;  aA  zZ  eE  rR  tT  yY  uU  iI  oO  pP  ^\e,A(\e(B  `$
 -;;   qQ  sS  dD  fF  gG  hH  jJ  kK  lL  mM  \e,Ay\e(B%  *|
 +;; &1  Ã©2  "3  '4  (5  Â§6  Ã¨7  !8  Ã§9  Ã 0  )° -_  @~
 +;;  aA  zZ  eE  rR  tT  yY  uU  iI  oO  pP  ^¨  `$
 +;;   qQ  sS  dD  fF  gG  hH  jJ  kK  lL  mM  Ã¹%  *|
  ;;    wW  xX  cC  vV  bB  nN  ,?  ;.  :/  =+
  
  (quail-define-rules
   ("1" ?&)
 - ("2" ?\e,Ai\e(B)
 + ("2" ?é)
   ("3" ?\")
   ("4" ?')
   ("5" ?\()
 - ("6" ?\e,A'\e(B)
 - ("7" ?\e,Ah\e(B)
 + ("6" ?§)
 + ("7" ?è)
   ("8" ?!)
 - ("9" ?\e,Ag\e(B)
 - ("0" ?\e,A`\e(B)
 + ("9" ?ç)
 + ("0" ?à)
   ("-" ?\))
   ("=" ?-)
   ("`" ?@)
   ("k" ?k)
   ("l" ?l)
   (";" ?m)
 - ("'" ?\e,Ay\e(B)
 + ("'" ?ù)
   ("\\" ?*)
   ("z" ?w)
   ("x" ?x)
   ("*" ?8)
   ("(" ?9)
   (")" ?0)
 - ("_" ?\e,A0\e(B)
 + ("_" ?°)
   ("+" ?_)
   ("~" ?~)
   ("Q" ?A)
   ("I" ?I)
   ("O" ?O)
   ("P" ?P)
 - ("{" ?\e,A(\e(B)
 + ("{" ?¨)
   ("}" ?$)
   ("A" ?Q)
   ("S" ?S)
   (">" ?/)
   ("?" ?+)
  
 - ("[q" ?\e,Ab\e(B)
 - ("[e" ?\e,Aj\e(B)
 - ("[i" ?\e,An\e(B)
 - ("[o" ?\e,At\e(B)
 - ("[u" ?\e,A{\e(B)
 + ("[q" ?â)
 + ("[e" ?ê)
 + ("[i" ?î)
 + ("[o" ?ô)
 + ("[u" ?û)
  
 - ("{e" ?\e,Ak\e(B)
 - ("{i" ?\e,Ao\e(B)
 - ("{u" ?\e,A|\e(B)
 + ("{e" ?ë)
 + ("{i" ?ï)
 + ("{u" ?ü)
  
   ("[[" ?^)
 - ("{{" ?\e,A(\e(B)
 + ("{{" ?¨)
   )
  
  ;;
  (quail-define-package
   "icelandic-keyboard" "Latin-1" "IS@" t
 - "Icelandic (\e,AM\e(Bslenska) input method simulating some Icelandic keyboard
 + "Icelandic (Ãslenska) input method simulating some Icelandic keyboard
  
 -Dead accent is right to \e,Af\e(B." nil t t t t nil nil nil nil nil t)
 +Dead accent is right to Ã¦." nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3#  4$  5%  6^  7&  8*  9(  0)  \e,AvV\e(B  -_  `~
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,ApP\e(B  '?
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,AfF\e(B  \e,A44\e(B  +*
 -;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  \e,A~^\e(B
 +;; 1!  2"  3#  4$  5%  6^  7&  8*  9(  0)  Ã¶Ã–  -_  `~
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã°Ã  '?
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã¦Ã†  Â´Â´  +*
 +;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  Ã¾Ãž
  
  (quail-define-rules
 - ("-" ?\e,Av\e(B)
 + ("-" ?ö)
   ("=" ?-)
 - ("[" ?\e,Ap\e(B)
 + ("[" ?ð)
   ("]" ?')
 - (";" ?\e,Af\e(B)
 - ("'" ?\e,A4\e(B)
 + (";" ?æ)
 + ("'" ?´)
   ("\\" ?+)
 - ("/" ?\e,A~\e(B)
 + ("/" ?þ)
  
   ("@" ?\")
 - ("_" ?\e,AV\e(B)
 + ("_" ?Ö)
   ("+" ?_)
 - ("{" ?\e,AP\e(B)
 + ("{" ?Ã)
   ("}" ??)
 - (":" ?\e,AF\e(B)
 - ("\"" ?\e,A4\e(B)
 + (":" ?Æ)
 + ("\"" ?´)
   ("|" ?*)
   ("<" ?\;)
   (">" ?:)
 - ("?" ?\e,A^\e(B)
 -
 - ("'a" ?\e,Aa\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'i" ?\e,Am\e(B)
 - ("'o" ?\e,As\e(B)
 - ("'u" ?\e,Az\e(B)
 - ("'y" ?\e,A}\e(B)
 - ("'A" ?\e,AA\e(B)
 - ("'E" ?\e,AI\e(B)
 - ("'I" ?\e,AM\e(B)
 - ("'O" ?\e,AS\e(B)
 - ("'U" ?\e,AZ\e(B)
 - ("'Y" ?\e,A]\e(B)
 -
 - ("''" ?\e,A4\e(B)
 + ("?" ?Þ)
 +
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
 + ("'y" ?ý)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'Y" ?Ã)
 +
 + ("''" ?´)
   )
  
  ;;
   "Danish input method simulating SUN Danish keyboard"
   nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3#  4\e,A$\e(B  5%  6&  7/  8(  9)  0=  +?  \e,A='\e(B  ~^
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,AeE\e(B  \e,AiI\e(B
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,AfF\e(B  \e,AxX\e(B  '*
 +;; 1!  2"  3#  4¤  5%  6&  7/  8(  9)  0=  +?  Â½Â§  ~^
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã¥Ã…  Ã©Ã‰
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã¦Ã†  Ã¸Ã˜  '*
  ;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  -_
  
  (quail-define-rules
   ("-" ?+)
 - ("=" ?\e,A=\e(B)
 + ("=" ?½)
   ("`" ?~)
 - ("[" ?\e,Ae\e(B)
 - ("]" ?\e,Ai\e(B)
 - (";" ?\e,Af\e(B)
 - ("'" ?\e,Ax\e(B)
 + ("[" ?Ã¥)
 + ("]" ?é)
 + (";" ?æ)
 + ("'" ?ø)
   ("\\" ?')
   ("/" ?-)
  
   ("@" ?\")
 - ("$" ?\e,A$\e(B)
 + ("$" ?¤)
   ("^" ?&)
   ("&" ?/)
   ("*" ?\()
   ("(" ?\))
   (")" ?=)
   ("_" ??)
 - ("+" ?\e,A'\e(B)
 + ("+" ?§)
   ("~" ?^)
 - ("{" ?\e,AE\e(B)
 - ("}" ?\e,AI\e(B)
 - (":" ?\e,AF\e(B)
 - ("\"" ?\e,AX\e(B)
 + ("{" ?Ã…)
 + ("}" ?É)
 + (":" ?Æ)
 + ("\"" ?Ø)
   ("|" ?*)
   ("<" ?\;)
   (">" ?:)
   "Norwegian (Norsk) input method simulating SUN Norwegian keyboard"
   nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3#  4\e,A$\e(B  5%  6&  7/  8(  9)  0=  +?  |\e,A'\e(B  ~^
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,AeE\e(B  \e,AiI\e(B
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,AxX\e(B  \e,AfF\e(B  '*
 +;; 1!  2"  3#  4¤  5%  6&  7/  8(  9)  0=  +?  |§  ~^
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã¥Ã…  Ã©Ã‰
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã¸Ã˜  Ã¦Ã†  '*
  ;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  '?
  
  (quail-define-rules
   ("-" ?+)
   ("=" ?|)
   ("`" ?~)
 - ("[" ?\e,Ae\e(B)
 - ("]" ?\e,Ai\e(B)
 - (";" ?\e,Ax\e(B)
 - ("'" ?\e,Af\e(B)
 + ("[" ?Ã¥)
 + ("]" ?é)
 + (";" ?ø)
 + ("'" ?æ)
   ("\\" ?')
   ("/" ?-)
  
   ("!" ?!)
   ("@" ?\")
 - ("$" ?\e,A$\e(B)
 + ("$" ?¤)
   ("^" ?&)
   ("&" ?/)
   ("*" ?\()
   ("(" ?\))
   (")" ?=)
   ("_" ??)
 - ("+" ?\e,A'\e(B)
 + ("+" ?§)
   ("~" ?^)
 - ("{" ?\e,AE\e(B)
 - ("}" ?\e,AI\e(B)
 - (":" ?\e,AX\e(B)
 - ("\"" ?\e,AF\e(B)
 + ("{" ?Ã…)
 + ("}" ?É)
 + (":" ?Ø)
 + ("\"" ?Æ)
   ("|" ?*)
   ("<" ?\;)
   (">" ?:)
   "Swedish (Svenska) input method simulating SUN Swedish/Finnish keyboard"
   nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3#  4\e,A$\e(B  5%  6&  7/  8(  9)  0=  +?  \e,A'=\e(B  ~^
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,AeE\e(B  \e,AiI\e(B
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,AvV\e(B  \e,AdD\e(B  '*
 +;; 1!  2"  3#  4¤  5%  6&  7/  8(  9)  0=  +?  Â§Â½  ~^
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã¥Ã…  Ã©Ã‰
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã¶Ã–  Ã¤Ã„  '*
  ;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  -_
  
  (quail-define-rules
   ("-" ?+)
 - ("=" ?\e,A'\e(B)
 + ("=" ?§)
   ("`" ?~)
 - ("[" ?\e,Ae\e(B)
 - ("]" ?\e,Ai\e(B)
 - (";" ?\e,Av\e(B)
 - ("'" ?\e,Ad\e(B)
 + ("[" ?Ã¥)
 + ("]" ?é)
 + (";" ?ö)
 + ("'" ?ä)
   ("\\" ?')
   ("/" ?-)
  
   ("@" ?\")
 - ("$" ?\e,A$\e(B)
 + ("$" ?¤)
   ("^" ?&)
   ("&" ?/)
   ("*" ?\()
   ("(" ?\))
   (")" ?=)
   ("_" ??)
 - ("+" ?\e,A=\e(B)
 + ("+" ?½)
   ("~" ?^)
 - ("{" ?\e,AE\e(B)
 - ("}" ?\e,AI\e(B)
 - (":" ?\e,AV\e(B)
 - ("\"" ?\e,AD\e(B)
 + ("{" ?Ã…)
 + ("}" ?É)
 + (":" ?Ö)
 + ("\"" ?Ä)
   ("|" ?*)
   ("<" ?\;)
   (">" ?:)
   "Finnish input method simulating SUN Finnish/Swedish keyboard"
   nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3#  4\e,A$\e(B  5%  6&  7/  8(  9)  0=  +?  \e,A'=\e(B  ~^
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,AeE\e(B  \e,AiI\e(B
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,AvV\e(B  \e,AdD\e(B  '*
 +;; 1!  2"  3#  4¤  5%  6&  7/  8(  9)  0=  +?  Â§Â½  ~^
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã¥Ã…  Ã©Ã‰
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã¶Ã–  Ã¤Ã„  '*
  ;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  -_
  
  (quail-define-rules
   ("-" ?+)
 - ("=" ?\e,A'\e(B)
 + ("=" ?§)
   ("`" ?~)
 - ("[" ?\e,Ae\e(B)
 - ("]" ?\e,Ai\e(B)
 - (";" ?\e,Av\e(B)
 - ("'" ?\e,Ad\e(B)
 + ("[" ?Ã¥)
 + ("]" ?é)
 + (";" ?ö)
 + ("'" ?ä)
   ("\\" ?')
   ("/" ?-)
  
   ("@" ?\")
 - ("$" ?\e,A$\e(B)
 + ("$" ?¤)
   ("^" ?&)
   ("&" ?/)
   ("*" ?\()
   ("(" ?\))
   (")" ?=)
   ("_" ??)
 - ("+" ?\e,A=\e(B)
 + ("+" ?½)
   ("~" ?^)
 - ("{" ?\e,AE\e(B)
 - ("}" ?\e,AI\e(B)
 - (":" ?\e,AV\e(B)
 - ("\"" ?\e,AD\e(B)
 + ("{" ?Ã…)
 + ("}" ?É)
 + (":" ?Ö)
 + ("\"" ?Ä)
   ("|" ?*)
   ("<" ?\;)
   (">" ?:)
   "German (Deutsch) input method simulating SUN German keyboard"
   nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3\e,A'\e(B  4$  5%  6&  7/  8(  9)  0=  \e,A_\e(B?  [{  ]}
 -;;  qQ  wW  eE  rR  tT  zZ  uU  iI  oO  pP  \e,A|\\e(B  +*
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,AvV\e(B  \e,AdD\e(B  #^
 +;; 1!  2"  3§  4$  5%  6&  7/  8(  9)  0=  ÃŸ?  [{  ]}
 +;;  qQ  wW  eE  rR  tT  zZ  uU  iI  oO  pP  Ã¼Ãœ  +*
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã¶Ã–  Ã¤Ã„  #^
  ;;    yY  xX  cC  vV  bB  nN  mM  ,;  .:  -_
  
  (quail-define-rules
 - ("-" ?\e,A_\e(B)
 + ("-" ?ß)
   ("=" ?\[)
   ("`" ?\])
   ("y" ?z)
 - ("[" ?\e,A|\e(B)
 + ("[" ?ü)
   ("]" ?+)
 - (";" ?\e,Av\e(B)
 - ("'" ?\e,Ad\e(B)
 + (";" ?ö)
 + ("'" ?ä)
   ("\\" ?#)
   ("z" ?y)
   ("/" ?-)
  
   ("@" ?\")
 - ("#" ?\e,A'\e(B)
 + ("#" ?§)
   ("^" ?&)
   ("&" ?/)
   ("*" ?\()
   ("_" ??)
   ("+" ?{)
   ("~" ?})
 - ("{" ?\e,A\\e(B)
 + ("{" ?Ãœ)
   ("}" ?*)
 - (":" ?\e,AV\e(B)
 - ("\"" ?\e,AD\e(B)
 + (":" ?Ö)
 + ("\"" ?Ä)
   ("|" ?^)
   ("Z" ?Y)
   ("<" ?\;)
   "Italian (Italiano) input method simulating SUN Italian keyboard"
   nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3\e,A#\e(B  4$  5%  6&  7/  8(  9)  0=  '?  \e,Al\e(B^  `~
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,Ahi\e(B  +*
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,Arg\e(B  \e,A`0\e(B  \e,Ay'\e(B
 +;; 1!  2"  3£  4$  5%  6&  7/  8(  9)  0=  '?  Ã¬^  `~
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã¨Ã©  +*
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã²Ã§  Ã Â°  Ã¹Â§
  ;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  -_
  
  (quail-define-rules
   ("-" ?')
 - ("=" ?\e,Al\e(B)
 - ("[" ?\e,Ah\e(B)
 + ("=" ?ì)
 + ("[" ?è)
   ("]" ?+)
 - (";" ?\e,Ar\e(B)
 - ("'" ?\e,A`\e(B)
 - ("\\" ?\e,Ay\e(B)
 + (";" ?ò)
 + ("'" ?à)
 + ("\\" ?ù)
   ("/" ?-)
  
   ("@" ?\")
 - ("#" ?\e,A#\e(B)
 + ("#" ?£)
   ("^" ?&)
   ("&" ?/)
   ("*" ?\()
   ("_" ??)
   ("+" ?^)
   ("~" ?~)
 - ("{" ?\e,Ai\e(B)
 + ("{" ?é)
   ("}" ?*)
 - (":" ?\e,Ag\e(B)
 - ("\"" ?\e,A0\e(B)
 - ("|" ?\e,A'\e(B)
 + (":" ?ç)
 + ("\"" ?°)
 + ("|" ?§)
   ("<" ?\;)
   (">" ?:)
   ("?" ?_)
  ;;
  (quail-define-package
   "spanish-keyboard" "Spanish" "ES@" t
 - "Spanish (Espa\e,Aq\e(Bol) input method simulating SUN Spanish keyboard"
 + "Spanish (Español) input method simulating SUN Spanish keyboard"
   nil t t t t nil nil nil nil nil t)
  
 -;; 1!  2"  3\e,A7\e(B  4$  5%  6&  7/  8(  9)  0=  '?  \e,A!?\e(B  \e,AmM\e(B
 -;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  \e,AiI\e(B  \e,AsS\e(B
 -;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  \e,AqQ\e(B  \e,AaA\e(B  \e,AzZ\e(B
 +;; 1!  2"  3·  4$  5%  6&  7/  8(  9)  0=  '?  Â¡Â¿  Ã­Ã
 +;;  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  Ã©Ã‰  Ã³Ã“
 +;;   aA  sS  dD  fF  gG  hH  jJ  kK  lL  Ã±Ã‘  Ã¡Ã  ÃºÃš
  ;;    zZ  xX  cC  vV  bB  nN  mM  ,;  .:  -_
  
  (quail-define-rules
   ("-" ?')
 - ("=" ?\e,A!\e(B)
 - ("`" ?\e,Am\e(B)
 - ("[" ?\e,Ai\e(B)
 - ("]" ?\e,As\e(B)
 - (";" ?\e,Aq\e(B)
 - ("'" ?\e,Aa\e(B)
 - ("\\" ?\e,Az\e(B)
 + ("=" ?¡)
 + ("`" ?í)
 + ("[" ?é)
 + ("]" ?ó)
 + (";" ?ñ)
 + ("'" ?á)
 + ("\\" ?ú)
   ("/" ?-)
  
   ("@" ?\")
 - ("#" ?\e,A7\e(B)
 + ("#" ?·)
   ("^" ?&)
   ("&" ?/)
   ("*" ?\()
   ("(" ?\))
   (")" ?=)
   ("_" ??)
 - ("+" ?\e,A?\e(B)
 - ("~" ?\e,AM\e(B)
 - ("{" ?\e,AI\e(B)
 - ("}" ?\e,AS\e(B)
 - (":" ?\e,AQ\e(B)
 - ("\"" ?\e,AA\e(B)
 - ("|" ?\e,AZ\e(B)
 + ("+" ?¿)
 + ("~" ?Ã)
 + ("{" ?É)
 + ("}" ?Ó)
 + (":" ?Ñ)
 + ("\"" ?Ã)
 + ("|" ?Ú)
   ("<" ?\;)
   (">" ?:)
   ("?" ?_)
@@@ -2079,215 -2138,215 +2081,215 @@@ of characters from a single Latin-N cha
  
               | postfix | examples
   ------------+---------+----------
 -  acute      |    '    | a' -> \e,Aa\e(B
 -  grave      |    `    | a` -> \e,A`\e(B
 -  circumflex |    ^    | a^ -> \e,Ab\e(B
 -  diaeresis  |    \"    | a\" -> \e,Ad\e(B
 -  tilde      |    ~    | a~ -> \e,Ac\e(B
 -  cedilla    |    ,    | c, -> \e,Ag\e(B
 -  ogonek     |    ,    | a, -> \e$,1 %\e(B
 -  breve      |    ~    | a~ -> \e$,1 #\e(B
 -  caron      |    ~    | c~ -> \e$,1 -\e(B
 -  dbl. acute |    :    | o: -> \e$,1 q\e(B
 -  ring       |    .    | u. -> \e$,1!/\e(B
 -  dot        |    .    | z. -> \e$,1!<\e(B
 -  stroke     |    /    | d/ -> \e$,1 1\e(B
 -  nordic     |    /    | d/ -> \e,Ap\e(B   t/ -> \e,A~\e(B   a/ -> \e,Ae\e(B   e/ -> \e,Af\e(B   o/ -> \e,Ax\e(B
 -  others     |    /    | s/ -> \e,A_\e(B   ?/ -> \e,A?\e(B   !/ -> \e,A!\e(B   // -> \e,A0\e(B
 -             | various | << -> \e,A+\e(B   >> -> \e,A;\e(B   o_ -> \e,A:\e(B   a_ -> \e,A*\e(B
 +  acute      |    '    | a' -> Ã¡
 +  grave      |    `    | a` -> Ã 
 +  circumflex |    ^    | a^ -> Ã¢
 +  diaeresis  |    \"    | a\" -> Ã¤
 +  tilde      |    ~    | a~ -> Ã£
 +  cedilla    |    ,    | c, -> Ã§
 +  ogonek     |    ,    | a, -> Ä…
 +  breve      |    ~    | a~ -> Äƒ
 +  caron      |    ~    | c~ -> Ä
 +  dbl. acute |    :    | o: -> Å‘
 +  ring       |    .    | u. -> Å¯
 +  dot        |    .    | z. -> Å¼
 +  stroke     |    /    | d/ -> Ä‘
 +  nordic     |    /    | d/ -> Ã°   t/ -> Ã¾   a/ -> Ã¥   e/ -> Ã¦   o/ -> Ã¸
 +  others     |    /    | s/ -> ÃŸ   ?/ -> Â¿   !/ -> Â¡   // -> Â°
 +             | various | << -> Â«   >> -> Â»   o_ -> Âº   a_ -> Âª
  
  Doubling the postfix separates the letter and postfix: e.g. a'' -> a'
  " nil t nil nil nil nil nil nil nil nil t)
  
 -;; Fixme: \e,A&\e(B \e,A'\e(B \e,A(\e(B \e,A)\e(B \e,A,\e(B \e,A-\e(B \e,A.\e(B \e,A/\e(B \e,A1\e(B \e,A2\e(B \e,A3\e(B \e,A4\e(B \e,A5\e(B \e,A6\e(B \e,A7\e(B \e,A8\e(B \e,A9\e(B \e,A<\e(B \e,A=\e(B \e,A>\e(B \e,AW\e(B \e,Aw\e(B
 +;; Fixme: Â¦ Â§ Â¨ Â© Â¬ Â­ Â® Â¯ Â± Â² Â³ Â´ Âµ Â¶ Â· Â¸ Â¹ Â¼ Â½ Â¾ Ã— Ã·
  (quail-define-rules
 - (" _" ?\e,A \e(B)
 - ("!/" ?\e,A!\e(B)
 - ("//" ?\e,A0\e(B)
 - ("<<" ?\\e,A+\e(B)
 - (">>" ?\\e,A;\e(B)
 - ("?/" ?\e,A?\e(B)
 - ("$/" ?\e,A#\e(B)
 - ("$/" ?\e,A$\e(B)
 - ("A'" ?\e,AA\e(B)
 - ("A," ?\e$,1 $\e(B)
 - ("A-" ?\e$,1  \e(B)
 - ("A/" ?\e,AE\e(B)
 - ("A\"" ?\e,AD\e(B)
 - ("A^" ?\e,AB\e(B)
 - ("A`" ?\e,A@\e(B)
 - ("A~" ?\e,AC\e(B)
 - ("A~" ?\e$,1 "\e(B)
 - ("C'" ?\e$,1 &\e(B)
 - ("C," ?\e,AG\e(B)
 - ("C." ?\e$,1 *\e(B)
 - ("C^" ?\e$,1 (\e(B)
 - ("C~" ?\e$,1 ,\e(B)
 - ("D/" ?\e,AP\e(B)
 - ("D/" ?\e$,1 0\e(B)
 - ("D~" ?\e$,1 .\e(B)
 - ("E'" ?\e,AI\e(B)
 - ("E," ?\e$,1 8\e(B)
 - ("E-" ?\e$,1 2\e(B)
 - ("E." ?\e$,1 6\e(B)
 - ("E/" ?\e,AF\e(B)
 - ("E\"" ?\e,AK\e(B)
 - ("E^" ?\e,AJ\e(B)
 - ("E`" ?\e,AH\e(B)
 - ("E~" ?\e$,1 :\e(B)
 - ("G," ?\e$,1 B\e(B)
 - ("G." ?\e$,1 @\e(B)
 - ("G^" ?\e$,1 <\e(B)
 - ("G~" ?\e$,1 >\e(B)
 - ("H/" ?\e$,1 F\e(B)
 - ("H^" ?\e$,1 D\e(B)
 - ("I'" ?\e,AM\e(B)
 - ("I," ?\e$,1 N\e(B)
 - ("I-" ?\e$,1 J\e(B)
 - ("I." ?\e$,1 P\e(B)
 - ("I\"" ?\e,AO\e(B)
 - ("I^" ?\e,AN\e(B)
 - ("I`" ?\e,AL\e(B)
 - ("I~" ?\e$,1 H\e(B)
 - ("J^" ?\e$,1 T\e(B)
 - ("K," ?\e$,1 V\e(B)
 - ("L'" ?\e$,1 Y\e(B)
 - ("L," ?\e$,1 [\e(B)
 - ("L/" ?\e$,1 a\e(B)
 - ("L~" ?\e$,1 ]\e(B)
 - ("N'" ?\e$,1 c\e(B)
 - ("N," ?\e$,1 e\e(B)
 - ("N/" ?\e$,1 j\e(B)
 - ("N~" ?\e,AQ\e(B)
 - ("N~" ?\e$,1 g\e(B)
 - ("O'" ?\e,AS\e(B)
 - ("O-" ?\e$,1 l\e(B)
 - ("O/" ?\e,AX\e(B)
 - ("O/" ?\e$,1 r\e(B)
 - ("O:" ?\e$,1 p\e(B)
 - ("O\"" ?\e,AV\e(B)
 - ("O^" ?\e,AT\e(B)
 - ("O`" ?\e,AR\e(B)
 - ("O~" ?\e,AU\e(B)
 - ("R'" ?\e$,1 t\e(B)
 - ("R," ?\e$,1 v\e(B)
 - ("R~" ?\e$,1 x\e(B)
 - ("S'" ?\e$,1 z\e(B)
 - ("S," ?\e$,1 ~\e(B)
 - ("S^" ?\e$,1 |\e(B)
 - ("S~" ?\e$,1! \e(B)
 - ("T," ?\e$,1!"\e(B)
 - ("T/" ?\e,A^\e(B)
 - ("T/" ?\e$,1!&\e(B)
 - ("T~" ?\e$,1!$\e(B)
 - ("U'" ?\e,AZ\e(B)
 - ("U," ?\e$,1!2\e(B)
 - ("U-" ?\e$,1!*\e(B)
 - ("U." ?\e$,1!.\e(B)
 - ("U:" ?\e$,1!0\e(B)
 - ("U\"" ?\e,A\\e(B)
 - ("U^" ?\e,A[\e(B)
 - ("U`" ?\e,AY\e(B)
 - ("U~" ?\e$,1!(\e(B)
 - ("U~" ?\e$,1!,\e(B)
 - ("Y'" ?\e,A]\e(B)
 - ("Y\"" ?\e$,1!8\e(B)
 - ("Y=" ?\e,A%\e(B)
 - ("Z'" ?\e$,1!9\e(B)
 - ("Z." ?\e$,1!;\e(B)
 - ("Z~" ?\e$,1!=\e(B)
 - ("a'" ?\e,Aa\e(B)
 - ("a," ?\e$,1 %\e(B)
 - ("a-" ?\e$,1 !\e(B)
 - ("a/" ?\e,Ae\e(B)
 - ("a\"" ?\e,Ad\e(B)
 - ("a^" ?\e,Ab\e(B)
 - ("a_" ?\e,A*\e(B)
 - ("a`" ?\e,A`\e(B)
 - ("a~" ?\e,Ac\e(B)
 - ("a~" ?\e$,1 #\e(B)
 - ("c'" ?\e$,1 '\e(B)
 - ("c," ?\e,Ag\e(B)
 - ("c." ?\e$,1 +\e(B)
 - ("c^" ?\e$,1 )\e(B)
 - ("c~" ?\e$,1 -\e(B)
 - ("c/" ?\e,A"\e(B)
 - ("d/" ?\e,Ap\e(B)
 - ("d/" ?\e$,1 1\e(B)
 - ("d~" ?\e$,1 /\e(B)
 - ("e'" ?\e,Ai\e(B)
 - ("e," ?\e$,1 9\e(B)
 - ("e-" ?\e$,1 3\e(B)
 - ("e." ?\e$,1 7\e(B)
 - ("e/" ?\e,Af\e(B)
 - ("e\"" ?\e,Ak\e(B)
 - ("e^" ?\e,Aj\e(B)
 - ("e`" ?\e,Ah\e(B)
 - ("e~" ?\e$,1 ;\e(B)
 - ("e=" ?\e$,1tL\e(B)
 - ("g," ?\e$,1 C\e(B)
 - ("g." ?\e$,1 A\e(B)
 - ("g^" ?\e$,1 =\e(B)
 - ("g~" ?\e$,1 ?\e(B)
 - ("h/" ?\e$,1 G\e(B)
 - ("h^" ?\e$,1 E\e(B)
 - ("i'" ?\e,Am\e(B)
 - ("i," ?\e$,1 O\e(B)
 - ("i-" ?\e$,1 K\e(B)
 - ("i." ?\e$,1 Q\e(B)
 - ("i\"" ?\e,Ao\e(B)
 - ("i^" ?\e,An\e(B)
 - ("i`" ?\e,Al\e(B)
 - ("i~" ?\e$,1 I\e(B)
 - ("j^" ?\e$,1 U\e(B)
 - ("k," ?\e$,1 W\e(B)
 - ("k/" ?\e$,1 X\e(B)
 - ("l'" ?\e$,1 Z\e(B)
 - ("l," ?\e$,1 \\e(B)
 - ("l/" ?\e$,1 b\e(B)
 - ("l~" ?\e$,1 ^\e(B)
 - ("n'" ?\e$,1 d\e(B)
 - ("n," ?\e$,1 f\e(B)
 - ("n/" ?\e$,1 k\e(B)
 - ("n~" ?\e,Aq\e(B)
 - ("n~" ?\e$,1 h\e(B)
 - ("o'" ?\e,As\e(B)
 - ("o-" ?\e$,1 m\e(B)
 - ("o/" ?\e,Ax\e(B)
 - ("o/" ?\e$,1 s\e(B)
 - ("o:" ?\e$,1 q\e(B)
 - ("o\"" ?\e,Av\e(B)
 - ("o^" ?\e,At\e(B)
 - ("o_" ?\e,A:\e(B)
 - ("o`" ?\e,Ar\e(B)
 - ("o~" ?\e,Au\e(B)
 - ("r'" ?\e$,1 u\e(B)
 - ("r," ?\e$,1 w\e(B)
 - ("r~" ?\e$,1 y\e(B)
 - ("s'" ?\e$,1 {\e(B)
 - ("s," ?\e$,1 \7f\e(B)
 - ("s/" ?\e,A_\e(B)
 - ("s^" ?\e$,1 }\e(B)
 - ("s~" ?\e$,1!!\e(B)
 - ("t," ?\e$,1!#\e(B)
 - ("t/" ?\e,A~\e(B)
 - ("t/" ?\e$,1!'\e(B)
 - ("t~" ?\e$,1!%\e(B)
 - ("u'" ?\e,Az\e(B)
 - ("u," ?\e$,1!3\e(B)
 - ("u-" ?\e$,1!+\e(B)
 - ("u." ?\e$,1!/\e(B)
 - ("u:" ?\e$,1!1\e(B)
 - ("u\"" ?\e,A|\e(B)
 - ("u^" ?\e,A{\e(B)
 - ("u`" ?\e,Ay\e(B)
 - ("u~" ?\e$,1!)\e(B)
 - ("u~" ?\e$,1!-\e(B)
 - ("y'" ?\e,A}\e(B)
 - ("y\"" ?\e,A\7f\e(B)
 - ("z'" ?\e$,1!:\e(B)
 - ("z." ?\e$,1!<\e(B)
 - ("z~" ?\e$,1!>\e(B)
 + (" _" ? )
 + ("!/" ?¡)
 + ("//" ?°)
 + ("<<" ?\«)
 + (">>" ?\»)
 + ("?/" ?¿)
 + ("$/" ?£)
 + ("$/" ?¤)
 + ("A'" ?Ã)
 + ("A," ?Ä„)
 + ("A-" ?Ä€)
 + ("A/" ?Ã…)
 + ("A\"" ?Ä)
 + ("A^" ?Â)
 + ("A`" ?À)
 + ("A~" ?Ã)
 + ("A~" ?Ä‚)
 + ("C'" ?Ć)
 + ("C," ?Ç)
 + ("C." ?ÄŠ)
 + ("C^" ?Ĉ)
 + ("C~" ?ÄŒ)
 + ("D/" ?Ã)
 + ("D/" ?Ä)
 + ("D~" ?ÄŽ)
 + ("E'" ?É)
 + ("E," ?Ę)
 + ("E-" ?Ä’)
 + ("E." ?Ä–)
 + ("E/" ?Æ)
 + ("E\"" ?Ë)
 + ("E^" ?Ê)
 + ("E`" ?È)
 + ("E~" ?Äš)
 + ("G," ?Ä¢)
 + ("G." ?Ä )
 + ("G^" ?Äœ)
 + ("G~" ?Äž)
 + ("H/" ?Ħ)
 + ("H^" ?Ĥ)
 + ("I'" ?Ã)
 + ("I," ?Ä®)
 + ("I-" ?Ī)
 + ("I." ?Ä°)
 + ("I\"" ?Ã)
 + ("I^" ?ÃŽ)
 + ("I`" ?ÃŒ)
 + ("I~" ?Ĩ)
 + ("J^" ?Ä´)
 + ("K," ?Ķ)
 + ("L'" ?Ĺ)
 + ("L," ?Ä»)
 + ("L/" ?Å)
 + ("L~" ?Ľ)
 + ("N'" ?Ń)
 + ("N," ?Å…)
 + ("N/" ?ÅŠ)
 + ("N~" ?Ñ)
 + ("N~" ?Ň)
 + ("O'" ?Ó)
 + ("O-" ?ÅŒ)
 + ("O/" ?Ø)
 + ("O/" ?Å’)
 + ("O:" ?Å)
 + ("O\"" ?Ö)
 + ("O^" ?Ô)
 + ("O`" ?Ã’)
 + ("O~" ?Õ)
 + ("R'" ?Å”)
 + ("R," ?Å–)
 + ("R~" ?Ř)
 + ("S'" ?Åš)
 + ("S," ?Åž)
 + ("S^" ?Åœ)
 + ("S~" ?Å )
 + ("T," ?Å¢)
 + ("T/" ?Þ)
 + ("T/" ?Ŧ)
 + ("T~" ?Ť)
 + ("U'" ?Ú)
 + ("U," ?Ų)
 + ("U-" ?Ū)
 + ("U." ?Å®)
 + ("U:" ?Å°)
 + ("U\"" ?Ãœ)
 + ("U^" ?Û)
 + ("U`" ?Ù)
 + ("U~" ?Ũ)
 + ("U~" ?Ŭ)
 + ("Y'" ?Ã)
 + ("Y\"" ?Ÿ)
 + ("Y=" ?Â¥)
 + ("Z'" ?Ź)
 + ("Z." ?Å»)
 + ("Z~" ?Ž)
 + ("a'" ?á)
 + ("a," ?Ä…)
 + ("a-" ?Ä)
 + ("a/" ?Ã¥)
 + ("a\"" ?ä)
 + ("a^" ?â)
 + ("a_" ?ª)
 + ("a`" ?à)
 + ("a~" ?ã)
 + ("a~" ?ă)
 + ("c'" ?ć)
 + ("c," ?ç)
 + ("c." ?Ä‹)
 + ("c^" ?ĉ)
 + ("c~" ?Ä)
 + ("c/" ?¢)
 + ("d/" ?ð)
 + ("d/" ?Ä‘)
 + ("d~" ?Ä)
 + ("e'" ?é)
 + ("e," ?Ä™)
 + ("e-" ?Ä“)
 + ("e." ?Ä—)
 + ("e/" ?æ)
 + ("e\"" ?ë)
 + ("e^" ?ê)
 + ("e`" ?è)
 + ("e~" ?Ä›)
 + ("e=" ?€)
 + ("g," ?Ä£)
 + ("g." ?Ä¡)
 + ("g^" ?Ä)
 + ("g~" ?ÄŸ)
 + ("h/" ?ħ)
 + ("h^" ?Ä¥)
 + ("i'" ?í)
 + ("i," ?į)
 + ("i-" ?Ä«)
 + ("i." ?ı)
 + ("i\"" ?ï)
 + ("i^" ?î)
 + ("i`" ?ì)
 + ("i~" ?Ä©)
 + ("j^" ?ĵ)
 + ("k," ?Ä·)
 + ("k/" ?ĸ)
 + ("l'" ?ĺ)
 + ("l," ?ļ)
 + ("l/" ?Å‚)
 + ("l~" ?ľ)
 + ("n'" ?Å„)
 + ("n," ?ņ)
 + ("n/" ?Å‹)
 + ("n~" ?ñ)
 + ("n~" ?ň)
 + ("o'" ?ó)
 + ("o-" ?Å)
 + ("o/" ?ø)
 + ("o/" ?Å“)
 + ("o:" ?Å‘)
 + ("o\"" ?ö)
 + ("o^" ?ô)
 + ("o_" ?º)
 + ("o`" ?ò)
 + ("o~" ?õ)
 + ("r'" ?Å•)
 + ("r," ?Å—)
 + ("r~" ?Å™)
 + ("s'" ?Å›)
 + ("s," ?ÅŸ)
 + ("s/" ?ß)
 + ("s^" ?Å)
 + ("s~" ?Å¡)
 + ("t," ?Å£)
 + ("t/" ?þ)
 + ("t/" ?ŧ)
 + ("t~" ?Å¥)
 + ("u'" ?ú)
 + ("u," ?ų)
 + ("u-" ?Å«)
 + ("u." ?ů)
 + ("u:" ?ű)
 + ("u\"" ?ü)
 + ("u^" ?û)
 + ("u`" ?ù)
 + ("u~" ?Å©)
 + ("u~" ?Å­)
 + ("y'" ?ý)
 + ("y\"" ?ÿ)
 + ("z'" ?ź)
 + ("z." ?ż)
 + ("z~" ?ž)
  
   ("!//" ["!/"])
   ("///" ["//"])
   nil t t t nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("C<" ?\e,BH\e(B)
 - ("C'" ?\e,BF\e(B)
 - ("D;" ?\e,BP\e(B)
 - ("S<" ?\e,B)\e(B)
 - ("Z<" ?\e,B.\e(B)
 - ("c<" ?\e,Bh\e(B)
 - ("c'" ?\e,Bf\e(B)
 - ("d;" ?\e,Bp\e(B)
 - ("s<" ?\e,B9\e(B)
 - ("z<" ?\e,B>\e(B))
 + ("C<" ?ÄŒ)
 + ("C'" ?Ć)
 + ("D;" ?Ä)
 + ("S<" ?Å )
 + ("Z<" ?Ž)
 + ("c<" ?Ä)
 + ("c'" ?ć)
 + ("d;" ?Ä‘)
 + ("s<" ?Å¡)
 + ("z<" ?ž))
  
  ;;; arch-tag: 170180fb-9617-4d58-9d51-65ca23c05d94
  ;;; latin-post.el ends here
diff --combined leim/quail/latin-pre.el
index be2a1b21749e2ebdfc31958031b5dcf937516704,76c2bc7937e5e8423604bcfe54d3f294767c6027..c3298be5bc981b215b0b4bc0ac9c89ad9b72e804
@@@ -1,8 -1,10 +1,10 @@@
 -;;; latin-pre.el --- Quail packages for inputting various European characters  -*-coding: iso-2022-7bit;-*-
 +;;; latin-pre.el --- Quail packages for inputting various European characters  -*-coding: utf-8;-*-
  
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
@@@ -33,8 -35,8 +35,8 @@@
  ;;                 by R.F. Smith <rsmith@xs4all.nl>
  ;;
  ;; polish-slash:
 -;; Author: W\e,B3\e(Bodek Bzyl <matwb@univ.gda.pl>
 -;; Maintainer: W\e,B3\e(Bodek Bzyl <matwb@univ.gda.pl>
 +;; Author: WÅ‚odek Bzyl <matwb@univ.gda.pl>
 +;; Maintainer: WÅ‚odek Bzyl <matwb@univ.gda.pl>
  ;;
  ;; latin-[89]-prefix: Dave Love <fx@gnu.org>
  
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,Aa\e(B, '' -> \e,A4\e(B
 -    grave    |   `    | `a -> \e,A`\e(B
 -  circumflex |   ^    | ^a -> \e,Ab\e(B
 -  diaeresis  |   \"    | \"a -> \e,Ad\e(B  \"\" -> \e,A(\e(B
 -    tilde    |   ~    | ~a -> \e,Ac\e(B
 -   cedilla   |   ~    | ~c -> \e,Ag\e(B
 -    misc     | \" ~ /  | \"s -> \e,A_\e(B  ~d -> \e,Ap\e(B  ~t -> \e,A~\e(B  /a -> \e,Ae\e(B  /e -> \e,Af\e(B  /o -> \e,Ax\e(B
 -   symbol    |   ~    | ~> -> \e,A;\e(B  ~< -> \e,A+\e(B  ~! -> \e,A!\e(B  ~? -> \e,A?\e(B  ~~ -> \e,A8\e(B
 -             |   ~    | ~s -> \e,A'\e(B  ~x -> \e,A$\e(B  ~. -> \e,A7\e(B  ~$ -> \e,A#\e(B  ~u -> \e,A5\e(B
 -             |   ~    | ~p -> \e,A6\e(B  ~- -> \e,A-\e(B  ~= -> \e,A/\e(B  ~| -> \e,A&\e(B
 -   symbol    |  _ /   | _o -> \e,A:\e(B  _a -> \e,A*\e(B  // -> \e,A0\e(B  /\\ -> \e,AW\e(B  _y -> \e,A%\e(B
 -             |  _ /   | _: -> \e,Aw\e(B  /c -> \e,A"\e(B  /2 -> \e,A=\e(B  /4 -> \e,A<\e(B  /3 -> \e,A>\e(B
 -             |  _ /   | /= -> \e,A,\e(B
 -   symbol    |   ^    | ^r -> \e,A.\e(B  ^c -> \e,A)\e(B  ^1 -> \e,A9\e(B  ^2 -> \e,A2\e(B  ^3 -> \e,A3\e(B
 +    acute    |   '    | 'a -> Ã¡, '' -> Â´
 +    grave    |   `    | `a -> Ã 
 +  circumflex |   ^    | ^a -> Ã¢
 +  diaeresis  |   \"    | \"a -> Ã¤  \"\" -> Â¨
 +    tilde    |   ~    | ~a -> Ã£
 +   cedilla   |   ~    | ~c -> Ã§
 +    misc     | \" ~ /  | \"s -> ÃŸ  ~d -> Ã°  ~t -> Ã¾  /a -> Ã¥  /e -> Ã¦  /o -> Ã¸
 +   symbol    |   ~    | ~> -> Â»  ~< -> Â«  ~! -> Â¡  ~? -> Â¿  ~~ -> Â¸
 +             |   ~    | ~s -> Â§  ~x -> Â¤  ~. -> Â·  ~$ -> Â£  ~u -> Âµ
 +             |   ~    | ~p -> Â¶  ~- -> Â­  ~= -> Â¯  ~| -> Â¦
 +   symbol    |  _ /   | _o -> Âº  _a -> Âª  // -> Â°  /\\ -> Ã—  _y -> Â¥
 +             |  _ /   | _: -> Ã·  /c -> Â¢  /2 -> Â½  /4 -> Â¼  /3 -> Â¾
 +             |  _ /   | /= -> Â¬
 +   symbol    |   ^    | ^r -> Â®  ^c -> Â©  ^1 -> Â¹  ^2 -> Â²  ^3 -> Â³
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,AA\e(B)
 - ("'E" ?\e,AI\e(B)
 - ("'I" ?\e,AM\e(B)
 - ("'O" ?\e,AS\e(B)
 - ("'U" ?\e,AZ\e(B)
 - ("'Y" ?\e,A]\e(B)
 - ("'a" ?\e,Aa\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'i" ?\e,Am\e(B)
 - ("'o" ?\e,As\e(B)
 - ("'u" ?\e,Az\e(B)
 - ("'y" ?\e,A}\e(B)
 - ("''" ?\e,A4\e(B)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'Y" ?Ã)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
 + ("'y" ?ý)
 + ("''" ?´)
   ("' " ?')
 - ("`A" ?\e,A@\e(B)
 - ("`E" ?\e,AH\e(B)
 - ("`I" ?\e,AL\e(B)
 - ("`O" ?\e,AR\e(B)
 - ("`U" ?\e,AY\e(B)
 - ("`a" ?\e,A`\e(B)
 - ("`e" ?\e,Ah\e(B)
 - ("`i" ?\e,Al\e(B)
 - ("`o" ?\e,Ar\e(B)
 - ("`u" ?\e,Ay\e(B)
 + ("`A" ?À)
 + ("`E" ?È)
 + ("`I" ?ÃŒ)
 + ("`O" ?Ã’)
 + ("`U" ?Ù)
 + ("`a" ?à)
 + ("`e" ?è)
 + ("`i" ?ì)
 + ("`o" ?ò)
 + ("`u" ?ù)
   ("``" ?`)
   ("` " ?`)
 - ("^A" ?\e,AB\e(B)
 - ("^E" ?\e,AJ\e(B)
 - ("^I" ?\e,AN\e(B)
 - ("^O" ?\e,AT\e(B)
 - ("^U" ?\e,A[\e(B)
 - ("^a" ?\e,Ab\e(B)
 - ("^e" ?\e,Aj\e(B)
 - ("^i" ?\e,An\e(B)
 - ("^o" ?\e,At\e(B)
 - ("^u" ?\e,A{\e(B)
 + ("^A" ?Â)
 + ("^E" ?Ê)
 + ("^I" ?ÃŽ)
 + ("^O" ?Ô)
 + ("^U" ?Û)
 + ("^a" ?â)
 + ("^e" ?ê)
 + ("^i" ?î)
 + ("^o" ?ô)
 + ("^u" ?û)
   ("^^" ?^)
   ("^ " ?^)
 - ("\"A" ?\e,AD\e(B)
 - ("\"E" ?\e,AK\e(B)
 - ("\"I" ?\e,AO\e(B)
 - ("\"O" ?\e,AV\e(B)
 - ("\"U" ?\e,A\\e(B)
 - ("\"a" ?\e,Ad\e(B)
 - ("\"e" ?\e,Ak\e(B)
 - ("\"i" ?\e,Ao\e(B)
 - ("\"o" ?\e,Av\e(B)
 - ("\"s" ?\e,A_\e(B)
 - ("\"u" ?\e,A|\e(B)
 - ("\"y" ?\e,A\7f\e(B)
 - ("\"\"" ?\e,A(\e(B)
 + ("\"A" ?Ä)
 + ("\"E" ?Ë)
 + ("\"I" ?Ã)
 + ("\"O" ?Ö)
 + ("\"U" ?Ãœ)
 + ("\"a" ?ä)
 + ("\"e" ?ë)
 + ("\"i" ?ï)
 + ("\"o" ?ö)
 + ("\"s" ?ß)
 + ("\"u" ?ü)
 + ("\"y" ?ÿ)
 + ("\"\"" ?¨)
   ("\" " ?\")
 - ("~A" ?\e,AC\e(B)
 - ("~C" ?\e,AG\e(B)
 - ("~D" ?\e,AP\e(B)
 - ("~N" ?\e,AQ\e(B)
 - ("~O" ?\e,AU\e(B)
 - ("~T" ?\e,A^\e(B)
 - ("~a" ?\e,Ac\e(B)
 - ("~c" ?\e,Ag\e(B)
 - ("~d" ?\e,Ap\e(B)
 - ("~n" ?\e,Aq\e(B)
 - ("~o" ?\e,Au\e(B)
 - ("~t" ?\e,A~\e(B)
 - ("~>" ?\\e,A;\e(B)
 - ("~<" ?\\e,A+\e(B)
 - ("~!" ?\e,A!\e(B)
 - ("~?" ?\e,A?\e(B)
 - ("~~" ?\e,A8\e(B)
 + ("~A" ?Ã)
 + ("~C" ?Ç)
 + ("~D" ?Ã)
 + ("~N" ?Ñ)
 + ("~O" ?Õ)
 + ("~T" ?Þ)
 + ("~a" ?ã)
 + ("~c" ?ç)
 + ("~d" ?ð)
 + ("~n" ?ñ)
 + ("~o" ?õ)
 + ("~t" ?þ)
 + ("~>" ?\»)
 + ("~<" ?\«)
 + ("~!" ?¡)
 + ("~?" ?¿)
 + ("~~" ?¸)
   ("~ " ?~)
 - ("/A" ?\e,AE\e(B)
 - ("/E" ?\e,AF\e(B)
 - ("/O" ?\e,AX\e(B)
 - ("/a" ?\e,Ae\e(B)
 - ("/e" ?\e,Af\e(B)
 - ("/o" ?\e,Ax\e(B)
 - ("//" ?\e,A0\e(B)
 + ("/A" ?Ã…)
 + ("/E" ?Æ)
 + ("/O" ?Ø)
 + ("/a" ?Ã¥)
 + ("/e" ?æ)
 + ("/o" ?ø)
 + ("//" ?°)
   ("/ " ?/)
 - ("_o" ?\e,A:\e(B)
 - ("_a" ?\e,A*\e(B)
 - ("_ " ?\e,A \e(B)
 + ("_o" ?º)
 + ("_a" ?ª)
 + ("_ " ? )
  ;; Symbols added by Roland Smith <rsmith@xs4all.nl>
 - ("_+" ?\e,A1\e(B)
 - ("_y" ?\e,A%\e(B)
 - ("_:" ?\e,Aw\e(B)
 + ("_+" ?±)
 + ("_y" ?Â¥)
 + ("_:" ?÷)
   ("__" ?_)
 - ("/c" ?\e,A"\e(B)
 - ("/\\" ?\e,AW\e(B)
 - ("/2" ?\e,A=\e(B)
 - ("/4" ?\e,A<\e(B)
 - ("/3" ?\e,A>\e(B)
 - ("~s" ?\e,A'\e(B)
 - ("~p" ?\e,A6\e(B)
 - ("~x" ?\e,A$\e(B)
 - ("~." ?\e,A7\e(B)
 - ("~$" ?\e,A#\e(B)
 - ("~u" ?\e,A5\e(B)
 - ("^r" ?\e,A.\e(B)
 - ("^c" ?\e,A)\e(B)
 - ("^1" ?\e,A9\e(B)
 - ("^2" ?\e,A2\e(B)
 - ("^3" ?\e,A3\e(B)
 - ("~-" ?\e,A-\e(B)
 - ("~|" ?\e,A&\e(B)
 - ("/=" ?\e,A,\e(B)
 - ("~=" ?\e,A/\e(B)
 + ("/c" ?¢)
 + ("/\\" ?×)
 + ("/2" ?½)
 + ("/4" ?¼)
 + ("/3" ?¾)
 + ("~s" ?§)
 + ("~p" ?¶)
 + ("~x" ?¤)
 + ("~." ?·)
 + ("~$" ?£)
 + ("~u" ?µ)
 + ("^r" ?®)
 + ("^c" ?©)
 + ("^1" ?¹)
 + ("^2" ?²)
 + ("^3" ?³)
 + ("~-" ?­)
 + ("~|" ?¦)
 + ("/=" ?¬)
 + ("~=" ?¯)
  )
  
  (quail-define-package
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,Aa\e(B   '' -> \e,A4\e(B
 -    grave    |   `    | `a -> \e,A`\e(B
 -  diaeresis  |   \"    | \"i -> \e,Ao\e(B   \"\" -> \e,A(\e(B
 -    tilde    |   ~    | ~n -> \e,Aq\e(B
 -   cedilla   |   ~    | ~c -> \e,Ag\e(B
 -   symbol    |   ~    | ~> -> \e,A;\e(B   ~< -> \e,A+\e(B   ~! -> \e,A!\e(B   ~? -> \e,A?\e(B
 +    acute    |   '    | 'a -> Ã¡   '' -> Â´
 +    grave    |   `    | `a -> Ã 
 +  diaeresis  |   \"    | \"i -> Ã¯   \"\" -> Â¨
 +    tilde    |   ~    | ~n -> Ã±
 +   cedilla   |   ~    | ~c -> Ã§
 +   symbol    |   ~    | ~> -> Â»   ~< -> Â«   ~! -> Â¡   ~? -> Â¿
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,AA\e(B)
 - ("'E" ?\e,AI\e(B)
 - ("'I" ?\e,AM\e(B)
 - ("'O" ?\e,AS\e(B)
 - ("'U" ?\e,AZ\e(B)
 - ("'a" ?\e,Aa\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'i" ?\e,Am\e(B)
 - ("'o" ?\e,As\e(B)
 - ("'u" ?\e,Az\e(B)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
   ("' " ?')
 - ("`A" ?\e,A@\e(B)
 - ("`E" ?\e,AH\e(B)
 - ("`O" ?\e,AR\e(B)
 - ("`a" ?\e,A`\e(B)
 - ("`e" ?\e,Ah\e(B)
 - ("`o" ?\e,Ar\e(B)
 + ("`A" ?À)
 + ("`E" ?È)
 + ("`O" ?Ã’)
 + ("`a" ?à)
 + ("`e" ?è)
 + ("`o" ?ò)
   ("` " ?`)
 - ("\"I" ?\e,AO\e(B)
 - ("\"U" ?\e,A\\e(B)
 - ("\"i" ?\e,Ao\e(B)
 - ("\"u" ?\e,A|\e(B)
 + ("\"I" ?Ã)
 + ("\"U" ?Ãœ)
 + ("\"i" ?ï)
 + ("\"u" ?ü)
   ("\" " ?\")
 - ("~C" ?\e,AG\e(B)
 - ("~N" ?\e,AQ\e(B)
 - ("~c" ?\e,Ag\e(B)
 - ("~n" ?\e,Aq\e(B)
 - ("~>" ?\\e,A;\e(B)
 - ("~<" ?\\e,A+\e(B)
 - ("~!" ?\e,A!\e(B)
 - ("~?" ?\e,A?\e(B)
 + ("~C" ?Ç)
 + ("~N" ?Ñ)
 + ("~c" ?ç)
 + ("~n" ?ñ)
 + ("~>" ?\»)
 + ("~<" ?\«)
 + ("~!" ?¡)
 + ("~?" ?¿)
   ("~ " ?~)
  )
  
   "esperanto-prefix" "Latin-3" "EO>" t
   "Esperanto input method with prefix modifiers
  Key translation rules are:
 - ^H -> ?\e,C&\e(B   ^J -> ?\e,C,\e(B   ^h -> ?\e,C6\e(B   ^j -> ?\e,C<\e(B   ^C -> ?\e,CF\e(B   ^G -> ?\e,CX\e(B,
 - ^S -> ?\e,C^\e(B   ^c -> ?\e,Cf\e(B   ^g -> ?\e,Cx\e(B   ^s -> ?\e,C~\e(B   ~U -> ?\e,C]\e(B   ~u -> ?\e,C}\e(B
 + ^H -> ?Ĥ   ^J -> ?Ä´   ^h -> ?Ä¥   ^j -> ?ĵ   ^C -> ?Ĉ   ^G -> ?Äœ,
 + ^S -> ?Åœ   ^c -> ?ĉ   ^g -> ?Ä   ^s -> ?Å   ~U -> ?Ŭ   ~u -> ?Å­
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("^H" ?\e,C&\e(B)
 - ("^J" ?\e,C,\e(B)
 - ("^h" ?\e,C6\e(B)
 - ("^j" ?\e,C<\e(B)
 - ("^C" ?\e,CF\e(B)
 - ("^G" ?\e,CX\e(B)
 - ("^S" ?\e,C^\e(B)
 - ("^c" ?\e,Cf\e(B)
 - ("^g" ?\e,Cx\e(B)
 - ("^s" ?\e,C~\e(B)
 + ("^H" ?Ĥ)
 + ("^J" ?Ä´)
 + ("^h" ?Ä¥)
 + ("^j" ?ĵ)
 + ("^C" ?Ĉ)
 + ("^G" ?Äœ)
 + ("^S" ?Åœ)
 + ("^c" ?ĉ)
 + ("^g" ?Ä)
 + ("^s" ?Å)
   ("^^" ?^)
   ("^ " ?^)
 - ("~U" ?\e,C]\e(B)
 - ("~u" ?\e,C}\e(B)
 + ("~U" ?Ŭ)
 + ("~u" ?Å­)
   ("~ " ?~)
  )
  
  (quail-define-package
   "french-prefix" "French" "FR>" t
 - "French (Fran\e,Ag\e(Bais) input method with prefix modifiers
 + "French (Français) input method with prefix modifiers
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'e -> \e,Ai\e(B
 -    grave    |   `    | `a -> \e,A`\e(B
 -  circumflex |   ^    | ^a -> \e,Ab\e(B
 -  diaeresis  |   \"    | \"i -> \e,Ao\e(B
 -   cedilla   | ~ or , | ~c -> \e,Ag\e(B   ,c -> \e,Ag\e(B
 -   symbol    |   ~    | ~> -> \e,A;\e(B   ~< -> \e,A+\e(B
 +    acute    |   '    | 'e -> Ã©
 +    grave    |   `    | `a -> Ã 
 +  circumflex |   ^    | ^a -> Ã¢
 +  diaeresis  |   \"    | \"i -> Ã¯
 +   cedilla   | ~ or , | ~c -> Ã§   ,c -> Ã§
 +   symbol    |   ~    | ~> -> Â»   ~< -> Â«
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'E" ?\e,AI\e(B)
 - ("'C" ?\e,AG\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'c" ?\e,Ag\e(B)
 + ("'E" ?É)
 + ("'C" ?Ç)
 + ("'e" ?é)
 + ("'c" ?ç)
   ("' " ?')
 - ("`A" ?\e,A@\e(B)
 - ("`E" ?\e,AH\e(B)
 - ("`U" ?\e,AY\e(B)
 - ("`a" ?\e,A`\e(B)
 - ("`e" ?\e,Ah\e(B)
 - ("`u" ?\e,Ay\e(B)
 + ("`A" ?À)
 + ("`E" ?È)
 + ("`U" ?Ù)
 + ("`a" ?à)
 + ("`e" ?è)
 + ("`u" ?ù)
   ("` " ?`)
 - ("^A" ?\e,AB\e(B)
 - ("^E" ?\e,AJ\e(B)
 - ("^I" ?\e,AN\e(B)
 - ("^O" ?\e,AT\e(B)
 - ("^U" ?\e,A[\e(B)
 - ("^a" ?\e,Ab\e(B)
 - ("^e" ?\e,Aj\e(B)
 - ("^i" ?\e,An\e(B)
 - ("^o" ?\e,At\e(B)
 - ("^u" ?\e,A{\e(B)
 + ("^A" ?Â)
 + ("^E" ?Ê)
 + ("^I" ?ÃŽ)
 + ("^O" ?Ô)
 + ("^U" ?Û)
 + ("^a" ?â)
 + ("^e" ?ê)
 + ("^i" ?î)
 + ("^o" ?ô)
 + ("^u" ?û)
   ("^ " ?^)
 - ("\"E" ?\e,AK\e(B)
 - ("\"I" ?\e,AO\e(B)
 - ("\"e" ?\e,Ak\e(B)
 - ("\"i" ?\e,Ao\e(B)
 + ("\"E" ?Ë)
 + ("\"I" ?Ã)
 + ("\"e" ?ë)
 + ("\"i" ?ï)
   ("\" " ?\")
 - ("~<" ?\\e,A+\e(B)
 - ("~>" ?\\e,A;\e(B)
 - ("~C" ?\e,AG\e(B)
 - ("~c" ?\e,Ag\e(B)
 + ("~<" ?\«)
 + ("~>" ?\»)
 + ("~C" ?Ç)
 + ("~c" ?ç)
   ("~ " ?~)
 - (",C" ?\e,AG\e(B)
 - (",c" ?\e,Ag\e(B)
 + (",C" ?Ç)
 + (",c" ?ç)
   (", " ?,)
  )
  
  (quail-define-package
   "romanian-prefix" "Romanian" "RO>" t
 - "Romanian (rom\e,Bb\e(Bne\e,B:\e(Bte) input method with prefix modifiers
 + "Romanian (româneÅŸte) input method with prefix modifiers
  
      effect   | prefix | examples
   ------------+--------+------------------
 -    tilde    |   ~    | ~a -> \e,Bc\e(B
 -  circumflex |   ^    | ^a -> \e,Bb\e(B, ^i -> \e,Bn\e(B
 -   cedilla   |   ,    | ,s -> \e,B:\e(B, ,t -> \e,B~\e(B
 +    tilde    |   ~    | ~a -> Äƒ
 +  circumflex |   ^    | ^a -> Ã¢, ^i -> Ã®
 +   cedilla   |   ,    | ,s -> ÅŸ, ,t -> Å£
     ~         |   ~    | ~~ -> ~
     ^         |   ^    | ^^ -> ^
     ,         |   ,    | ,, -> ,
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("~A" ?\e,BC\e(B) ("~a" ?\e,Bc\e(B)
 - ("^A" ?\e,BB\e(B) ("^a" ?\e,Bb\e(B)
 - ("^I" ?\e,BN\e(B) ("^i" ?\e,Bn\e(B)
 - (",S" ?\e,B*\e(B) (",s" ?\e,B:\e(B)
 - (",T" ?\e,B^\e(B) (",t" ?\e,B~\e(B)
 + ("~A" ?Ä‚) ("~a" ?ă)
 + ("^A" ?Â) ("^a" ?â)
 + ("^I" ?ÃŽ) ("^i" ?î)
 + (",S" ?Åž) (",s" ?ÅŸ)
 + (",T" ?Å¢) (",t" ?Å£)
   ("^^" ?^) ("~~" ?~) (",," ?,))
  
  (quail-define-package
   "romanian-alt-prefix" "Romanian" "RO>" t
 - "Alternative Romanian (rom\e,Bb\e(Bne\e,B:\e(Bte) input method with prefix modifiers
 + "Alternative Romanian (româneÅŸte) input method with prefix modifiers
  
      effect   | prefix | examples
   ------------+--------+------------------
 -    tilde    |   \"    | \"a -> \e,Bb\e(B
 -  circumflex |   '    | 'a -> \e,Bb\e(B, 'i -> \e,Bn\e(B
 -   cedilla   |   '    | 's -> \e,B:\e(B, 't -> \e,B~\e(B
 +    tilde    |   \"    | \"a -> Ã¢
 +  circumflex |   '    | 'a -> Ã¢, 'i -> Ã®
 +   cedilla   |   '    | 's -> ÅŸ, 't -> Å£
     '         |   '    | '' -> '
     \"         |   \"    | \"\" -> \"
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,BC\e(B) ("'a" ?\e,Bc\e(B)
 - ("\"A" ?\e,BB\e(B) ("\"a" ?\e,Bb\e(B)
 - ("'I" ?\e,BN\e(B) ("'i" ?\e,Bn\e(B)
 - ("'S" ?\e,B*\e(B) ("'s" ?\e,B:\e(B)
 - ("'T" ?\e,B^\e(B) ("'t" ?\e,B~\e(B)
 + ("'A" ?Ä‚) ("'a" ?ă)
 + ("\"A" ?Â) ("\"a" ?â)
 + ("'I" ?ÃŽ) ("'i" ?î)
 + ("'S" ?Åž) ("'s" ?ÅŸ)
 + ("'T" ?Å¢) ("'t" ?Å£)
   ("''" ?') ("\"\"" ?\"))
  
  (quail-define-package
   "german-prefix" "German" "DE>" t
   "German (Deutsch) input method with prefix modifiers
  Key translation rules are:
 - \"A -> \e,AD\e(B ->   \"O -> \e,AV\e(B   \"U -> \e,A\\e(B   \"s -> \e,A_\e(B
 + \"A -> Ã„ ->   \"O -> Ã–   \"U -> Ãœ   \"s -> ÃŸ
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("\"A" ?\e,AD\e(B)
 - ("\"O" ?\e,AV\e(B)
 - ("\"U" ?\e,A\\e(B)
 - ("\"a" ?\e,Ad\e(B)
 - ("\"o" ?\e,Av\e(B)
 - ("\"u" ?\e,A|\e(B)
 - ("\"s" ?\e,A_\e(B)
 + ("\"A" ?Ä)
 + ("\"O" ?Ö)
 + ("\"U" ?Ãœ)
 + ("\"a" ?ä)
 + ("\"o" ?ö)
 + ("\"u" ?ü)
 + ("\"s" ?ß)
   ("\" " ?\")
  )
  
   "irish-prefix" "Latin-1" "GA>" t
   "Irish input method with prefix modifiers
  Key translation rules are:
 - 'A -> \e,AA\e(B   'E -> \e,AI\e(B   'I -> \e,AM\e(B   'O -> \e,AS\e(B   'U -> \e,AZ\e(B
 + 'A -> Ã   'E -> Ã‰   'I -> Ã   'O -> Ã“   'U -> Ãš
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,AA\e(B)
 - ("'E" ?\e,AI\e(B)
 - ("'I" ?\e,AM\e(B)
 - ("'O" ?\e,AS\e(B)
 - ("'U" ?\e,AZ\e(B)
 - ("'a" ?\e,Aa\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'i" ?\e,Am\e(B)
 - ("'o" ?\e,As\e(B)
 - ("'u" ?\e,Az\e(B)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
   ("' " ?')
  )
  
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,Aa\e(B   '' -> \e,A4\e(B
 -    grave    |   `    | `a -> \e,A`\e(B
 -  circumflex |   ^    | ^a -> \e,Ab\e(B
 -  diaeresis  |   \"    | \"u -> \e,A|\e(B
 -    tilde    |   ~    | ~a -> \e,Ac\e(B
 -   cedilla   | ' or , | 'c -> \e,Ag\e(B   ,c -> \e,Ag\e(B
 +    acute    |   '    | 'a -> Ã¡   '' -> Â´
 +    grave    |   `    | `a -> Ã 
 +  circumflex |   ^    | ^a -> Ã¢
 +  diaeresis  |   \"    | \"u -> Ã¼
 +    tilde    |   ~    | ~a -> Ã£
 +   cedilla   | ' or , | 'c -> Ã§   ,c -> Ã§
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,AA\e(B)
 - ("'E" ?\e,AI\e(B)
 - ("'I" ?\e,AM\e(B)
 - ("'O" ?\e,AS\e(B)
 - ("'U" ?\e,AZ\e(B)
 - ("'C" ?\e,AG\e(B)
 - ("'a" ?\e,Aa\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'i" ?\e,Am\e(B)
 - ("'o" ?\e,As\e(B)
 - ("'u" ?\e,Az\e(B)
 - ("'c" ?\e,Ag\e(B)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'C" ?Ç)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
 + ("'c" ?ç)
   ("' " ?')
 - ("`A" ?\e,A@\e(B)
 - ("`a" ?\e,A`\e(B)
 + ("`A" ?À)
 + ("`a" ?à)
   ("` " ?`)
 - ("^A" ?\e,AB\e(B)
 - ("^E" ?\e,AJ\e(B)
 - ("^O" ?\e,AT\e(B)
 - ("^a" ?\e,Ab\e(B)
 - ("^e" ?\e,Aj\e(B)
 - ("^o" ?\e,At\e(B)
 + ("^A" ?Â)
 + ("^E" ?Ê)
 + ("^O" ?Ô)
 + ("^a" ?â)
 + ("^e" ?ê)
 + ("^o" ?ô)
   ("^ " ?^)
 - ("\"U" ?\e,A\\e(B)
 - ("\"u" ?\e,A|\e(B)
 + ("\"U" ?Ãœ)
 + ("\"u" ?ü)
   ("\" " ?\")
 - ("~A" ?\e,AC\e(B)
 - ("~O" ?\e,AU\e(B)
 - ("~a" ?\e,Ac\e(B)
 - ("~o" ?\e,Au\e(B)
 + ("~A" ?Ã)
 + ("~O" ?Õ)
 + ("~a" ?ã)
 + ("~o" ?õ)
   ("~ " ?~)
 - (",c" ?\e,Ag\e(B)
 - (",C" ?\e,AG\e(B)
 + (",c" ?ç)
 + (",C" ?Ç)
   (",," ?,)
  )
  
  (quail-define-package
   "spanish-prefix" "Spanish" "ES>" t
 - "Spanish (Espa\e,Aq\e(Bol) input method with prefix modifiers
 + "Spanish (Español) input method with prefix modifiers
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,Aa\e(B
 -  diaeresis  |   \"    | \"u -> \e,A|\e(B
 -    tilde    |   ~    | ~n -> \e,Aq\e(B
 -   symbol    |   ~    | ~> -> \e,A;\e(B   ~< -> \e,A+\e(B   ~! -> \e,A!\e(B   ~? -> \e,A?\e(B
 +    acute    |   '    | 'a -> Ã¡
 +  diaeresis  |   \"    | \"u -> Ã¼
 +    tilde    |   ~    | ~n -> Ã±
 +   symbol    |   ~    | ~> -> Â»   ~< -> Â«   ~! -> Â¡   ~? -> Â¿
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,AA\e(B)
 - ("'E" ?\e,AI\e(B)
 - ("'I" ?\e,AM\e(B)
 - ("'O" ?\e,AS\e(B)
 - ("'U" ?\e,AZ\e(B)
 - ("'a" ?\e,Aa\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'i" ?\e,Am\e(B)
 - ("'o" ?\e,As\e(B)
 - ("'u" ?\e,Az\e(B)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
   ("' " ?')
 - ("\"U" ?\e,A\\e(B)
 - ("\"u" ?\e,A|\e(B)
 + ("\"U" ?Ãœ)
 + ("\"u" ?ü)
   ("\" " ?\")
 - ("~N" ?\e,AQ\e(B)
 - ("~n" ?\e,Aq\e(B)
 - ("~>" ?\\e,A;\e(B)
 - ("~<" ?\\e,A+\e(B)
 - ("~!" ?\e,A!\e(B)
 - ("~?" ?\e,A?\e(B)
 + ("~N" ?Ñ)
 + ("~n" ?ñ)
 + ("~>" ?\»)
 + ("~<" ?\«)
 + ("~!" ?¡)
 + ("~?" ?¿)
   ("~ " ?~)
  )
  
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,Ba\e(B   '' -> ?\e,B4\e(B
 -  circumflex |   ^    | ^a -> \e,Bb\e(B
 -  diaeresis  |   \"    | \"a -> \e,Bd\e(B   \"\" -> \e,B(\e(B
 -    breve    |   ~    | ~a -> \e,Bc\e(B
 -    caron    |   ~    | ~c -> \e,Bh\e(B
 -   cedilla   |   `    | `c -> \e,Bg\e(B   `e -> ?\e,Bj\e(B
 -    misc     | ' ` ~  | 'd -> \e,Bp\e(B   `l -> \e,B3\e(B   `z -> \e,B?\e(B   ~o -> \e,Bu\e(B   ~u -> \e,B{\e(B
 -   symbol    |   ~    | `. -> \e,B\7f\e(B   ~~ -> \e,B"\e(B   ~. -> ?\e,B8\e(B
 +    acute    |   '    | 'a -> Ã¡   '' -> ?´
 +  circumflex |   ^    | ^a -> Ã¢
 +  diaeresis  |   \"    | \"a -> Ã¤   \"\" -> Â¨
 +    breve    |   ~    | ~a -> Äƒ
 +    caron    |   ~    | ~c -> Ä
 +   cedilla   |   `    | `c -> Ã§   `e -> ?Ä™
 +    misc     | ' ` ~  | 'd -> Ä‘   `l -> Å‚   `z -> Å¼   ~o -> Å‘   ~u -> Å±
 +   symbol    |   ~    | `. -> Ë™   ~~ -> Ë˜   ~. -> ?¸
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,BA\e(B)
 - ("'C" ?\e,BF\e(B)
 - ("'D" ?\e,BP\e(B)
 - ("'E" ?\e,BI\e(B)
 - ("'I" ?\e,BM\e(B)
 - ("'L" ?\e,BE\e(B)
 - ("'N" ?\e,BQ\e(B)
 - ("'O" ?\e,BS\e(B)
 - ("'R" ?\e,B@\e(B)
 - ("'S" ?\e,B&\e(B)
 - ("'U" ?\e,BZ\e(B)
 - ("'Y" ?\e,B]\e(B)
 - ("'Z" ?\e,B,\e(B)
 - ("'a" ?\e,Ba\e(B)
 - ("'c" ?\e,Bf\e(B)
 - ("'d" ?\e,Bp\e(B)
 - ("'e" ?\e,Bi\e(B)
 - ("'i" ?\e,Bm\e(B)
 - ("'l" ?\e,Be\e(B)
 - ("'n" ?\e,Bq\e(B)
 - ("'o" ?\e,Bs\e(B)
 - ("'r" ?\e,B`\e(B)
 - ("'s" ?\e,B6\e(B)
 - ("'u" ?\e,Bz\e(B)
 - ("'y" ?\e,B}\e(B)
 - ("'z" ?\e,B<\e(B)
 - ("''" ?\e,B4\e(B)
 + ("'A" ?Ã)
 + ("'C" ?Ć)
 + ("'D" ?Ä)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'L" ?Ĺ)
 + ("'N" ?Ń)
 + ("'O" ?Ó)
 + ("'R" ?Å”)
 + ("'S" ?Åš)
 + ("'U" ?Ú)
 + ("'Y" ?Ã)
 + ("'Z" ?Ź)
 + ("'a" ?á)
 + ("'c" ?ć)
 + ("'d" ?Ä‘)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'l" ?ĺ)
 + ("'n" ?Å„)
 + ("'o" ?ó)
 + ("'r" ?Å•)
 + ("'s" ?Å›)
 + ("'u" ?ú)
 + ("'y" ?ý)
 + ("'z" ?ź)
 + ("''" ?´)
   ("' " ?')
 - ("`A" ?\e,B!\e(B)
 - ("`C" ?\e,BG\e(B)
 - ("`E" ?\e,BJ\e(B)
 - ("`L" ?\e,B#\e(B)
 - ("`S" ?\e,B*\e(B)
 - ("`T" ?\e,B^\e(B)
 - ("`Z" ?\e,B/\e(B)
 - ("`a" ?\e,B1\e(B)
 - ("`l" ?\e,B3\e(B)
 - ("`c" ?\e,Bg\e(B)
 - ("`e" ?\e,Bj\e(B)
 - ("`s" ?\e,B:\e(B)
 - ("`t" ?\e,B~\e(B)
 - ("`z" ?\e,B?\e(B)
 - ("``" ?\e,B*\e(B)
 - ("`." ?\e,B\7f\e(B)
 + ("`A" ?Ä„)
 + ("`C" ?Ç)
 + ("`E" ?Ę)
 + ("`L" ?Å)
 + ("`S" ?Åž)
 + ("`T" ?Å¢)
 + ("`Z" ?Å»)
 + ("`a" ?Ä…)
 + ("`l" ?Å‚)
 + ("`c" ?ç)
 + ("`e" ?Ä™)
 + ("`s" ?ÅŸ)
 + ("`t" ?Å£)
 + ("`z" ?ż)
 + ("``" ?Åž)
 + ("`." ?Ë™)
   ("` " ?`)
 - ("^A" ?\e,BB\e(B)
 - ("^I" ?\e,BN\e(B)
 - ("^O" ?\e,BT\e(B)
 - ("^a" ?\e,Bb\e(B)
 - ("^i" ?\e,Bn\e(B)
 - ("^o" ?\e,Bt\e(B)
 + ("^A" ?Â)
 + ("^I" ?ÃŽ)
 + ("^O" ?Ô)
 + ("^a" ?â)
 + ("^i" ?î)
 + ("^o" ?ô)
   ("^^" ?^)
   ("^ " ?^)
 - ("\"A" ?\e,BD\e(B)
 - ("\"E" ?\e,BK\e(B)
 - ("\"O" ?\e,BV\e(B)
 - ("\"U" ?\e,B\\e(B)
 - ("\"a" ?\e,Bd\e(B)
 - ("\"e" ?\e,Bk\e(B)
 - ("\"o" ?\e,Bv\e(B)
 - ("\"s" ?\e,B_\e(B)
 - ("\"u" ?\e,B|\e(B)
 - ("\"\"" ?\e,B(\e(B)
 + ("\"A" ?Ä)
 + ("\"E" ?Ë)
 + ("\"O" ?Ö)
 + ("\"U" ?Ãœ)
 + ("\"a" ?ä)
 + ("\"e" ?ë)
 + ("\"o" ?ö)
 + ("\"s" ?ß)
 + ("\"u" ?ü)
 + ("\"\"" ?¨)
   ("\" " ?\")
 - ("~A" ?\e,BC\e(B)
 - ("~C" ?\e,BH\e(B)
 - ("~D" ?\e,BO\e(B)
 - ("~E" ?\e,BL\e(B)
 - ("~L" ?\e,B%\e(B)
 - ("~N" ?\e,BR\e(B)
 - ("~O" ?\e,BU\e(B)
 - ("~R" ?\e,BX\e(B)
 - ("~S" ?\e,B)\e(B)
 - ("~T" ?\e,B+\e(B)
 - ("~U" ?\e,B[\e(B)
 - ("~Z" ?\e,B.\e(B)
 - ("~a" ?\e,Bc\e(B)
 - ("~c" ?\e,Bh\e(B)
 - ("~d" ?\e,Bo\e(B)
 - ("~e" ?\e,Bl\e(B)
 - ("~l" ?\e,B5\e(B)
 - ("~n" ?\e,Br\e(B)
 - ("~o" ?\e,Bu\e(B)
 - ("~r" ?\e,Bx\e(B)
 - ("~s" ?\e,B9\e(B)
 - ("~t" ?\e,B;\e(B)
 - ("~u" ?\e,B{\e(B)
 - ("~z" ?\e,B>\e(B)
 - ("~v" ?\e,B"\e(B)
 - ("~~" ?\e,B"\e(B)
 - ("~." ?\e,B8\e(B)
 + ("~A" ?Ä‚)
 + ("~C" ?ÄŒ)
 + ("~D" ?ÄŽ)
 + ("~E" ?Äš)
 + ("~L" ?Ľ)
 + ("~N" ?Ň)
 + ("~O" ?Å)
 + ("~R" ?Ř)
 + ("~S" ?Å )
 + ("~T" ?Ť)
 + ("~U" ?Å°)
 + ("~Z" ?Ž)
 + ("~a" ?ă)
 + ("~c" ?Ä)
 + ("~d" ?Ä)
 + ("~e" ?Ä›)
 + ("~l" ?ľ)
 + ("~n" ?ň)
 + ("~o" ?Å‘)
 + ("~r" ?Å™)
 + ("~s" ?Å¡)
 + ("~t" ?Å¥)
 + ("~u" ?ű)
 + ("~z" ?ž)
 + ("~v" ?˘)
 + ("~~" ?˘)
 + ("~." ?¸)
   ("~ " ?~)
  )
  
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,Ca\e(B   '' -> ?\e,C4\e(B
 -    grave    |   `    | `a -> \e,C`\e(B
 -  circumflex |   ^    | ^a -> \e,Cb\e(B
 -  diaeresis  |   \"    | \"a -> \e,Cd\e(B   \"\" -> \e,C(\e(B
 -   cedilla   |   ~    | ~c -> \e,Cg\e(B   ~s -> \e,C:\e(B   ~~ -> \e,C8\e(B
 -  dot above  |   / .  | /g -> \e,Cu\e(B   .o -> \e,Cu\e(B
 -    misc     | \" ~ /  | \"s -> \e,C_\e(B   ~g -> \e,C;\e(B   ~u -> \e,C}\e(B   /h -> \e,C1\e(B   /i -> \e,C9\e(B
 -   symbol    |   ~    | ~` -> \e,C"\e(B   /# -> \e,C#\e(B   /$ -> \e,C$\e(B   // -> \e,C0\e(B
 +    acute    |   '    | 'a -> Ã¡   '' -> ?´
 +    grave    |   `    | `a -> Ã 
 +  circumflex |   ^    | ^a -> Ã¢
 +  diaeresis  |   \"    | \"a -> Ã¤   \"\" -> Â¨
 +   cedilla   |   ~    | ~c -> Ã§   ~s -> ÅŸ   ~~ -> Â¸
 +  dot above  |   / .  | /g -> Ä¡   .o -> Ä¡
 +    misc     | \" ~ /  | \"s -> ÃŸ   ~g -> ÄŸ   ~u -> Å­   /h -> Ä§   /i -> Ä±
 +   symbol    |   ~    | ~` -> Ë˜   /# -> Â£   /$ -> Â¤   // -> Â°
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,CA\e(B)
 - ("'E" ?\e,CI\e(B)
 - ("'I" ?\e,CM\e(B)
 - ("'O" ?\e,CS\e(B)
 - ("'U" ?\e,CZ\e(B)
 - ("'a" ?\e,Ca\e(B)
 - ("'e" ?\e,Ci\e(B)
 - ("'i" ?\e,Cm\e(B)
 - ("'o" ?\e,Cs\e(B)
 - ("'u" ?\e,Cz\e(B)
 - ("''" ?\e,C4\e(B)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
 + ("''" ?´)
   ("' " ?')
 - ("`A" ?\e,C@\e(B)
 - ("`E" ?\e,CH\e(B)
 - ("`I" ?\e,CL\e(B)
 - ("`O" ?\e,CR\e(B)
 - ("`U" ?\e,CY\e(B)
 - ("`a" ?\e,C`\e(B)
 - ("`e" ?\e,Ch\e(B)
 - ("`i" ?\e,Cl\e(B)
 - ("`o" ?\e,Cr\e(B)
 - ("`u" ?\e,Cy\e(B)
 + ("`A" ?À)
 + ("`E" ?È)
 + ("`I" ?ÃŒ)
 + ("`O" ?Ã’)
 + ("`U" ?Ù)
 + ("`a" ?à)
 + ("`e" ?è)
 + ("`i" ?ì)
 + ("`o" ?ò)
 + ("`u" ?ù)
   ("``" ?`)
   ("` " ?`)
 - ("^A" ?\e,CB\e(B)
 - ("^C" ?\e,CF\e(B)
 - ("^E" ?\e,CJ\e(B)
 - ("^G" ?\e,CX\e(B)
 - ("^H" ?\e,C&\e(B)
 - ("^I" ?\e,CN\e(B)
 - ("^J" ?\e,C,\e(B)
 - ("^O" ?\e,CT\e(B)
 - ("^S" ?\e,C^\e(B)
 - ("^U" ?\e,C[\e(B)
 - ("^a" ?\e,Cb\e(B)
 - ("^c" ?\e,Cf\e(B)
 - ("^e" ?\e,Cj\e(B)
 - ("^g" ?\e,Cx\e(B)
 - ("^h" ?\e,C6\e(B)
 - ("^i" ?\e,Cn\e(B)
 - ("^j" ?\e,C<\e(B)
 - ("^o" ?\e,Ct\e(B)
 - ("^s" ?\e,C~\e(B)
 - ("^u" ?\e,C{\e(B)
 + ("^A" ?Â)
 + ("^C" ?Ĉ)
 + ("^E" ?Ê)
 + ("^G" ?Äœ)
 + ("^H" ?Ĥ)
 + ("^I" ?ÃŽ)
 + ("^J" ?Ä´)
 + ("^O" ?Ô)
 + ("^S" ?Åœ)
 + ("^U" ?Û)
 + ("^a" ?â)
 + ("^c" ?ĉ)
 + ("^e" ?ê)
 + ("^g" ?Ä)
 + ("^h" ?Ä¥)
 + ("^i" ?î)
 + ("^j" ?ĵ)
 + ("^o" ?ô)
 + ("^s" ?Å)
 + ("^u" ?û)
   ("^^" ?^)
   ("^ " ?^)
 - ("\"A" ?\e,CD\e(B)
 - ("\"E" ?\e,CK\e(B)
 - ("\"I" ?\e,CO\e(B)
 - ("\"O" ?\e,CV\e(B)
 - ("\"U" ?\e,C\\e(B)
 - ("\"a" ?\e,Cd\e(B)
 - ("\"e" ?\e,Ck\e(B)
 - ("\"i" ?\e,Co\e(B)
 - ("\"o" ?\e,Cv\e(B)
 - ("\"u" ?\e,C|\e(B)
 - ("\"s" ?\e,C_\e(B)
 - ("\"\"" ?\e,C(\e(B)
 + ("\"A" ?Ä)
 + ("\"E" ?Ë)
 + ("\"I" ?Ã)
 + ("\"O" ?Ö)
 + ("\"U" ?Ãœ)
 + ("\"a" ?ä)
 + ("\"e" ?ë)
 + ("\"i" ?ï)
 + ("\"o" ?ö)
 + ("\"u" ?ü)
 + ("\"s" ?ß)
 + ("\"\"" ?¨)
   ("\" " ?\")
 - ("~C" ?\e,CG\e(B)
 - ("~N" ?\e,CQ\e(B)
 - ("~c" ?\e,Cg\e(B)
 - ("~n" ?\e,Cq\e(B)
 - ("~S" ?\e,C*\e(B)
 - ("~s" ?\e,C:\e(B)
 - ("~G" ?\e,C+\e(B)
 - ("~g" ?\e,C;\e(B)
 - ("~U" ?\e,C]\e(B)
 - ("~u" ?\e,C}\e(B)
 - ("~`" ?\e,C"\e(B)
 - ("~~" ?\e,C8\e(B)
 + ("~C" ?Ç)
 + ("~N" ?Ñ)
 + ("~c" ?ç)
 + ("~n" ?ñ)
 + ("~S" ?Åž)
 + ("~s" ?ÅŸ)
 + ("~G" ?Äž)
 + ("~g" ?ÄŸ)
 + ("~U" ?Ŭ)
 + ("~u" ?Å­)
 + ("~`" ?˘)
 + ("~~" ?¸)
   ("~ " ?~)
 - ("/C" ?\e,CE\e(B)
 - ("/G" ?\e,CU\e(B)
 - ("/H" ?\e,C!\e(B)
 - ("/I" ?\e,C)\e(B)
 - ("/Z" ?\e,C/\e(B)
 - ("/c" ?\e,Ce\e(B)
 - ("/g" ?\e,Cu\e(B)
 - ("/h" ?\e,C1\e(B)
 - ("/i" ?\e,C9\e(B)
 - ("/z" ?\e,C?\e(B)
 - ("/." ?\e,C\7f\e(B)
 - ("/#" ?\e,C#\e(B)
 - ("/$" ?\e,C$\e(B)
 - ("//" ?\e,C0\e(B)
 + ("/C" ?ÄŠ)
 + ("/G" ?Ä )
 + ("/H" ?Ħ)
 + ("/I" ?Ä°)
 + ("/Z" ?Å»)
 + ("/c" ?Ä‹)
 + ("/g" ?Ä¡)
 + ("/h" ?ħ)
 + ("/i" ?ı)
 + ("/z" ?ż)
 + ("/." ?Ë™)
 + ("/#" ?£)
 + ("/$" ?¤)
 + ("//" ?°)
   ("/ " ?/)
 - (".C" ?\e,CE\e(B)
 - (".G" ?\e,CU\e(B)
 - (".I" ?\e,C)\e(B)
 - (".Z" ?\e,C/\e(B)
 - (".c" ?\e,Ce\e(B)
 - (".g" ?\e,Cu\e(B)
 - (".z" ?\e,C?\e(B)
 + (".C" ?ÄŠ)
 + (".G" ?Ä )
 + (".I" ?Ä°)
 + (".Z" ?Å»)
 + (".c" ?Ä‹)
 + (".g" ?Ä¡)
 + (".z" ?ż)
  )
  
  
@@@ -709,24 -711,24 +711,24 @@@ For example, the character named `aogon
  
  (quail-define-rules
   ("//" ?/)
 - ("/a" ?\e,B1\e(B)
 - ("/c" ?\e,Bf\e(B)
 - ("/e" ?\e,Bj\e(B)
 - ("/l" ?\e,B3\e(B)
 - ("/n" ?\e,Bq\e(B)
 - ("/o" ?\e,Bs\e(B)
 - ("/s" ?\e,B6\e(B)
 - ("/x" ?\e,B<\e(B)
 - ("/z" ?\e,B?\e(B)
 - ("/A" ?\e,B!\e(B)
 - ("/C" ?\e,BF\e(B)
 - ("/E" ?\e,BJ\e(B)
 - ("/L" ?\e,B#\e(B)
 - ("/N" ?\e,BQ\e(B)
 - ("/O" ?\e,BS\e(B)
 - ("/S" ?\e,B&\e(B)
 - ("/X" ?\e,B,\e(B)
 - ("/Z" ?\e,B/\e(B))
 + ("/a" ?Ä…)
 + ("/c" ?ć)
 + ("/e" ?Ä™)
 + ("/l" ?Å‚)
 + ("/n" ?Å„)
 + ("/o" ?ó)
 + ("/s" ?Å›)
 + ("/x" ?ź)
 + ("/z" ?ż)
 + ("/A" ?Ä„)
 + ("/C" ?Ć)
 + ("/E" ?Ę)
 + ("/L" ?Å)
 + ("/N" ?Ń)
 + ("/O" ?Ó)
 + ("/S" ?Åš)
 + ("/X" ?Ź)
 + ("/Z" ?Å»))
  
  (quail-define-package
   "latin-9-prefix" "Latin-9" "0>" t
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,ba\e(B
 -    grave    |   `    | `a -> \e,b`\e(B
 -  circumflex |   ^    | ^a -> \e,bb\e(B
 -  diaeresis  |   \"    | \"a -> \e,bd\e(B, \"Y -> \e,b>\e(B
 -    tilde    |   ~    | ~a -> \e,bc\e(B
 -    caron    |   ~    | ~z -> \e,b8\e(B
 -   cedilla   |   ~    | ~c -> \e,bg\e(B
 -    misc     | \" ~ /  | \"s -> \e,b_\e(B  ~d -> \e,bp\e(B  ~t -> \e,b~\e(B  /a -> \e,be\e(B  /e -> \e,bf\e(B  /o -> \e,bx\e(B
 -             | \" ~ /  | /o -> \e,b=\e(B
 -   symbol    |   ~    | ~> -> \e,b;\e(B  ~< -> \e,b+\e(B  ~! -> \e,b!\e(B  ~? -> \e,b?\e(B  ~~ -> \e,b8\e(B
 -             |   ~    | ~s -> \e,b'\e(B  ~e -> \e,b$\e(B  ~. -> \e,b7\e(B  ~$ -> \e,b#\e(B  ~u -> \e,b5\e(B
 -             |   ~    | ~- -> \e,b-\e(B  ~= -> \e,b/\e(B
 -   symbol    |  _ /   | _o -> \e,b:\e(B  _a -> \e,b*\e(B  // -> \e,b0\e(B  /\\ -> \e,bW\e(B  _y -> \e,b%\e(B
 -             |  _ /   | _: -> \e,bw\e(B  /c -> \e,b"\e(B  ~p -> \e,b6\e(B
 -             |  _ /   | /= -> \e,b,\e(B
 -   symbol    |   ^    | ^r -> \e,b.\e(B  ^c -> \e,b)\e(B  ^1 -> \e,b9\e(B  ^2 -> \e,b2\e(B  ^3 -> \e,b3\e(B  _a -> \e,b*\e(B
 +    acute    |   '    | 'a -> Ã¡
 +    grave    |   `    | `a -> Ã 
 +  circumflex |   ^    | ^a -> Ã¢
 +  diaeresis  |   \"    | \"a -> Ã¤, \"Y -> Å¸
 +    tilde    |   ~    | ~a -> Ã£
 +    caron    |   ~    | ~z -> Å¾
 +   cedilla   |   ~    | ~c -> Ã§
 +    misc     | \" ~ /  | \"s -> ÃŸ  ~d -> Ã°  ~t -> Ã¾  /a -> Ã¥  /e -> Ã¦  /o -> Ã¸
 +             | \" ~ /  | /o -> Å“
 +   symbol    |   ~    | ~> -> Â»  ~< -> Â«  ~! -> Â¡  ~? -> Â¿  ~~ -> Å¾
 +             |   ~    | ~s -> Â§  ~e -> â‚¬  ~. -> Â·  ~$ -> Â£  ~u -> Âµ
 +             |   ~    | ~- -> Â­  ~= -> Â¯
 +   symbol    |  _ /   | _o -> Âº  _a -> Âª  // -> Â°  /\\ -> Ã—  _y -> Â¥
 +             |  _ /   | _: -> Ã·  /c -> Â¢  ~p -> Â¶
 +             |  _ /   | /= -> Â¬
 +   symbol    |   ^    | ^r -> Â®  ^c -> Â©  ^1 -> Â¹  ^2 -> Â²  ^3 -> Â³  _a -> Âª
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
 - ("'A" ?\e,bA\e(B)
 - ("'E" ?\e,bI\e(B)
 - ("'I" ?\e,bM\e(B)
 - ("'O" ?\e,bS\e(B)
 - ("'U" ?\e,bZ\e(B)
 - ("'Y" ?\e,b]\e(B)
 - ("'a" ?\e,ba\e(B)
 - ("'e" ?\e,bi\e(B)
 - ("'i" ?\e,bm\e(B)
 - ("'o" ?\e,bs\e(B)
 - ("'u" ?\e,bz\e(B)
 - ("'y" ?\e,b}\e(B)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'Y" ?Ã)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
 + ("'y" ?ý)
   ("' " ?')
 - ("`A" ?\e,b@\e(B)
 - ("`E" ?\e,bH\e(B)
 - ("`I" ?\e,bL\e(B)
 - ("`O" ?\e,bR\e(B)
 - ("`U" ?\e,bY\e(B)
 - ("`a" ?\e,b`\e(B)
 - ("`e" ?\e,bh\e(B)
 - ("`i" ?\e,bl\e(B)
 - ("`o" ?\e,br\e(B)
 - ("`u" ?\e,by\e(B)
 + ("`A" ?À)
 + ("`E" ?È)
 + ("`I" ?ÃŒ)
 + ("`O" ?Ã’)
 + ("`U" ?Ù)
 + ("`a" ?à)
 + ("`e" ?è)
 + ("`i" ?ì)
 + ("`o" ?ò)
 + ("`u" ?ù)
   ("``" ?`)
   ("` " ?`)
 - ("^A" ?\e,bB\e(B)
 - ("^E" ?\e,bJ\e(B)
 - ("^I" ?\e,bN\e(B)
 - ("^O" ?\e,bT\e(B)
 - ("^U" ?\e,b[\e(B)
 - ("^a" ?\e,bb\e(B)
 - ("^e" ?\e,bj\e(B)
 - ("^i" ?\e,bn\e(B)
 - ("^o" ?\e,bt\e(B)
 - ("^u" ?\e,b{\e(B)
 + ("^A" ?Â)
 + ("^E" ?Ê)
 + ("^I" ?ÃŽ)
 + ("^O" ?Ô)
 + ("^U" ?Û)
 + ("^a" ?â)
 + ("^e" ?ê)
 + ("^i" ?î)
 + ("^o" ?ô)
 + ("^u" ?û)
   ("^^" ?^)
   ("^ " ?^)
 - ("\"A" ?\e,bD\e(B)
 - ("\"E" ?\e,bK\e(B)
 - ("\"I" ?\e,bO\e(B)
 - ("\"O" ?\e,bV\e(B)
 - ("\"U" ?\e,b\\e(B)
 - ("\"a" ?\e,bd\e(B)
 - ("\"e" ?\e,bk\e(B)
 - ("\"i" ?\e,bo\e(B)
 - ("\"o" ?\e,bv\e(B)
 - ("\"s" ?\e,b_\e(B)
 - ("\"u" ?\e,b|\e(B)
 - ("\"y" ?\e,b\7f\e(B)
 + ("\"A" ?Ä)
 + ("\"E" ?Ë)
 + ("\"I" ?Ã)
 + ("\"O" ?Ö)
 + ("\"U" ?Ãœ)
 + ("\"a" ?ä)
 + ("\"e" ?ë)
 + ("\"i" ?ï)
 + ("\"o" ?ö)
 + ("\"s" ?ß)
 + ("\"u" ?ü)
 + ("\"y" ?ÿ)
   ("\" " ?\")
 - ("~A" ?\e,bC\e(B)
 - ("~C" ?\e,bG\e(B)
 - ("~D" ?\e,bP\e(B)
 - ("~N" ?\e,bQ\e(B)
 - ("~O" ?\e,bU\e(B)
 - ("~S" ?\e,b&\e(B)
 - ("~T" ?\e,b^\e(B)
 - ("~Z" ?\e,b4\e(B)
 - ("~a" ?\e,bc\e(B)
 - ("~c" ?\e,bg\e(B)
 - ("~d" ?\e,bp\e(B)
 - ("~n" ?\e,bq\e(B)
 - ("~o" ?\e,bu\e(B)
 - ("~s" ?\e,b(\e(B)
 - ("~t" ?\e,b~\e(B)
 - ("~z" ?\e,b8\e(B)
 - ("~>" ?\\e,b;\e(B)
 - ("~<" ?\\e,b+\e(B)
 - ("~!" ?\e,b!\e(B)
 - ("~?" ?\e,b?\e(B)
 + ("~A" ?Ã)
 + ("~C" ?Ç)
 + ("~D" ?Ã)
 + ("~N" ?Ñ)
 + ("~O" ?Õ)
 + ("~S" ?Å )
 + ("~T" ?Þ)
 + ("~Z" ?Ž)
 + ("~a" ?ã)
 + ("~c" ?ç)
 + ("~d" ?ð)
 + ("~n" ?ñ)
 + ("~o" ?õ)
 + ("~s" ?Å¡)
 + ("~t" ?þ)
 + ("~z" ?ž)
 + ("~>" ?\»)
 + ("~<" ?\«)
 + ("~!" ?¡)
 + ("~?" ?¿)
   ("~ " ?~)
 - ("/A" ?\e,bE\e(B)
 - ("/E" ?\e,bF\e(B)
 - ("/O" ?\e,bX\e(B)
 - ("/a" ?\e,be\e(B)
 - ("/e" ?\e,bf\e(B)
 - ("/o" ?\e,bx\e(B)
 - ("//" ?\e,b0\e(B)
 + ("/A" ?Ã…)
 + ("/E" ?Æ)
 + ("/O" ?Ø)
 + ("/a" ?Ã¥)
 + ("/e" ?æ)
 + ("/o" ?ø)
 + ("//" ?°)
   ("/ " ?/)
 - ("_o" ?\e,b:\e(B)
 - ("_a" ?\e,b*\e(B)
 - ("_+" ?\e,b1\e(B)
 - ("_y" ?\e,b%\e(B)
 - ("_:" ?\e,bw\e(B)
 - ("_ " ?\e,b \e(B)
 + ("_o" ?º)
 + ("_a" ?ª)
 + ("_+" ?±)
 + ("_y" ?Â¥)
 + ("_:" ?÷)
 + ("_ " ? )
   ("__" ?_)
 - ("/c" ?\e,b"\e(B)
 - ("/\\" ?\e,bW\e(B)
 - ("/o" ?\e,b=\e(B)                              ; clash with \e,bx\e(B, but \e,bf\e(B uses /
 - ("/O" ?\e,b<\e(B)
 - ("\"Y" ?\e,b>\e(B)
 - ("~s" ?\e,b'\e(B)
 - ("~p" ?\e,b6\e(B)
 + ("/c" ?¢)
 + ("/\\" ?×)
 + ("/o" ?Å“)                           ; clash with Ã¸, but Ã¦ uses /
 + ("/O" ?Å’)
 + ("\"Y" ?Ÿ)
 + ("~s" ?§)
 + ("~p" ?¶)
   ;; Is this the best option for Euro entry?
 - ("~e" ?\e,b$\e(B)
 - ("~." ?\e,b7\e(B)
 - ("~$" ?\e,b#\e(B)
 - ("~u" ?\e,b5\e(B)
 - ("^r" ?\e,b.\e(B)
 - ("^c" ?\e,b)\e(B)
 - ("^1" ?\e,b9\e(B)
 - ("^2" ?\e,b2\e(B)
 - ("^3" ?\e,b3\e(B)
 - ("~-" ?\e,b-\e(B)
 - ("~=" ?\e,b/\e(B)
 - ("/=" ?\e,b,\e(B))
 + ("~e" ?€)
 + ("~." ?·)
 + ("~$" ?£)
 + ("~u" ?µ)
 + ("^r" ?®)
 + ("^c" ?©)
 + ("^1" ?¹)
 + ("^2" ?²)
 + ("^3" ?³)
 + ("~-" ?­)
 + ("~=" ?¯)
 + ("/=" ?¬))
  
  ;; Latin-8 was done by an Englishman -- Johnny Celt should take a
  ;; squint at it.
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,_a\e(B
 -    grave    |   `    | `a -> \e,_`\e(B
 -  circumflex |   ^    | ^w -> \e,_p\e(B
 -  diaeresis  |   \"    | \"a -> \e,_d\e(B
 -  dot above  |   .    | .b -> \e,_"\e(B
 -    tilde    |   ~    | ~a -> \e,_c\e(B
 -   cedilla   |   ~    | ~c -> \e,_g\e(B
 -    misc     | \" ~ /  | \"s -> \e,__\e(B   /a -> \e,_e\e(B  /e -> \e,_f\e(B  /o -> \e,_x\e(B
 -             |   ~    | ~s -> \e,_'\e(B  ~$ -> \e,_#\e(B  ~p -> \e,_6\e(B
 -   symbol    |   ^    | ^r -> \e,_.\e(B  ^c -> \e,_)\e(B
 +    acute    |   '    | 'a -> Ã¡
 +    grave    |   `    | `a -> Ã 
 +  circumflex |   ^    | ^w -> Åµ
 +  diaeresis  |   \"    | \"a -> Ã¤
 +  dot above  |   .    | .b -> á¸ƒ
 +    tilde    |   ~    | ~a -> Ã£
 +   cedilla   |   ~    | ~c -> Ã§
 +    misc     | \" ~ /  | \"s -> ÃŸ   /a -> Ã¥  /e -> Ã¦  /o -> Ã¸
 +             |   ~    | ~s -> Â§  ~$ -> Â£  ~p -> Â¶
 +   symbol    |   ^    | ^r -> Â®  ^c -> Â©
  " nil t nil nil nil nil nil nil nil nil t)
  
  ;; Basically following Latin-1, plus dottiness from Latin-3.
  (quail-define-rules
 - (".B" ?\e,_!\e(B)
 - (".b" ?\e,_"\e(B)
 - (".c" ?\e,_%\e(B)
 - (".C" ?\e,_$\e(B)
 - (".D" ?\e,_&\e(B)
 - (".d" ?\e,_+\e(B)
 - (".f" ?\e,_1\e(B)
 - (".F" ?\e,_0\e(B)
 - (".g" ?\e,_3\e(B)
 - (".G" ?\e,_2\e(B)
 - (".m" ?\e,_5\e(B)
 - (".M" ?\e,_4\e(B)
 - (".p" ?\e,_9\e(B)
 - (".P" ?\e,_7\e(B)
 - (".s" ?\e,_?\e(B)
 - (".S" ?\e,_;\e(B)
 - (".t" ?\e,_w\e(B)
 - (".T" ?\e,_W\e(B)
 - ("'A" ?\e,_A\e(B)
 - ("'E" ?\e,_I\e(B)
 - ("'I" ?\e,_M\e(B)
 - ("'O" ?\e,_S\e(B)
 - ("'U" ?\e,_Z\e(B)
 - ("'Y" ?\e,_]\e(B)
 - ("'W" ?\e,_*\e(B)
 - ("'a" ?\e,_a\e(B)
 - ("'e" ?\e,_i\e(B)
 - ("'i" ?\e,_m\e(B)
 - ("'o" ?\e,_s\e(B)
 - ("'u" ?\e,_z\e(B)
 - ("'w" ?\e,_:\e(B)
 - ("'y" ?\e,_}\e(B)
 + (".B" ?Ḃ)
 + (".b" ?ḃ)
 + (".c" ?Ä‹)
 + (".C" ?ÄŠ)
 + (".D" ?Ḋ)
 + (".d" ?ḋ)
 + (".f" ?ḟ)
 + (".F" ?Ḟ)
 + (".g" ?Ä¡)
 + (".G" ?Ä )
 + (".m" ?á¹)
 + (".M" ?á¹€)
 + (".p" ?á¹—)
 + (".P" ?á¹–)
 + (".s" ?ṡ)
 + (".S" ?á¹ )
 + (".t" ?ṫ)
 + (".T" ?Ṫ)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'Y" ?Ã)
 + ("'W" ?Ẃ)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
 + ("'w" ?ẃ)
 + ("'y" ?ý)
   ("' " ?')
 - ("`A" ?\e,_@\e(B)
 - ("`E" ?\e,_H\e(B)
 - ("`I" ?\e,_L\e(B)
 - ("`O" ?\e,_R\e(B)
 - ("`U" ?\e,_Y\e(B)
 - ("`W" ?\e,_(\e(B)
 - ("`Y" ?\e,_,\e(B)
 - ("`a" ?\e,_`\e(B)
 - ("`e" ?\e,_h\e(B)
 - ("`i" ?\e,_l\e(B)
 - ("`o" ?\e,_r\e(B)
 - ("`u" ?\e,_y\e(B)
 - ("`w" ?\e,_8\e(B)
 - ("`y" ?\e,_<\e(B)
 + ("`A" ?À)
 + ("`E" ?È)
 + ("`I" ?ÃŒ)
 + ("`O" ?Ã’)
 + ("`U" ?Ù)
 + ("`W" ?Ẁ)
 + ("`Y" ?Ỳ)
 + ("`a" ?à)
 + ("`e" ?è)
 + ("`i" ?ì)
 + ("`o" ?ò)
 + ("`u" ?ù)
 + ("`w" ?áº)
 + ("`y" ?ỳ)
   ("``" ?`)
   ("` " ?`)
 - ("^A" ?\e,_B\e(B)
 - ("^E" ?\e,_J\e(B)
 - ("^I" ?\e,_N\e(B)
 - ("^O" ?\e,_T\e(B)
 - ("^U" ?\e,_[\e(B)
 - ("^a" ?\e,_b\e(B)
 - ("^e" ?\e,_j\e(B)
 - ("^i" ?\e,_n\e(B)
 - ("^o" ?\e,_t\e(B)
 - ("^u" ?\e,_{\e(B)
 - ("^w" ?\e,_p\e(B)
 - ("^W" ?\e,_P\e(B)
 - ("^y" ?\e,_~\e(B)
 - ("^Y" ?\e,_^\e(B)
 + ("^A" ?Â)
 + ("^E" ?Ê)
 + ("^I" ?ÃŽ)
 + ("^O" ?Ô)
 + ("^U" ?Û)
 + ("^a" ?â)
 + ("^e" ?ê)
 + ("^i" ?î)
 + ("^o" ?ô)
 + ("^u" ?û)
 + ("^w" ?ŵ)
 + ("^W" ?Å´)
 + ("^y" ?Å·)
 + ("^Y" ?Ŷ)
   ("^^" ?^)
   ("^ " ?^)
 - ("\"A" ?\e,_D\e(B)
 - ("\"E" ?\e,_K\e(B)
 - ("\"I" ?\e,_O\e(B)
 - ("\"O" ?\e,_V\e(B)
 - ("\"U" ?\e,_\\e(B)
 - ("\"a" ?\e,_d\e(B)
 - ("\"e" ?\e,_k\e(B)
 - ("\"i" ?\e,_o\e(B)
 - ("\"o" ?\e,_v\e(B)
 - ("\"s" ?\e,__\e(B)
 - ("\"u" ?\e,_|\e(B)
 - ("\"w" ?\e,_>\e(B)
 - ("\"W" ?\e,_=\e(B)
 - ("\"y" ?\e,_\7f\e(B)
 - ("\"Y" ?\e,_/\e(B)
 + ("\"A" ?Ä)
 + ("\"E" ?Ë)
 + ("\"I" ?Ã)
 + ("\"O" ?Ö)
 + ("\"U" ?Ãœ)
 + ("\"a" ?ä)
 + ("\"e" ?ë)
 + ("\"i" ?ï)
 + ("\"o" ?ö)
 + ("\"s" ?ß)
 + ("\"u" ?ü)
 + ("\"w" ?ẅ)
 + ("\"W" ?Ẅ)
 + ("\"y" ?ÿ)
 + ("\"Y" ?Ÿ)
   ("\" " ?\")
 - ("~A" ?\e,_C\e(B)
 - ("~C" ?\e,_G\e(B)
 - ("~N" ?\e,_Q\e(B)
 - ("~O" ?\e,_U\e(B)
 - ("~a" ?\e,_c\e(B)
 - ("~c" ?\e,_g\e(B)
 - ("~n" ?\e,_q\e(B)
 - ("~o" ?\e,_u\e(B)
 + ("~A" ?Ã)
 + ("~C" ?Ç)
 + ("~N" ?Ñ)
 + ("~O" ?Õ)
 + ("~a" ?ã)
 + ("~c" ?ç)
 + ("~n" ?ñ)
 + ("~o" ?õ)
   ("~ " ?~)
 - ("/A" ?\e,_E\e(B)
 - ("/E" ?\e,_F\e(B)
 - ("/O" ?\e,_X\e(B)
 - ("/a" ?\e,_e\e(B)
 - ("/e" ?\e,_f\e(B)
 - ("/o" ?\e,_x\e(B)
 + ("/A" ?Ã…)
 + ("/E" ?Æ)
 + ("/O" ?Ø)
 + ("/a" ?Ã¥)
 + ("/e" ?æ)
 + ("/o" ?ø)
   ("/ " ?/)
 - ("~p" ?\e,_6\e(B)
 - ("~s" ?\e,_'\e(B)
 - ("~$" ?\e,_#\e(B)
 - ("^r" ?\e,_.\e(B)
 - ("^c" ?\e,_)\e(B))
 + ("~p" ?¶)
 + ("~s" ?§)
 + ("~$" ?£)
 + ("^r" ?®)
 + ("^c" ?©))
  
  (quail-define-package
   "latin-prefix" "Latin" "L>" t
@@@ -994,199 -996,199 +996,199 @@@ of characters from a single Latin-N cha
  
      effect   | prefix | examples
   ------------+--------+----------
 -    acute    |   '    | 'a -> \e,Aa\e(B, '' -> \e,A4\e(B
 -    grave    |   `    | `a -> \e,A`\e(B
 -  circumflex |   ^    | ^a -> \e,Ab\e(B
 -  diaeresis  |   \"    | \"a -> \e,Ad\e(B  \"\" -> \e,A(\e(B
 -    tilde    |   ~    | ~a -> \e,Ac\e(B
 -   cedilla   |   ~    | ~c -> \e,Ag\e(B
 -    breve    |   ~    | ~a -> \e$,1 #\e(B
 -    caron    |   ~    | ~c -> \e$,1 -\e(B
 -  dot above  | ~ / .  | ~o -> \e$,1 A\e(B   /o -> \e$,1 A\e(B   .o -> \e$,1 A\e(B
 -    misc     | \" ~ /  | \"s -> \e,A_\e(B  ~d -> \e,Ap\e(B  ~t -> \e,A~\e(B  /a -> \e,Ae\e(B  /e -> \e,Af\e(B  /o -> \e,Ax\e(B
 -   symbol    |   ~    | ~> -> \e,A;\e(B  ~< -> \e,A+\e(B  ~! -> \e,A!\e(B  ~? -> \e,A?\e(B  ~~ -> \e,A8\e(B
 -   symbol    |  _ /   | _o -> \e,A:\e(B  _a -> \e,A*\e(B  // -> \e,A0\e(B  /\\ -> \e,AW\e(B  _y -> \e,A%\e(B
 -   symbol    |   ^    | ^r -> \e,A.\e(B  ^c -> \e,A)\e(B  ^1 -> \e,A9\e(B  ^2 -> \e,A2\e(B  ^3 -> \e,A3\e(B
 +    acute    |   '    | 'a -> Ã¡, '' -> Â´
 +    grave    |   `    | `a -> Ã 
 +  circumflex |   ^    | ^a -> Ã¢
 +  diaeresis  |   \"    | \"a -> Ã¤  \"\" -> Â¨
 +    tilde    |   ~    | ~a -> Ã£
 +   cedilla   |   ~    | ~c -> Ã§
 +    breve    |   ~    | ~a -> Äƒ
 +    caron    |   ~    | ~c -> Ä
 +  dot above  | ~ / .  | ~o -> Ä¡   /o -> Ä¡   .o -> Ä¡
 +    misc     | \" ~ /  | \"s -> ÃŸ  ~d -> Ã°  ~t -> Ã¾  /a -> Ã¥  /e -> Ã¦  /o -> Ã¸
 +   symbol    |   ~    | ~> -> Â»  ~< -> Â«  ~! -> Â¡  ~? -> Â¿  ~~ -> Â¸
 +   symbol    |  _ /   | _o -> Âº  _a -> Âª  // -> Â°  /\\ -> Ã—  _y -> Â¥
 +   symbol    |   ^    | ^r -> Â®  ^c -> Â©  ^1 -> Â¹  ^2 -> Â²  ^3 -> Â³
  " nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
   ("' " ?')
 - ("''" ?\e,A4\e(B)
 - ("'A" ?\e,AA\e(B)
 - ("'E" ?\e,AI\e(B)
 - ("'I" ?\e,AM\e(B)
 - ("'O" ?\e,AS\e(B)
 - ("'U" ?\e,AZ\e(B)
 - ("'W" ?\e$,1nb\e(B)
 - ("'Y" ?\e,A]\e(B)
 - ("'a" ?\e,Aa\e(B)
 - ("'e" ?\e,Ai\e(B)
 - ("'i" ?\e,Am\e(B)
 - ("'o" ?\e,As\e(B)
 - ("'u" ?\e,Az\e(B)
 - ("'w" ?\e$,1nc\e(B)
 - ("'y" ?\e,A}\e(B)
 - (".B" ?\e$,1mB\e(B)
 - (".C" ?\e$,1 *\e(B)
 - (".D" ?\e$,1mJ\e(B)
 - (".F" ?\e$,1m^\e(B)
 - (".G" ?\e$,1 @\e(B)
 - (".I" ?\e$,1 P\e(B)
 - (".M" ?\e$,1n \e(B)
 - (".P" ?\e$,1n6\e(B)
 - (".S" ?\e$,1n@\e(B)
 - (".T" ?\e$,1nJ\e(B)
 - (".Z" ?\e$,1!;\e(B)
 - (".b" ?\e$,1mC\e(B)
 - (".c" ?\e$,1 +\e(B)
 - (".d" ?\e$,1mK\e(B)
 - (".f" ?\e$,1m_\e(B)
 - (".g" ?\e$,1 A\e(B)
 - (".m" ?\e$,1n!\e(B)
 - (".p" ?\e$,1n7\e(B)
 - (".s" ?\e$,1nA\e(B)
 - (".t" ?\e$,1nK\e(B)
 - (".z" ?\e$,1!<\e(B)
 + ("''" ?´)
 + ("'A" ?Ã)
 + ("'E" ?É)
 + ("'I" ?Ã)
 + ("'O" ?Ó)
 + ("'U" ?Ú)
 + ("'W" ?Ẃ)
 + ("'Y" ?Ã)
 + ("'a" ?á)
 + ("'e" ?é)
 + ("'i" ?í)
 + ("'o" ?ó)
 + ("'u" ?ú)
 + ("'w" ?ẃ)
 + ("'y" ?ý)
 + (".B" ?Ḃ)
 + (".C" ?ÄŠ)
 + (".D" ?Ḋ)
 + (".F" ?Ḟ)
 + (".G" ?Ä )
 + (".I" ?Ä°)
 + (".M" ?á¹€)
 + (".P" ?á¹–)
 + (".S" ?á¹ )
 + (".T" ?Ṫ)
 + (".Z" ?Å»)
 + (".b" ?ḃ)
 + (".c" ?Ä‹)
 + (".d" ?ḋ)
 + (".f" ?ḟ)
 + (".g" ?Ä¡)
 + (".m" ?á¹)
 + (".p" ?á¹—)
 + (".s" ?ṡ)
 + (".t" ?ṫ)
 + (".z" ?ż)
   ("/ " ?/)
 - ("/#" ?\e,A#\e(B)
 - ("/$" ?\e,A$\e(B)
 - ("/." ?\e$,1$y\e(B)
 - ("//" ?\e,A0\e(B)
 - ("/2" ?\e,A=\e(B)
 - ("/3" ?\e,A>\e(B)
 - ("/4" ?\e,A<\e(B)
 - ("/=" ?\e,A,\e(B)
 - ("/A" ?\e,AE\e(B)
 - ("/C" ?\e$,1 *\e(B)
 - ("/E" ?\e,AF\e(B)
 - ("/G" ?\e$,1 @\e(B)
 - ("/H" ?\e$,1 F\e(B)
 - ("/I" ?\e$,1 P\e(B)
 - ("/O" ?\e,AX\e(B)
 - ("/O" ?\e$,1 r\e(B)
 - ("/Z" ?\e$,1!;\e(B)
 - ("/\\" ?\e,AW\e(B)
 - ("/a" ?\e,Ae\e(B)
 - ("/c" ?\e,A"\e(B)
 - ("/c" ?\e$,1 +\e(B)
 - ("/e" ?\e,Af\e(B)
 - ("/g" ?\e$,1 A\e(B)
 - ("/h" ?\e$,1 G\e(B)
 - ("/i" ?\e$,1 Q\e(B)
 - ("/o" ?\e,Ax\e(B)
 - ("/o" ?\e$,1 s\e(B)
 - ("/z" ?\e$,1!<\e(B)
 + ("/#" ?£)
 + ("/$" ?¤)
 + ("/." ?Ë™)
 + ("//" ?°)
 + ("/2" ?½)
 + ("/3" ?¾)
 + ("/4" ?¼)
 + ("/=" ?¬)
 + ("/A" ?Ã…)
 + ("/C" ?ÄŠ)
 + ("/E" ?Æ)
 + ("/G" ?Ä )
 + ("/H" ?Ħ)
 + ("/I" ?Ä°)
 + ("/O" ?Ø)
 + ("/O" ?Å’)
 + ("/Z" ?Å»)
 + ("/\\" ?×)
 + ("/a" ?Ã¥)
 + ("/c" ?¢)
 + ("/c" ?Ä‹)
 + ("/e" ?æ)
 + ("/g" ?Ä¡)
 + ("/h" ?ħ)
 + ("/i" ?ı)
 + ("/o" ?ø)
 + ("/o" ?Å“)
 + ("/z" ?ż)
   ("\" " ?\")
 - ("\"A" ?\e,AD\e(B)
 - ("\"E" ?\e,AK\e(B)
 - ("\"I" ?\e,AO\e(B)
 - ("\"O" ?\e,AV\e(B)
 - ("\"U" ?\e,A\\e(B)
 - ("\"W" ?\e$,1nd\e(B)
 - ("\"Y" ?\e$,1!8\e(B)
 - ("\"\"" ?\e,A(\e(B)
 - ("\"a" ?\e,Ad\e(B)
 - ("\"e" ?\e,Ak\e(B)
 - ("\"i" ?\e,Ao\e(B)
 - ("\"o" ?\e,Av\e(B)
 - ("\"s" ?\e,A_\e(B)
 - ("\"u" ?\e,A|\e(B)
 - ("\"w" ?\e$,1ne\e(B)
 - ("\"y" ?\e,A\7f\e(B)
 + ("\"A" ?Ä)
 + ("\"E" ?Ë)
 + ("\"I" ?Ã)
 + ("\"O" ?Ö)
 + ("\"U" ?Ãœ)
 + ("\"W" ?Ẅ)
 + ("\"Y" ?Ÿ)
 + ("\"\"" ?¨)
 + ("\"a" ?ä)
 + ("\"e" ?ë)
 + ("\"i" ?ï)
 + ("\"o" ?ö)
 + ("\"s" ?ß)
 + ("\"u" ?ü)
 + ("\"w" ?ẅ)
 + ("\"y" ?ÿ)
   ("^ " ?^)
 - ("^1" ?\e,A9\e(B)
 - ("^2" ?\e,A2\e(B)
 - ("^3" ?\e,A3\e(B)
 - ("^A" ?\e,AB\e(B)
 - ("^C" ?\e$,1 (\e(B)
 - ("^E" ?\e,AJ\e(B)
 - ("^G" ?\e$,1 <\e(B)
 - ("^H" ?\e$,1 D\e(B)
 - ("^I" ?\e,AN\e(B)
 - ("^J" ?\e$,1 T\e(B)
 - ("^O" ?\e,AT\e(B)
 - ("^S" ?\e$,1 |\e(B)
 - ("^U" ?\e,A[\e(B)
 - ("^W" ?\e$,1!4\e(B)
 - ("^Y" ?\e$,1!6\e(B)
 + ("^1" ?¹)
 + ("^2" ?²)
 + ("^3" ?³)
 + ("^A" ?Â)
 + ("^C" ?Ĉ)
 + ("^E" ?Ê)
 + ("^G" ?Äœ)
 + ("^H" ?Ĥ)
 + ("^I" ?ÃŽ)
 + ("^J" ?Ä´)
 + ("^O" ?Ô)
 + ("^S" ?Åœ)
 + ("^U" ?Û)
 + ("^W" ?Å´)
 + ("^Y" ?Ŷ)
   ("^^" ?^)
 - ("^a" ?\e,Ab\e(B)
 - ("^c" ?\e,A)\e(B)
 - ("^c" ?\e$,1 )\e(B)
 - ("^e" ?\e,Aj\e(B)
 - ("^g" ?\e$,1 =\e(B)
 - ("^h" ?\e$,1 E\e(B)
 - ("^i" ?\e,An\e(B)
 - ("^j" ?\e$,1 U\e(B)
 - ("^o" ?\e,At\e(B)
 - ("^r" ?\e,A.\e(B)
 - ("^s" ?\e$,1 }\e(B)
 - ("^u" ?\e,A{\e(B)
 - ("^w" ?\e$,1!5\e(B)
 - ("^y" ?\e$,1!7\e(B)
 - ("_+" ?\e,A1\e(B)
 - ("_:" ?\e,Aw\e(B)
 - ("_a" ?\e,A*\e(B)
 - ("_o" ?\e,A:\e(B)
 - ("_y" ?\e,A%\e(B)
 - ("_ " ?\e,A \e(B)
 + ("^a" ?â)
 + ("^c" ?©)
 + ("^c" ?ĉ)
 + ("^e" ?ê)
 + ("^g" ?Ä)
 + ("^h" ?Ä¥)
 + ("^i" ?î)
 + ("^j" ?ĵ)
 + ("^o" ?ô)
 + ("^r" ?®)
 + ("^s" ?Å)
 + ("^u" ?û)
 + ("^w" ?ŵ)
 + ("^y" ?Å·)
 + ("_+" ?±)
 + ("_:" ?÷)
 + ("_a" ?ª)
 + ("_o" ?º)
 + ("_y" ?Â¥)
 + ("_ " ? )
   ("` " ?`)
 - ("`A" ?\e,A@\e(B)
 - ("`E" ?\e,AH\e(B)
 - ("`I" ?\e,AL\e(B)
 - ("`O" ?\e,AR\e(B)
 - ("`U" ?\e,AY\e(B)
 - ("`W" ?\e$,1n`\e(B)
 - ("`Y" ?\e$,1or\e(B)
 + ("`A" ?À)
 + ("`E" ?È)
 + ("`I" ?ÃŒ)
 + ("`O" ?Ã’)
 + ("`U" ?Ù)
 + ("`W" ?Ẁ)
 + ("`Y" ?Ỳ)
   ("``" ?`)
 - ("`a" ?\e,A`\e(B)
 - ("`e" ?\e,Ah\e(B)
 - ("`i" ?\e,Al\e(B)
 - ("`o" ?\e,Ar\e(B)
 - ("`u" ?\e,Ay\e(B)
 - ("`w" ?\e$,1na\e(B)
 - ("`y" ?\e$,1os\e(B)
 + ("`a" ?à)
 + ("`e" ?è)
 + ("`i" ?ì)
 + ("`o" ?ò)
 + ("`u" ?ù)
 + ("`w" ?áº)
 + ("`y" ?ỳ)
   ("~ " ?~)
 - ("~!" ?\e,A!\e(B)
 - ("~$" ?\e,A#\e(B)
 - ("~-" ?\e,A-\e(B)
 - ("~." ?\e,A7\e(B)
 - ("~<" ?\\e,A+\e(B)
 - ("~=" ?\e,A/\e(B)
 - ("~>" ?\\e,A;\e(B)
 - ("~?" ?\e,A?\e(B)
 - ("~A" ?\e,AC\e(B)
 - ("~C" ?\e,AG\e(B)
 - ("~D" ?\e,AP\e(B)
 - ("~G" ?\e$,1 >\e(B)
 - ("~N" ?\e,AQ\e(B)
 - ("~O" ?\e,AU\e(B)
 - ("~O" ?\e$,1 @\e(B)
 - ("~S" ?\e$,1 ~\e(B)
 - ("~S" ?\e$,1! \e(B)
 - ("~T" ?\e,A^\e(B)
 - ("~U" ?\e$,1!,\e(B)
 - ("~Z" ?\e$,1!=\e(B)
 - ("~`" ?\e$,1$x\e(B)
 - ("~a" ?\e,Ac\e(B)
 - ("~c" ?\e,Ag\e(B)
 - ("~d" ?\e,Ap\e(B)
 - ("~e" ?\e$,1tL\e(B)
 - ("~g" ?\e$,1 ?\e(B)
 - ("~n" ?\e,Aq\e(B)
 - ("~o" ?\e,Au\e(B)
 - ("~o" ?\e$,1 A\e(B)
 - ("~p" ?\e,A6\e(B)
 - ("~s" ?\e,A'\e(B)
 - ("~s" ?\e$,1 \7f\e(B)
 - ("~s" ?\e$,1!!\e(B)
 - ("~t" ?\e,A~\e(B)
 - ("~u" ?\e,A5\e(B)
 - ("~u" ?\e$,1!-\e(B)
 - ("~x" ?\e,A$\e(B)
 - ("~z" ?\e$,1!>\e(B)
 - ("~|" ?\e,A&\e(B)
 - ("~~" ?\e,A8\e(B)
 + ("~!" ?¡)
 + ("~$" ?£)
 + ("~-" ?­)
 + ("~." ?·)
 + ("~<" ?\«)
 + ("~=" ?¯)
 + ("~>" ?\»)
 + ("~?" ?¿)
 + ("~A" ?Ã)
 + ("~C" ?Ç)
 + ("~D" ?Ã)
 + ("~G" ?Äž)
 + ("~N" ?Ñ)
 + ("~O" ?Õ)
 + ("~O" ?Ä )
 + ("~S" ?Åž)
 + ("~S" ?Å )
 + ("~T" ?Þ)
 + ("~U" ?Ŭ)
 + ("~Z" ?Ž)
 + ("~`" ?˘)
 + ("~a" ?ã)
 + ("~c" ?ç)
 + ("~d" ?ð)
 + ("~e" ?€)
 + ("~g" ?ÄŸ)
 + ("~n" ?ñ)
 + ("~o" ?õ)
 + ("~o" ?Ä¡)
 + ("~p" ?¶)
 + ("~s" ?§)
 + ("~s" ?ÅŸ)
 + ("~s" ?Å¡)
 + ("~t" ?þ)
 + ("~u" ?µ)
 + ("~u" ?Å­)
 + ("~x" ?¤)
 + ("~z" ?ž)
 + ("~|" ?¦)
 + ("~~" ?¸)
  )
  
  ;;; arch-tag: 83017837-6b84-4366-b183-e0577e3ed838
diff --combined leim/quail/pypunct-b5.el
index 8d57e42b141e6deca945b8438c17d3ea05cfee9b,9aa7257b8244bafb4113032384960795110a56ea..bb206525ab3cc0c29b5390a418499cea201ae52b
@@@ -1,6 -1,7 +1,7 @@@
 -;;; pypunct-b5.el --- Quail packages for Chinese (pinyin + extra symbols)
 +;;; pypunct-b5.el --- Quail packages for Chinese (pinyin + extra symbols) -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
diff --combined leim/quail/symbol-ksc.el
index de7386aa2d08361974bf2a747a1413818bce3911,ebaeff371623ccea9ebbbaea5d0fcbcfb905e873..aa6f7e98c2e90f1e1a887fb07b67f48cb401c339
@@@ -1,7 -1,9 +1,9 @@@
 -;;; symbol-ksc.el --- Quail-package for Korean Symbol (KSC5601)
 +;;; symbol-ksc.el --- Quail-package for Korean Symbol (KSC5601) -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 1997, 2005, 2006  Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
diff --combined leim/quail/thai.el
index 6d7f16cae80ae2d99466bad5478dc4f7e1db0251,2d25a935425d143c3e8e32bca19a493a379d2356..fded06ffb5ce45a6791516370d6477fbd1e0e94a
@@@ -1,7 -1,7 +1,7 @@@
 -;;; thai.el --- Quail package for inputting Thai characters
 +;;; thai.el --- Quail package for inputting Thai characters -*-coding: iso-2022-7bit;-*-
  
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
@@@ -29,6 -29,7 +29,6 @@@
  ;;; Code:
  
  (require 'quail)
 -(require 'thai-util)
  
  (defmacro thai-generate-quail-map (translation-table)
    (let (map)
@@@ -53,39 -54,41 +53,39 @@@ The difference from the ordinal Thai ke
      Don't know where to assign characters '\e,Tz\e(B' and '\e,T{\e(B'."
   nil t t t t nil nil nil nil nil t)
  
 -(quail-install-map
 - (thai-generate-quail-map
 -  [
 -   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    ; control codes
 -   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    ; control codes
 +(thai-generate-quail-map
 + [
 +  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0     ; control codes
 +  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0     ; control codes
  ;; This data is quite old.
 -;;    0   "#" "." "\e,Tr\e(B" "\e,Ts\e(B" "\e,Tt\e(B" "\e,TQi\e(B" "\e,T'\e(B"  ; SPC .. '
 -;;    "\e,Tv\e(B" "\e,Tw\e(B" "\e,Tu\e(B" "\e,Ty\e(B" "\e,TA\e(B" "\e,T"\e(B" "\e,Tc\e(B" "\e,T=\e(B" ; ( .. /
 -;;    "\e,T(\e(B" "\e,TE\e(B" "/" "_" "\e,T@\e(B" "\e,T6\e(B" "\e,TX\e(B" "\e,TV\e(B"     ; 0 .. 7
 -;;    "\e,T$\e(B" "\e,T5\e(B" "\e,T+\e(B" "\e,TG\e(B" "\e,T2\e(B" "\e,T*\e(B" "\e,TL\e(B" "\e,TF\e(B" ; 8 .. ?
 -;;    "\e,Tq\e(B" "\e,TD\e(B" "\e,TZ\e(B" "\e,T)\e(B" "\e,T/\e(B" "\e,T.\e(B" "\e,Tb\e(B" "\e,T,\e(B" ; @ .. G
 -;;    "\e,Tg\e(B" "\e,T3\e(B" "\e,Tk\e(B" "\e,TI\e(B" "\e,TH\e(B" "\e,Tn\e(B" "\e,Tl\e(B" "\e,TO\e(B" ; H .. O
 -;;    "\e,T-\e(B" "\e,Tp\e(B" "\e,T1\e(B" "\e,T&\e(B" "\e,T8\e(B" "\e,Tj\e(B" "\e,TN\e(B" "\""      ; P .. W
 -;;    ")" "\e,Tm\e(B" "(" "\e,T:\e(B" "\e,T_\e(B" "\e,TE\e(B" "\e,TY\e(B" "\e,Tx\e(B"     ; X .. _
 -;;    "\e,T#\e(B" "\e,T?\e(B" "\e,TT\e(B" "\e,Ta\e(B" "\e,T!\e(B" "\e,TS\e(B" "\e,T4\e(B" "\e,T`\e(B" ; ` .. g
 -;;    "\e,Ti\e(B" "\e,TC\e(B" "\e,Th\e(B" "\e,TR\e(B" "\e,TJ\e(B" "\e,T7\e(B" "\e,TW\e(B" "\e,T9\e(B" ; h .. o
 -;;    "\e,TB\e(B" "\e,Tf\e(B" "\e,T>\e(B" "\e,TK\e(B" "\e,TP\e(B" "\e,TU\e(B" "\e,TM\e(B" "\e,Td\e(B" ; p .. w
 -;;    "\e,T;\e(B" "\e,TQ\e(B" "\e,T<\e(B" "\e,T0\e(B" "\e,To\e(B" "," "\e,T%\e(B" 0       ; x .. DEL
 +;;   0   "#" "." "\e,Tr\e(B" "\e,Ts\e(B" "\e,Tt\e(B" "\e,TQi\e(B" "\e,T'\e(B"   ; SPC .. '
 +;;   "\e,Tv\e(B" "\e,Tw\e(B" "\e,Tu\e(B" "\e,Ty\e(B" "\e,TA\e(B" "\e,T"\e(B" "\e,Tc\e(B" "\e,T=\e(B"  ; ( .. /
 +;;   "\e,T(\e(B" "\e,TE\e(B" "/" "_" "\e,T@\e(B" "\e,T6\e(B" "\e,TX\e(B" "\e,TV\e(B"      ; 0 .. 7
 +;;   "\e,T$\e(B" "\e,T5\e(B" "\e,T+\e(B" "\e,TG\e(B" "\e,T2\e(B" "\e,T*\e(B" "\e,TL\e(B" "\e,TF\e(B"  ; 8 .. ?
 +;;   "\e,Tq\e(B" "\e,TD\e(B" "\e,TZ\e(B" "\e,T)\e(B" "\e,T/\e(B" "\e,T.\e(B" "\e,Tb\e(B" "\e,T,\e(B"  ; @ .. G
 +;;   "\e,Tg\e(B" "\e,T3\e(B" "\e,Tk\e(B" "\e,TI\e(B" "\e,TH\e(B" "\e,Tn\e(B" "\e,Tl\e(B" "\e,TO\e(B"  ; H .. O
 +;;   "\e,T-\e(B" "\e,Tp\e(B" "\e,T1\e(B" "\e,T&\e(B" "\e,T8\e(B" "\e,Tj\e(B" "\e,TN\e(B" "\""       ; P .. W
 +;;   ")" "\e,Tm\e(B" "(" "\e,T:\e(B" "\e,T_\e(B" "\e,TE\e(B" "\e,TY\e(B" "\e,Tx\e(B"      ; X .. _
 +;;   "\e,T#\e(B" "\e,T?\e(B" "\e,TT\e(B" "\e,Ta\e(B" "\e,T!\e(B" "\e,TS\e(B" "\e,T4\e(B" "\e,T`\e(B"  ; ` .. g
 +;;   "\e,Ti\e(B" "\e,TC\e(B" "\e,Th\e(B" "\e,TR\e(B" "\e,TJ\e(B" "\e,T7\e(B" "\e,TW\e(B" "\e,T9\e(B"  ; h .. o
 +;;   "\e,TB\e(B" "\e,Tf\e(B" "\e,T>\e(B" "\e,TK\e(B" "\e,TP\e(B" "\e,TU\e(B" "\e,TM\e(B" "\e,Td\e(B"  ; p .. w
 +;;   "\e,T;\e(B" "\e,TQ\e(B" "\e,T<\e(B" "\e,T0\e(B" "\e,To\e(B" "," "\e,T%\e(B" 0        ; x .. DEL
  ;; This is the correct data nowadays.
 -   0  "+" "." "\e,Tr\e(B" "\e,Ts\e(B" "\e,Tt\e(B" "\e,T_\e(B" "\e,T'\e(B"       ; SPC .. '
 -   "\e,Tv\e(B" "\e,Tw\e(B" "\e,Tu\e(B" "\e,Ty\e(B" "\e,TA\e(B" "\e,T"\e(B" "\e,Tc\e(B" "\e,T=\e(B"    ; ( .. /
 -   "\e,T(\e(B" "\e,Te\e(B" "/" "-" "\e,T@\e(B" "\e,T6\e(B" "\e,TX\e(B" "\e,TV\e(B"        ; 0 .. 7
 -   "\e,T$\e(B" "\e,T5\e(B" "\e,T+\e(B" "\e,TG\e(B" "\e,T2\e(B" "\e,T*\e(B" "\e,TL\e(B" "\e,TF\e(B"    ; 8 .. ?
 -   "\e,Tq\e(B" "\e,TD\e(B" "\e,TZ\e(B" "\e,T)\e(B" "\e,T/\e(B" "\e,T.\e(B" "\e,Tb\e(B" "\e,T,\e(B"    ; @ .. G
 -   "\e,Tg\e(B" "\e,T3\e(B" "\e,Tk\e(B" "\e,TI\e(B" "\e,TH\e(B" "?" "\e,Tl\e(B" "\e,TO\e(B"  ; H .. O
 -   "\e,T-\e(B" "\e,Tp\e(B" "\e,T1\e(B" "\e,T&\e(B" "\e,T8\e(B" "\e,Tj\e(B" "\e,TN\e(B" "\"" ; P .. W
 -   "\)" "\e,Tm\e(B" "\(" "\e,T:\e(B" "\e,T#\e(B" "\e,TE\e(B" "\e,TY\e(B" "\e,Tx\e(B"      ; X .. _
 -   "_" "\e,T?\e(B" "\e,TT\e(B" "\e,Ta\e(B" "\e,T!\e(B" "\e,TS\e(B" "\e,T4\e(B" "\e,T`\e(B"  ; ` .. g
 -   "\e,Ti\e(B" "\e,TC\e(B" "\e,Th\e(B" "\e,TR\e(B" "\e,TJ\e(B" "\e,T7\e(B" "\e,TW\e(B" "\e,T9\e(B"    ; h .. o
 -   "\e,TB\e(B" "\e,Tf\e(B" "\e,T>\e(B" "\e,TK\e(B" "\e,TP\e(B" "\e,TU\e(B" "\e,TM\e(B" "\e,Td\e(B"    ; p .. w
 -   "\e,T;\e(B" "\e,TQ\e(B" "\e,T<\e(B" "\e,T0\e(B" "\e,T%\e(B" "," "%" 0        ; x .. DEL
 -   ]))
 -
 -
 -\f
 +  0  "+" "." "\e,Tr\e(B" "\e,Ts\e(B" "\e,Tt\e(B" "\e,T_\e(B" "\e,T'\e(B"        ; SPC .. '
 +  "\e,Tv\e(B" "\e,Tw\e(B" "\e,Tu\e(B" "\e,Ty\e(B" "\e,TA\e(B" "\e,T"\e(B" "\e,Tc\e(B" "\e,T=\e(B"     ; ( .. /
 +  "\e,T(\e(B" "\e,Te\e(B" "/" "-" "\e,T@\e(B" "\e,T6\e(B" "\e,TX\e(B" "\e,TV\e(B" ; 0 .. 7
 +  "\e,T$\e(B" "\e,T5\e(B" "\e,T+\e(B" "\e,TG\e(B" "\e,T2\e(B" "\e,T*\e(B" "\e,TL\e(B" "\e,TF\e(B"     ; 8 .. ?
 +  "\e,Tq\e(B" "\e,TD\e(B" "\e,TZ\e(B" "\e,T)\e(B" "\e,T/\e(B" "\e,T.\e(B" "\e,Tb\e(B" "\e,T,\e(B"     ; @ .. G
 +  "\e,Tg\e(B" "\e,T3\e(B" "\e,Tk\e(B" "\e,TI\e(B" "\e,TH\e(B" "?" "\e,Tl\e(B" "\e,TO\e(B"   ; H .. O
 +  "\e,T-\e(B" "\e,Tp\e(B" "\e,T1\e(B" "\e,T&\e(B" "\e,T8\e(B" "\e,Tj\e(B" "\e,TN\e(B" "\""  ; P .. W
 +  "\)" "\e,Tm\e(B" "\(" "\e,T:\e(B" "\e,T#\e(B" "\e,TE\e(B" "\e,TY\e(B" "\e,Tx\e(B"       ; X .. _
 +  "_" "\e,T?\e(B" "\e,TT\e(B" "\e,Ta\e(B" "\e,T!\e(B" "\e,TS\e(B" "\e,T4\e(B" "\e,T`\e(B"   ; ` .. g
 +  "\e,Ti\e(B" "\e,TC\e(B" "\e,Th\e(B" "\e,TR\e(B" "\e,TJ\e(B" "\e,T7\e(B" "\e,TW\e(B" "\e,T9\e(B"     ; h .. o
 +  "\e,TB\e(B" "\e,Tf\e(B" "\e,T>\e(B" "\e,TK\e(B" "\e,TP\e(B" "\e,TU\e(B" "\e,TM\e(B" "\e,Td\e(B"     ; p .. w
 +  "\e,T;\e(B" "\e,TQ\e(B" "\e,T<\e(B" "\e,T0\e(B" "\e,T%\e(B" "," "%" 0 ; x .. DEL
 +  ])
 +
 +
  ;; Thai Pattachote keyboard support.
  
  (quail-define-package
   "Thai Pattachote input method with TIS620 keyboard layout"
   nil t t t t nil nil nil nil nil t)
  
 -(quail-install-map
 - (thai-generate-quail-map
 -  [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   ; control codes
 -    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   ; control codes
 -    0 "+" "\e,T1\e(B" "/" "," "?" "_" "\e,T"\e(B" ; SPC .. '
 -    "(" ")" "." "%" "\e,TP\e(B" "\e,Tq\e(B" "\e,T(\e(B" "\e,T>\e(B"   ; ( .. /
 -    "\e,Tp\e(B" "=" "\e,Tr\e(B" "\e,Ts\e(B" "\e,Tt\e(B" "\e,Tu\e(B" "\e,TY\e(B" "\e,Tw\e(B" ; 0 .. 7
 -    "\e,Tx\e(B" "\e,Ty\e(B" "\e,T&\e(B" "\e,Td\e(B" "\e,T?\e(B" "\e,Tv\e(B" "\e,T2\e(B" "\e,TL\e(B"   ; 8 .. ?
 -    "\"" "\e,Tk\e(B" "\e,TQ\e(B" "\e,T0\e(B" "\e,TS\e(B" "\e,Tf\e(B" "\e,T3\e(B" "\e,Tl\e(B"        ; @ .. G
 -    "\e,TW\e(B" "\e,T+\e(B" "\e,T<\e(B" "\e,T*\e(B" "\e,Tb\e(B" "\e,TN\e(B" "\e,TH\e(B" "\e,T6\e(B"   ; H .. O
 -    "\e,T2\e(B" "\e,Tj\e(B" "\e,T-\e(B" "\e,T8\e(B" "\e,TI\e(B" "\e,T=\e(B" "\e,T@\e(B" "\e,TD\e(B"   ; P .. W
 -    "\e,T.\e(B" "\e,TV\e(B" "\e,T.\e(B" "\e,Tc\e(B" "\e,TZ\e(B" "\e,T2\e(B" "\e,TX\e(B" "-" ; X .. _
 -    "\e,T#\e(B" "\e,Ti\e(B" "\e,TT\e(B" "\e,TE\e(B" "\e,T'\e(B" "\e,TB\e(B" "\e,T!\e(B" "\e,TQ\e(B"   ; ` .. g
 -    "\e,TU\e(B" "\e,TA\e(B" "\e,TR\e(B" "\e,T9\e(B" "\e,T`\e(B" "\e,TJ\e(B" "\e,T$\e(B" "\e,TG\e(B"   ; h .. o
 -    "\e,Ta\e(B" "\e,Tg\e(B" "\e,TM\e(B" "\e,T7\e(B" "\e,TC\e(B" "\e,T4\e(B" "\e,TK\e(B" "\e,T5\e(B"   ; p .. w
 -    "\e,T;\e(B" "\e,Th\e(B" "\e,T:\e(B" "\e,TO\e(B" "\e,Tm\e(B" "\e,TF\e(B" "\e,T%\e(B" 0   ; x .. DEL
 -    ]))
 +(thai-generate-quail-map
 + [
 +  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0     ; control codes
 +  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0     ; control codes
 +  0 "+" "\e,T1\e(B" "/" "," "?" "_" "\e,T"\e(B"           ; SPC .. '
 +  "(" ")" "." "%" "\e,TP\e(B" "\e,Tq\e(B" "\e,T(\e(B" "\e,T>\e(B"     ; ( .. /
 +  "\e,Tp\e(B" "=" "\e,Tr\e(B" "\e,Ts\e(B" "\e,Tt\e(B" "\e,Tu\e(B" "\e,TY\e(B" "\e,Tw\e(B"   ; 0 .. 7
 +  "\e,Tx\e(B" "\e,Ty\e(B" "\e,T&\e(B" "\e,Td\e(B" "\e,T?\e(B" "\e,Tv\e(B" "\e,T2\e(B" "\e,TL\e(B"     ; 8 .. ?
 +  "\"" "\e,Tk\e(B" "\e,TQ\e(B" "\e,T0\e(B" "\e,TS\e(B" "\e,Tf\e(B" "\e,T3\e(B" "\e,Tl\e(B"  ; @ .. G
 +  "\e,TW\e(B" "\e,T+\e(B" "\e,T<\e(B" "\e,T*\e(B" "\e,Tb\e(B" "\e,TN\e(B" "\e,TH\e(B" "\e,T6\e(B"     ; H .. O
 +  "\e,T2\e(B" "\e,Tj\e(B" "\e,T-\e(B" "\e,T8\e(B" "\e,TI\e(B" "\e,T=\e(B" "\e,T@\e(B" "\e,TD\e(B"     ; P .. W
 +  "\e,T.\e(B" "\e,TV\e(B" "\e,T.\e(B" "\e,Tc\e(B" "\e,TZ\e(B" "\e,T2\e(B" "\e,TX\e(B" "-"   ; X .. _
 +  "\e,T#\e(B" "\e,Ti\e(B" "\e,TT\e(B" "\e,TE\e(B" "\e,T'\e(B" "\e,TB\e(B" "\e,T!\e(B" "\e,TQ\e(B"     ; ` .. g
 +  "\e,TU\e(B" "\e,TA\e(B" "\e,TR\e(B" "\e,T9\e(B" "\e,T`\e(B" "\e,TJ\e(B" "\e,T$\e(B" "\e,TG\e(B"     ; h .. o
 +  "\e,Ta\e(B" "\e,Tg\e(B" "\e,TM\e(B" "\e,T7\e(B" "\e,TC\e(B" "\e,T4\e(B" "\e,TK\e(B" "\e,T5\e(B"     ; p .. w
 +  "\e,T;\e(B" "\e,Th\e(B" "\e,T:\e(B" "\e,TO\e(B" "\e,Tm\e(B" "\e,TF\e(B" "\e,T%\e(B" 0             ; x .. DEL
 +  ])
  
  ;;; arch-tag: fed6c468-0616-44b0-88bf-47347bf64825
  ;;; thai.el ends here
diff --combined leim/quail/tibetan.el
index e710cada9149d5f428f3eaae3d496a6c36cca2a3,97bab8d93d36eff8f5e81eeb44467384528eb8c9..04bade325c44d2f8891f99f0293ba0340cbfd91c
@@@ -1,7 -1,9 +1,9 @@@
 -;;; tibetan.el --- Quail package for inputting Tibetan characters
 +;;; tibetan.el --- Quail package for inputting Tibetan characters -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 1997, 2006  Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ ;;   2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
diff --combined leim/quail/uni-input.el
index a5f32068424249361425d248c4dda9aaed64e548,bf91d2ecff8e81b6cfb60cd6d17deadc3afde4a2..3611b59b92f4a18d0ac9b09773fb170f32e4e8b3
@@@ -1,7 -1,8 +1,8 @@@
  ;;; uni-input.el --- Hex Unicode input method
  
- ;; Copyright (C) 2001, 2002, 2003, 2006  Free Software Foundation, Inc.
- ;; Copyright (C) 2004, 2005, 2006
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
+ ;; Copyright (C) 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  ;; This is not really a Quail method, but uses some Quail functions.
  ;; There is probably A Better Way.
  
 -;; Compare `ucs-insert', which explicitly inserts a unicoded character
 -;; rather than supplying an input method.
 +;; You can get a similar effect by using C-q with
 +;; `read-quoted-char-radix' set to 16.
 +
 +;; Note that this only allows you to enter BMP values unless someone
 +;; extends it to use variable numbers of digits.
  
  ;;; Code:
  
  (require 'quail)
  
 -;; Maybe stolen from Mule-UCS -- I don't remember.
 -(define-ccl-program utf-8-ccl-encode
 -  `(4 (if (r0 < ?\x80)
 -      ((write r0))
 -      (if (r0 < #x800)
 -        ((write ((r0 >> 6) | ?\xC0))
 -         (write ((r0 & ?\x3F) | ?\x80)))
 -      (if (r0 < #x10000)
 -          ((write ((r0 >> 12) | ?\xE0))
 -           (write (((r0 >> 6) & ?\x3F) | ?\x80))
 -           (write ((r0 & ?\x3F) | ?\x80)))
 -        (if (r0 < #x200000)
 -            ((write ((r0 >> 18) | ?\xF0))
 -             (write (((r0 >> 12) & ?\x3F) | ?\x80))
 -             (write (((r0 >> 6) & ?\x3F) | ?\x80))
 -             (write ((r0 & ?\x3F) | ?\x80)))
 -          (if (r0 < #x4000000)
 -              ((write ((r0 >> 24) | ?\xF8))
 -               (write (((r0 >> 18) & ?\x3F) | ?\x80))
 -               (write (((r0 >> 12) & ?\x3F) | ?\x80))
 -               (write (((r0 >> 6) & ?\x3F) | ?\x80))
 -               (write ((r0 & ?\x3F) | ?\x80)))
 -            ((write ((r0 >> 30) | ?\xFC))
 -             (write (((r0 >> 24) & ?\x3F) | ?\x80))
 -             (write (((r0 >> 18) & ?\x3F) | ?\x80))
 -             (write (((r0 >> 12) & ?\x3F) | ?\x80))
 -             (write (((r0 >> 6) & ?\x3F) | ?\x80))
 -             (write ((r0 & ?\x3F) | ?\x80))))))))))
 -
  (defun ucs-input-insert-char (char)
    (insert char)
    (move-overlay quail-overlay (overlay-start quail-overlay) (point)))
@@@ -70,7 -97,7 +71,7 @@@
                           (= 1 (length seq))
                           (setq key (aref seq 0))
                           (memq key '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a
 -                                     ?b ?c ?d ?e ?f ?A ?B ?C ?D ?E ?F)))
 +                                        ?b ?c ?d ?e ?f ?A ?B ?C ?D ?E ?F)))
                      (progn
                        (push key events)
                        (ucs-input-insert-char key))
                    (throw 'non-digit (append (reverse events)
                                              (listify-key-sequence seq))))))
              (quail-delete-region)
 -            (let* ((n (string-to-number (apply 'string
 -                                               (cdr (nreverse events)))
 -                                        16))
 -                   (c (decode-char 'ucs n)))
 -              (if c
 -                  (list c)
 -                ;; The intention of the following code is to insert
 -                ;; a correct UTF-8 sequence by raw bytes, but
 -                ;; currently it doesn't work.
 -                ;; (let ((status (make-vector 9 nil)))
 -                ;;   (aset status 0 n)
 -                ;;   (string-to-list (ccl-execute-on-string
 -                ;;                    'utf-8-ccl-encode status "")))
 -                (error "Character U+%04X is not yet supported" n)))))
 +            (let ((n (string-to-number (apply 'string
 +                                          (cdr (nreverse events)))
 +                                   16)))
 +              (if (characterp n)
 +                  (list n)))))
        (quail-delete-overlays)
        (set-buffer-modified-p modified-p)
        (run-hooks 'input-method-after-insert-chunk-hook)))))
diff --combined leim/quail/welsh.el
index 50fa9621d4ada84382650f9064e10e9a5f6518ee,af97d267057ec9c0d424c848d029eb9218ec2011..a967e32681c398faa05116f0d100784be0f024f4
@@@ -1,6 -1,7 +1,7 @@@
  ;;; welsh.el --- Quail package for inputting Welsh characters  -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc.
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ ;;   Free Software Foundation, Inc.
  
  ;; Author: Dave Love <fx@gnu.org>
  ;; Keywords: i18n
@@@ -25,6 -26,8 +26,6 @@@
  ;;; Commentary:
  
  ;; Welsh input following the Yudit map by david@sheetmusic.org.uk.
 -;; This is set up to produce utf-8.  A Latin-8 version of most of it
 -;; is commented-out at the end.
  
  ;;; Code:
  
@@@ -32,7 -35,7 +33,7 @@@
  
  (quail-define-package
   "welsh" "Welsh" "\e$,1!4\e(B" t
 - "Welsh postfix input method, using Unicode"
 + "Welsh postfix input method"
   nil t nil nil nil nil nil nil nil nil t)
  
  (quail-define-rules
diff --combined lib-src/makefile.w32-in
index 7b669c42bd455c4e283d5ac0060b9d122206799c,3cb0c264a2307c9534a0f39b69a29e20e8b45e58..0a3045b477d2c4a40fe23eb870c9bf61e53eab20
@@@ -1,6 -1,6 +1,6 @@@
  #  -*- Makefile -*- for GNU Emacs on the Microsoft W32 API.
  #  Copyright (C) 2000, 2001, 2002, 2003, 2004,
- #                2005, 2006 Free Software Foundation, Inc.
+ #                2005, 2006, 2007 Free Software Foundation, Inc.
  #
  #  This file is part of GNU Emacs.
  #
@@@ -24,7 -24,7 +24,7 @@@ ALL = make-docfile hexl ctags etags mov
  
  .PHONY: $(ALL)
  
- VERSION               = 22.0.92
+ VERSION               = 22.0.93
  
  LOCAL_FLAGS   = -DWINDOWSNT -DDOS_NT -DSTDC_HEADERS=1 -DNO_LDAV=1 \
                  -DNO_ARCHIVES=1 -DHAVE_CONFIG_H=1 -I../nt/inc \
@@@ -204,6 -204,16 +204,6 @@@ lisp1= 
        $(lispsource)international/mule-conf.el \
        $(lispsource)international/mule-cmds.elc \
        $(lispsource)international/characters.elc \
 -      $(lispsource)international/ucs-tables.elc \
 -      $(lispsource)international/utf-8.elc \
 -      $(lispsource)international/utf-16.elc \
 -      $(lispsource)international/latin-1.el \
 -      $(lispsource)international/latin-2.el \
 -      $(lispsource)international/latin-3.el \
 -      $(lispsource)international/latin-4.el \
 -      $(lispsource)international/latin-5.el \
 -      $(lispsource)international/latin-8.el \
 -      $(lispsource)international/latin-9.el \
        $(lispsource)fringe.elc \
        $(lispsource)image.elc \
        $(lispsource)international/fontset.elc \
diff --combined lisp/ChangeLog
index 4ab077fedd38a5ca6aa389ddd1b94fb834169e25,306e84c378889310dbbb1a7083f846fb9b8152a9..3b9e3b621b326ea3cb589bf239824f91f36b37ca
+ 2007-01-24  Miles Bader  <miles@gnu.org>
+       * emacs-lisp/bytecomp.el (byte-compile-output-file-form)
+       (byte-compile-output-docform): Bind `print-circle' to t.
+ 2007-01-24  Kenichi Handa  <handa@m17n.org>
+       * international/ja-dic-cnv.el (skkdic-convert): Insert a related
+       file name of the original SKK dictionary file.
+ 2007-01-24  Kim F. Storm  <storm@cua.dk>
+       * ido.el (ido-initial-position): New variable.
+       (ido-read-internal): Set it if default item is specified.
+       (ido-minibuffer-setup): Position cursor accordingly if set.
+       (ido-edit-input): C-e moves to end of input if not already there.
+       (ido-magic-backward-char): C-b does like M-b if prev char is /.
+       Don't switch to buffer mode if repeating C-b at start of input.
+       (ido-toggle-ignore): C-a only toggles ignore at start or end of
+       input; else it moves to start of input.
+       (ido-kill-buffer-at-head, ido-delete-file-at-head): If cursor is
+       not at end of input, delete rest of input, rather than normal op.
+ 2007-01-23  Michael Kifer  <kifer@cs.stonybrook.edu>
+       * viper-keym.el (viper-insert-basic-map): Delete binding for S-TAB.
+       * ediff-util.el (ediff-clone-buffer-for-region-comparison): Change text
+       of message. Activate mark.
+       (ediff-activate-mark): Set transient-mark-mode to t.
+       * ediff.el (ediff-regions-wordwise, ediff-regions-linewise): Doc fix.
+ 2007-01-23  Martin Rudalics  <rudalics@gmx.at>
+       * help-fns.el (describe-variable): Don't suppress display of
+       buffer local value when the value is "large".
+ 2007-01-22  Kim F. Storm  <storm@cua.dk>
+       * ido.el (ido-active): Add xemacs test from ido-minibuffer-setup.
+       (ido-initiate-auto-merge, ido-exhibit, ido-minibuffer-setup)
+       (ido-tidy): Use ido-active.
+ 2007-01-22  Chris Moore  <christopher.ian.moore@gmail.com>  (tiny change)
+       * hexl.el (hexl-mode-exit): Add missing quote.
+ 2007-01-22  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * term/mac-win.el (mac-keyboard-modifier-mask-alist): New constant.
+       (mac-ae-keyboard-modifiers): New function.
+       (mac-handle-toolbar-switch-mode): Use it.
+       (mac-dnd-handle-drag-n-drop-event): Likewise.  Set action to `copy'
+       if keyboard modifiers on drop contain option key.
+       (mac-dnd-drop-data): Add optional argument `action'.
+       (special-event-map): Remove binding for M-drag-n-drop.
+ 2007-01-21  Guanpeng Xu  <herberteuler@hotmail.com>
+       * add-log.el (add-log-current-defun): Use CC Mode functions to
+       find the beginning and end of a defun.
+ 2007-01-21  Nick Roberts  <nickrob@snap.net.nz>
+       * progmodes/gdb-ui.el (gdb-var-create-regexp)
+       (gdb-var-create-handler): Handle value field in GDB output of
+       -var-create.
+       (gdb-max-frames): New variable.
+       (gdb-stack-buffer, gdb-frames-select): Use it.
+       (gdb-info-stack-custom): Help user customize gdb-max-frames,
+       if necessary.
+       (gdb-get-frame-number): Simplify.
+ 2007-01-21  Glenn Morris  <rgm@gnu.org>
+       * net/tramp.el (tramp-perl-encode, tramp-perl-decode):
+       Update copyrights.
+ 2007-01-21  Alan Mackenzie  <acm@muc.de>
+       * progmodes/cc-cmds.el (c-where-wrt-brace-construct): Correct the
+       handling of K&R stuff.
+ 2007-01-21  Roland Winkler  <Roland.Winkler@physik.uni-erlangen.de>
+       * textmodes/bibtex.el (bibtex-files): Fix customization type.
+ 2007-01-21  Vinicius Jose Latorre  <viniciusjl@ig.com.br>
+       * ps-print.el: Handle frame parameters (background and/or foreground
+       colors) changing dynamically.  Reported by Leo <sdl.web@gmail.com>.
+       (ps-print-version): New Version 6.7.1.
+       (ps-x-frame-property, ps-e-frame-parameter): New aliases.
+       (ps-frame-parameter): New fun.
+       (ps-default-fg, ps-default-bg): New default value ('frame-parameter).
+       Fix doc and customization.
+       (ps-begin-job): Get frame parameters (background and/or foreground
+       colors).
+       (ps-do-despool): Ensure ps-printer-name has a valid value.
+ 2007-01-21  Nick Roberts  <nickrob@snap.net.nz>
+       * progmodes/gdb-ui.el (gdb-debug-log): Rename from gdb-debug-ring.
+       (gdb-debug-log-max): Rename from gdb-debug-ring-max.
+       (gud-gdba-marker-filter): Make a value of nil for gdb-debug-ring-max
+       mean unlimited.
+ 2007-01-20  Alan Mackenzie  <acm@muc.de>
+       * progmodes/cc-engine.el (c-in-knr-argdecl): Reformulate to do
+       much more rigorous analysis of putative K&R regions.
+ 2007-01-20  Alan Mackenzie  <acm@muc.de>
+       * progmodes/cc-defs.el (c-go-list-forward, c-go-list-backward):
+       New functions.
+ 2007-01-20  Alan Mackenzie  <acm@muc.de>
+       * progmodes/cc-align.el, progmodes/cc-cmds.el,
+       * progmodes/cc-defs.el, progmodes/cc-engine.el,
+       * progmodes/cc-langs.el, progmodes/cc-styles.el,
+       * progmodes/cc-vars.el: Add my name.
+ 2007-01-20  Chong Yidong  <cyd@stupidchicken.com>
+       * files.el (find-alternate-file): Revert query message to Emacs 21
+       version.
+ 2007-01-20  Eric Hanchrow  <offby1@blarg.net>  (tiny change)
+       * progmodes/cperl-mode.el (cperl-electric-keywords): Document in
+       the doc string how to use personal abbrevs without electric
+       keywords.
+ 2007-01-20  Alin C. Soare  <alinsoar@voila.fr>  (tiny change)
+       * lisp/emacs-lisp/lisp-mode.el (last-sexp-toggle-display):
+       Fixed cursor position when toggle abbreviated display.
+ 2007-01-20  Nick Roberts  <nickrob@snap.net.nz>
+       * t-mouse.el: Update copyright following assignment by
+       Alessandro Rubini.
+ 2007-01-20  Chong Yidong  <cyd@stupidchicken.com>
+       * type-break.el (type-break-demo-hanoi, type-break-demo-life)
+       (type-break-demo-boring): Call read-event instead of read-char.
+ 2007-01-19  Daniel Pfeiffer  <occitan@esperanto.org>  (small change)
+       * progmodes/compile.el: Add handling for makepplog.
+ 2007-01-19  Reiner Steib  <Reiner.Steib@gmx.de>
+       * textmodes/ispell.el (ispell-change-dictionary): Ensure that
+       aspell dictionaries are initialized when called non-interactively.
+ 2007-01-19  Chong Yidong  <cyd@stupidchicken.com>
+       * progmodes/compile.el (compilation-loop): New arg limit.
+       Handle case where the first error is at point-min.
+       (compilation-next-error): New arg to compilation-loop call.
+ 2007-01-18  Bruno Haible  <bruno@clisp.org>  (tiny change)
+       * info.el (Info-default-dirs): Change default info dir to
+       share/info.
+       * paths.el (Info-default-directory-list): Ditto.
+ 2007-01-18  Chris Moore  <christopher.ian.moore@gmail.com>  (tiny change)
+       * hexl.el (hexl-before-revert-hook): New function.
+       (hexl-mode): Use it.
+       (hexl-after-revert-hook): Just call hexl-mode.
+       (hexl-mode-exit): Remove before-revert-hook.
+ 2007-01-17  Stefan Monnier  <monnier@iro.umontreal.ca>
+       * isearch.el (isearch-no-upper-case-p): Look for [:upper:] as well.
+ 2007-01-16  Martin Rudalics  <rudalics@gmx.at>
+       * textmodes/ispell.el (ispell-dictionary-alist-3): Replace "---"
+       by "-" in francais7 otherchars entry.
+       (ispell-dictionary-alist-5): Replace "." by "[.]" for polish
+       otherchars entry.
+ 2007-01-15  Karl Fogel  <kfogel@red-bean.com>
+       * bookmark.el (bookmark-buffer-file-name): Abbreviate the bookmark
+       path.  Rewrite function in `cond' style for readability.
+       Suggested by: Stephen Eglen <S.J.Eglen{_AT_}damtp.cam.ac.uk>.
+       (The path shortening, that is, not the rearrarangement.)
+ 2007-01-15  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * term/mac-win.el (mac-ae-quit-application): New function.
+       (mac-apple-event-map): Bind "quit application" Apple event to it.
+ 2007-01-14  Stefan Monnier  <monnier@iro.umontreal.ca>
+       * vc-svn.el (vc-svn-parse-status): Trust the filename argument more
+       than the program's output.
+ 2007-01-14  Juanma Barranquero  <lekktu@gmail.com>
+       * kmacro.el (kmacro-insert-counter, kmacro-set-counter)
+       (kmacro-start-macro-or-insert-counter)
+       (kmacro-step-edit-prefix-commands): Fix typos in docstrings.
+       (kmacro-call-ring-2nd, kmacro-call-ring-2nd-repeat): Doc fixes.
+       * longlines.el (longlines-show-hard-newlines):
+       * ruler-mode.el (ruler-mode-ruler):
+       * emulation/keypad.el (keypad-setup):
+       * progmodes/antlr-mode.el (antlr-indent-at-bol-alist):
+       Fix typo in docstring.
+ 2007-01-13  Mathias Dahl  <mathias.dahl@gmail.com>
+       * tumme.el (tumme-cmd-rotate-original-options): Add -outfile option.
+       Remove redirect character ">".
+ 2007-01-13  Juanma Barranquero  <lekktu@gmail.com>
+       * replace.el (perform-replace): Remove leftover code.
+ 2007-01-12  Richard Stallman  <rms@gnu.org>
+       * replace.el (perform-replace): Don't clear NODENT when computing
+       the replacement string.
+ 2007-01-11  Michael Albinus  <michael.albinus@gmx.de>
+       * net/tramp.el (tramp-handle-file-local-copy):
+       Set `enable-multibyte-characters' to nil.  Reported by Chris Moore
+       <christopher.ian.moore@gmail.com>.
+ 2007-01-11  Stefan Monnier  <monnier@iro.umontreal.ca>
+       * diff-mode.el (diff-sanity-check-context-hunk-half)
+       (diff-sanity-check-hunk): New functions.
+       (diff-find-source-location): Use'em to check the hunks are well-formed.
+       * hexl.el (hexlify-buffer, dehexlify-buffer): Don't complain and don't
+       activate undo when undo is not active.
+       Reported by Chris Moore <christopher.ian.moore@gmail.com>.
+ 2007-01-10  Stefan Monnier  <monnier@iro.umontreal.ca>
+       * ffap.el (ffap-next-regexp, ffap-machine-p, ffap-newsgroup-regexp)
+       (ffap-newsgroup-p, ffap-alist, ffap-string-at-point-mode-alist)
+       (ffap-url-at-point): Use char-classes rather than "a-z".
+ 2007-01-10  Juanma Barranquero  <lekktu@gmail.com>
+       * ediff-init.el (ediff-autostore-merges):
+       * textmodes/fill.el (fill-region): Doc fix.
+ 2007-01-10  Stefan Monnier  <monnier@iro.umontreal.ca>
+       * server.el (server-ensure-safe-dir): UIDs may be floats.
+ 2007-01-10  Richard Stallman  <rms@gnu.org>
+       * battery.el (battery-linux-proc-acpi): Use ignore-errors
+       around calls to directory-files.
+       * subr.el (momentary-string-display): Use save-excursion.
+       * emacs-lisp/pp.el (pp-eval-expression): Once again eval the
+       argument, but read it as `X' does.
+ 2007-01-09  Juri Linkov  <juri@jurta.org>
+       * info.el (Info-fontify-node): Don't hide node names of index entries.
+       * faces.el (momentary): Change :group to basic-faces where all
+       basic faces belong to.  Add :version.
+ 2007-01-09  Lennart Borgman  <lennart.borgman.073@student.lu.se>
+       * tutorial.el (tutorial--display-changes): Show M-x sequence if no
+       keybinding is found.
+       (tutorial--find-changed-keys): Never treat null keybinding as a
+       remapping.
+ 2007-01-09  Martin Rudalics  <rudalics@gmx.at>
+       * wdired.el (wdired-xcase-word): Skip non-word read-only characters.
+ 2007-01-09  Kenichi Handa  <handa@m17n.org>
+       * international/mule-cmds.el
+       (select-safe-coding-system-interactively): Fix message.
+ 2007-01-09  Michael Albinus  <michael.albinus@gmx.de>
+       * net/tramp.el (tramp-process-one-action): Remove `with-timeout'.
+       (tramp-process-actions): Add optional parameter TIMEOUT.
+       (tramp-open-connection-telnet, tramp-open-connection-rsh)
+       (tramp-open-connection-su): Add timeout of 60".
+ 2007-01-09  Richard Stallman  <rms@gnu.org>
+       * progmodes/compile.el (compile): Doc fix.
+ 2007-01-09  Markus Triska  <markus.triska@gmx.at>
+       * tumme.el (tumme-display-thumb): Doc fix.
+ 2007-01-08  Juanma Barranquero  <lekktu@gmail.com>
+       * battery.el (battery-search-for-one-match-in-files):
+       * bindings.el (mode-line-minor-mode-help):
+       * x-dnd.el (x-dnd-types-alist):
+       * calendar/icalendar.el (icalendar-import-buffer):
+       * term/mac-win.el (mac-dnd-types-alist): Fix typo in docstring.
+       * progmodes/vhdl-mode.el (vhdl-save-caches): Fix typo in error message.
+ 2007-01-07  Chris Moore  <christopher.ian.moore@gmail.com>  (tiny change)
+       * replace.el (replace-regexp): Fix typo in docstring.
+ 2007-01-07  Alan Mackenzie  <acm@muc.de>
+       * progmodes/cc-langs.el (c-operators, c-filter-ops):
+       Amend doc-string and comments.
+ 2007-01-06  Eli Zaretskii  <eliz@gnu.org>
+       * files.el (abbreviate-file-name): Doc fix.
+ 2007-01-06  Markus Triska  <triska@gmx.at>
+       * subr.el (split-string): Remove spurious ")" from doc string.
+ 2007-01-05  Takaaki Ota  <Takaaki.Ota@am.sony.com>
+       * textmodes/table.el (table--warn-incompatibility):
+       Use display-warning instead of momentary-string-display.
+ 2007-01-05  Richard Stallman  <rms@gnu.org>
+       * image.el (image-type-header-regexps): Recognize xbm more strictly.
+       * simple.el (backward-kill-word): Doc fix.
+ 2007-01-05  Romain Francoise  <romain@orebokech.com>
+       * international/mule.el (sgml-html-meta-auto-coding-function):
+       Ensure that the buffer contains a HTML document.
+ 2007-01-05  Dan Nicolaescu  <dann@ics.uci.edu>
+       * faces.el (momentary): Move here ...
+       * subr.el (momentary): ... from here.
+ 2007-01-05  Nick Roberts  <nickrob@snap.net.nz>
+       * progmodes/gdb-ui.el (gdb-max-children): New customizable variable.
+       (gdb-speedbar-expand-node): Ask user for confirmation before expanding
+       large structures/arrays.
+ 2007-01-04  Juanma Barranquero  <lekktu@gmail.com>
+       * files.el (find-file-noselect-1, set-visited-file-name):
+       Allow backup-enable-predicate to be nil.
+ 2007-01-04  Kevin Rodgers  <kevin.d.rodgers@gmail.com>
+       * subr.el (momentary): New face.
+       (momentary-string-display): Display the string via a temporary
+       overlay using the new face, instead of inserting it in the buffer.
+ 2007-01-04  Andreas Schwab  <schwab@suse.de>
+       * progmodes/ebrowse.el (ebrowse-global-prefix-key): Fix typo in
+       last change.
+ 2007-01-03  Richard Stallman  <rms@gnu.org>
+       * woman.el (woman-decode-buffer): Clarify error message.
+ 2007-01-03  Alan Mackenzie  <acm@muc.de>
+       * progmode/cc-cmds.el (c-mask-paragraph): Fix yesterday's buggy
+       patch.
+ 2007-01-03  Chris Moore  <christopher.ian.moore@gmail.com>  (tiny change)
+       * tutorial.el (tutorial--describe-nonstandard-key): Fix typo.
+ 2007-01-03  Stefan Monnier  <monnier@iro.umontreal.ca>
+       * iswitchb.el (iswitchb-global-map): Use command-remapping if available.
+ 2007-01-02  Juanma Barranquero  <lekktu@gmail.com>
+       * emulation/viper.el (viper-custom-file-name, viper-mode):
+       Fix typos in docstrings.
+       * subr.el (momentary-string-display): After moving point, set POS
+       variable to it to avoid later errors once the buffer is modified.
+       Doc fix.
+ 2007-01-02  Alan Mackenzie  <acm@muc.de>
+       * progmodes/cc-cmds.el (c-mask-paragraph): In a block comment,
+       check that the "*/" is present before trying to manipulate it.
+ 2007-01-02  Richard Stallman  <rms@gnu.org>
+       * wid-edit.el (widget-choose): Avoid ugly error for function keys.
+       * progmodes/cfengine.el (cfengine-font-lock-syntactic-keywords):
+       Fix format of value.
+       * cus-edit.el (customize-unsaved): Rename from customize-customized.
+       Change messages accordingly.
+       (customize-customized): Now alias.
  2007-01-02  Juanma Barranquero  <lekktu@gmail.com>
  
        * files.el (version-control): Doc fix.
  
  2007-01-01  Alan Mackenzie  <acm@muc.de>
  
-       * progmodes/cc-engine.el (c-guess-basic-syntax, case 5N): Check
-       the format of c-state-cache is valid for an optimisation before
+       * progmodes/cc-engine.el (c-guess-basic-syntax, case 5N):
+       Check the format of c-state-cache is valid for an optimisation before
        using it.
  
        * progmodes/cc-engine.el (c-guess-basic-syntax): New case 5Q "we
        the first continuation line in a macro gets the symbol
        `cpp-define-intro', the others getting `statement', or whatever.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-cmds.el (c-context-line-break): When invoked within
        a string, preserve whitespace.  Add a backslash only when also in
        a macro.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-defs.el: Correct typos.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-cmds.el (c-context-line-break): Don't indent the
        new line after an escaped EOL in a string.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-engine.el (c-forward-label): Recognise "foo:" as a
        label when it directly follows "else", "do", ....
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-engine.el (c-backward-<>-arglist): Tolerate empty
        angle brackets (as seen in "explicit specialisations" of C++
        templates).
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-vars.el (c-indentation-style): Mention c-file-style
        in the doc-string.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-cmds.el (c-mask-paragraph): Fix for C comments,
        when the comment ender looks like "=========*/" and is alone on
        its line.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-langs.el, progmodes/cc-engine.el: Correct the
        spelling of c-opt-op-identiTier-prefix, t -> f.  Leave an alias
        for the old name.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-mode.el: Bind C-M-a and C-M-e to
        c-\(beginning\|end\)-of-defun by default.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
-       * progmodes/cc-align.el (c-lineup-gnu-DEFUN-intro-cont): New
-       line-up function, for the DEFUN macro in the Emacs C sources.
+       * progmodes/cc-align.el (c-lineup-gnu-DEFUN-intro-cont):
+       New line-up function, for the DEFUN macro in the Emacs C sources.
        Only used in "gnu" style.
  
        * progmodes/cc-styles.el (c-style-alist): Use this new function in
        the "gnu" style.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-cmds.el (c-electric-slash): Extend the handling of
        clean-up comment-close-slash also to work when there's a comment
        terminator on the line.
        (c-backward-to-nth-BOF-{, c-forward-to-nth-EOF-}): New functions to
        support c-\(beginning\|end\)-of-defun.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-engine.el (c-forward-label): Analyze ":"
        expressions more rigorously, to exclude bit-field specifiers from
        being classed as labels.
        (c-beginning-of-decl-1): Whilst searching for "=" as evidence of a
        stmt boundary, check for "operator=", etc.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
-       * progmodes/cc-mode.el (c-postprocess-file-styles): Bind
-       inhibit-read-only to t, around the call to
+       * progmodes/cc-mode.el (c-postprocess-file-styles):
+       Bind inhibit-read-only to t, around the call to
        c-remove-any-local-eval-or-mode-variables, so that it works on a
        RO file.
  
- 2007-01-01  Alan Mackenzie  <acm@muc.de>
        * progmodes/cc-defs.el (c-version): Update the version number to
        "5.31.4".
  
        * ido.el (ido-set-matches-1): Fix last change.  If default item is
        current buffer, it is ok to be first.
  
+ 2006-12-27  Kenichi Handa  <handa@m17n.org>
+       * international/mule-cmds.el (select-safe-coding-system-interactively):
+       Use face `link' for problematic chars.
  2006-12-27  Kenichi Handa  <handa@m17n.org>
  
        * international/mule-cmds.el (select-safe-coding-system-interactively):
        (image-type-from-buffer): Handle new format.  New arg INCLUDE-MAYBES.
        (image-type-from-file-header): Pass t for INCLUDE-MAYBES.
  
- 2006-12-26  Guanpeng Xu  <herberteuler@hotmail.com>  (tiny change)
+ 2006-12-26  Guanpeng Xu  <herberteuler@hotmail.com>
  
        * add-log.el (add-log-current-defun): Call `forward-sexp'
        multiple times to pick a member function name defined as
  
  2006-12-25  Michael R. Mauger  <mmaug@yahoo.com>
  
-       * progmodes/sql.el (sql-mode-abbrev-table): Corrected initialization.
+       * progmodes/sql.el (sql-mode-abbrev-table): Correct initialization.
        (sql-mode-syntax-table): Disable double quoted strings.
-       (sql-mode-font-lock-object-name): Added TYPE and TYPE BODY.
+       (sql-mode-font-lock-object-name): Add TYPE and TYPE BODY.
  
  2006-12-25  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
  
  
  2006-10-19  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
  
-       * select.el (ccl-check-utf-8, string-utf-8-p): New functions
-       (by Kenichi Handa).
+       * select.el (ccl-check-utf-8, string-utf-8-p): New functions (by
+       Kenichi Handa).
        (xselect-convert-to-string): Decline requests for UTF8_STRING if
        the selection is not UTF-8.
  
        * textmodes/table.el: Add move-beginning-of-line and
        move-end-of-line to Point Motion Only Group.
  
- 2006-07-22  Eric Hanchrow  <offby1@blarg.net>
+ 2006-07-22  Eric Hanchrow  <offby1@blarg.net>  (tiny change)
  
        * progmodes/delphi.el (delphi-fill-comment): Use save-restriction.
  
  2006-05-11  Reiner Steib  <Reiner.Steib@gmx.de>
  
        * files.el, newcomment.el, outline.el, simple.el,
-       emacs-lisp/bytecomp.el, progmodes/cc-compat.el,
-       progmodes/cc-vars.el, progmodes/compile.el:
+       emacs-lisp/bytecomp.el, progmodes/cc-compat.el,
+       progmodes/cc-vars.el, progmodes/compile.el:
        Move `safe-local-variable' declarations to the respective files.
  
        * help-fns.el (describe-variable): Don't print safe-var if it is
        Sync with Tramp 2.0.52.
  
        * net/tramp.el, net/tramp-ftp.el, net/tramp-util.el,
-       net/tramp-vc.el: Add code for unloading Tramp.  See comment before
+       net/tramp-vc.el: Add code for unloading Tramp.  See comment before
        `tramp-unload-tramp' for checklist.
  
        * net/tramp.el: Require `timer-funcs' instead of `timer' if in
        * elide-head.el (elide-head-headers-to-hide): Recognize the FSF's
        new address as well.
  
 -2005-07-07  Kenichi Handa  <handa@m17n.org>
 -
 -      * international/mule.el (make-coding-system):
 -      Describe `ascii-incompatible' property in the docstring.
 -      (set-file-name-coding-system): Signal an error if coding-system is
 -      ascii-incompatible.
 -      (set-keyboard-coding-system): Likewise.
 -
 -      * international/mule-cmds.el (set-default-coding-systems):
 -      Don't set default-file-name-coding-system and
 -      default-keyboard-coding-system if coding-system is ASCII-incompatible.
 -
 -      * international/utf-16.el: Declare that all UTF-16-based coding
 -      systems are ASCII-incompatible.
 -
  2005-07-07  Nick Roberts  <nickrob@snap.net.nz>
  
        * progmodes/gud.el: Require font-lock for displaying errors.
@@@ -30556,7 -30975,7 +30960,7 @@@ See ChangeLog.11 for earlier changes
  ;; add-log-time-zone-rule: t
  ;; End:
  
-     Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+     Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
    Copying and distribution of this file, with or without modification,
    are permitted provided the copyright notice and this notice are preserved.
  
diff --combined lisp/ChangeLog.10
index b626a61c8d366f56b375f0f4f0a54173cbfe9533,02affab175fef5178cb598a78971f744cac854e7..3eae5a69401e7c66031c5556cbee9e1748d96e7d
        (face-spec-set): Set face-modified prop to nil
        when we change the new-frame defaults.
  
 -      * cus-edit.el (custom-face-state-set): Non-nil `face-modified'
 +      * cus-edit.el (custom-face-state-set): non-nil `face-modified'
        means face was set outside of Custom.
  
  2003-05-28  Richard M. Stallman  <rms@gnu.org>
        (gdb-display-source-buffer): Display assembler during execution,
        when requested.
        (gud-menu-map): Add a toggle button to menubar for gdb-many-windows.
 -      (gdb-many-windows): Define explicitly as a function and a variable
 +      (gdb-many-windows): Define explicitly as a function and a variable.
        (formerly as a minor mode).  These need to be global so layout can
        be reset from any buffer.
        (gdb-assembler-mode): Keep fringe outside margin as the overlay
        (ada-set-default-project-file): New parameter KEEP-EXISTING.
        (ada-prj-find-prj-file): New parameter FILE.
        (ada-parse-prj-file): Take into account the ADA_INCLUDE_PATH and
 -      ADA_OBJECTS_PATH environment variables.  Minor reorganization of
 -      the code.
 +      ADA_OBJECTS_PATH environment variables.  Minor reorganization of the
 +      code.
        (ada-get-all-references): Add support for GNAT 3.16 cross-references.
  
        * progmodes/ada-prj.el (ada-prj-add-keymap): Move to ada-mode.el
@@@ -23533,7 -23533,7 +23533,7 @@@ See ChangeLog.9 for earlier changes
  ;; coding: iso-2022-7bit
  ;; End:
  
-     Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+     Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
      Free Software Foundation, Inc.
    Copying and distribution of this file, with or without modification,
    are permitted provided the copyright notice and this notice are preserved.
diff --combined lisp/Makefile.in
index ae7afb0ff1cb14769642f527350ae8e77ad730bd,6ddc0b56f4685612b54ef65e0f1981b5e45acb19..9c3d9ce7187f9b527141d86cf88dfe601286dc86
@@@ -1,6 -1,6 +1,6 @@@
  # Maintenance productions for the Lisp directory
  # Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,
- #   2006 Free Software Foundation, Inc.
+ #   2006, 2007 Free Software Foundation, Inc.
  
  # This file is part of GNU Emacs.
  
@@@ -46,9 -46,7 +46,9 @@@ AUTOGENEL = loaddefs.el 
        finder-inf.el \
        subdirs.el \
        eshell/esh-groups.el \
 -      mh-e/mh-loaddefs.el
 +      mh-e/mh-loaddefs.el \
 +      international/charprop.el \
 +      international/uni-*.el
  
  # Files to compile before others during a bootstrap.  This is done to
  # speed up the bootstrap process.  The CC files are compiled first
@@@ -65,7 -63,7 +65,7 @@@ COMPILE_FIRST = 
  
  # The actual Emacs command run in the targets below.
  
 -emacs = EMACSLOADPATH=$(lisp) $(EMACS) $(EMACSOPT)
 +emacs = EMACSLOADPATH=$(lisp) LC_ALL=C $(EMACS) $(EMACSOPT)
  
  # Common command to find subdirectories
  
@@@ -92,12 -90,12 +92,12 @@@ $(lisp)/cus-load.el
  custom-deps: $(lisp)/cus-load.el doit
        wd=$(lisp); $(setwins_almost); \
        echo Directories: $$wins; \
 -      $(EMACS) $(EMACSOPT) -l cus-dep --eval '(setq generated-custom-dependencies-file "$(lisp)/cus-load.el")' -f custom-make-dependencies $$wins
 +      LC_ALL=C $(EMACS) $(EMACSOPT) -l cus-dep --eval '(setq generated-custom-dependencies-file "$(lisp)/cus-load.el")' -f custom-make-dependencies $$wins
  
  finder-data: doit
        wd=$(lisp); $(setwins_almost); \
        echo Directories: $$wins; \
 -      $(EMACS) $(EMACSOPT) -l finder --eval '(setq generated-finder-keywords-file "$(lisp)/finder-inf.el")' -f finder-compile-keywords-make-dist $$wins
 +      LC_ALL=C $(EMACS) $(EMACSOPT) -l finder --eval '(setq generated-finder-keywords-file "$(lisp)/finder-inf.el")' -f finder-compile-keywords-make-dist $$wins
  
  $(lisp)/loaddefs.el:
        echo ";;; loaddefs.el --- automatically extracted autoloads" >> $@
  autoloads: $(lisp)/loaddefs.el doit
        wd=$(lisp); $(setwins_almost); \
        echo Directories: $$wins; \
 -      $(EMACS) $(EMACSOPT) -l autoload --eval '(setq generated-autoload-file "$(lisp)/loaddefs.el")' -f batch-update-autoloads $$wins
 +      LC_ALL=C $(EMACS) $(EMACSOPT) -l autoload --eval '(setq generated-autoload-file "$(lisp)/loaddefs.el")' -f batch-update-autoloads $$wins
  
  $(lisp)/subdirs.el:
        $(MAKE) $(MFLAGS) update-subdirs
@@@ -212,7 -210,7 +212,7 @@@ compile-after-backup: backup-compiled-f
  # new ones.
  
  recompile: doit mh-autoloads $(lisp)/progmodes/cc-mode.elc
 -      $(EMACS) $(EMACSOPT) --eval "(batch-byte-recompile-directory 0)" $(lisp)
 +      LC_ALL=C $(EMACS) $(EMACSOPT) --eval "(batch-byte-recompile-directory 0)" $(lisp)
  
  # CC Mode uses a compile time macro system which causes a compile time
  # dependency in cc-mode.elc on the macros in cc-langs.el and the
@@@ -244,7 -242,7 +244,7 @@@ mh-autoloads: $(lisp)/mh-e/mh-loaddefs.
  $(lisp)/mh-e/mh-loaddefs.el: $(MH_E_SRC)
        echo ";;; mh-loaddefs.el --- automatically extracted autoloads" > $@
        echo "" >> $@
-       echo ";; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc." >> $@
+       echo ";; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc." >> $@
        echo ";; Author: Bill Wohler <wohler@newt.com>" >> $@
        echo ";; Keywords: mail" >> $@
        echo ";;; Commentary:" >> $@
diff --combined lisp/arc-mode.el
index 9cfee88fc1a8cda74cfe5514b6e9916a37c8eea3,1b0f3a3d5847dda25ff5157a815d97aad80b50f5..07a48c761aa5a9ea2ea35011e89b9907f0fadd52
@@@ -1,7 -1,7 +1,7 @@@
  ;;; arc-mode.el --- simple editing of archives
  
  ;; Copyright (C) 1995, 1997, 1998, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Morten Welinder <terra@gnu.org>
  ;; Keywords: archives msdog editing major-mode
@@@ -452,10 -452,6 +452,10 @@@ Archive and member name will be added.
  (make-variable-buffer-local 'archive-subfile-mode)
  (put 'archive-subfile-mode 'permanent-local t)
  
 +(defvar archive-file-name-coding-system nil)
 +(make-variable-buffer-local 'archive-file-name-coding-system)
 +(put 'archive-file-name-coding-system 'permanent-local t)
 +
  (defvar archive-files nil
    "Vector of file descriptors.
  Each descriptor is a vector of the form
  ;; -------------------------------------------------------------------------
  ;; Section: Support functions.
  
 +(eval-when-compile
 +  (defsubst byte-after (pos)
 +    "Like char-after but an eight-bit char is converted to unibyte."
 +    (multibyte-char-to-unibyte (char-after pos)))
 +  (defsubst insert-unibyte (&rest args)
 +    "Like insert but don't make unibyte string and eight-bit char multibyte."
 +    (dolist (elt args)
 +      (if (integerp elt)
 +        (insert (if (< elt 128) elt (decode-char 'eight-bit elt)))
 +      (insert (string-to-multibyte elt)))))
 +  )
 +
  (defsubst archive-name (suffix)
    (intern (concat "archive-" (symbol-name archive-subtype) "-" suffix)))
  
@@@ -489,7 -473,6 +489,7 @@@ FLOAT, if non-nil, means generate and r
    (if (stringp str)
        (setq len (length str))
      (setq str (buffer-substring str (+ str len))))
 +  (setq str (string-as-unibyte str))
    (let ((result 0)
          (i 0))
      (while (< i len)
@@@ -694,12 -677,6 +694,12 @@@ archive
        (make-local-variable 'archive-file-list-start)
        (make-local-variable 'archive-file-list-end)
        (make-local-variable 'archive-file-name-indent)
 +      (setq archive-file-name-coding-system
 +          (or file-name-coding-system
 +              default-file-name-coding-system
 +              locale-coding-system))
 +      (if default-enable-multibyte-characters
 +        (set-buffer-multibyte 'to))
        (archive-summarize nil)
        (setq buffer-read-only t))))
  
@@@ -733,6 -710,7 +733,6 @@@ is visible (and the real data of the bu
  Optional argument SHUT-UP, if non-nil, means don't print messages
  when parsing the archive."
    (widen)
 -  (set-buffer-multibyte nil)
    (let ((inhibit-read-only t))
      (or shut-up
        (message "Parsing archive file..."))
@@@ -940,8 -918,7 +940,8 @@@ using `make-temp-file', and the generat
                          (string-match file-name-invalid-regexp ename)))
         (arcfilename (expand-file-name (concat arcname ":" iname)))
           (buffer (get-buffer bufname))
 -         (just-created nil))
 +         (just-created nil)
 +       (file-name-coding archive-file-name-coding-system))
        (if (and buffer
               (string= (buffer-file-name buffer) arcfilename))
            nil
            (setq archive-superior-buffer archive-buffer)
            (add-hook 'write-file-functions 'archive-write-file-member nil t)
            (setq archive-subfile-mode descr)
 +        (setq archive-file-name-coding-system file-name-coding)
          (if (and
               (null
                (let (;; We may have to encode file name arguement for
                      ;; external programs.
                      (coding-system-for-write
                       (and enable-multibyte-characters
 -                          file-name-coding-system))
 +                          archive-file-name-coding-system))
                      ;; We read an archive member by no-conversion at
                      ;; first, then decode appropriately by calling
                      ;; archive-set-buffer-as-visiting-file later.
          (if (aref descr 3)
              ;; Set the file modes, but make sure we can read it.
              (set-file-modes tmpfile (logior ?\400 (aref descr 3))))
 -        (if enable-multibyte-characters
 -            (setq ename
 -                  (encode-coding-string ename file-name-coding-system)))
 -          (let ((exitcode (apply 'call-process
 -                                 (car command)
 -                                 nil
 -                                 nil
 -                                 nil
 -                                 (append (cdr command) (list archive ename)))))
 +        (setq ename
 +              (encode-coding-string ename archive-file-name-coding-system))
 +          (let* ((coding-system-for-write 'no-conversion)
 +               (exitcode (apply 'call-process
 +                                (car command)
 +                                nil
 +                                nil
 +                                nil
 +                                (append (cdr command)
 +                                        (list archive ename)))))
              (if (equal exitcode 0)
                  nil
                (error "Updating was unsuccessful (%S)" exitcode))))
@@@ -1325,8 -1300,9 +1325,8 @@@ as a relative change like \"g+rw\" as f
      (if (fboundp func)
          (progn
          (funcall func
 -                 (if enable-multibyte-characters
 -                     (encode-coding-string newname file-name-coding-system)
 -                   newname)
 +                 (encode-coding-string newname
 +                                       archive-file-name-coding-system)
                   descr)
          (archive-resummarize))
        (error "Renaming is not supported for this archive type"))))
      (setq archive-files nil)
      (let ((revert-buffer-function nil)
          (coding-system-for-read 'no-conversion))
 -      (set-buffer-multibyte nil)
        (revert-buffer t t))
      (archive-mode)
      (goto-char archive-file-list-start)
@@@ -1358,12 -1335,11 +1358,12 @@@ This doesn't recover lost files, it jus
          files
        visual)
      (while (and (< (+ p 29) (point-max))
 -              (= (char-after p) ?\C-z)
 -              (> (char-after (1+ p)) 0))
 +              (= (byte-after p) ?\C-z)
 +              (> (byte-after (1+ p)) 0))
        (let* ((namefld (buffer-substring (+ p 2) (+ p 2 13)))
             (fnlen   (or (string-match "\0" namefld) 13))
 -           (efnname (substring namefld 0 fnlen))
 +           (efnname (decode-coding-string (substring namefld 0 fnlen)
 +                                          archive-file-name-coding-system))
             ;; Convert to float to avoid overflow for very large files.
               (csize   (archive-l-e (+ p 15) 4 'float))
               (moddate (archive-l-e (+ p 19) 2))
      (save-restriction
        (save-excursion
        (widen)
 -      (set-buffer-multibyte nil)
        (goto-char (+ archive-proper-file-start (aref descr 4) 2))
        (delete-char 13)
 -      (insert name)))))
 +      (insert-unibyte name)))))
  ;; -------------------------------------------------------------------------
  ;; Section: Lzh Archives
  
        visual)
      (while (progn (goto-char p)               ;beginning of a base header.
                  (looking-at "\\(.\\|\n\\)\\(.\\|\n\\)-l[hz][0-9ds]-"))
 -      (let* ((hsize   (char-after p)) ;size of the base header (level 0 and 1)
 +      (let* ((hsize   (byte-after p)) ;size of the base header (level 0 and 1)
             ;; Convert to float to avoid overflow for very large files.
             (csize   (archive-l-e (+ p 7) 4 'float)) ;size of a compressed file to follow (level 0 and 2),
                                        ;size of extended headers + the compressed file to follow (level 1).
               (ucsize  (archive-l-e (+ p 11) 4 'float))        ;size of an uncompressed file.
             (time1   (archive-l-e (+ p 15) 2)) ;date/time (MSDOS format in level 0, 1 headers
             (time2   (archive-l-e (+ p 17) 2)) ;and UNIX format in level 2 header.)
 -           (hdrlvl  (char-after (+ p 20))) ;header level
 +           (hdrlvl  (byte-after (+ p 20))) ;header level
             thsize             ;total header size (base + extensions)
             fnlen efnname fiddle ifnname width p2
             neh        ;beginning of next extension header (level 1 and 2)
             gname uname modtime moddate)
        (if (= hdrlvl 3) (error "can't handle lzh level 3 header type"))
        (when (or (= hdrlvl 0) (= hdrlvl 1))
 -        (setq fnlen   (char-after (+ p 21))) ;filename length
 +        (setq fnlen   (byte-after (+ p 21))) ;filename length
          (setq efnname (let ((str (buffer-substring (+ p 22) (+ p 22 fnlen)))) ;filename from offset 22
 -                      (if file-name-coding-system
 -                          (decode-coding-string str file-name-coding-system)
 -                        (string-as-multibyte str))))
 +                      (decode-coding-string
 +                       str archive-file-name-coding-system)))
          (setq p2      (+ p 22 fnlen))) ;
        (if (= hdrlvl 1)
              (setq neh (+ p2 3))         ;specific to level 1 header
                (setq neh (+ p 24))))     ;specific to level 2 header
        (if neh         ;if level 1 or 2 we expect extension headers to follow
            (let* ((ehsize (archive-l-e neh 2)) ;size of the extension header
 -                 (etype (char-after (+ neh 2)))) ;extension type
 +                 (etype (byte-after (+ neh 2)))) ;extension type
              (while (not (= ehsize 0))
                  (cond
                 ((= etype 1)   ;file name
                  (let ((i (+ neh 3)))
                    (while (< i (+ neh ehsize))
 -                    (setq efnname (concat efnname (char-to-string (char-after i))))
 +                    (setq efnname (concat efnname (char-to-string (byte-after i))))
                      (setq i (1+ i)))))
                 ((= etype 2)   ;directory name
                  (let ((i (+ neh 3)))
                    (while (< i (+ neh ehsize))
                                    (setq dir (concat dir
 -                                                     (if (= (char-after i)
 +                                                     (if (= (byte-after i)
                                                              255)
                                                           "/"
                                                         (char-to-string
                   )
                (setq neh (+ neh ehsize))
                (setq ehsize (archive-l-e neh 2))
 -              (setq etype (char-after (+ neh 2))))
 +              (setq etype (byte-after (+ neh 2))))
              ;;get total header size for level 1 and 2 headers
              (setq thsize (- neh p))))
        (if (= hdrlvl 0)  ;total header size
               (setq p (+ p thsize 2 (round csize)))))
        ))
      (goto-char (point-min))
 -    (set-buffer-multibyte default-enable-multibyte-characters)
      (let ((dash (concat (if archive-alternate-display
                            "- --------  -----  -----  "
                          "- ----------  --------  -----------  --------  ")
    (let ((sum 0))
      (while (> count 0)
        (setq count (1- count)
 -          sum (+ sum (char-after p))
 +          sum (+ sum (byte-after p))
            p (1+ p)))
      (logand sum 255)))
  
    (save-restriction
      (save-excursion
        (widen)
 -      (set-buffer-multibyte nil)
        (let* ((p        (+ archive-proper-file-start (aref descr 4)))
 -           (oldhsize (char-after p))
 -           (oldfnlen (char-after (+ p 21)))
 +           (oldhsize (byte-after p))
 +           (oldfnlen (byte-after (+ p 21)))
             (newfnlen (length newname))
             (newhsize (+ oldhsize newfnlen (- oldfnlen)))
             (inhibit-read-only t))
            (error "The file name is too long"))
        (goto-char (+ p 21))
        (delete-char (1+ oldfnlen))
 -      (insert newfnlen newname)
 +      (insert-unibyte newfnlen newname)
        (goto-char p)
        (delete-char 2)
 -      (insert newhsize (archive-lzh-resum p newhsize))))))
 +      (insert-unibyte newhsize (archive-lzh-resum p newhsize))))))
  
  (defun archive-lzh-ogm (newval files errtxt ofs)
    (save-excursion
      (save-restriction
        (widen)
 -      (set-buffer-multibyte nil)
        (dolist (fil files)
        (let* ((p (+ archive-proper-file-start (aref fil 4)))
 -             (hsize   (char-after p))
 -             (fnlen   (char-after (+ p 21)))
 +             (hsize   (byte-after p))
 +             (fnlen   (byte-after (+ p 21)))
               (p2      (+ p 22 fnlen))
 -             (creator (if (>= (- hsize fnlen) 24) (char-after (+ p2 2)) 0))
 +             (creator (if (>= (- hsize fnlen) 24) (byte-after (+ p2 2)) 0))
               (inhibit-read-only t))
          (if (= creator ?U)
              (progn
                    (setq newval (funcall newval (archive-l-e (+ p2 ofs) 2))))
                (goto-char (+ p2 ofs))
                (delete-char 2)
 -              (insert (logand newval 255) (lsh newval -8))
 +              (insert-unibyte (logand newval 255) (lsh newval -8))
                (goto-char (1+ p))
                (delete-char 1)
 -              (insert (archive-lzh-resum (1+ p) hsize)))
 +              (insert-unibyte (archive-lzh-resum (1+ p) hsize)))
            (message "Member %s does not have %s field"
                     (aref fil 1) errtxt)))))))
  
          files
        visual)
      (while (string= "PK\001\002" (buffer-substring p (+ p 4)))
 -      (let* ((creator (char-after (+ p 5)))
 +      (let* ((creator (byte-after (+ p 5)))
             ;; (method  (archive-l-e (+ p 10) 2))
               (modtime (archive-l-e (+ p 12) 2))
               (moddate (archive-l-e (+ p 14) 2))
               (fclen   (archive-l-e (+ p 32) 2))
               (lheader (archive-l-e (+ p 42) 4))
               (efnname (let ((str (buffer-substring (+ p 46) (+ p 46 fnlen))))
 -                      (if file-name-coding-system
 -                          (decode-coding-string str file-name-coding-system)
 -                        (string-as-multibyte str))))
 +                      (decode-coding-string
 +                       str archive-file-name-coding-system)))
             (isdir   (and (= ucsize 0)
                           (string= (file-name-nondirectory efnname) "")))
             (mode    (cond ((memq creator '(2 3)) ; Unix + VMS
                             (logior ?\444
                                     (if isdir (logior 16384 ?\111) 0)
                                     (if (zerop
 -                                        (logand 1 (char-after (+ p 38))))
 +                                        (logand 1 (byte-after (+ p 38))))
                                         ?\222 0)))
                            (t nil)))
             (modestr (if mode (archive-int-to-mode mode) "??????????"))
    (save-restriction
      (save-excursion
        (widen)
 -      (set-buffer-multibyte nil)
        (dolist (fil files)
        (let* ((p (+ archive-proper-file-start (car (aref fil 4))))
 -             (creator (char-after (+ p 5)))
 +             (creator (byte-after (+ p 5)))
               (oldmode (aref fil 3))
               (newval  (archive-calc-mode oldmode newmode t))
               (inhibit-read-only t))
          (cond ((memq creator '(2 3)) ; Unix + VMS
                 (goto-char (+ p 40))
                 (delete-char 2)
 -               (insert (logand newval 255) (lsh newval -8)))
 +               (insert-unibyte (logand newval 255) (lsh newval -8)))
                ((memq creator '(0 5 6 7 10 11 15)) ; Dos etc.
                 (goto-char (+ p 38))
 -               (insert (logior (logand (char-after (point)) 254)
 -                               (logand (logxor 1 (lsh newval -7)) 1)))
 +               (insert-unibyte (logior (logand (byte-after (point)) 254)
 +                                       (logand (logxor 1 (lsh newval -7)) 1)))
                 (delete-char 1))
                (t (message "Don't know how to change mode for this member"))))
          ))))
             ;; Convert to float to avoid overflow for very large files.
               (ucsize  (archive-l-e (+ p 20) 4 'float))
             (namefld (buffer-substring (+ p 38) (+ p 38 13)))
 -           (dirtype (char-after (+ p 4)))
 -           (lfnlen  (if (= dirtype 2) (char-after (+ p 56)) 0))
 -           (ldirlen (if (= dirtype 2) (char-after (+ p 57)) 0))
 +           (dirtype (byte-after (+ p 4)))
 +           (lfnlen  (if (= dirtype 2) (byte-after (+ p 56)) 0))
 +           (ldirlen (if (= dirtype 2) (byte-after (+ p 57)) 0))
             (fnlen   (or (string-match "\0" namefld) 13))
             (efnname (let ((str
                             (concat
                                  (buffer-substring (+ p 58)
                                                    (+ p 58 lfnlen -1))
                                (substring namefld 0 fnlen)))))
 -                      (if file-name-coding-system
 -                          (decode-coding-string str file-name-coding-system)
 -                        (string-as-multibyte str))))
 +                      (decode-coding-string
 +                       str archive-file-name-coding-system)))
             (fiddle  (and (= lfnlen 0) (string= efnname (upcase efnname))))
               (ifnname (if fiddle (downcase efnname) efnname))
             (width (string-width ifnname))
diff --combined lisp/bindings.el
index 591e8aad122e2b7d8ee39791714f4ee7a43e149c,b0c0b87c7eef9dbd8fef646a41d12984a1d4fd79..a8fda72bbffbf52cb743a100b7a3b9d3e026552b
@@@ -1,7 -1,7 +1,7 @@@
  ;;; bindings.el --- define standard key bindings and some variables
  
  ;; Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994, 1995, 1996, 1999,
- ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: internal
@@@ -468,7 -468,7 +468,7 @@@ Menu of mode operations in the mode lin
    (x-popup-menu event mode-line-mode-menu))
  
  (defun mode-line-minor-mode-help (event)
-   "Describe minor mode for EVENT occured on minor modes area of the mode line."
+   "Describe minor mode for EVENT occurred on minor modes area of the mode line."
    (interactive "@e")
    (let ((indicator (car (nth 4 (car (cdr event))))))
      (describe-minor-mode-from-indicator indicator)))
@@@ -597,6 -597,12 +597,6 @@@ language you are using.
  ;; that we will not need to keep permanently.
  (garbage-collect)
  \f
 -;; Make all multibyte characters self-insert.
 -(let ((l (generic-character-list))
 -      (table (nth 1 global-map)))
 -  (while l
 -    (aset table (car l) 'self-insert-command)
 -    (setq l (cdr l))))
  
  (setq help-event-list '(help f1))
  
diff --combined lisp/case-table.el
index be4b48439f3d4caec9e609e1ee738f3363daf05b,64cf69ba2bfb660f30d0fbe3a40813a9d7ad71c4..878500cc4417b357774e7c074e79aa9f0d76419b
@@@ -1,7 -1,7 +1,7 @@@
  ;;; case-table.el --- code to extend the character set and support case tables
  
  ;; Copyright (C) 1988, 1994, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Howard Gayle
  ;; Maintainer: FSF
  
  ;;; Code:
  
 -(defvar set-case-syntax-offset 0)
 -
 -(defvar set-case-syntax-set-multibyte nil)
 -
  (defun describe-buffer-case-table ()
    "Describe the case table of the current buffer."
    (interactive)
    (let ((description (make-char-table 'case-table)))
      (map-char-table
       (function (lambda (key value)
 -               (aset
 -                description key
 -                (cond ((not (natnump value))
 -                       "case-invariant")
 -                      ((/= key (downcase key))
 -                       (concat "uppercase, matches "
 -                               (char-to-string (downcase key))))
 -                      ((/= key (upcase key))
 -                       (concat "lowercase, matches "
 -                               (char-to-string (upcase key))))
 -                      (t "case-invariant")))))
 +               (if (consp key)
 +                   (set-char-table-range description key "case-invariant")
 +                 (aset
 +                  description key
 +                  (cond ((not (natnump value))
 +                         "case-invariant")
 +                        ((/= key (downcase key))
 +                         (concat "uppercase, matches "
 +                                 (char-to-string (downcase key))))
 +                        ((/= key (upcase key))
 +                         (concat "lowercase, matches "
 +                                 (char-to-string (upcase key))))
 +                        (t "case-invariant"))))))
       (current-case-table))
      (save-excursion
       (with-output-to-temp-buffer "*Help*"
      (set-char-table-extra-slot copy 2 nil)
      copy))
  
 -(defsubst set-case-syntax-1 (char)
 -  "Offset CHAR by `set-case-syntax-offset' if CHAR is a non-ASCII 8-bit char."
 -  (if (and (>= char 128) (< char 256))
 -      (+ char set-case-syntax-offset)
 -    char))
 -
  (defun set-case-syntax-delims (l r table)
    "Make characters L and R a matching pair of non-case-converting delimiters.
  This sets the entries for L and R in TABLE, which is a string
  that will be used as the downcase part of a case table.
  It also modifies `standard-syntax-table' to
  indicate left and right delimiters."
 -  (setq l (set-case-syntax-1 l))
 -  (setq r (set-case-syntax-1 r))
    (aset table l l)
    (aset table r r)
    (let ((up (get-upcase-table table)))
@@@ -111,6 -121,8 +111,6 @@@ This sets the entries for characters U
  that will be used as the downcase part of a case table.
  It also modifies `standard-syntax-table' to give them the syntax of
  word constituents."
 -  (setq uc (set-case-syntax-1 uc))
 -  (setq lc (set-case-syntax-1 lc))
    (aset table uc lc)
    (aset table lc lc)
    (let ((up (get-upcase-table table)))
    "Make character UC an upcase of character LC.
  It also modifies `standard-syntax-table' to give them the syntax of
  word constituents."
 -  (setq uc (set-case-syntax-1 uc))
 -  (setq lc (set-case-syntax-1 lc))
    (aset table lc lc)
    (let ((up (get-upcase-table table)))
      (aset up uc uc)
    "Make character LC a downcase of character UC.
  It also modifies `standard-syntax-table' to give them the syntax of
  word constituents."
 -  (setq uc (set-case-syntax-1 uc))
 -  (setq lc (set-case-syntax-1 lc))
    (aset table uc lc)
    (aset table lc lc)
    (let ((up (get-upcase-table table)))
@@@ -159,6 -175,7 +159,6 @@@ This sets the entry for character C in 
  that will be used as the downcase part of a case table.
  It also modifies `standard-syntax-table'.
  SYNTAX should be \" \", \"w\", \".\" or \"_\"."
 -  (setq c (set-case-syntax-1 c))
    (aset table c c)
    (let ((up (get-upcase-table table)))
      (aset up c c))
diff --combined lisp/composite.el
index c59e3f792e12e8db99cd9c2916df5bb67656f6e2,ede7d023e87cc81c1db93248aea5ad291ebbfdad..b5da251bb85920b430e4705979ccab56ffc7d8f6
@@@ -1,6 -1,6 +1,6 @@@
  ;;; composite.el --- support character composition
  
- ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
@@@ -27,6 -27,7 +27,6 @@@
  
  ;;; Code:
  
 -;;;###autoload
  (defconst reference-point-alist
    '((tl . 0) (tc . 1) (tr . 2)
      (Bl . 3) (Bc . 4) (Br . 5)
@@@ -41,7 -42,8 +41,7 @@@
      (mid-left . 3) (mid-center . 10) (mid-right . 5))
    "Alist of symbols vs integer codes of glyph reference points.
  A glyph reference point symbol is to be used to specify a composition
 -rule in COMPONENTS argument to such functions as `compose-region' and
 -`make-composition'.
 +rule in COMPONENTS argument to such functions as `compose-region'.
  
  Meanings of glyph reference point codes are as follows:
  
@@@ -74,12 -76,7 +74,12 @@@ follows (the point `*' corresponds to b
      |    | new |
      |    |glyph|
      +----+-----+ <--- new descent
 -")
 +
 +A composition rule may have the form \(GLOBAL-REF-POINT
 +NEW-REF-POINT XOFF YOFF), where XOFF and YOFF specifies how much
 +to shift NEW-REF-POINT from GLOBAL-REF-POINT.  In this case, XOFF
 +and YOFF are integers in the range -100..100 representing the
 +shifting percentage against the font size.")
  
  
  ;;;###autoload
@@@ -94,29 -91,17 +94,29 @@@ RULE is a cons of global and new refere
    (if (and (integerp rule) (< rule 144))
        ;; Already encoded.
        rule
 -    (or (consp rule)
 -      (error "Invalid composition rule: %S" rule))
 -    (let ((gref (car rule))
 -        (nref (cdr rule)))
 -      (or (integerp gref)
 -        (setq gref (cdr (assq gref reference-point-alist))))
 -      (or (integerp nref)
 -        (setq nref (cdr (assq nref reference-point-alist))))
 -      (or (and (>= gref 0) (< gref 12) (>= nref 0) (< nref 12))
 -        (error "Invalid composition rule: %S" rule))
 -      (+ (* gref 12) nref))))
 +    (if (consp rule)
 +      (let ((gref (car rule))
 +            (nref (cdr rule))
 +            xoff yoff)
 +        (if (consp nref)              ; (GREF NREF XOFF YOFF)
 +            (progn
 +              (setq xoff (nth 1 nref)
 +                    yoff (nth 2 nref)
 +                    nref (car nref))
 +              (or (and (>= xoff -100) (<= xoff 100)
 +                       (>= yoff -100) (<= yoff 100))
 +                  (error "Invalid compostion rule: %s" rule))
 +              (setq xoff (+ xoff 128) yoff (+ yoff 128)))
 +          ;; (GREF . NREF)
 +          (setq xoff 0 yoff 0))
 +        (or (integerp gref)
 +            (setq gref (cdr (assq gref reference-point-alist))))
 +        (or (integerp nref)
 +            (setq nref (cdr (assq nref reference-point-alist))))
 +        (or (and (>= gref 0) (< gref 12) (>= nref 0) (< nref 12))
 +            (error "Invalid composition rule: %S" rule))
 +        (logior (lsh xoff 16) (lsh yoff 8) (+ (* gref 12) nref)))
 +      (error "Invalid composition rule: %S" rule))))
  
  ;; Decode encoded composition rule RULE-CODE.  The value is a cons of
  ;; global and new reference point symbols.
  ;; defined in composite.h.
  
  (defun decode-composition-rule (rule-code)
 -  (or (and (natnump rule-code) (< rule-code 144))
 +  (or (and (natnump rule-code) (< rule-code #x1000000))
        (error "Invalid encoded composition rule: %S" rule-code))
 -  (let ((gref (car (rassq (/ rule-code 12) reference-point-alist)))
 -      (nref (car (rassq (% rule-code 12) reference-point-alist))))
 +  (let ((xoff (lsh rule-code -16))
 +      (yoff (logand (lsh rule-code -8) #xFF))
 +      gref nref)
 +    (setq rule-code (logand rule-code #xFF)
 +        gref (car (rassq (/ rule-code 12) reference-point-alist))
 +        nref (car (rassq (% rule-code 12) reference-point-alist)))
      (or (and gref (symbolp gref) nref (symbolp nref))
        (error "Invalid composition rule code: %S" rule-code))
 -    (cons gref nref)))
 +    (if (and (= xoff 0) (= yoff 0))
 +      (cons gref nref)
 +      (setq xoff (- xoff 128) yoff (- yoff 128))
 +      (list gref xoff yoff nref))))
  
  ;; Encode composition rules in composition components COMPONENTS.  The
  ;; value is a copy of COMPONENTS, where composition rules (cons of
        (setq i (+ i 2))))
    components)
  
 -;;;###autoload
  (defun compose-region (start end &optional components modification-func)
    "Compose characters in the current region.
  
@@@ -192,8 -171,9 +192,8 @@@ When called from a program, expects the
  First two arguments START and END are positions (integers or markers)
  specifying the region.
  
 -Optional 3rd argument COMPONENTS, if non-nil, is a character or a
 -sequence (vector, list, or string) of integers.  In this case,
 -characters are composed not relatively but according to COMPONENTS.
 +Optional 3rd argument COMPONENTS, if non-nil, is a character, a string
 +or a vector or list of integers and rules.
  
  If it is a character, it is an alternate character to display instead
  of the text in the region.
@@@ -220,6 -200,7 +220,6 @@@ text in the composition.
      (compose-region-internal start end components modification-func)
      (restore-buffer-modified-p modified-p)))
  
 -;;;###autoload
  (defun decompose-region (start end)
    "Decompose text in the current region.
  
@@@ -231,10 -212,11 +231,10 @@@ positions (integers or markers) specify
      (remove-text-properties start end '(composition nil))
      (set-buffer-modified-p modified-p)))
  
 -;;;###autoload
  (defun compose-string (string &optional start end components modification-func)
    "Compose characters in string STRING.
  
 -The return value is STRING where `composition' property is put on all
 +The return value is STRING with the `composition' property put on all
  the characters in it.
  
  Optional 2nd and 3rd arguments START and END specify the range of
@@@ -255,11 -237,13 +255,11 @@@ text in the composition.
    (compose-string-internal string start end components modification-func)
    string)
  
 -;;;###autoload
  (defun decompose-string (string)
    "Return STRING where `composition' property is removed."
    (remove-text-properties 0 (length string) '(composition nil) string)
    string)
  
 -;;;###autoload
  (defun compose-chars (&rest args)
    "Return a string from arguments in which all characters are composed.
  For relative composition, arguments are characters.
@@@ -283,6 -267,7 +283,6 @@@ A composition rule is a cons of glyph r
        (setq str (concat args)))
      (compose-string-internal str 0 (length str) components)))
  
 -;;;###autoload
  (defun find-composition (pos &optional limit string detail-p)
    "Return information about a composition at or nearest to buffer position POS.
  
@@@ -322,6 -307,7 +322,6 @@@ WIDTH is a number of columns the compos
      result))
  
  \f
 -;;;###autoload
  (defun compose-chars-after (pos &optional limit object)
    "Compose characters in current buffer after position POS.
  
@@@ -342,7 -328,7 +342,7 @@@ is
  Optional 2nd arg LIMIT, if non-nil, limits the matching of text.
  
  Optional 3rd arg OBJECT, if non-nil, is a string that contains the
 -text to compose.  In that case, POS and LIMIT index to the string.
 +text to compose.  In that case, POS and LIMIT index into the string.
  
  This function is the default value of `compose-chars-after-function'."
    (let ((tail (aref composition-function-table (char-after pos)))
              (setq func nil tail (cdr tail)))))))
        result))
  
 -;;;###autoload
  (defun compose-last-chars (args)
    "Compose last characters.
  The argument is a parameterized event of the form
@@@ -382,275 -369,13 +382,275 @@@ after a sequence of character events.
            (compose-region (- (point) chars) (point) (nth 2 args))
          (compose-chars-after (- (point) chars) (point))))))
  
 -;;;###autoload(global-set-key [compose-last-chars] 'compose-last-chars)
 +(global-set-key [compose-last-chars] 'compose-last-chars)
 +
 +\f
 +;;; Automatic character composition.
 +
 +(defvar composition-function-table
 +  (make-char-table nil)
 +  "Char table of functions for automatic character composition.
 +For each character that has to be composed automatically with
 +preceding and/or following characters, this char table contains
 +a function to call to compose that character.
 +
 +Each function is called with two arguments, POS and STRING.
 +
 +If STRING is nil, POS is a position in the current buffer, and the
 +function has to compose a character at POS with surrounding characters
 +in the current buffer.
 +
 +Otherwise, STRING is a string, and POS is an index into the string.  In
 +this case, the function has to compose a character at POS with
 +surrounding characters in the string.
 +
 +See also the command `toggle-auto-composition'.")
 +
 +;; Copied from font-lock.el.
 +(eval-when-compile
 +  ;; Borrowed from lazy-lock.el.
 +  ;; We use this to preserve or protect things when modifying text properties.
 +  (defmacro save-buffer-state (varlist &rest body)
 +    "Bind variables according to VARLIST and eval BODY restoring buffer state."
 +    `(let* ,(append varlist
 +                  '((modified (buffer-modified-p)) (buffer-undo-list t)
 +                    (inhibit-read-only t) (inhibit-point-motion-hooks t)
 +                    (inhibit-modification-hooks t)
 +                    deactivate-mark buffer-file-name buffer-file-truename))
 +       ,@body
 +       (unless modified
 +       (restore-buffer-modified-p nil))))
 +  ;; Fixme: This makes bootstrapping fail with this error.
 +  ;;   Symbol's function definition is void: eval-defun
 +  ;;(def-edebug-spec save-buffer-state let)
 +  )
 +
 +(put 'save-buffer-state 'lisp-indent-function 1)
 +
 +;; This function is called when a composition created by
 +;; terminal-composition-function is partially modified.
 +(defun terminal-composition-modification (from to)
 +  (terminal-composition-function from))
 +
 +(defun terminal-composition-function (pos &optional string)
 +  "General composition function used on terminal.
 +Non-spacing characters are composed with the preceding spacing
 +character.  All non-spacing characters has this function in
 +`terminal-composition-function-table'."
 +  (let ((from (1- pos))
 +      ch)
 +    (if string
 +      (length string)
 +      (setq pos (1+ pos))
 +      (while (and (< pos (point-max))
 +                (= (aref char-width-table (char-after pos)) 0))
 +      (setq pos (1+ pos)))
 +      (if (and (>= from (point-min))
 +             (= (aref (symbol-name (get-char-code-property
 +                                    (char-after from)
 +                                    'general-category)) 0) ?L))
 +        (compose-region from pos (buffer-substring from pos))
 +      (compose-region (1+ from) pos
 +                      (concat " " (buffer-substring (1+ from) pos))
 +                      'terminal-composition-modification))
 +      pos)))
 +
 +(defvar terminal-composition-function-table
 +  (let ((table (make-char-table nil)))
 +    (map-char-table
 +     #'(lambda (key val)
 +       (if (= val 0) (set-char-table-range table key
 +                                           'terminal-composition-function)))
 +     char-width-table)
 +    table)
 +  "Char table of functions for automatic character composition on terminal.
 +This is like `composition-function-table' but used when Emacs is running
 +on a terminal.")
 +
 +(defvar auto-compose-current-font nil
 +  "The current font-object used for characters being composed automatically.")
 +
 +(defun auto-compose-chars (pos string font-object)
 +  "Compose characters after the buffer position POS.
 +If STRING is non-nil, it is a string, and POS is an index into the string.
 +In that case, compose characters in the string.
 +FONT-OBJECT is a font selected for the character at POS.
 +
 +This function is the default value of `auto-composition-function' (which see)."
 +  (save-buffer-state nil
 +    (save-excursion
 +      (save-match-data
 +      (condition-case nil
 +          (let ((start pos)
 +                (limit (if string (length string) (point-max)))
 +                (auto-compose-current-font font-object)
 +                (table (if (display-graphic-p)
 +                           composition-function-table
 +                         terminal-composition-function-table))
 +                ch func newpos)
 +            (setq limit
 +                  (or (text-property-any pos limit 'auto-composed t string)
 +                      limit)
 +                  pos 
 +                  (catch 'tag
 +                    (if string
 +                        (while (< pos limit)
 +                          (setq ch (aref string pos))
 +                          (if (= ch ?\n)
 +                              (throw 'tag (1+ pos)))
 +                          (setq func (aref table ch))
 +                          (if (and (functionp func)
 +                                   (setq newpos (funcall func pos string))
 +                                   (> newpos pos))
 +                              (setq pos newpos)
 +                            (setq pos (1+ pos))))
 +                      (while (< pos limit)
 +                        (setq ch (char-after pos))
 +                        (if (= ch ?\n)
 +                            (throw 'tag (1+ pos)))
 +                        (setq func (aref table ch))
 +                        (if (and (functionp func)
 +                                 (setq newpos (funcall func pos string))
 +                                 (> newpos pos))
 +                            (setq pos newpos)
 +                          (setq pos (1+ pos)))))
 +                    limit))
 +            (put-text-property start pos 'auto-composed t string))
 +        (error nil))))))
 +
 +(make-variable-buffer-local 'auto-composition-function)
 +
 +;;;###autoload
 +(define-minor-mode auto-composition-mode
 +  "Toggle Auto Compostion mode.
 +With arg, turn Auto Compostion mode off if and only if arg is a non-positive
 +number; if arg is nil, toggle Auto Compostion mode; anything else turns Auto
 +Compostion on.
 +
 +When Auto Composition is enabled, text characters are automatically composed
 +by functions registered in `composition-function-table' (which see).
 +
 +You can use Global Auto Composition mode to automagically turn on
 +Auto Composition mode in all buffers (this is the default)."
 +  nil nil nil
 +  (if noninteractive
 +      (setq auto-composition-mode nil))
 +  (cond (auto-composition-mode
 +       (add-hook 'after-change-functions 'auto-composition-after-change nil t)
 +       (setq auto-composition-function 'auto-compose-chars))
 +      (t
 +       (remove-hook 'after-change-functions 'auto-composition-after-change t)
 +       (setq auto-composition-function nil)))
 +  (save-buffer-state nil
 +    (save-restriction
 +      (widen)
 +      (remove-text-properties (point-min) (point-max) '(auto-composed nil))
 +      (decompose-region (point-min) (point-max)))))
 +
 +(defun auto-composition-after-change (start end old-len)
 +  (save-buffer-state nil
 +    (if (< start (point-min))
 +      (setq start (point-min)))
 +    (if (> end (point-max))
 +      (setq end (point-max)))
 +    (when (and auto-composition-mode (not memory-full))
 +      (let (func1 func2)
 +      (when (and (> start (point-min))
 +                 (setq func2 (aref composition-function-table
 +                                   (char-after (1- start))))
 +                 (or (= start (point-max))
 +                     (not (setq func1 (aref composition-function-table
 +                                            (char-after start))))
 +                     (eq func1 func2)))
 +        (setq start (1- start)
 +              func1 func2)
 +        (while (eq func1 func2)
 +          (if (> start (point-min))
 +              (setq start (1- start)
 +                    func2 (aref composition-function-table
 +                                (char-after start)))
 +            (setq func2 nil))))
 +      (when (and (< end (point-max))
 +                 (setq func2 (aref composition-function-table
 +                                   (char-after end)))
 +                 (or (= end (point-min))
 +                     (not (setq func1 (aref composition-function-table
 +                                            (char-after (1- end)))))
 +                     (eq func1 func2)))
 +        (setq end (1+ end)
 +              func1 func2)
 +        (while (eq func1 func2)
 +          (if (< end (point-max))
 +              (setq func2 (aref composition-function-table
 +                                (char-after end))
 +                    end (1+ end))
 +            (setq func2 nil))))
 +      (if (< start end)
 +          (remove-text-properties start end '(auto-composed nil)))))))
 +
 +(defun turn-on-auto-composition-if-enabled ()
 +  (if enable-multibyte-characters
 +      (auto-composition-mode 1)))
 +
 +;;;###autoload
 +(define-global-minor-mode global-auto-composition-mode
 +  auto-composition-mode turn-on-auto-composition-if-enabled
 +  :extra-args (dummy)
 +  :initialize 'custom-initialize-safe-default
 +  :init-value (not noninteractive)
 +  :group 'auto-composition
 +  :version "23.1")
 +
 +(defun toggle-auto-composition (&optional arg)
 +  "Change whether automatic character composition is enabled in this buffer.
 +With arg, enable it iff arg is positive."
 +  (interactive "P")
 +  (let ((enable (if (null arg) (not auto-composition-function)
 +                (> (prefix-numeric-value arg) 0))))
 +    (if enable
 +      (kill-local-variable 'auto-composition-function)
 +      (make-local-variable 'auto-composition-function)
 +      (setq auto-composition-function nil)
 +      (save-buffer-state nil
 +      (save-restriction
 +        (widen)
 +        (decompose-region (point-min) (point-max)))))
 +
 +    (save-buffer-state nil
 +      (save-restriction
 +      (widen)
 +      (remove-text-properties (point-min) (point-max)
 +                              '(auto-composed nil))))))
 +
 +(defun auto-compose-region (from to)
 +  "Force automatic character composition on the region FROM and TO."
 +  (save-excursion
 +    (if (get-text-property from 'auto-composed)
 +      (setq from (next-single-property-change from 'auto-composed nil to)))
 +    (goto-char from)
 +    (let ((modified-p (buffer-modified-p))
 +        (inhibit-read-only '(composition auto-composed))
 +        (stop (next-single-property-change (point) 'auto-composed nil to)))
 +      (while (< (point) to)
 +      (if (= (point) stop)
 +          (progn
 +            (goto-char (next-single-property-change (point)
 +                                                    'auto-composed nil to))
 +            (setq stop (next-single-property-change (point)
 +                                                    'auto-composed nil to)))
 +        (let ((func (aref composition-function-table (following-char)))
 +              (pos (point)))
 +          (if (functionp func)
 +              (goto-char (funcall func (point) nil)))
 +          (if (<= (point) pos)
 +              (forward-char 1)))))
 +      (put-text-property from to 'auto-composed t)
 +      (set-buffer-modified-p modified-p))))
  
  \f
  ;;; The following codes are only for backward compatibility with Emacs
  ;;; 20.4 and earlier.
  
 -;;;###autoload
  (defun decompose-composite-char (char &optional type with-composition-rule)
    "Convert CHAR to string.
  
@@@ -662,6 -387,7 +662,6 @@@ Optional 3rd arg WITH-COMPOSITION-RULE 
        ((eq type 'list) (list char))
        (t (vector char))))
  
 -;;;###autoload
  (make-obsolete 'decompose-composite-char 'char-to-string "21.1")
  
  \f
diff --combined lisp/cus-start.el
index 9610800ee0bb2fbba2666c2edb030c9453108454,da2f0a54c2cfc39e2278180529d43050633cb057..eba4de8b835e39e8ba287fabde4144dc4e6ba985
@@@ -1,7 -1,7 +1,7 @@@
  ;;; cus-start.el --- define customization properties of builtins
  ;;
  ;; Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  ;;
  ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
  ;; Keywords: internal
@@@ -106,9 -106,6 +106,9 @@@ Leaving \"Default\" unchecked is equiva
             (exec-path execute
                        (repeat (choice (const :tag "default directory" nil)
                                        (directory :format "%v"))))
 +           ;; charset.c
 +           (charset-map-path installation
 +                             (repeat (directory :format "%v")))
             ;; coding.c
             (inhibit-eol-conversion mule boolean)
             (eol-mnemonic-undecided mule string)
diff --combined lisp/descr-text.el
index 2d5734c81709f4035c1ab2c66cd8568c635fe984,64920336db9de235dcfa70b2f5c68f9da7ca036a..6a4b99ddb6c62e00e2986a685a2b18d98844a202
@@@ -1,7 -1,7 +1,7 @@@
  ;;; descr-text.el --- describe text mode
  
  ;; Copyright (C) 1994, 1995, 1996, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Boris Goldowsky <boris@gnu.org>
  ;; Maintainer: FSF
@@@ -183,27 -183,6 +183,27 @@@ otherwise.
        (insert "There are text properties here:\n")
        (describe-property-list properties)))))
  \f
 +(defcustom describe-char-unidata-list nil
 +  "List of Unicode-based character property names shown by `describe-char'."
 +  :group 'mule
 +  :version "23.1"
 +  :type '(set
 +        (const :tag "Unicode Name" name)
 +        (const :tag "Unicode general category " general-category)
 +        (const :tag "Unicode canonical combining class"
 +               canonical-combining-class)
 +        (const :tag "Unicode bidi class" bidi-class)
 +        (const :tag "Unicode decomposition mapping" decomposition)
 +        (const :tag "Unicode decimal digit value" decimal-digit-value)
 +        (const :tag "Unicode digit value" digit-value)
 +        (const :tag "Unicode numeric value" numeric-value)
 +        (const :tag "Unicode mirrored" mirrored)
 +        (const :tag "Unicode old name" old-name)
 +        (const :tag "Unicode ISO 10646 comment" iso-10646-comment)
 +        (const :tag "Unicode simple uppercase mapping" uppercase)
 +        (const :tag "Unicode simple lowercase mapping" lowercase)
 +        (const :tag "Unicode simple titlecase mapping" titlecase)))
 +
  (defcustom describe-char-unicodedata-file nil
    "Location of Unicode data file.
  This is the UnicodeData.txt file from the Unicode Consortium, used for
@@@ -229,8 -208,7 +229,8 @@@ At the time of writing it is at the UR
  (defun describe-char-unicode-data (char)
    "Return a list of Unicode data for unicode CHAR.
  Each element is a list of a property description and the property value.
 -The list is null if CHAR isn't found in `describe-char-unicodedata-file'."
 +The list is null if CHAR isn't found in `describe-char-unicodedata-file'.
 +This function is semi-obsolete.  Use `get-char-code-property'."
    (when describe-char-unicodedata-file
      (unless (file-exists-p describe-char-unicodedata-file)
        (error "`unicodedata-file' %s not found" describe-char-unicodedata-file))
                                  (concat (match-string 1 name) ">")
                                name)))
               (list "Category"
 -                   (cdr (assoc
 -                         (nth 1 fields)
 -                         '(("Lu" . "uppercase letter")
 -                           ("Ll" . "lowercase letter")
 -                           ("Lt" . "titlecase letter")
 -                           ("Mn" . "non-spacing mark")
 -                           ("Mc" . "spacing-combining mark")
 -                           ("Me" . "enclosing mark")
 -                           ("Nd" . "decimal digit")
 -                           ("Nl" . "letter number")
 -                           ("No" . "other number")
 -                           ("Zs" . "space separator")
 -                           ("Zl" . "line separator")
 -                           ("Zp" . "paragraph separator")
 -                           ("Cc" . "other control")
 -                           ("Cf" . "other format")
 -                           ("Cs" . "surrogate")
 -                           ("Co" . "private use")
 -                           ("Cn" . "not assigned")
 -                           ("Lm" . "modifier letter")
 -                           ("Lo" . "other letter")
 -                           ("Pc" . "connector punctuation")
 -                           ("Pd" . "dash punctuation")
 -                           ("Ps" . "open punctuation")
 -                           ("Pe" . "close punctuation")
 -                           ("Pi" . "initial-quotation punctuation")
 -                           ("Pf" . "final-quotation punctuation")
 -                           ("Po" . "other punctuation")
 -                           ("Sm" . "math symbol")
 -                           ("Sc" . "currency symbol")
 -                           ("Sk" . "modifier symbol")
 -                           ("So" . "other symbol")))))
 +                   (let ((val (nth 1 fields)))
 +                     (or (char-code-property-description
 +                          'general-category (intern val))
 +                         val)))
               (list "Combining class"
 -                   (cdr (assoc
 -                         (string-to-number (nth 2 fields))
 -                         '((0 . "Spacing")
 -                           (1 . "Overlays and interior")
 -                           (7 . "Nuktas")
 -                           (8 . "Hiragana/Katakana voicing marks")
 -                           (9 . "Viramas")
 -                           (10 . "Start of fixed position classes")
 -                           (199 . "End of fixed position classes")
 -                           (200 . "Below left attached")
 -                           (202 . "Below attached")
 -                           (204 . "Below right attached")
 -                           (208 . "Left attached (reordrant around \
 -single base character)")
 -                           (210 . "Right attached")
 -                           (212 . "Above left attached")
 -                           (214 . "Above attached")
 -                           (216 . "Above right attached")
 -                           (218 . "Below left")
 -                           (220 . "Below")
 -                           (222 . "Below right")
 -                           (224 . "Left (reordrant around single base \
 -character)")
 -                           (226 . "Right")
 -                           (228 . "Above left")
 -                           (230 . "Above")
 -                           (232 . "Above right")
 -                           (233 . "Double below")
 -                           (234 . "Double above")
 -                           (240 . "Below (iota subscript)")))))
 +                   (let ((val (nth 1 fields)))
 +                     (or (char-code-property-description
 +                          'canonical-combining-class (intern val))
 +                         val)))
               (list "Bidi category"
 -                   (cdr (assoc
 -                         (nth 3 fields)
 -                         '(("L" . "Left-to-Right")
 -                           ("LRE" . "Left-to-Right Embedding")
 -                           ("LRO" . "Left-to-Right Override")
 -                           ("R" . "Right-to-Left")
 -                           ("AL" . "Right-to-Left Arabic")
 -                           ("RLE" . "Right-to-Left Embedding")
 -                           ("RLO" . "Right-to-Left Override")
 -                           ("PDF" . "Pop Directional Format")
 -                           ("EN" . "European Number")
 -                           ("ES" . "European Number Separator")
 -                           ("ET" . "European Number Terminator")
 -                           ("AN" . "Arabic Number")
 -                           ("CS" . "Common Number Separator")
 -                           ("NSM" . "Non-Spacing Mark")
 -                           ("BN" . "Boundary Neutral")
 -                           ("B" . "Paragraph Separator")
 -                           ("S" . "Segment Separator")
 -                           ("WS" . "Whitespace")
 -                           ("ON" . "Other Neutrals")))))
 +                   (let ((val (nth 1 fields)))
 +                     (or (char-code-property-description
 +                          'bidi-class (intern val))
 +                         val)))
               (list
                "Decomposition"
                (if (nth 4 fields)
                          (setq info (match-string 1 info))
                        (setq info nil))
                      (if info (setq parts (cdr parts)))
 -                    ;; Maybe printing ? for unrepresentable unicodes
 -                    ;; here and below should be changed?
                      (setq parts (mapconcat
                                   (lambda (arg)
 -                                   (string (or (decode-char
 -                                                'ucs
 -                                                (string-to-number arg 16))
 -                                               ??)))
 +                                   (string (string-to-number arg 16)))
                                   parts " "))
                      (concat info parts))))
               (list "Decimal digit value"
               (list "Old name" (nth 9 fields))
               (list "ISO 10646 comment" (nth 10 fields))
               (list "Uppercase" (and (nth 11 fields)
 -                                    (string (or (decode-char
 -                                                 'ucs
 -                                                 (string-to-number
 -                                                  (nth 11 fields) 16))
 -                                                ??))))
 +                                    (string (string-to-number
 +                                             (nth 11 fields) 16))))
               (list "Lowercase" (and (nth 12 fields)
 -                                    (string (or (decode-char
 -                                                 'ucs
 -                                                 (string-to-number
 -                                                  (nth 12 fields) 16))
 -                                                ??))))
 +                                    (string (string-to-number
 +                                             (nth 12 fields) 16))))
               (list "Titlecase" (and (nth 13 fields)
 -                                    (string (or (decode-char
 -                                                 'ucs
 -                                                 (string-to-number
 -                                                  (nth 13 fields) 16))
 -                                                ??)))))))))))
 +                                    (string (string-to-number
 +                                             (nth 13 fields) 16)))))))))))
  
  ;; Return information about how CHAR is displayed at the buffer
  ;; position POS.  If the selected frame is on a graphic display,
@@@ -375,40 -438,45 +375,40 @@@ as well as widgets, buttons, overlays, 
                  (describe-text-properties pos tmp-buf)
                  (with-current-buffer tmp-buf (buffer-string)))
              (kill-buffer tmp-buf))))
 -       item-list max-width unicode)
 +       item-list max-width code)
  
 -    (if (or (< char 256)
 -          (memq 'mule-utf-8 (find-coding-systems-region pos (1+ pos)))
 -          (get-char-property pos 'untranslated-utf-8))
 -      (setq unicode (or (get-char-property pos 'untranslated-utf-8)
 -                        (encode-char char 'ucs))))
 +    (setq code (encode-char char charset))
      (setq item-list
          `(("character"
 -           ,(format "%s (%d, #o%o, #x%x%s)"
 +           ,(format "%s (%d, #o%o, #x%x)"
                      (apply 'propertize char-description
                             (text-properties-at pos))
 -                    char char char
 -                    (if unicode
 -                        (format ", U+%04X" unicode)
 -                      "")))
 -          ("charset"
 +                    char char char))
 +          ("preferred charset"
             ,`(insert-text-button
                ,(symbol-name charset)
                'type 'help-character-set 'help-args '(,charset))
             ,(format "(%s)" (charset-description charset)))
            ("code point"
 -           ,(let ((split (split-char char)))
 -              `(insert-text-button
 -                ,(if (= (charset-dimension charset) 1)
 -                     (format "#x%02X" (nth 1 split))
 -                   (format "#x%02X #x%02X" (nth 1 split)
 -                           (nth 2 split)))
 -                'action (lambda (&rest ignore)
 -                          (list-charset-chars ',charset)
 -                          (with-selected-window
 -                              (get-buffer-window "*Character List*" 0)
 -                            (goto-char (point-min))
 -                            (forward-line 2) ;Skip the header.
 -                            (let ((case-fold-search nil))
 -                              (search-forward ,(char-to-string char)
 -                                              nil t))))
 -                'help-echo
 -                "mouse-2, RET: show this character in its character set")))
 +           ,(let ((str (if (integerp code)
 +                           (format (if (< code 256) "0x%02X" "0x%04X") code)
 +                         (format "0x%04X%04X" (car code) (cdr code)))))
 +              (if (<= (charset-dimension charset) 2)
 +                  `(insert-text-button
 +                    ,str
 +                    'action (lambda (&rest ignore)
 +                              (list-charset-chars ',charset)
 +                              (with-selected-window
 +                                  (get-buffer-window "*Character List*" 0)
 +                                (goto-char (point-min))
 +                                (forward-line 2) ;Skip the header.
 +                                (let ((case-fold-search nil))
 +                                  (if (search-forward ,(char-to-string char)
 +                                                      nil t)
 +                                      (goto-char (match-beginning 0))))))
 +                    'help-echo
 +                    "mouse-2, RET: show this character in its character set")
 +                str)))
            ("syntax"
             ,(let ((syntax (syntax-after pos)))
                (with-temp-buffer
                   (mapcar #'(lambda (x) (format "%c:%s"
                                                 x (category-docstring x)))
                           (category-set-mnemonics category-set)))))
 -          ,@(let ((props (aref char-code-property-table char))
 -                  ps)
 -              (when props
 -                (while props
 -                  (push (format "%s:" (pop props)) ps)
 -                  (push (format "%s;" (pop props)) ps))
 -                (list (cons "Properties" (nreverse ps)))))
            ("to input"
             ,@(let ((key-list (and (eq input-method-function
                                        'quail-input-method)
                                (save-excursion (goto-char pos)
                                                (looking-at "[ \t]+$")))
                           'trailing-whitespace)
 -                        ((and nobreak-char-display unicode (eq unicode '#xa0))
 +                        ((and nobreak-char-display char (eq char '#xa0))
                           'nobreak-space)
 -                        ((and nobreak-char-display unicode (eq unicode '#xad))
 +                        ((and nobreak-char-display char (eq char '#xad))
                           'escape-glyph)
                          ((and (< char 32) (not (memq char '(9 10))))
                           'escape-glyph)))))
                                     `(insert-text-button
                                       ,(symbol-name face)
                                       'type 'help-face 'help-args '(,face))))))
 -          ,@(let ((unicodedata (and unicode
 -                                    (describe-char-unicode-data unicode))))
 +          ,@(let ((unicodedata (describe-char-unicode-data char)))
                (if unicodedata
                    (cons (list "Unicode data" " ") unicodedata)))))
 -    (setq max-width (apply #'max (mapcar #'(lambda (x)
 +    (setq max-width (apply #'max (mapcar #'(lambda (x) 
                                             (if (cadr x) (length (car x)) 0))
                                         item-list)))
      (help-setup-xref nil (interactive-p))
          (insert "\nSee the variable `reference-point-alist' for "
                  "the meaning of the rule.\n"))
  
 +      (if (not describe-char-unidata-list)
 +          (insert "\nCharacter code properties are not shown: ")
 +        (insert "\nCharacter code properties: "))
 +      (insert-text-button
 +       "customize what to show"
 +       'action (lambda (&rest ignore)
 +                 (customize-variable
 +                  'describe-char-unidata-list)))
 +      (insert "\n")
 +      (dolist (elt describe-char-unidata-list)
 +        (let ((val (get-char-code-property char elt))
 +              description)
 +          (when val
 +            (setq description (char-code-property-description elt val))
 +            (if description
 +                (insert (format "  %s: %s (%s)\n" elt val description))
 +              (insert (format "  %s: %s\n" elt val))))))
 +
          (if text-props-desc (insert text-props-desc))
        (setq help-xref-stack-item (list 'help-insert-string (buffer-string)))
        (toggle-read-only 1)
diff --combined lisp/desktop.el
index 3030bf5ecd146791fb242f86aa14bc9687a58ed2,442c81bf730d2b376b10c816c0eca63780671868..12cd378f0f41194e98027c2eec92503ba90bb462
@@@ -1,7 -1,7 +1,7 @@@
  ;;; desktop.el --- save partial status of Emacs when killed
  
  ;; Copyright (C) 1993, 1994, 1995, 1997, 2000, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Morten Welinder <terra@diku.dk>
  ;; Maintainter: Lars Hansen <larsh@soem.dk>
@@@ -776,40 -776,40 +776,40 @@@ See also `desktop-base-file-name'.
                (buffer-list)))
            (eager desktop-restore-eager))
        (with-temp-buffer
 -        (insert
 -         ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n"
 -         desktop-header
 -         ";; Created " (current-time-string) "\n"
 -         ";; Desktop file format version " desktop-file-version "\n"
 -         ";; Emacs version " emacs-version "\n\n"
 -         ";; Global section:\n")
 -        (mapc (function desktop-outvar) desktop-globals-to-save)
 -        (if (memq 'kill-ring desktop-globals-to-save)
 -            (insert
 -             "(setq kill-ring-yank-pointer (nthcdr "
 -             (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer)))
 -             " kill-ring))\n"))
 -
 -        (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n")
 -        (mapc #'(lambda (l)
 -                  (when (apply 'desktop-save-buffer-p l)
 -                    (insert "("
 -                            (if (or (not (integerp eager))
 -                                    (unless (zerop eager)
 -                                      (setq eager (1- eager))
 -                                      t))
 -                                "desktop-create-buffer"
 -                              "desktop-append-buffer-args")
 -                            " "
 -                            desktop-file-version)
 -                    (mapc #'(lambda (e)
 -                              (insert "\n  " (desktop-value-to-string e)))
 -                          l)
 -                    (insert ")\n\n")))
 -              info)
 -        (setq default-directory dirname)
 -        (let ((coding-system-for-write 'emacs-mule))
 -          (write-region (point-min) (point-max) filename nil 'nomessage)))))
 +      (insert
 +        ";; -*- mode: emacs-lisp; coding: utf-8-emacs; -*-\n"
 +        desktop-header
 +        ";; Created " (current-time-string) "\n"
 +        ";; Desktop file format version " desktop-file-version "\n"
 +        ";; Emacs version " emacs-version "\n\n"
 +        ";; Global section:\n")
 +      (mapc (function desktop-outvar) desktop-globals-to-save)
 +      (if (memq 'kill-ring desktop-globals-to-save)
 +        (insert
 +          "(setq kill-ring-yank-pointer (nthcdr "
 +          (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer)))
 +          " kill-ring))\n"))
 +
 +      (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n")
 +      (mapc #'(lambda (l)
 +                (when (apply 'desktop-save-buffer-p l)
 +                  (insert "("
 +                          (if (or (not (integerp eager))
 +                                  (unless (zerop eager)
 +                                    (setq eager (1- eager))
 +                                    t))
 +                              "desktop-create-buffer"
 +                            "desktop-append-buffer-args")
 +                          " "
 +                          desktop-file-version)
 +                  (mapc #'(lambda (e)
 +                            (insert "\n  " (desktop-value-to-string e)))
 +                        l)
 +                  (insert ")\n\n")))
 +            info)
 +      (setq default-directory dirname)
 +      (let ((coding-system-for-write 'utf-8-emacs))
 +        (write-region (point-min) (point-max) filename nil 'nomessage)))))
    (setq desktop-dirname dirname))
  
  ;; ----------------------------------------------------------------------------
diff --combined lisp/disp-table.el
index 20aae96aa94273d17b009751437c1df83ecda724,fa98086b0bccb7d19fae4e8a51eb0379cd4c24bb..dd884b246dbfcd0b5404d1fe6b59b663614229f2
@@@ -1,7 -1,7 +1,7 @@@
  ;;; disp-table.el --- functions for dealing with char tables
  
  ;; Copyright (C) 1987, 1994, 1995, 1999, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Erik Naggum <erik@naggum.no>
  ;; Based on a previous version by Howard Gayle
@@@ -126,7 -126,7 +126,7 @@@ Valid symbols are `truncation', `wrap'
    (or standard-display-table
        (setq standard-display-table (make-display-table)))
    (while (<= l h)
 -    (if (and (>= l ?\s) (char-valid-p l))
 +    (if (and (>= l ?\s) (characterp l))
        (aset standard-display-table l nil))
      (setq l (1+ l))))
  
diff --combined lisp/dnd.el
index 3b16489da5b02598c6ff7390e39218b988e504ea,2b523476a4f071484436bdfcb1912cac9faa430d..972354f39083324e6540de7cec9fda940fe46b31
@@@ -1,6 -1,6 +1,6 @@@
  ;;; dnd.el --- drag and drop support.
  
- ;; Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ ;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Jan Dj\e,Ad\e(Brv <jan.h.d@swipnet.se>
  ;; Maintainer: FSF
@@@ -148,9 -148,7 +148,9 @@@ Return nil if URI is not a local file.
        (setq f (replace-regexp-in-string
               "%[A-Z0-9][A-Z0-9]"
               (lambda (arg)
 -               (format "%c" (string-to-number (substring arg 1) 16)))
 +               (let ((str (make-string 1 0)))
 +                 (aset str 0 (string-to-number (substring arg 1) 16))
 +                 str))
               f nil t))
        (let* ((decoded-f (decode-coding-string
                         f
diff --combined lisp/edmacro.el
index b70e8a142b6bb87d5d9a9c82ce8514a0b0361c50,0842d63836fb7bce3ba3803917fedff38cb4b199..e21dbaa8f35ae3419c52d12ecaf3cf4cff15bc12
@@@ -1,7 -1,7 +1,7 @@@
  ;;; edmacro.el --- keyboard macro editor
  
  ;; Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Dave Gillespie <daveg@synaptics.com>
  ;; Maintainer: Dave Gillespie <daveg@synaptics.com>
@@@ -771,7 -771,7 +771,7 @@@ This function assumes that the events c
        (setq res (edmacro-subseq res 2 -2)))
      (if (and (not need-vector)
             (loop for ch across res
 -                 always (and (char-valid-p ch)
 +                 always (and (characterp ch)
                               (let ((ch2 (logand ch (lognot ?\M-\^@))))
                                 (and (>= ch2 0) (<= ch2 127))))))
        (concat (loop for ch across res
index db6d96ee9a01605f605b790687ac2cdb83b2c5d2,dd7e042499c6315033d6d964eefe02f9a994f816..80a537cadb5c857e7ca85f36b06d02081800a226
@@@ -1,7 -1,7 +1,7 @@@
  ;;; byte-opt.el --- the optimization passes of the emacs-lisp byte compiler
  
  ;; Copyright (C) 1991, 1994, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Jamie Zawinski <jwz@lucid.com>
  ;;    Hallvard Furuseth <hbf@ulrik.uio.no>
@@@ -1221,9 -1221,8 +1221,9 @@@ of FORM by signaling the error at compi
         char-equal char-to-string char-width
         compare-strings concat coordinates-in-window-p
         copy-alist copy-sequence copy-marker cos count-lines
 +       decdoe-char
         decode-time default-boundp default-value documentation downcase
 -       elt exp expt encode-time error-message-string
 +       elt encode-char exp expt encode-time error-message-string
         fboundp fceiling featurep ffloor
         file-directory-p file-exists-p file-locked-p file-name-absolute-p
         file-newer-than-file-p file-readable-p file-symlink-p file-writable-p
         int-to-string intern-soft
         keymap-parent
         length local-variable-if-set-p local-variable-p log log10 logand
 -       logb logior lognot logxor lsh
 +       logb logior lognot logxor lsh langinfo
         make-list make-string make-symbol
         marker-buffer max member memq min mod multibyte-char-to-unibyte
         next-window nth nthcdr number-to-string
         string-to-int string-to-number substring sxhash symbol-function
         symbol-name symbol-plist symbol-value string-make-unibyte
         string-make-multibyte string-as-multibyte string-as-unibyte
 +       string-to-multibyte
         tan truncate
         unibyte-char-to-multibyte upcase user-full-name
         user-login-name user-original-login-name user-variable-p
         '(arrayp atom
         bobp bolp bool-vector-p
         buffer-end buffer-list buffer-size buffer-string bufferp
 -       car-safe case-table-p cdr-safe char-or-string-p commandp cons consp
 +       car-safe case-table-p cdr-safe char-or-string-p characterp
 +       charsetp commandp cons consp
         current-buffer current-global-map current-indentation
         current-local-map current-minor-mode-maps current-time
         current-time-string current-time-zone
         invocation-directory invocation-name
         keymapp
         line-beginning-position line-end-position list listp
 -       make-marker mark mark-marker markerp memory-limit minibuffer-window
 +       make-marker mark mark-marker markerp max-char
 +       memory-limit minibuffer-window
         mouse-movement-p
         natnump nlistp not null number-or-marker-p numberp
         one-window-p overlayp
 -       point point-marker point-min point-max preceding-char processp
 +       point point-marker point-min point-max preceding-char primary-charset
 +       processp
         recent-keys recursion-depth
         safe-length selected-frame selected-window sequencep
         standard-case-table standard-syntax-table stringp subrp symbolp
index b7b961f1cbbe41afe56da383fed338ce003d1713,4b31a0e69431e4cbe78d6067207872a5ae46ff38..400537649eee13169693443201f068522cca0b22
@@@ -1,7 -1,7 +1,7 @@@
  ;;; bytecomp.el --- compilation of Lisp code into byte code
  
  ;; Copyright (C) 1985, 1986, 1987, 1992, 1994, 1998, 2000, 2001, 2002,
- ;;   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Jamie Zawinski <jwz@lucid.com>
  ;;    Hallvard Furuseth <hbf@ulrik.uio.no>
@@@ -803,7 -803,7 +803,7 @@@ otherwise pop it"
               (setcar (cdr bytes) (logand pc 255))
               (setcar bytes (lsh pc -8))))
        (setq patchlist (cdr patchlist))))
 -    (concat (nreverse bytes))))
 +    (string-make-unibyte (concat (nreverse bytes)))))
  
  \f
  ;;; compile-time evaluation
@@@ -1887,13 -1887,13 +1887,13 @@@ With argument, insert value in current 
        (delete-region (point) (progn (re-search-forward "^(")
                                      (beginning-of-line)
                                      (point)))
 -      (insert ";;; This file contains multibyte non-ASCII characters\n"
 -              ";;; and therefore cannot be loaded into Emacs 19.\n")
 -      ;; Replace "19" or "19.29" with "20", twice.
 +      (insert ";;; This file contains utf-8 non-ASCII characters\n"
 +              ";;; and therefore cannot be loaded into Emacs 21 or earlier.\n")
 +      ;; Replace "19" or "19.29" with "22", twice.
        (re-search-forward "19\\(\\.[0-9]+\\)")
 -      (replace-match "20")
 +      (replace-match "23")
        (re-search-forward "19\\(\\.[0-9]+\\)")
 -      (replace-match "20")
 +      (replace-match "23")
        ;; Now compensate for the change in size,
        ;; to make sure all positions in the file remain valid.
        (setq delta (- (point-max) old-header-end))
      (set-buffer outbuffer)
      (goto-char 1)
      ;; The magic number of .elc files is ";ELC", or 0x3B454C43.  After
 -    ;; that is the file-format version number (18, 19 or 20) as a
 +    ;; that is the file-format version number (18, 19, 20, or 23) as a
      ;; byte, followed by some nulls.  The primary motivation for doing
      ;; this is to get some binary characters up in the first line of
      ;; the file so that `diff' will simply say "Binary files differ"
  
      (insert
       ";ELC"
 -     (if (byte-compile-version-cond byte-compile-compatibility) 18 20)
 +     (if (byte-compile-version-cond byte-compile-compatibility) 18 23)
       "\000\000\000\n"
       )
      (insert ";;; Compiled by "
           ;; Insert semicolons as ballast, so that byte-compile-fix-header
           ;; can delete them so as to keep the buffer positions
           ;; constant for the actual compiled code.
 -         ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n"))
 +         ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n"))
        ;; Here if we want Emacs 18 compatibility.
        (when dynamic-docstrings
        (error "Version-18 compatibility doesn't support dynamic doc strings"))
          (print-length nil)
          (print-level nil)
          (print-quoted t)
-         (print-gensym t))
+         (print-gensym t)
+         (print-circle t))            ; handle circular data structures
        (princ "\n" outbuffer)
        (prin1 form outbuffer)
        nil)))
@@@ -2059,6 -2060,7 +2060,7 @@@ list that represents a doc string refer
               ;; print-gensym-alist not to be cleared
               ;; between calls to print functions.
               (print-gensym '(t))
+              (print-circle t)        ; handle circular data structures
               print-gensym-alist    ; was used before print-circle existed.
               (print-continuous-numbering t)
               print-number-table
@@@ -3369,8 -3371,6 +3371,8 @@@ That command is designed for interactiv
  (byte-defop-compiler-1 mapc byte-compile-funarg)
  (byte-defop-compiler-1 maphash byte-compile-funarg)
  (byte-defop-compiler-1 map-char-table byte-compile-funarg)
 +(byte-defop-compiler-1 map-char-table byte-compile-funarg-2)
 +;; map-charset-chars should be funarg but has optional third arg
  (byte-defop-compiler-1 sort byte-compile-funarg-2)
  (byte-defop-compiler-1 let)
  (byte-defop-compiler-1 let*)
index 915bde800eec1e2ac59c461e51e62ec93f56875a,adbe7054cda31c2554efc8cd0329bf5abc37ec60..a28e11055edf31630b12ba96c5cce352c86ce11e
@@@ -1,6 -1,6 +1,6 @@@
  ;;; cl-macs.el --- Common Lisp macros -*-byte-compile-dynamic: t;-*-
  
- ;; Copyright (C) 1993, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1993, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  
  ;; Author: Dave Gillespie <daveg@synaptics.com>
@@@ -2400,7 -2400,7 +2400,7 @@@ The type name can then be used in `type
            ((eq type 'real) `(numberp ,val))
            ((eq type 'fixnum) `(integerp ,val))
            ;; FIXME: Should `character' accept things like ?\C-\M-a ?  -stef
 -          ((memq type '(character string-char)) `(char-valid-p ,val))
 +          ((memq type '(character string-char)) `(characterp ,val))
            (t
             (let* ((name (symbol-name type))
                    (namep (intern (concat name "p"))))
index 371fdd66b60afe2850670bf0f1e387f3659909f0,5f5aecea97a69bc0100b4a7d70eaf22dda6b740d..c7194a096e1de77191fe45364ec13f5ac8f84551
@@@ -1,7 -1,7 +1,7 @@@
  ;;; copyright.el --- update the copyright notice in current buffer
  
  ;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1998, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Daniel Pfeiffer <occitan@esperanto.org>
  ;; Keywords: maint, tools
@@@ -43,10 -43,12 +43,10 @@@ A value of nil means to search whole bu
    :type '(choice (integer :tag "Limit")
                 (const :tag "No limit")))
  
 -;; The character classes have the Latin-1 version and the Latin-9
 -;; version, which is probably enough.
  (defcustom copyright-regexp
 - "\\([\81©\8e©]\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\
 -\\|[Cc]opyright\\s *:?\\s *[\81©\8e©]\\)\
 -\\s *\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
 + "\\(©\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\
 +\\|[Cc]opyright\\s *:?\\s *©\\)\
 +\\s *\\([1-9]\\([-0-9, ';\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
    "*What your copyright notice looks like.
  The second \\( \\) construct must match the years."
    :group 'copyright
@@@ -230,7 -232,7 +230,7 @@@ Uses heuristic: year >= 50 means 19xx, 
  
  ;; For the copyright sign:
  ;; Local Variables:
 -;; coding: emacs-mule
 +;; coding: utf-8
  ;; End:
  
  ;;; arch-tag: b4991afb-b6b1-4590-bebe-e076d9d4aee8
index 0f38c4c54c6e68ff23bdc7d966e7b69700bf1ddb,22ed0c531754b2c4f9723029d6c2d20a57730259..a0507c1f1bbeebb6b2d97f2041d94a1c176d24da
@@@ -1,7 -1,7 +1,7 @@@
  ;;; generic.el --- defining simple major modes with comment and font-lock
  ;;
  ;; Copyright (C) 1997, 1999, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  ;;
  ;; Author:  Peter Breton <pbreton@cs.umb.edu>
  ;; Created: Fri Sep 27 1996
@@@ -240,9 -240,9 +240,9 @@@ Some generic modes are defined in `gene
        (when (consp start)
          (setq end (cdr start))
          (setq start (car start)))
 -      (when (char-valid-p start) (setq start (char-to-string start)))
 +      (when (characterp start) (setq start (char-to-string start)))
        (cond
 -       ((char-valid-p end)   (setq end (char-to-string end)))
 +       ((characterp end)   (setq end (char-to-string end)))
         ((zerop (length end)) (setq end "\n")))
  
        ;; Setup the vars for `comment-region'
index 2832dd1cbf03a51e761a398eed5c51a1e3de1242,34cd97775dcc888598b6a74ec08c7be2b7dfcbc0..9f75578e09dea570cd7128c1309edd444ebcf99b
@@@ -1,7 -1,7 +1,7 @@@
  ;;; regexp-opt.el --- generate efficient regexps to match strings
  
  ;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- ;;   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Simon Marshall <simon@gnu.org>
  ;; Maintainer: FSF
@@@ -263,21 -263,13 +263,21 @@@ This means the number of non-shy regex
      (map-char-table
       (lambda (c v)
         (when v
 -       (if (= (1- c) end) (setq end c)
 -         (if (> end (+ start 2))
 +       (if (consp c)
 +           (if (= (1- (car c)) end) (setq end (cdr c))
 +             (if (> end (+ start 2))
 +                 (setq charset (format "%s%c-%c" charset start end))
 +               (while (>= end start)
 +                 (setq charset (format "%s%c" charset start))
 +                 (incf start)))
 +             (setq start (car c) end (cdr c)))
 +         (if (= (1- c) end) (setq end c)
 +           (if (> end (+ start 2))
               (setq charset (format "%s%c-%c" charset start end))
             (while (>= end start)
               (setq charset (format "%s%c" charset start))
               (incf start)))
 -         (setq start c end c))))
 +           (setq start c end c)))))
       charmap)
      (when (>= end start)
        (if (> end (+ start 2))
diff --combined lisp/emulation/keypad.el
index fa6310e901774e84507fffa174193a8a06708f8d,28054c2dcb3d70dccb676fdc3d8969d39105d0d1..d691cf5fdf74bb60699afe24c10c91b2ec0925c3
@@@ -1,7 -1,7 +1,7 @@@
  ;;; keypad.el --- simplified keypad bindings
  
- ;; Copyright (C) 2002, 2003, 2004, 2005,
- ;;   2006 Free Software Foundation, Inc.
+ ;; Copyright (C) 2002, 2003, 2004, 2005, 2006,
+ ;;   2007 Free Software Foundation, Inc.
  
  ;; Author: Kim F. Storm <storm@cua.dk>
  ;; Keywords: keyboard convenience
@@@ -194,9 -194,9 +194,9 @@@ decimal key must be specified.
  
  ;;;###autoload
  (defun keypad-setup (setup &optional numlock shift decimal)
-   "Set keypad bindings in function-key-map according to SETUP.
+   "Set keypad bindings in `function-key-map' according to SETUP.
  If optional second argument NUMLOCK is non-nil, the NumLock On bindings
- are changed. Otherwise, the NumLock Off bindings are changed.
+ are changed.  Otherwise, the NumLock Off bindings are changed.
  If optional third argument SHIFT is non-nil, the shifted keypad
  keys are bound.
  
@@@ -234,7 -234,7 +234,7 @@@ the decimal key on the keypad is mappe
         (bind
          (cond
           ((or (eq setup 'numeric)
 -              (char-valid-p setup))
 +              (characterp setup))
            (if (eq decimal 'numeric)
                (setq decimal nil))
            (vector (or decimal ?.) ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
diff --combined lisp/eshell/esh-mode.el
index 35c3fb36850548922d2456c76ef3bc7f4a01dfd7,c185e88d8a87114558e04a3b5fc1bfff63401f99..0c565ed61c00619222f648a930b06267eeeecf01
@@@ -1,7 -1,7 +1,7 @@@
  ;;; esh-mode.el --- user interface
  
  ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: John Wiegley <johnw@gnu.org>
  
@@@ -281,11 -281,8 +281,11 @@@ This is used by `eshell-watch-for-passw
        (map-char-table
         (function
          (lambda (key val)
 -          (and (>= key 256)
 -               (/= (char-syntax key) ?w)
 +          (and (if (consp key)
 +                   (and (>= (car key) 128)
 +                        (/= (char-syntax (car key)) ?w))
 +                 (and (>= key 256)
 +                      (/= (char-syntax key) ?w)))
                 (modify-syntax-entry key "_   "
                                      eshell-mode-syntax-table))))
         (standard-syntax-table)))))
diff --combined lisp/eshell/esh-opt.el
index 8c4c5f5fdc118b0f3c5ffde4b336f73d44627d73,8e7b44174ce5f6209bbe946b6144d949dab88456..7f697c7ba4364428076bcbb3cce526dee4694e0d
@@@ -1,7 -1,7 +1,7 @@@
  ;;; esh-opt.el --- command options processing
  
  ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: John Wiegley <johnw@gnu.org>
  
@@@ -195,7 -195,7 +195,7 @@@ switch is unrecognized.
          (setq extcmd (eshell-search-path (cadr extcmd)))
          (if extcmd
              (throw 'eshell-ext-command extcmd)
 -          (if (char-valid-p switch)
 +          (if (characterp switch)
                (error "%s: unrecognized option -%c" name switch)
              (error "%s: unrecognized option --%s" name switch))))))))
  
diff --combined lisp/faces.el
index 8beb5d69f5c2880bfd487a008c191452b95850b6,7b521d385b1a8c0e42ba2f8b2900abeddd78ff75..f622bb0426c85643177e31b5d88872bb218189fd
@@@ -1,7 -1,7 +1,7 @@@
  ;;; faces.el --- Lisp faces
  
  ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
- ;;   2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: internal
@@@ -81,11 -81,11 +81,11 @@@ ALTERNATIVE2 etc.
  (defcustom face-font-registry-alternatives
    (if (eq system-type 'windows-nt)
        '(("iso8859-1" "ms-oemlatin")
 -      ("gb2312.1980" "gb2312")
 +      ("gb2312.1980" "gb2312" "gbk" "gb18030")
        ("jisx0208.1990" "jisx0208.1983" "jisx0208.1978")
        ("ksc5601.1989" "ksx1001.1992" "ksc5601.1987")
        ("muletibetan-2" "muletibetan-0"))
 -    '(("gb2312.1980" "gb2312.80&gb8565.88" "gbk*")
 +    '(("gb2312.1980" "gb2312.80&gb8565.88" "gbk" "gb18030")
        ("jisx0208.1990" "jisx0208.1983" "jisx0208.1978")
        ("ksc5601.1989" "ksx1001.1992" "ksc5601.1987")
        ("muletibetan-2" "muletibetan-0")))
@@@ -103,63 -103,6 +103,63 @@@ REGISTRY, ALTERNATIVE1, ALTERNATIVE2, a
           (internal-set-alternative-font-registry-alist value)))
  
  
 +(defcustom font-weight-table
 +  '((thin . 0)
 +    (ultralight . 40) (ultra-light . 40) (extra-light . 40)
 +    (light . 50)
 +    (semilight . 65) (semi-light . 65)
 +    (book . 75)
 +    (medium . 100) (regular . 100) (normal . 100)
 +    (semibold . 180) (semi-bold . 180) (demibold . 180) (demi . 180)
 +    (bold . 200)
 +    (extrabold . 205) (extra-bold . 205)
 +    (ultrabold . 205) (ultra-bold . 205)
 +    (black . 210) (heavy . 210))
 +  "*Alist of font weight symbols vs the corresponding numeric values."
 +  :tag "Font weight table"
 +  :version "23.1"
 +  :group 'font-selection
 +  :type '(repeat (cons symbol integer))
 +  :set #'(lambda (symbol value)
 +         (set-default symbol value)
 +         (if (fboundp 'internal-set-font-style-table)
 +             (internal-set-font-style-table :weight value))))
 +
 +(defcustom font-slant-table
 +  '((ro . 0)
 +    (ri . 10)
 +    (r . 100) (roman . 100) (normal . 100)
 +    (i . 200) (italic . 200) (ot . 200)
 +    (o . 210) (oblique . 210))
 +  "*Alist of font slant symbols vs the corresponding numeric values."
 +  :tag "Font slant table"
 +  :version "23.1"
 +  :group 'font-selection
 +  :type '(repeat (cons symbol integer))
 +  :set #'(lambda (symbol value)
 +         (set-default symbol value)
 +         (if (fboundp 'internal-set-font-style-table)
 +             (internal-set-font-style-table :slant value))))
 +
 +(defcustom font-swidth-table
 +  '((ultracondensed . 50) (ultra-condensed . 50)
 +    (extracondensed . 63) (extra-condensed . 63)
 +    (condensed . 75) (compressed . 75) (narrow . 75)
 +    (semicondensed . 87) (semi-condensed . 87)
 +    (normal . 100) (medium . 100) (regular . 100)
 +    (semiexpanded . 113) (semi-expanded . 113) (demiexpanded . 113)
 +    (expanded . 125)
 +    (extraexpanded . 150) (extra-expanded . 150)
 +    (ultraexpanded . 200) (ultra-expanded . 200) (wide . 200))
 +  "*Alist of font swidth symbols vs the corresponding numeric values."
 +  :tag "Font swidth table"
 +  :version "23.1"
 +  :group 'font-selection
 +  :type '(repeat (cons symbol integer))
 +  :set #'(lambda (symbol value)
 +         (set-default symbol value)
 +         (if (fboundp 'internal-set-font-style-table)
 +             (internal-set-font-style-table :width value))))
  \f
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;; Creation, copying.
@@@ -1158,7 -1101,7 +1158,7 @@@ of a global face.  Value is the new att
  If optional argument FRAME is nil or omitted, use the selected frame."
    (let ((completion-ignore-case t))
      (completing-read (format "Set font attributes of face `%s' from font: " face)
 -                   (x-list-fonts "*" nil frame))))
 +                   (append (fontset-list) (x-list-fonts "*" nil frame)))))
  
  
  (defun read-all-face-attributes (face &optional frame)
@@@ -1332,8 -1275,7 +1332,8 @@@ If FRAME is omitted or nil, use the sel
                  (:box . "Box")
                  (:inverse-video . "Inverse")
                  (:stipple . "Stipple")
 -                (:font . "Font or fontset")
 +                (:font . "Font")
 +                (:fontset . "Fontset")
                  (:inherit . "Inherit")))
        (max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x)))
                                        attrs))))
@@@ -2176,6 -2118,12 +2176,12 @@@ created.
    :version "22.1"
    :group 'basic-faces)
  
+ (defface momentary
+   '((t (:inherit mode-line)))
+   "Face for momentarily displaying text in the current buffer."
+   :version "22.1"
+   :group 'basic-faces)
  (defface minibuffer-prompt
    '((((background dark)) :foreground "cyan")
      ;; Don't use blue because many users of the MS-DOS port customize
diff --combined lisp/font-lock.el
index 1bae9cba362a62cac07851e10ab28cbbb1805feb,69ba694340ba1d7e18deec8c43390cfb3134be38..fc57a6548b671f647890c4c5333cf9963d293935
@@@ -1,7 -1,7 +1,7 @@@
  ;;; font-lock.el --- Electric font lock mode
  
  ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Author: jwz, then rms, then sm
  ;; Maintainer: FSF
@@@ -2102,8 -2102,7 +2102,8 @@@ This function could be MATCHER in a MAT
            ;; Move over any item value, etc., to the next item.
            (while (not (looking-at "[ \t\n]*\\(\\(,\\)\\|;\\|\\'\\)"))
              (goto-char (or (scan-sexps (point) 1) (point-max))))
 -          (goto-char (match-end 2)))
 +          (if (match-end 2)
 +              (goto-char (match-end 2))))
        (error t)))))
  
  ;; C preprocessor(cpp) is used outside of C, C++ and Objective-C source file.
diff --combined lisp/format.el
index 5f3c02ed7c41f89cec17fae598438822e6235af1,287f2d7ce72379cc104c52c0e9a00eafae4f117b..a52f27c4b41fa86653e4d1759b172206be735ed7
@@@ -1,7 -1,7 +1,7 @@@
  ;;; format.el --- read and save files in multiple formats
  
  ;; Copyright (C) 1994, 1995, 1997, 1999, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Boris Goldowsky <boris@gnu.org>
  
           ;; Plain only exists so that there is an obvious neutral choice in
           ;; the completion list.
           nil nil nil nil nil)
 -    (ibm   "IBM Code Page 850 (DOS)"
 -         nil                          ; The original "1\\(^\\)" is obscure.
 -         "recode -f ibm-pc:latin1" "recode -f latin1:ibm-pc" t nil)
 -    (mac   "Apple Macintosh"
 -         nil
 -         "recode -f mac:latin1" "recode -f latin1:mac" t nil)
 -    (hp    "HP Roman8"
 -         nil
 -         "recode -f roman8:latin1" "recode -f latin1:roman8" t nil)
      (TeX   "TeX (encoding)"
           nil
           iso-tex2iso iso-iso2tex t nil)
diff --combined lisp/gnus/gnus-start.el
index 0486392818ec83cf0357bee55fb82043fd7d0249,9fbab8b340b1bfebf43a0f579e9457bbc48222ca..72748fc359c7e17b966dc46ae418f583d2296e11
@@@ -1,7 -1,7 +1,7 @@@
  ;;; gnus-start.el --- startup functions for Gnus
  
  ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  ;; Keywords: news
@@@ -458,8 -458,6 +458,8 @@@ Can be used to turn version control on 
  
  ;;; Internal variables
  
 +;; Fixme: deal with old emacs-mule when mm-universal-coding-system is
 +;; utf-8-emacs.
  (defvar gnus-ding-file-coding-system mm-universal-coding-system
    "Coding system for ding file.")
  
@@@ -2373,7 -2371,8 +2373,7 @@@ If FORCE is non-nil, the .newsrc file i
        ;; We always, always read the .eld file.
        (gnus-message 5 "Reading %s..." ding-file)
        (let (gnus-newsrc-assoc)
 -      (let ((coding-system-for-read gnus-ding-file-coding-system))
 -        (gnus-load ding-file))
 +      (gnus-load ding-file)
        ;; Older versions of `gnus-format-specs' are no longer valid
        ;; in Oort Gnus 0.01.
        (let ((version
  
  (defun gnus-gnus-to-quick-newsrc-format (&optional minimal name &rest specific-variables)
    "Print Gnus variables such as `gnus-newsrc-alist' in Lisp format."
 -    (princ ";; -*- emacs-lisp -*-\n")
 +    (princ (format ";; -*- mode:emacs-lisp; coding: %s; -*-\n"
 +                 gnus-ding-file-coding-system))
      (if name
        (princ (format ";; %s\n" name))
        (princ ";; Gnus startup file.\n"))
diff --combined lisp/gnus/mm-bodies.el
index a1d51a1b9ead39f19126f1609bbe5ac7922c0654,c701932ebf6adad937adc962c8b4d7b3be422e6a..46f6fb83187fd346463dfe5ecbf490ac26c12807
@@@ -1,7 -1,7 +1,7 @@@
  ;;; mm-bodies.el --- Functions for decoding MIME things
  
  ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  ;;    MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@@ -101,7 -101,8 +101,7 @@@ If no encoding was done, nil is returne
                                     (mm-charset-to-coding-system charset))
            charset)
        (goto-char (point-min))
 -      (let ((charsets (mm-find-mime-charset-region (point-min) (point-max)
 -                                                   mm-hack-charsets)))
 +      (let ((charsets (mm-find-mime-charset-region (point-min) (point-max))))
          (cond
           ;; No encoding.
           ((null charsets)
diff --combined lisp/gnus/mm-util.el
index 402e824af23f87390df22e0dd7530da28299e206,742bbc223aef9b0ba11e077f77f48a7c006f1dc7..3508c1ac4064b8f3b3221791c6493e0afcb26d59
@@@ -1,7 -1,7 +1,7 @@@
  ;;; mm-util.el --- Utility functions for Mule and low level things
  
  ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  ;;    MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@@ -450,10 -450,6 +450,10 @@@ could use `autoload-coding-system' here
      (iso-2022-jp latin-jisx0201 japanese-jisx0208 japanese-jisx0208-1978)
      (euc-kr korean-ksc5601)
      (gb2312 chinese-gb2312)
 +    (gbk chinese-gbk)
 +    (gb18030 gb18030-2-byte
 +           gb18030-4-byte-bmp gb18030-4-byte-smp
 +           gb18030-4-byte-ext-1 gb18030-4-byte-ext-2)
      (big5 chinese-big5-1 chinese-big5-2)
      (tibetan tibetan)
      (thai-tis620 thai-tis620)
@@@ -522,7 -518,7 +522,7 @@@ with Mule charsets.  It is completely u
          cs mime mule alist)
        (while css
        (setq cs (pop css)
 -            mime (or (coding-system-get cs :mime-charset) ; Emacs 23 (unicode)
 +            mime (or (coding-system-get cs :mime-charset); Emacs 23 (unicode)
                       (coding-system-get cs 'mime-charset)))
        (when (and mime
                   (not (eq t (setq mule
          (push (cons mime (delq 'ascii mule)) alist)))
        (setq mm-mime-mule-charset-alist (nreverse alist)))))
  
 -(defvar mm-hack-charsets '(iso-8859-15 iso-2022-jp-2)
 -  "A list of special charsets.
 -Valid elements include:
 -`iso-8859-15'    convert ISO-8859-1, -9 to ISO-8859-15 if ISO-8859-15 exists.
 -`iso-2022-jp-2'  convert ISO-2022-jp to ISO-2022-jp-2 if ISO-2022-jp-2 exists."
 -)
 -
 -(defvar mm-iso-8859-15-compatible
 -  '((iso-8859-1 "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE")
 -    (iso-8859-9 "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xD0\xDD\xDE\xF0\xFD\xFE"))
 -  "ISO-8859-15 exchangeable coding systems and inconvertible characters.")
 -
 -(defvar mm-iso-8859-x-to-15-table
 -  (and (fboundp 'coding-system-p)
 -       (mm-coding-system-p 'iso-8859-15)
 -       (mapcar
 -      (lambda (cs)
 -        (if (mm-coding-system-p (car cs))
 -            (let ((c (string-to-char
 -                      (decode-coding-string "\341" (car cs)))))
 -              (cons (char-charset c)
 -                    (cons
 -                     (- (string-to-char
 -                         (decode-coding-string "\341" 'iso-8859-15)) c)
 -                     (string-to-list (decode-coding-string (car (cdr cs))
 -                                                           (car cs))))))
 -          '(gnus-charset 0)))
 -      mm-iso-8859-15-compatible))
 -  "A table of the difference character between ISO-8859-X and ISO-8859-15.")
 -
  (defcustom mm-coding-system-priorities
    (if (boundp 'current-language-environment)
        (let ((lang (symbol-value 'current-language-environment)))
@@@ -787,6 -813,27 +787,6 @@@ This affects whether coding conversion 
          default-enable-multibyte-characters
        t)))
  
 -(defun mm-iso-8859-x-to-15-region (&optional b e)
 -  (if (fboundp 'char-charset)
 -      (let (charset item c inconvertible)
 -      (save-restriction
 -        (if e (narrow-to-region b e))
 -        (goto-char (point-min))
 -        (skip-chars-forward "\0-\177")
 -        (while (not (eobp))
 -          (cond
 -           ((not (setq item (assq (char-charset (setq c (char-after)))
 -                                  mm-iso-8859-x-to-15-table)))
 -            (forward-char))
 -           ((memq c (cdr (cdr item)))
 -            (setq inconvertible t)
 -            (forward-char))
 -           (t
 -            (insert-before-markers (prog1 (+ c (car (cdr item)))
 -                                     (delete-char 1)))))
 -          (skip-chars-forward "\0-\177")))
 -      (not inconvertible))))
 -
  (defun mm-sort-coding-systems-predicate (a b)
    (let ((priorities
         (mapcar (lambda (cs)
@@@ -923,14 -970,32 +923,14 @@@ charset, and a longer list means no app
        ;; Otherwise, we'll get nil, and the next setq will get invoked.
        (setq charsets (mm-xemacs-find-mime-charset b e))
  
 +      ;; Fixme: won't work for unibyte Emacs 23:
 +
        ;; We're not multibyte, or a single coding system won't cover it.
        (setq charsets
              (mm-delete-duplicates
               (mapcar 'mm-mime-charset
                       (delq 'ascii
                             (mm-find-charset-region b e))))))
 -    (if (and (> (length charsets) 1)
 -           (memq 'iso-8859-15 charsets)
 -           (memq 'iso-8859-15 hack-charsets)
 -           (save-excursion (mm-iso-8859-x-to-15-region b e)))
 -      (mapcar (lambda (x) (setq charsets (delq (car x) charsets)))
 -              mm-iso-8859-15-compatible))
 -    (if (and (memq 'iso-2022-jp-2 charsets)
 -           (memq 'iso-2022-jp-2 hack-charsets))
 -      (setq charsets (delq 'iso-2022-jp charsets)))
 -    ;; Attempt to reduce the number of charsets if utf-8 is available.
 -    (if (and (featurep 'xemacs)
 -           (> (length charsets) 1)
 -           (mm-coding-system-p 'utf-8))
 -      (let ((mm-coding-system-priorities
 -             (cons 'utf-8 mm-coding-system-priorities)))
 -        (setq charsets
 -              (mm-delete-duplicates
 -               (mapcar 'mm-mime-charset
 -                       (delq 'ascii
 -                             (mm-find-charset-region b e)))))))
      charsets))
  
  (defmacro mm-with-unibyte-buffer (&rest forms)
diff --combined lisp/gnus/mml.el
index 9744ab0ac8641331f3fc46b868f05e8fb1f54571,ae4de03edd01fbb284b05be6e2169ceb6bb0b58c..afa33632fa23c5e3f02ba407010224bad33455b5
@@@ -1,7 -1,7 +1,7 @@@
  ;;; mml.el --- A package for parsing and validating MML documents
  
  ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  ;; This file is part of GNU Emacs.
@@@ -233,7 -233,8 +233,7 @@@ part.  This is for the internal use, yo
                         (list
                          (intern (downcase (cdr (assq 'charset tag))))))
                        (t
 -                       (mm-find-mime-charset-region point (point)
 -                                                    mm-hack-charsets))))
 +                       (mm-find-mime-charset-region point (point)))))
        (when (and (not raw) (memq nil charsets))
          (if (or (memq 'unknown-encoding mml-confirmation-set)
                  (message-options-get 'unknown-encoding)
diff --combined lisp/gnus/rfc2047.el
index 4ac26c1615821aa6a342df0d3c9b6c674ee6b2b3,6dc432daf796aefe7db364523dd6b627a000713c..b7d25d87c68800710a7678b3c5c8676f2954a090
@@@ -1,7 -1,7 +1,7 @@@
  ;;; rfc2047.el --- functions for encoding and decoding rfc2047 messages
  
  ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  ;;    MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@@ -107,8 -107,6 +107,8 @@@ The values can be
      (iso-2022-jp . B)
      (iso-2022-kr . B)
      (gb2312 . B)
 +    (gbk . B)
 +    (gb18030 . B)
      (big5 . B)
      (cn-big5 . B)
      (cn-gb . B)
@@@ -328,7 -326,7 +328,7 @@@ The buffer may be narrowed.
    ;; (make-char-table 'syntax-table '(2)) only works in Emacs.
    (let ((table (make-syntax-table)))
      ;; The following is done to work for setting all elements of the table
 -    ;; in Emacs 21 and 22 and XEmacs; it appears to be the cleanest way.
 +    ;; in Emacs 21-23 and XEmacs; it appears to be the cleanest way.
      ;; Play safe and don't assume the form of the word syntax entry --
      ;; copy it from ?a.
      (if (fboundp 'set-char-table-range)       ; Emacs
diff --combined lisp/gnus/rfc2104.el
index e0727984bb4de01e73efb0e87a0873e38568ff81,8af59e00a3b7b1b8b252a91e71bc886ed671c734..c52d47b3e158f3ce9dc5c2bd10c3988d8b25a10e
@@@ -1,7 -1,7 +1,7 @@@
  ;;; rfc2104.el --- RFC2104 Hashed Message Authentication Codes
  
  ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Simon Josefsson <jas@pdc.kth.se>
  ;; Keywords: mail
@@@ -53,7 -53,6 +53,7 @@@
  ;;; 1999-10-23  included in pgnus
  ;;; 2000-08-15  `rfc2104-hexstring-to-bitstring'
  ;;; 2000-05-12  added sha-1 example, added test case reference
 +;;; 2003-11-13  change rfc2104-hexstring-to-bitstring to ...-byte-list
  
  ;;; Code:
  
        (rfc2104-hex-to-int (reverse (append str nil))))
      0))
  
 -(defun rfc2104-hexstring-to-bitstring (str)
 +(defun rfc2104-hexstring-to-byte-list (str)
    (let (out)
      (while (< 0 (length str))
        (push (rfc2104-hex-to-int (substring str -2)) out)
        (setq str (substring str 0 -2)))
 -    (concat out)))
 +    out))
  
  (defun rfc2104-hash (hash block-length hash-length key text)
    (let* (;; if key is longer than B, reset it to HASH(key)
      (setq k_ipad (mapcar (lambda (c) (logxor c rfc2104-ipad)) k_ipad))
      (setq k_opad (mapcar (lambda (c) (logxor c rfc2104-opad)) k_opad))
      ;; perform outer hash
 -    (funcall hash (concat k_opad (rfc2104-hexstring-to-bitstring
 -                                ;; perform inner hash
 -                                (funcall hash (concat k_ipad text)))))))
 +    (funcall hash
 +           (encode-coding-string
 +            (concat k_opad (rfc2104-hexstring-to-byte-list
 +                            ;; perform inner hash
 +                            (funcall hash (concat k_ipad text))))
 +            'iso-latin-1))))
  
  (provide 'rfc2104)
  
diff --combined lisp/info.el
index 237ca7a968e60477fba0c694ca5302b4988ccc2a,fb124d6ff542d07cc07c4716f94e7d5526dcc6a9..2ed881080092c0ed79cd35c77cf1882f97ee8a75
@@@ -1,7 -1,7 +1,7 @@@
  ;;; info.el --- info package for Emacs
  
  ;; Copyright (C) 1985, 1986, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: help
@@@ -463,12 -463,12 +463,12 @@@ Do the right thing if the file has bee
                     (expand-file-name "info/" installation-directory)
                   (if invocation-directory
                       (let ((infodir (expand-file-name
-                                      "../info/"
+                                      "../share/info/"
                                       invocation-directory)))
                         (if (file-exists-p infodir)
                             infodir
                           (setq infodir (expand-file-name
-                                         "../../../info/"
+                                         "../../../share/info/"
                                          invocation-directory))
                           (and (file-exists-p infodir)
                                infodir))))))
@@@ -3700,8 -3700,7 +3700,8 @@@ the variable `Info-file-list-for-emacs'
             (case-fold-search t)
             paragraph-markers
             (not-fontified-p ; the node hasn't already been fontified
 -            (not (let ((where (next-property-change (point-min))))
 +            (not (let ((where (next-single-property-change (point-min) 
 +                                                         'font-lock-face)))
                     (and where (not (= where (point-max)))))))
             (fontify-visited-p ; visited nodes need to be re-fontified
              (and Info-fontify-visited-nodes
                                    (setq res (car hl) hl nil)
                                  (setq hl (cdr hl))))
                                res))) 'info-xref-visited 'info-xref)))
-             (when (and not-fontified-p (memq Info-hide-note-references '(t hide)))
+             (when (and not-fontified-p
+                        (memq Info-hide-note-references '(t hide))
+                        (not (Info-index-node)))
                (put-text-property (match-beginning 2) (1- (match-end 6))
                                   'invisible t)
                ;; Unhide the file name in parens
index 9e8160d9c10145ac5d1908bab2e7638a7a232b21,2a6939da5f57de220d2c03771c4e2982300741b0..5a00f4b9bf25ab50a17ce611ca758c306c6b5b87
@@@ -1,9 -1,9 +1,9 @@@
  ;;; ccl.el --- CCL (Code Conversion Language) compiler
  
  ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005,
- ;;   2006  Free Software Foundation, Inc.
+ ;;   2006, 2007  Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  ;; Embed string STR of length LEN in `ccl-program-vector' at
  ;; `ccl-current-ic'.
  (defun ccl-embed-string (len str)
 -  (let ((i 0))
 -    (while (< i len)
 -      (ccl-embed-data (logior (ash (aref str i) 16)
 -                             (if (< (1+ i) len)
 -                                 (ash (aref str (1+ i)) 8)
 -                               0)
 -                             (if (< (+ i 2) len)
 -                                 (aref str (+ i 2))
 -                               0)))
 -      (setq i (+ i 3)))))
 +  (if (> len #xFFFFF)
 +      (error "CCL: String too long: %d" len))
 +  (if (> (string-bytes str) len)
 +      (dotimes (i len)
 +      (ccl-embed-data (logior #x1000000 (aref str i))))
 +    (let ((i 0))
 +      (while (< i len)
 +      (ccl-embed-data (logior (ash (aref str i) 16)
 +                              (if (< (1+ i) len)
 +                                  (ash (aref str (1+ i)) 8)
 +                                0)
 +                              (if (< (+ i 2) len)
 +                                  (aref str (+ i 2))
 +                                0)))
 +      (setq i (+ i 3))))))
  
  ;; Embed a relative jump address to `ccl-current-ic' in
  ;; `ccl-program-vector' at IC without altering the other bit field.
  
  ;; Compile WRITE statement with string argument.
  (defun ccl-compile-write-string (str)
 -  (setq str (string-as-unibyte str))
    (let ((len (length str)))
      (ccl-embed-code 'write-const-string 1 len)
      (ccl-embed-string len str))
           (ccl-embed-code 'write-const-jump 0 ccl-loop-head)
           (ccl-embed-data arg))
          ((stringp arg)
 -         (setq arg (string-as-unibyte arg))
           (let ((len (length arg))
                 (i 0))
             (ccl-embed-code 'write-string-jump 0 ccl-loop-head)
        (error "CCL: Invalid number of arguments: %s" cmd))
    (let ((rrr (nth 1 cmd)))
      (cond ((integerp rrr)
 -         (ccl-embed-code 'write-const-string 0 rrr))
 +         (if (> rrr #xFFFFF)
 +             (ccl-compile-write-string (string rrr))
 +           (ccl-embed-code 'write-const-string 0 rrr)))
          ((stringp rrr)
           (ccl-compile-write-string rrr))
          ((and (symbolp rrr) (vectorp (nth 2 cmd)))
        (insert "write \"")
        (while (< i len)
        (let ((code (ccl-get-next-code)))
 -        (insert (format "%c" (lsh code -16)))
 -        (if (< (1+ i) len)
 -            (insert (format "%c" (logand (lsh code -8) 255))))
 -        (if (< (+ i 2) len)
 -            (insert (format "%c" (logand code 255))))
 -        (setq i (+ i 3))))
 +        (if (/= (logand code #x1000000) 0)
 +            (progn
 +              (insert (logand code #xFFFFFF))
 +              (setq i (1+ i)))
 +          (insert (format "%c" (lsh code -16)))
 +          (if (< (1+ i) len)
 +              (insert (format "%c" (logand (lsh code -8) 255))))
 +          (if (< (+ i 2) len)
 +              (insert (format "%c" (logand code 255))))
 +          (setq i (+ i 3)))))
        (insert "\"\n"))))
  
  (defun ccl-dump-write-array (rrr cc)
@@@ -1518,12 -1509,7 +1518,12 @@@ MAP-IDs := MAP-ID ..
  MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET
  MAP-ID := integer
  "
 -  `(let ((prog ,(ccl-compile (eval ccl-program))))
 +  `(let ((prog ,(unwind-protect
 +                  (progn
 +                    ;; To make ,(charset-id CHARSET) works well.
 +                    (fset 'charset-id 'charset-id-internal)
 +                    (ccl-compile (eval ccl-program)))
 +                (fmakunbound 'charset-id))))
       (defconst ,name prog ,doc)
       (put ',name 'ccl-program-idx (register-ccl-program ',name prog))
       nil))
index e52df15a9b2dd2c539da4da1b0ab91c7fececfe0,acc1458ac9cce1975cace3d2cf6117aeda3bc54c..a75fe28a08b37d3c6bba3f65cef47d4b9e167eb9
@@@ -1,14 -1,11 +1,14 @@@
  ;;; characters.el --- set syntax and category for multibyte characters
  
- ;; Copyright (C) 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multibyte character, character set, syntax, category
  
  
  ;;; Commentary:
  
 -;; This file contains multibyte characters.  Save this file always in
 -;; the coding system `iso-2022-7bit'.
 -
 -;; This file does not define the syntax for Latin-N character sets;
 -;; those are defined by the files latin-N.el.
 -
  ;;; Code:
  
 -;; We must set utf-translate-cjk-mode to nil while loading this file
 -;; to avoid translating CJK characters in decode-char.
 -(defvar saved-utf-translate-cjk-mode utf-translate-cjk-mode)
 -(setq utf-translate-cjk-mode nil)
 -
  ;;; Predefined categories.
  
  ;; For each character set.
  
  ;; ASCII
  
 -(let ((ch 32))
 -  (while (< ch 127)                   ; All ASCII characters have
 -    (modify-category-entry ch ?a)     ; the category `a' (ASCII)
 -    (modify-category-entry ch ?l)     ; and `l' (Latin).
 -    (setq ch (1+ ch))))
 +;; All ASCII characters have the category `a' (ASCII) and `l' (Latin).
 +(modify-category-entry '(32 . 127) ?a)
 +(modify-category-entry '(32 . 127) ?l)
  
 -;; Arabic character set
 +;; Deal with the CJK charsets first.  Since the syntax of blocks is
 +;; defined per charset, and the charsets may contain e.g. Latin
 +;; characters, we end up with the wrong syntax definitions if we're
 +;; not careful.
  
 -(let ((charsets '(arabic-iso8859-6
 -                arabic-digit
 -                arabic-1-column
 -                arabic-2-column)))
 -  (while charsets
 -;;     (modify-syntax-entry (make-char (car charsets)) "w")
 -    (modify-category-entry (make-char (car charsets)) ?b)
 -    (setq charsets (cdr charsets))))
 -(let ((ch #x600))
 -  (while (<= ch #x6ff)
 -    (modify-category-entry (decode-char 'ucs ch) ?b)
 -    (setq ch (1+ ch)))
 -  (setq ch #xfb50)
 -  (while (<= ch #xfdff)
 -    (modify-category-entry (decode-char 'ucs ch) ?b)
 -    (setq ch (1+ ch)))
 -  (setq ch #xfe70)
 -  (while (<= ch #xfefe)
 -    (modify-category-entry (decode-char 'ucs ch) ?b)
 -    (setq ch (1+ ch))))
 -
 -;; Chinese character set (GB2312)
 +;; Chinese characters (Unicode)
 +(modify-category-entry '(#x2E80 . #x312F) ?|)
 +(modify-category-entry '(#x3190 . #x33FF) ?|)
 +(modify-category-entry '(#x3400 . #x9FAF) ?C)
 +(modify-category-entry '(#x3400 . #x9FAF) ?c)
 +(modify-category-entry '(#x3400 . #x9FAF) ?|)
 +(modify-category-entry '(#xF900 . #xFAFF) ?C)
 +(modify-category-entry '(#xF900 . #xFAFF) ?c)
 +(modify-category-entry '(#xF900 . #xFAFF) ?|)
 +(modify-category-entry '(#x20000 . #x2AFFF) ?|)
 +(modify-category-entry '(#x2F800 . #x2FFFF) ?|)
  
 -;; (modify-syntax-entry (make-char 'chinese-gb2312) "w")
 -(modify-syntax-entry (make-char 'chinese-gb2312 33) "_")
 -(modify-syntax-entry (make-char 'chinese-gb2312 34) "_")
 -(modify-syntax-entry (make-char 'chinese-gb2312 41) "_")
 -(modify-syntax-entry ?\\e$A!2\e(B "(\e$A!3\e(B")
 -(modify-syntax-entry ?\\e$A!4\e(B "(\e$A!5\e(B")
 -(modify-syntax-entry ?\\e$A!6\e(B "(\e$A!7\e(B")
 -(modify-syntax-entry ?\\e$A!8\e(B "(\e$A!9\e(B")
 -(modify-syntax-entry ?\\e$A!:\e(B "(\e$A!;\e(B")
 -(modify-syntax-entry ?\\e$A!<\e(B "(\e$A!=\e(B")
 -(modify-syntax-entry ?\\e$A!>\e(B "(\e$A!?\e(B")
 -(modify-syntax-entry ?\\e$A#(\e(B "(\e$A#)\e(B")
 -(modify-syntax-entry ?\\e$A#{\e(B "(\e$A#}\e(B")
 -(modify-syntax-entry ?\\e$A#[\e(B "(\e$A#]\e(B")
 -(modify-syntax-entry ?\\e$A!3\e(B ")\e$A!2\e(B")
 -(modify-syntax-entry ?\\e$A!5\e(B ")\e$A!4\e(B")
 -(modify-syntax-entry ?\\e$A!7\e(B ")\e$A!6\e(B")
 -(modify-syntax-entry ?\\e$A!9\e(B ")\e$A!8\e(B")
 -(modify-syntax-entry ?\\e$A!;\e(B ")\e$A!:\e(B")
 -(modify-syntax-entry ?\\e$A!=\e(B ")\e$A!<\e(B")
 -(modify-syntax-entry ?\\e$A!?\e(B ")\e$A!>\e(B")
 -(modify-syntax-entry ?\\e$A#)\e(B ")\e$A#(\e(B")
 -(modify-syntax-entry ?\\e$A#}\e(B ")\e$A#{\e(B")
 -(modify-syntax-entry ?\\e$A#]\e(B ")\e$A#[\e(B")
 -
 -(let ((chars "\e$A#,!"!##.!$#;#:#?#!!C!-!'#|#_!.!/!0!1#"!e#`!d\e(B"))
 -  (dotimes (i (length chars))
 -    (modify-syntax-entry (aref chars i) ".")))
 -
 -(modify-category-entry (make-char 'chinese-gb2312) ?c)
 -(modify-category-entry (make-char 'chinese-gb2312) ?\|)
 -(modify-category-entry (make-char 'chinese-gb2312 35) ?A)
 -(modify-category-entry (make-char 'chinese-gb2312 36) ?H)
 -(modify-category-entry (make-char 'chinese-gb2312 37) ?K)
 -(modify-category-entry (make-char 'chinese-gb2312 38) ?G)
 -(modify-category-entry (make-char 'chinese-gb2312 39) ?Y)
 -(let ((row 48))
 -  (while (< row 127)
 -    (modify-category-entry (make-char 'chinese-gb2312 row) ?C)
 -    (setq row (1+ row))))
 -
 -(let ((tbl (standard-case-table)))
 -  (dotimes (i 26)
 -    (set-case-syntax-pair (make-char 'chinese-gb2312 #x23 (+ #x41 i))
 -                        (make-char 'chinese-gb2312 #x23 (+ #x61 i)) tbl))
 -  (dotimes (i 24)
 -    (set-case-syntax-pair (make-char 'chinese-gb2312 #x26 (+ #x21 i))
 -                        (make-char 'chinese-gb2312 #x26 (+ #x41 i)) tbl))
 -  (dotimes (i 33)
 -    (set-case-syntax-pair (make-char 'chinese-gb2312 #x27 (+ #x21 i))
 -                        (make-char 'chinese-gb2312 #x27 (+ #x51 i)) tbl)))
 -
 -;; Chinese character set (BIG5)
  
 -(let ((from (decode-big5-char #xA141))
 -      (to (decode-big5-char #xA15D)))
 -  (while (< from to)
 -    (modify-syntax-entry from ".")
 -    (setq from (1+ from))))
 -(let ((from (decode-big5-char #xA1A5))
 -      (to (decode-big5-char #xA1AD)))
 -  (while (< from to)
 -    (modify-syntax-entry from ".")
 -    (setq from (1+ from))))
 -(let ((from (decode-big5-char #xA1AD))
 -      (to (decode-big5-char #xA2AF)))
 -  (while (< from to)
 -    (modify-syntax-entry from "_")
 -    (setq from (1+ from))))
 -
 -(let ((parens "\e$(0!>!?!@!A!B!C!D!E!F!G!H!I!J!K!L!M!N!O!P!Q!R!S!T!U!V!W!X!Y!Z![!\!]!^!_!`!a!b!c\e(B")
 -      open close)
 -  (dotimes (i (/ (length parens) 2))
 -    (setq open (aref parens (* i 2))
 -        close (aref parens (1+ (* i 2))))
 -    (modify-syntax-entry open (format "(%c" close))
 -    (modify-syntax-entry close (format ")%c" open))))
 -
 -(let ((generic-big5-1-char (make-char 'chinese-big5-1))
 -      (generic-big5-2-char (make-char 'chinese-big5-2)))
 -;;   (modify-syntax-entry generic-big5-1-char "w")
 -;;   (modify-syntax-entry generic-big5-2-char "w")
 -
 -  (modify-category-entry generic-big5-1-char ?c)
 -  (modify-category-entry generic-big5-2-char ?c)
 +;; Chinese character set (GB2312)
  
 -  (modify-category-entry generic-big5-1-char ?C)
 -  (modify-category-entry generic-big5-2-char ?C)
 +(map-charset-chars #'modify-syntax-entry 'chinese-gb2312 "_" #x2121 #x217E)
 +(map-charset-chars #'modify-syntax-entry 'chinese-gb2312 "_" #x2221 #x227E)
 +(map-charset-chars #'modify-syntax-entry 'chinese-gb2312 "_" #x2921 #x297E)
  
 -  (modify-category-entry generic-big5-1-char ?\|)
 -  (modify-category-entry generic-big5-2-char ?\|))
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?c)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?A #x2330 #x2339)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?A #x2341 #x235A)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?A #x2361 #x237A)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?H #x2421 #x247E)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?K #x2521 #x257E)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?G #x2621 #x267E)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?Y #x2721 #x277E)
 +(map-charset-chars #'modify-category-entry 'chinese-gb2312 ?C #x3021 #x7E7E)
  
 -(let ((tbl (standard-case-table)))
 -  (dotimes (i 22)
 -    (set-case-syntax-pair (decode-big5-char (+ #xA2CF i))
 -                        (decode-big5-char (+ #xA2CF i 26)) tbl))
 -  (dotimes (i 4)
 -    (set-case-syntax-pair (decode-big5-char (+ #xA2E4 i))
 -                        (decode-big5-char (+ #xA340 i)) tbl))
 -  (dotimes (i 24)
 -    (set-case-syntax-pair (decode-big5-char (+ #xA344 i))
 -                        (decode-big5-char (+ #xA344 i 24)) tbl)))
 +;; Chinese character set (BIG5)
  
 +(map-charset-chars #'modify-category-entry 'big5 ?c)
 +(map-charset-chars #'modify-category-entry 'big5 ?C #xA259 #xA25F)
 +(map-charset-chars #'modify-category-entry 'big5 ?C #xA440 #xC67E)
 +(map-charset-chars #'modify-category-entry 'big5 ?C #xC940 #xF9DF)
  
  ;; Chinese character set (CNS11643)
  
 -(let ((cns-list '(chinese-cns11643-1
 -                chinese-cns11643-2
 -                chinese-cns11643-3
 -                chinese-cns11643-4
 -                chinese-cns11643-5
 -                chinese-cns11643-6
 -                chinese-cns11643-7))
 -      generic-char)
 -  (while cns-list
 -    (setq generic-char (make-char (car cns-list)))
 -;;     (modify-syntax-entry generic-char "w")
 -    (modify-category-entry generic-char ?c)
 -    (modify-category-entry generic-char ?C)
 -    (modify-category-entry generic-char ?|)
 -    (setq cns-list (cdr cns-list))))
 -
 -(let ((parens "\e$(G!>!?!@!A!B!C!D!E!F!G!H!I!J!K!L!M!N!O!P!Q!R!S!T!U!V!W!X!Y!Z![!\!]!^!_!`!a!b!c\e(B")
 -      open close)
 -  (dotimes (i (/ (length parens) 2))
 -    (setq open (aref parens (* i 2))
 -        close (aref parens (1+ (* i 2))))
 -    (modify-syntax-entry open (format "(%c" close))
 -    (modify-syntax-entry close (format ")%c" open))))
 -
 -;; Cyrillic character set (ISO-8859-5)
 +(dolist (c '(chinese-cns11643-1 chinese-cns11643-2 chinese-cns11643-3
 +           chinese-cns11643-4 chinese-cns11643-5 chinese-cns11643-6
 +           chinese-cns11643-7))
 +  (map-charset-chars #'modify-category-entry c ?c)
 +  (if (eq c 'chinese-cns11643-1)
 +      (map-charset-chars #'modify-category-entry c ?C #x4421 #x7E7E)
 +    (map-charset-chars #'modify-category-entry c ?C)))
  
 -(modify-category-entry (make-char 'cyrillic-iso8859-5) ?y)
 -
 -(modify-syntax-entry (make-char 'cyrillic-iso8859-5 160) " ")
 -(modify-syntax-entry ?\e,L-\e(B ".")
 -(modify-syntax-entry ?\e,Lp\e(B ".")
 -(modify-syntax-entry ?\e,L}\e(B ".")
 -(let ((tbl (standard-case-table)))
 -  (set-case-syntax-pair ?\e,L!\e(B ?\e,Lq\e(B tbl)
 -  (set-case-syntax-pair ?\e,L"\e(B ?\e,Lr\e(B tbl)
 -  (set-case-syntax-pair ?\e,L#\e(B ?\e,Ls\e(B tbl)
 -  (set-case-syntax-pair ?\e,L$\e(B ?\e,Lt\e(B tbl)
 -  (set-case-syntax-pair ?\e,L%\e(B ?\e,Lu\e(B tbl)
 -  (set-case-syntax-pair ?\e,L&\e(B ?\e,Lv\e(B tbl)
 -  (set-case-syntax-pair ?\e,L'\e(B ?\e,Lw\e(B tbl)
 -  (set-case-syntax-pair ?\e,L(\e(B ?\e,Lx\e(B tbl)
 -  (set-case-syntax-pair ?\e,L)\e(B ?\e,Ly\e(B tbl)
 -  (set-case-syntax-pair ?\e,L*\e(B ?\e,Lz\e(B tbl)
 -  (set-case-syntax-pair ?\e,L+\e(B ?\e,L{\e(B tbl)
 -  (set-case-syntax-pair ?\e,L,\e(B ?\e,L|\e(B tbl)
 -  (set-case-syntax-pair ?\e,L.\e(B ?\e,L~\e(B tbl)
 -  (set-case-syntax-pair ?\e,L/\e(B ?\e,L\7f\e(B tbl)
 -  (set-case-syntax-pair ?\e,L0\e(B ?\e,LP\e(B tbl)
 -  (set-case-syntax-pair ?\e,L1\e(B ?\e,LQ\e(B tbl)
 -  (set-case-syntax-pair ?\e,L2\e(B ?\e,LR\e(B tbl)
 -  (set-case-syntax-pair ?\e,L3\e(B ?\e,LS\e(B tbl)
 -  (set-case-syntax-pair ?\e,L4\e(B ?\e,LT\e(B tbl)
 -  (set-case-syntax-pair ?\e,L5\e(B ?\e,LU\e(B tbl)
 -  (set-case-syntax-pair ?\e,L6\e(B ?\e,LV\e(B tbl)
 -  (set-case-syntax-pair ?\e,L7\e(B ?\e,LW\e(B tbl)
 -  (set-case-syntax-pair ?\e,L8\e(B ?\e,LX\e(B tbl)
 -  (set-case-syntax-pair ?\e,L9\e(B ?\e,LY\e(B tbl)
 -  (set-case-syntax-pair ?\e,L:\e(B ?\e,LZ\e(B tbl)
 -  (set-case-syntax-pair ?\e,L;\e(B ?\e,L[\e(B tbl)
 -  (set-case-syntax-pair ?\e,L<\e(B ?\e,L\\e(B tbl)
 -  (set-case-syntax-pair ?\e,L=\e(B ?\e,L]\e(B tbl)
 -  (set-case-syntax-pair ?\e,L>\e(B ?\e,L^\e(B tbl)
 -  (set-case-syntax-pair ?\e,L?\e(B ?\e,L_\e(B tbl)
 -  (set-case-syntax-pair ?\e,L@\e(B ?\e,L`\e(B tbl)
 -  (set-case-syntax-pair ?\e,LA\e(B ?\e,La\e(B tbl)
 -  (set-case-syntax-pair ?\e,LB\e(B ?\e,Lb\e(B tbl)
 -  (set-case-syntax-pair ?\e,LC\e(B ?\e,Lc\e(B tbl)
 -  (set-case-syntax-pair ?\e,LD\e(B ?\e,Ld\e(B tbl)
 -  (set-case-syntax-pair ?\e,LE\e(B ?\e,Le\e(B tbl)
 -  (set-case-syntax-pair ?\e,LF\e(B ?\e,Lf\e(B tbl)
 -  (set-case-syntax-pair ?\e,LG\e(B ?\e,Lg\e(B tbl)
 -  (set-case-syntax-pair ?\e,LH\e(B ?\e,Lh\e(B tbl)
 -  (set-case-syntax-pair ?\e,LI\e(B ?\e,Li\e(B tbl)
 -  (set-case-syntax-pair ?\e,LJ\e(B ?\e,Lj\e(B tbl)
 -  (set-case-syntax-pair ?\e,LK\e(B ?\e,Lk\e(B tbl)
 -  (set-case-syntax-pair ?\e,LL\e(B ?\e,Ll\e(B tbl)
 -  (set-case-syntax-pair ?\e,LM\e(B ?\e,Lm\e(B tbl)
 -  (set-case-syntax-pair ?\e,LN\e(B ?\e,Ln\e(B tbl)
 -  (set-case-syntax-pair ?\e,LO\e(B ?\e,Lo\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(!\e(B ?\e$,1(q\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1("\e(B ?\e$,1(r\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(#\e(B ?\e$,1(s\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1($\e(B ?\e$,1(t\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(%\e(B ?\e$,1(u\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(&\e(B ?\e$,1(v\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1('\e(B ?\e$,1(w\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1((\e(B ?\e$,1(x\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1()\e(B ?\e$,1(y\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(*\e(B ?\e$,1(z\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(+\e(B ?\e$,1({\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(,\e(B ?\e$,1(|\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(.\e(B ?\e$,1(~\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(/\e(B ?\e$,1(\7f\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(0\e(B ?\e$,1(P\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(1\e(B ?\e$,1(Q\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(2\e(B ?\e$,1(R\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(3\e(B ?\e$,1(S\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(4\e(B ?\e$,1(T\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(5\e(B ?\e$,1(U\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(6\e(B ?\e$,1(V\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(7\e(B ?\e$,1(W\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(8\e(B ?\e$,1(X\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(9\e(B ?\e$,1(Y\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(:\e(B ?\e$,1(Z\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(;\e(B ?\e$,1([\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(<\e(B ?\e$,1(\\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(=\e(B ?\e$,1(]\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(>\e(B ?\e$,1(^\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(?\e(B ?\e$,1(_\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(@\e(B ?\e$,1(`\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(A\e(B ?\e$,1(a\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(B\e(B ?\e$,1(b\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(C\e(B ?\e$,1(c\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(D\e(B ?\e$,1(d\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(E\e(B ?\e$,1(e\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(F\e(B ?\e$,1(f\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(G\e(B ?\e$,1(g\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(H\e(B ?\e$,1(h\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(I\e(B ?\e$,1(i\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(J\e(B ?\e$,1(j\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(K\e(B ?\e$,1(k\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(L\e(B ?\e$,1(l\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(M\e(B ?\e$,1(m\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(N\e(B ?\e$,1(n\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1(O\e(B ?\e$,1(o\e(B tbl))
 -
 -;; Devanagari character set
 -
 -;;; Commented out since the categories appear not to be used anywhere
 -;;; and word syntax is the default.
 -;; (let ((deflist     '(;; chars      syntax  category
 -;;              ("\e$(5!!!"!#\e(B"      "w"     ?7) ; vowel-modifying diacritical mark
 -;;                                        ; chandrabindu, anuswar, visarga
 -;;              ("\e$(5!$\e(B-\e$(5!2\e(B"        "w"     ?1) ; independent vowel
 -;;              ("\e$(5!3\e(B-\e$(5!X\e(B"        "w"     ?0) ; consonant
 -;;              ("\e$(5!Z\e(B-\e$(5!g\e(B"        "w"     ?8) ; matra
 -;;              ("\e$(5!q\e(B-\e$(5!z\e(B"        "w"     ?6) ; digit
 -;;              ;; Unicode equivalents
 -;;              ("\e$,15A5B5C\e(B"      "w"     ?7) ; vowel-modifying diacritical mark
 -;;                                        ; chandrabindu, anuswar, visarga
 -;;              ("\e$,15E\e(B-\e$,15M\e(B"        "w"     ?1) ; independent vowel
 -;;              ("\e$,15U\e(B-\e$,15y\e(B"        "w"     ?0) ; consonant
 -;;              ("\e$,15~\e(B-\e$,16)\e(B"        "w"     ?8) ; matra
 -;;              ("\e$,16F\e(B-\e$,16O\e(B"        "w"     ?6) ; digit
 -;;              ))
 -;;       elm chars len syntax category to ch i)
 -;;   (while deflist
 -;;     (setq elm (car deflist))
 -;;     (setq chars (car elm)
 -;;      len (length chars)
 -;;      syntax (nth 1 elm)
 -;;      category (nth 2 elm)
 -;;      i 0)
 -;;     (while (< i len)
 -;;       (if (= (aref chars i) ?-)
 -;;      (setq i (1+ i)
 -;;            to (aref chars i))
 -;;    (setq ch (aref chars i)
 -;;          to ch))
 -;;       (while (<= ch to)
 -;;    (modify-syntax-entry ch syntax)
 -;;    (modify-category-entry ch category)
 -;;    (setq ch (1+ ch)))
 -;;       (setq i (1+ i)))
 -;;     (setq deflist (cdr deflist))))
 +;; Japanese character set (JISX0201, JISX0208, JISX0212, JISX0213)
  
 -;; Ethiopic character set
 +(map-charset-chars #'modify-category-entry 'katakana-jisx0201 ?k)
  
 -(modify-category-entry (make-char 'ethiopic) ?e)
 -;; (modify-syntax-entry (make-char 'ethiopic) "w")
 -(dotimes (i (1+ (- #x137c #x1200)))
 -  (modify-category-entry (decode-char 'ucs (+ #x1200 i)) ?e))
 -(let ((chars '(?\e$(3$h\e(B ?\e$(3$i\e(B ?\e$(3$j\e(B ?\e$(3$k\e(B ?\e$(3$l\e(B ?\e$(3$m\e(B ?\e$(3$n\e(B ?\e$(3$o\e(B ?\e$(3%i\e(B ?\e$(3%t\e(B ?\e$(3%u\e(B ?\e$(3%v\e(B ?\e$(3%w\e(B ?\e$(3%x\e(B
 -             ;; Unicode equivalents of the above:
 -             ?\e$,1Q!\e(B ?\e$,1Q"\e(B ?\e$,1Q#\e(B ?\e$,1Q$\e(B ?\e$,1Q%\e(B ?\e$,1Q&\e(B ?\e$,1Q'\e(B ?\e$,1Q(\e(B ?\e$,3op\e(B ?\e$,3o{\e(B ?\e$,3o|\e(B ?\e$,3o}\e(B ?\e$,3o~\e(B ?\e$,3o\7f\e(B)))
 -  (while chars
 -    (modify-syntax-entry (car chars) ".")
 -    (setq chars (cdr chars))))
 +(map-charset-chars #'modify-category-entry 'latin-jisx0201 ?r)
  
 -;; Greek character set (ISO-8859-7)
 -
 -(modify-category-entry (make-char 'greek-iso8859-7) ?g)
 -(let ((c #x370))
 -  (while (<= c #x3ff)
 -    (modify-category-entry (decode-char 'ucs c) ?g)
 -    (setq c (1+ c))))
 -
 -;; (let ((c 182))
 -;;   (while (< c 255)
 -;;     (modify-syntax-entry (make-char 'greek-iso8859-7 c) "w")
 -;;     (setq c (1+ c))))
 -;; (modify-syntax-entry (make-char 'greek-iso8859-7 160) "w") ; NBSP
 -(modify-syntax-entry ?\e,F7\e(B ".")
 -(modify-syntax-entry ?\e,F;\e(B ".")
 -(modify-syntax-entry ?\e,F=\e(B ".")
 -(let ((tbl (standard-case-table)))
 -  ;; Fixme: non-letter syntax copied from latin-1, but that's dubious
 -  ;; in several cases.
 -  (set-case-syntax ?\e,F!\e(B "." tbl)
 -  (set-case-syntax ?\e,F"\e(B "." tbl)
 -  (set-case-syntax ?\e,F&\e(B "." tbl)
 -  (set-case-syntax ?\e,F&\e(B "_" tbl)
 -  (set-case-syntax ?\e,F'\e(B "." tbl)
 -  (set-case-syntax ?\e,F)\e(B "_" tbl)
 -  (set-case-syntax ?\e,F+\e(B "." tbl)
 -  (set-case-syntax ?\e,F,\e(B "_" tbl)
 -  (set-case-syntax ?\e,F-\e(B "_" tbl)
 -  (set-case-syntax ?\e,F/\e(B "." tbl)
 -  (set-case-syntax ?\e,F0\e(B "_" tbl)
 -  (set-case-syntax ?\e,F1\e(B "_" tbl)
 -;;  (set-case-syntax ?\e,F7\e(B "_" tbl)
 -;;  (set-case-syntax ?\e,F=\e(B "_" tbl)
 -  (set-case-syntax-pair ?\e,FA\e(B ?\e,Fa\e(B tbl)
 -  (set-case-syntax-pair ?\e,FB\e(B ?\e,Fb\e(B tbl)
 -  (set-case-syntax-pair ?\e,FC\e(B ?\e,Fc\e(B tbl)
 -  (set-case-syntax-pair ?\e,FD\e(B ?\e,Fd\e(B tbl)
 -  (set-case-syntax-pair ?\e,FE\e(B ?\e,Fe\e(B tbl)
 -  (set-case-syntax-pair ?\e,FF\e(B ?\e,Ff\e(B tbl)
 -  (set-case-syntax-pair ?\e,FG\e(B ?\e,Fg\e(B tbl)
 -  (set-case-syntax-pair ?\e,FH\e(B ?\e,Fh\e(B tbl)
 -  (set-case-syntax-pair ?\e,FI\e(B ?\e,Fi\e(B tbl)
 -  (set-case-syntax-pair ?\e,FJ\e(B ?\e,Fj\e(B tbl)
 -  (set-case-syntax-pair ?\e,FK\e(B ?\e,Fk\e(B tbl)
 -  (set-case-syntax-pair ?\e,FL\e(B ?\e,Fl\e(B tbl)
 -  (set-case-syntax-pair ?\e,FM\e(B ?\e,Fm\e(B tbl)
 -  (set-case-syntax-pair ?\e,FN\e(B ?\e,Fn\e(B tbl)
 -  (set-case-syntax-pair ?\e,FO\e(B ?\e,Fo\e(B tbl)
 -  (set-case-syntax-pair ?\e,FP\e(B ?\e,Fp\e(B tbl)
 -  (set-case-syntax-pair ?\e,FQ\e(B ?\e,Fq\e(B tbl)
 -  (set-upcase-syntax    ?\e,FS\e(B ?\e,Fr\e(B tbl)
 -  (set-case-syntax-pair ?\e,FS\e(B ?\e,Fs\e(B tbl)
 -  (set-case-syntax-pair ?\e,FT\e(B ?\e,Ft\e(B tbl)
 -  (set-case-syntax-pair ?\e,FU\e(B ?\e,Fu\e(B tbl)
 -  (set-case-syntax-pair ?\e,FV\e(B ?\e,Fv\e(B tbl)
 -  (set-case-syntax-pair ?\e,FW\e(B ?\e,Fw\e(B tbl)
 -  (set-case-syntax-pair ?\e,FX\e(B ?\e,Fx\e(B tbl)
 -  (set-case-syntax-pair ?\e,FY\e(B ?\e,Fy\e(B tbl)
 -  (set-case-syntax-pair ?\e,FZ\e(B ?\e,Fz\e(B tbl)
 -  (set-case-syntax-pair ?\e,F[\e(B ?\e,F{\e(B tbl)
 -  (set-case-syntax-pair ?\e,F?\e(B ?\e,F~\e(B tbl)
 -  (set-case-syntax-pair ?\e,F>\e(B ?\e,F}\e(B tbl)
 -  (set-case-syntax-pair ?\e,F<\e(B ?\e,F|\e(B tbl)
 -  (set-case-syntax-pair ?\e,F6\e(B ?\e,F\\e(B tbl)
 -  (set-case-syntax-pair ?\e,F8\e(B ?\e,F]\e(B tbl)
 -  (set-case-syntax-pair ?\e,F9\e(B ?\e,F^\e(B tbl)
 -  (set-case-syntax-pair ?\e,F:\e(B ?\e,F_\e(B tbl)
 -  ;; Unicode equivalents
 -  (set-case-syntax-pair ?\e$,1&q\e(B ?\e$,1'1\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&r\e(B ?\e$,1'2\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&s\e(B ?\e$,1'3\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&t\e(B ?\e$,1'4\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&u\e(B ?\e$,1'5\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&v\e(B ?\e$,1'6\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&w\e(B ?\e$,1'7\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&x\e(B ?\e$,1'8\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&y\e(B ?\e$,1'9\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&z\e(B ?\e$,1':\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&{\e(B ?\e$,1';\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&|\e(B ?\e$,1'<\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&}\e(B ?\e$,1'=\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&~\e(B ?\e$,1'>\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&\7f\e(B ?\e$,1'?\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1' \e(B ?\e$,1'@\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'!\e(B ?\e$,1'A\e(B tbl)
 -  (set-upcase-syntax    ?\e$,1'#\e(B ?\e$,1'B\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'#\e(B ?\e$,1'C\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'$\e(B ?\e$,1'D\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'%\e(B ?\e$,1'E\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'&\e(B ?\e$,1'F\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1''\e(B ?\e$,1'G\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'(\e(B ?\e$,1'H\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1')\e(B ?\e$,1'I\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'*\e(B ?\e$,1'J\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1'+\e(B ?\e$,1'K\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&o\e(B ?\e$,1'N\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&n\e(B ?\e$,1'M\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&l\e(B ?\e$,1'L\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&f\e(B ?\e$,1',\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&h\e(B ?\e$,1'-\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&i\e(B ?\e$,1'.\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&j\e(B ?\e$,1'/\e(B tbl))
 -
 -;; Hebrew character set (ISO-8859-8)
 -
 -(modify-category-entry (make-char 'hebrew-iso8859-8) ?w)
 -(let ((c #x591))
 -  (while (<= c #x5f4)
 -    (modify-category-entry (decode-char 'ucs c) ?w)
 -    (setq c (1+ c))))
 -
 -(modify-syntax-entry (make-char 'hebrew-iso8859-8 208) ".") ; PASEQ
 -(modify-syntax-entry (make-char 'hebrew-iso8859-8 211) ".") ; SOF PASUQ
 -(modify-syntax-entry (decode-char 'ucs #x5be) ".") ; MAQAF
 -(modify-syntax-entry (decode-char 'ucs #x5c0) ".") ; PASEQ
 -(modify-syntax-entry (decode-char 'ucs #x5c3) ".") ; SOF PASUQ
 -(modify-syntax-entry (decode-char 'ucs #x5f3) ".") ; GERESH
 -(modify-syntax-entry (decode-char 'ucs #x5f4) ".") ; GERSHAYIM
 -
 -;; (let ((c 224))
 -;;   (while (< c 251)
 -;;     (modify-syntax-entry (make-char 'hebrew-iso8859-8 c) "w")
 -;;     (setq c (1+ c))))
 -;; (modify-syntax-entry (make-char 'hebrew-iso8859-8 160) "w") ; NBSP
 -
 -;; Indian character set (IS 13194 and other Emacs original Indian charsets)
 -
 -(modify-category-entry (make-char 'indian-is13194) ?i)
 -(modify-category-entry (make-char 'indian-2-column) ?I)
 -(modify-category-entry (make-char 'indian-glyph) ?I)
 -;; Unicode Devanagari block
 -(let ((c #x901))
 -  (while (<= c #x970)
 -    (modify-category-entry (decode-char 'ucs c) ?i)
 -    (setq c (1+ c))))
 -
 -(let ((l '(;; RANGE   CATEGORY                MEANINGS
 -         (#x01 #x03 ?7)               ; vowel modifier
 -         (#x05 #x14 ?1)               ; base vowel
 -         (#x15 #x39 ?0)               ; consonants
 -         (#x3e #x4d ?8)               ; vowel modifier
 -         (#x51 #x54 ?4)               ; stress/tone mark
 -         (#x58 #x5f ?0)               ; consonants
 -         (#x60 #x61 ?1)               ; base vowel
 -         (#x62 #x63 ?8)               ; vowel modifier
 -         (#x66 #x6f ?6)               ; digits
 -         )))
 -  (dolist (elt1 '(#x900 #x980 #xa00 #xa80 #xb00 #xb80 #xc00 #xc80 #xd00))
 -    (dolist (elt2 l)
 -      (let* ((from (car elt2))
 -           (counts (1+ (- (nth 1 elt2) from)))
 -           (category (nth 2 elt2)))
 -      (dotimes (i counts)
 -        (modify-category-entry (decode-char 'ucs (+ elt1 from i)) 
 -                               category))))))
 -
 -;; Japanese character set (JISX0201-kana, JISX0201-roman, JISX0208, JISX0212)
 -
 -(modify-category-entry (make-char 'katakana-jisx0201) ?k)
 -(modify-category-entry (make-char 'katakana-jisx0201) ?j)
 -(modify-category-entry (make-char 'latin-jisx0201) ?r)
 -(modify-category-entry (make-char 'japanese-jisx0208) ?j)
 -(modify-category-entry (make-char 'japanese-jisx0212) ?j)
 -(modify-category-entry (make-char 'katakana-jisx0201) ?\|)
 -(modify-category-entry (make-char 'japanese-jisx0208) ?\|)
 -(modify-category-entry (make-char 'japanese-jisx0212) ?\|)
 +(dolist (l '(katakana-jisx0201 japanese-jisx0208 japanese-jisx0212
 +                             japanese-jisx0213-1 japanese-jisx0213-2))
 +  (map-charset-chars #'modify-category-entry l ?j))
  
  ;; Unicode equivalents of JISX0201-kana
 -(let ((c #xff61))
 -  (while (<= c #xff9f)
 -    (modify-category-entry (decode-char 'ucs c) ?k)
 -    (modify-category-entry (decode-char 'ucs c) ?j)
 -    (modify-category-entry (decode-char 'ucs c) ?\|)
 -    (setq c (1+ c))))
 +(let ((range '(#xff61 . #xff9f)))
 +  (modify-category-entry range  ?k)
 +  (modify-category-entry range ?j)
 +  (modify-category-entry range ?\|))
  
  ;; Katakana block
 -(let ((c #x30a0))
 -  (while (<= c #x30ff)
 -    ;; ?K is double width, ?k isn't specified
 -    (modify-category-entry (decode-char 'ucs c) ?k)
 -    (modify-category-entry (decode-char 'ucs c) ?j)
 -    (modify-category-entry (decode-char 'ucs c) ?\|)
 -    (setq c (1+ c))))
 +(let ((range '(#x30a0 . #x30ff)))
 +  ;; ?K is double width, ?k isn't specified
 +  (modify-category-entry range ?K)
 +  (modify-category-entry range ?\|))
  
  ;; Hiragana block
 -(let ((c #x3040))
 -  (while (<= c #x309f)
 -    ;; ?H is actually defined to be double width
 -    (modify-category-entry (decode-char 'ucs c) ?H)
 -    ;;(modify-category-entry (decode-char 'ucs c) ?j)
 -    (modify-category-entry (decode-char 'ucs c) ?\|)
 -    (setq c (1+ c))))
 +(let ((range '(#x3040 . #x309d)))
 +  ;; ?H is actually defined to be double width
 +  ;;(modify-category-entry range ?H)
 +  (modify-category-entry range ?\|)
 +  )
  
  ;; JISX0208
 -;; (modify-syntax-entry (make-char 'japanese-jisx0208) "w")
 -(modify-syntax-entry (make-char 'japanese-jisx0208 33) "_")
 -(modify-syntax-entry (make-char 'japanese-jisx0208 34) "_")
 -(modify-syntax-entry (make-char 'japanese-jisx0208 40) "_")
 -(let ((chars '(?\e$B!<\e(B ?\e$B!+\e(B ?\e$B!,\e(B ?\e$B!3\e(B ?\e$B!4\e(B ?\e$B!5\e(B ?\e$B!6\e(B ?\e$B!7\e(B ?\e$B!8\e(B ?\e$B!9\e(B ?\e$B!:\e(B ?\e$B!;\e(B)))
 -  (while chars
 -    (modify-syntax-entry (car chars) "w")
 -    (setq chars (cdr chars))))
 -(let ((parens "\e$B!J!K!L!M!N!O!P!Q!R!S!T!U!V!W!X!Y!Z![\e(B" )
 -      open close)
 -  (dotimes (i (/ (length parens) 2))
 -    (setq open (aref parens (* i 2))
 -        close (aref parens (1+ (* i 2))))
 -    (modify-syntax-entry open (format "(%c" close))
 -    (modify-syntax-entry close (format ")%c" open))))
 -
 -(modify-category-entry (make-char 'japanese-jisx0208 35) ?A)
 -(modify-category-entry (make-char 'japanese-jisx0208 36) ?H)
 -(modify-category-entry (make-char 'japanese-jisx0208 37) ?K)
 -(modify-category-entry (make-char 'japanese-jisx0208 38) ?G)
 -(modify-category-entry (make-char 'japanese-jisx0208 39) ?Y)
 -(let ((row 48))
 -  (while (< row 127)
 -    (modify-category-entry (make-char 'japanese-jisx0208 row) ?C)
 -    (setq row (1+ row))))
 -(modify-category-entry ?\e$B!<\e(B ?K)
 -(let ((chars '(?\e$B!+\e(B ?\e$B!,\e(B)))
 +(map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2121 #x227E)
 +(map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2821 #x287E)
 +(let ((chars '(?ー ?ã‚› ?ã‚œ ?ヽ ?ヾ ?ã‚ ?ã‚ž ?〃 ?ä» ?々 ?〆 ?〇)))
 +  (dolist (elt chars)
 +    (modify-syntax-entry (car chars) "w")))
 +
 +(map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?A #x2321 #x237E)
 +(map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?H #x2421 #x247E)
 +(map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?K #x2521 #x257E)
 +(map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?G #x2621 #x267E)
 +(map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?Y #x2721 #x277E)
 +(map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?C #x3021 #x7E7E)
 +(modify-category-entry ?ー ?K)
 +(let ((chars '(?ã‚› ?ã‚œ)))
    (while chars
      (modify-category-entry (car chars) ?K)
      (modify-category-entry (car chars) ?H)
      (setq chars (cdr chars))))
 -(let ((chars '(?\e$B!3\e(B ?\e$B!4\e(B ?\e$B!5\e(B ?\e$B!6\e(B ?\e$B!7\e(B ?\e$B!8\e(B ?\e$B!9\e(B ?\e$B!:\e(B ?\e$B!;\e(B)))
 +(let ((chars '(?ヽ ?ヾ ?ã‚ ?ã‚ž ?〃 ?ä» ?々 ?〆 ?〇)))
    (while chars
      (modify-category-entry (car chars) ?C)
      (setq chars (cdr chars))))
  
 -(let ((tbl (standard-case-table)))
 -  (dotimes (i 26)
 -    (set-case-syntax-pair (make-char 'japanese-jisx0208 #x23 (+ #x41 i))
 -                        (make-char 'japanese-jisx0208 #x23 (+ #x61 i)) tbl))
 -  (dotimes (i 24)
 -    (set-case-syntax-pair (make-char 'japanese-jisx0208 #x26 (+ #x21 i))
 -                        (make-char 'japanese-jisx0208 #x26 (+ #x41 i)) tbl))
 -  (dotimes (i 33)
 -    (set-case-syntax-pair (make-char 'japanese-jisx0208 #x27 (+ #x21 i))
 -                        (make-char 'japanese-jisx0208 #x27 (+ #x51 i)) tbl)))
 -
  ;; JISX0212
 -;; (modify-syntax-entry (make-char 'japanese-jisx0212) "w")
 -(modify-syntax-entry (make-char 'japanese-jisx0212 33) "_")
 -(modify-syntax-entry (make-char 'japanese-jisx0212 34) "_")
 -(modify-syntax-entry (make-char 'japanese-jisx0212 35) "_")
  
 -(modify-category-entry (make-char 'japanese-jisx0212 ) ?C)
 +(map-charset-chars #'modify-syntax-entry 'japanese-jisx0212 "_" #x2121 #x237E)
  
  ;; JISX0201-Kana
 -;; (modify-syntax-entry (make-char 'katakana-jisx0201) "w")
 -(let ((chars '(?\e(I!\e(B ?\e(I$\e(B ?\e(I%\e(B
 -             ;; Unicode:
 -             ?\e$,3sa\e(B ?\e$,3sd\e(B ?\e$,3se\e(B)))
 +
 +(let ((chars '(?。 ?、 ?ï½¥)))
    (while chars
      (modify-syntax-entry (car chars) ".")
      (setq chars (cdr chars))))
  
 -(modify-syntax-entry ?\\e(I"\e(B "(\e(I#\e(B")
 -(modify-syntax-entry ?\\e(I#\e(B "(\e(I"\e(B")
 +(modify-syntax-entry ?\ï½¢ "(ï½£")
 +(modify-syntax-entry ?\ï½£ "(ï½¢")
  
  ;; Korean character set (KSC5601)
  
 -;; (modify-syntax-entry (make-char 'korean-ksc5601) "w")
 -(modify-syntax-entry (make-char 'korean-ksc5601 33) "_")
 -(modify-syntax-entry (make-char 'korean-ksc5601 34) "_")
 -(modify-syntax-entry (make-char 'korean-ksc5601 38) "_")
 -(modify-syntax-entry (make-char 'korean-ksc5601 39) "_")
 -(modify-syntax-entry (make-char 'korean-ksc5601 40) "_")
 -(modify-syntax-entry (make-char 'korean-ksc5601 41) "_")
 -
 -(modify-category-entry (make-char 'korean-ksc5601) ?h)
 -(modify-category-entry (make-char 'korean-ksc5601 35) ?A)
 -(modify-category-entry (make-char 'korean-ksc5601 37) ?G)
 -(modify-category-entry (make-char 'korean-ksc5601 42) ?H)
 -(modify-category-entry (make-char 'korean-ksc5601 43) ?K)
 -(modify-category-entry (make-char 'korean-ksc5601 44) ?Y)
 -
 -(let ((parens "\e$(C!2!3!4!5!6!7!8!9!:!;!<!=#(#)#[#]#{#}\e(B" )
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?h)
 +
 +(map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2121 #x227E)
 +(map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2621 #x277E)
 +(map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2830 #x287E)
 +(map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2930 #x297E)
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2330 #x2339)
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2341 #x235A)
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2361 #x237A)
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?G #x2521 #x257E)
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?H #x2A21 #x2A7E)
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?K #x2B21 #x2B7E)
 +(map-charset-chars #'modify-category-entry 'korean-ksc5601 ?Y #x2C21 #x2C7E)
 +
 +;; These are in more than one charset.
 +(let ((parens (concat "〈〉《》「ã€ã€Žã€ã€ã€‘〔〕〖〗〘〙〚〛"
 +                    "︵︶︷︸︹︺︻︼︽︾︿﹀ï¹ï¹‚﹃﹄"
 +                    "()[]{ï½"))
        open close)
    (dotimes (i (/ (length parens) 2))
      (setq open (aref parens (* i 2))
      (modify-syntax-entry open (format "(%c" close))
      (modify-syntax-entry close (format ")%c" open))))
  
 -(let ((tbl (standard-case-table)))
 -  (dotimes (i 26)
 -    (set-case-syntax-pair (make-char 'korean-ksc5601 #x23 (+ #x41 i))
 -                        (make-char 'korean-ksc5601 #x23 (+ #x61 i)) tbl))
 -  (dotimes (i 10)
 -    (set-case-syntax-pair (make-char 'korean-ksc5601 #x25 (+ #x21 i))
 -                        (make-char 'korean-ksc5601 #x25 (+ #x30 i)) tbl))
 -  (dotimes (i 24)
 -    (set-case-syntax-pair (make-char 'korean-ksc5601 #x25 (+ #x41 i))
 -                        (make-char 'korean-ksc5601 #x25 (+ #x61 i)) tbl))
 -  (dotimes (i 33)
 -    (set-case-syntax-pair (make-char 'korean-ksc5601 #x2C (+ #x21 i))
 -                        (make-char 'korean-ksc5601 #x2C (+ #x51 i)) tbl)))
 -
 -;; Latin character set (latin-1,2,3,4,5,8,9)
 -
 -(modify-category-entry (make-char 'latin-iso8859-1) ?l)
 -(modify-category-entry (make-char 'latin-iso8859-2) ?l)
 -(modify-category-entry (make-char 'latin-iso8859-3) ?l)
 -(modify-category-entry (make-char 'latin-iso8859-4) ?l)
 -(modify-category-entry (make-char 'latin-iso8859-9) ?l)
 -(modify-category-entry (make-char 'latin-iso8859-14) ?l)
 -(modify-category-entry (make-char 'latin-iso8859-15) ?l)
 -
 -(modify-category-entry (make-char 'latin-iso8859-1 160) ?\ )
 -(modify-category-entry (make-char 'latin-iso8859-2 160) ?\ )
 -(modify-category-entry (make-char 'latin-iso8859-3 160) ?\ )
 -(modify-category-entry (make-char 'latin-iso8859-4 160) ?\ )
 -(modify-category-entry (make-char 'latin-iso8859-9 160) ?\ )
 -(modify-category-entry (make-char 'latin-iso8859-14 160) ?\ )
 -(modify-category-entry (make-char 'latin-iso8859-15 160) ?\ )
 +;; Arabic character set
  
 -;; Lao character set
 +(let ((charsets '(arabic-iso8859-6
 +                arabic-digit
 +                arabic-1-column
 +                arabic-2-column)))
 +  (while charsets
 +    (map-charset-chars #'modify-category-entry (car charsets) ?b)
 +    (setq charsets (cdr charsets))))
 +(modify-category-entry '(#x600 . #x6ff) ?b)
 +(modify-category-entry '(#xfb50 . #xfdff) ?b)
 +(modify-category-entry '(#xfe70 . #xfefe) ?b)
 +
 +;; Cyrillic character set (ISO-8859-5)
  
 -(modify-category-entry (make-char 'lao) ?o)
 -(dotimes (i (1+ (- #xeff #xe80)))
 -  (modify-category-entry (decode-char 'ucs (+ i #xe80)) ?o))
 +(modify-syntax-entry ?â„– ".")
  
 -(let ((deflist        '(;; chars      syntax  category
 -                ("\e(1!\e(B-\e(1N\e(B"    "w"     ?0) ; consonant
 -                ("\e(1PRS]`\e(B-\e(1d\e(B"        "w"     ?1) ; vowel base
 -                ("\e(1QT\e(B-\e(1W[m\e(B" "w"     ?2) ; vowel upper
 -                ("\e(1XY\e(B"           "w"     ?3) ; vowel lower
 -                ("\e(1h\e(B-\e(1l\e(B"    "w"     ?4) ; tone mark
 -                ("\e(1\\e(B"            "w"     ?9) ; semivowel lower
 -                ("\e(1p\e(B-\e(1y\e(B"    "w"     ?6) ; digit
 -                ("\e(1Of\e(B"           "_"     ?5) ; symbol
 -                ;; Unicode equivalents
 -                ("\e$,1D!\e(B-\e$,1DN\e(B"        "w"     ?0) ; consonant
 -                ("\e$,1DPDRDSD]D`\e(B-\e$,1Dd\e(B"        "w"     ?1) ; vowel base
 -                ("\e$,1DQDT\e(B-\e$,1DWD[Dm\e(B"  "w"     ?2) ; vowel upper
 -                ("\e$,1DXDY\e(B"        "w"     ?3) ; vowel lower
 -                ("\e$,1Dh\e(B-\e$,1Dk\e(B"        "w"     ?4) ; tone mark
 -                ("\e$,1D\D]\e(B"        "w"     ?9) ; semivowel lower
 -                ("\e$,1Dp\e(B-\e$,1Dy\e(B"        "w"     ?6) ; digit
 -                ("\e$,1DODf\e(B"        "_"     ?5) ; symbol
 +;; Ethiopic character set
 +
 +(modify-category-entry '(#x1200 . #x1399) ?e)
 +(modify-category-entry '(#x2d80 . #x2dde) ?e)
 +(let ((chars '(?á¡ ?ᢠ?ᣠ?ᤠ?ᥠ?ᦠ?᧠?ᨠ?ö ‡€ ?ö ‡‹ ?ö ‡Œ ?ö ‡ ?ö ‡Ž ?ö ‡)))
 +  (while chars
 +    (modify-syntax-entry (car chars) ".")
 +    (setq chars (cdr chars))))
 +(map-charset-chars #'modify-category-entry 'ethiopic ?e)
 +
 +;; Hebrew character set (ISO-8859-8)
 +
 +(modify-syntax-entry #x5be ".") ; MAQAF
 +(modify-syntax-entry #x5c0 ".") ; PASEQ
 +(modify-syntax-entry #x5c3 ".") ; SOF PASUQ
 +(modify-syntax-entry #x5f3 ".") ; GERESH
 +(modify-syntax-entry #x5f4 ".") ; GERSHAYIM
 +
 +;; Indian character set (IS 13194 and other Emacs original Indian charsets)
 +
 +(modify-category-entry '(#x901 . #x970) ?i)
 +(map-charset-chars #'modify-category-entry 'indian-is13194 ?i)
 +(map-charset-chars #'modify-category-entry 'indian-2-column ?i)
 +
 +;; Lao character set
 +
 +(modify-category-entry '(#xe80 . #xeff) ?o)
 +(map-charset-chars #'modify-category-entry 'lao ?o)
 +
 +(let ((deflist        '(("àº-ຮ"    "w"     ?0) ; consonant
 +                ("ະາຳຽເ-ໄ"        "w"     ?1) ; vowel base
 +                ("ັິ-ືົà»"   "w"     ?2) ; vowel upper
 +                ("ຸູ"     "w"     ?3) ; vowel lower
 +                ("່-໋"    "w"     ?4) ; tone mark
 +                ("ຼຽ"     "w"     ?9) ; semivowel lower
 +                ("à»-à»™"    "w"     ?6) ; digit
 +                ("ຯໆ"     "_"     ?5) ; symbol
                  ))
        elm chars len syntax category to ch i)
    (while deflist
  
  ;; Thai character set (TIS620)
  
 -(modify-category-entry (make-char 'thai-tis620) ?t)
 -(dotimes (i (1+ (- #xe7f #xe00)))
 -  (modify-category-entry (decode-char 'ucs (+ i #xe00)) ?t))
 +(modify-category-entry '(#xe00 . #xe7f) ?t)
 +(map-charset-chars #'modify-category-entry 'thai-tis620 ?t)
  
  (let ((deflist        '(;; chars      syntax  category
 -                ("\e,T!\e(B-\e,TCEG\e(B-\e,TN\e(B"  "w"     ?0) ; consonant
 -                ("\e,TDFPRS`\e(B-\e,Te\e(B"       "w"     ?1) ; vowel base
 -                ("\e,TQT\e(B-\e,TWgn\e(B" "w"     ?2) ; vowel upper
 -                ("\e,TX\e(B-\e,TZ\e(B"    "w"     ?3) ; vowel lower
 -                ("\e,Th\e(B-\e,Tm\e(B"    "w"     ?4) ; tone mark
 -                ("\e,Tp\e(B-\e,Ty\e(B"    "w"     ?6) ; digit
 -                ("\e,TOf_oz{\e(B"       "_"     ?5) ; symbol
 -                ;; Unicode equivalents
 -                ("\e$,1Ba\e(B-\e$,1C#C%C'\e(B-\e$,1C.\e(B"  "w"     ?0) ; consonant
 -                ("\e$,1C$C&C0C2C3C@\e(B-\e$,1CE\e(B"      "w"     ?1) ; vowel base
 -                ("\e$,1C1C4\e(B-\e$,1C7CGCN\e(B"  "w"     ?2) ; vowel upper
 -                ("\e$,1C8\e(B-\e$,1C:\e(B"        "w"     ?3) ; vowel lower
 -                ("\e$,1CH\e(B-\e$,1CM\e(B"        "w"     ?4) ; tone mark
 -                ("\e$,1CP\e(B-\e$,1CY\e(B"        "w"     ?6) ; digit
 -                ("\e$,1C/CFC?COCZC[\e(B"        "_"     ?5) ; symbol
 +                ("à¸-รลว-ฮ"  "w"     ?0) ; consonant
 +                ("ฤฦะาำเ-ๅ"     "w"     ?1) ; vowel base
 +                ("ัิ-ื็๎"   "w"     ?2) ; vowel upper
 +                ("ุ-ฺ"    "w"     ?3) ; vowel lower
 +                ("่-à¹"    "w"     ?4) ; tone mark
 +                ("à¹-๙"    "w"     ?6) ; digit
 +                ("ฯๆ฿à¹à¹šà¹›" "_"     ?5) ; symbol
                  ))
        elm chars len syntax category to ch i)
    (while deflist
  
  ;; Tibetan character set
  
 -(modify-category-entry (make-char 'tibetan) ?q)
 -(modify-category-entry (make-char 'tibetan-1-column) ?q)
 -(dotimes (i (1+ (- #xfff #xf00)))
 -  (modify-category-entry (decode-char 'ucs (+ i #xf00)) ?q))
 +(modify-category-entry '(#xf00 . #xfff) ?q)
 +(map-charset-chars #'modify-category-entry 'tibetan ?q)
 +(map-charset-chars #'modify-category-entry 'tibetan-1-column ?q)
  
  (let ((deflist        '(;; chars             syntax category
 -                ("\e4\e$(7"!\e0"!\e1\e(B-\e4\e$(7"J\e0"J\e1\e4"K\e0"K\e1\e(B"              "w"     ?0) ; consonant
 -                ("\e$(7#!\e(B-\e$(7#J#K#L#M!"!#\e(B"       "w"     ?0) ;
 -                ("\e$(7$!\e(B-\e$(7$e\e(B"              "w"     ?0) ;
 -                ("\e$(7%!\e(B-\e$(7%u\e(B"              "w"     ?0) ;
 -                ("\e$(7"S"["\"]"^"a\e(B"       "w"      ?2) ; upper vowel
 -                ("\e$(7"_"c"d"g"h"i"j"k"l\e(B" "w"      ?2) ; upper modifier
 -                ("\e$(7!I"Q"R"U"e!e!g\e(B"       "w"    ?3) ; lowel vowel/modifier
 -                ("\e$(7!P\e(B-\e$(7!Y!Z\e(B-\e$(7!c\e(B"            "w"     ?6) ; digit
 -                ("\e$(7!;!=\e(B-\e$(7!B!D"`\e(B"        "."     ?|) ; line-break char
 -                ("\e$(8!;!=!?!@!A!D"`\e(B"            "."     ?|) ;
 -                ("\e$(7!8!;!=\e(B-\e$(7!B!D"`!m!d\e(B"  "."     ?>) ; prohibition
 -                ("\e$(8!;!=!?!@!A!D"`\e(B"            "."     ?>) ;
 -                ("\e$(7!0\e(B-\e$(7!:!l#R#S"f\e(B"      "."     ?<) ; prohibition
 -                ("\e$(7!C!E\e(B-\e$(7!H!J\e(B-\e$(7!O!f!h\e(B-\e$(7!k!n!o#O#P\e(B-\e$(7#`\e(B" "." ?q) ; others
 -
 -                ;; Unicode version (not complete)
 -                ("\e$,1F \e(B-\e$,1FIFJ\e(B"              "w"     ?0) ; consonant
 -                ("\e$,1Fp\e(B-\e$,1G9G:G;G<\e(B"       "w"     ?0) ;
 -                ("\e$,1FRFZF[F\F]F`\e(B"       "w"      ?2) ; upper vowel
 -                ("\e$,1F^FbFcFfFgFhFiFjFk\e(B" "w"      ?2) ; upper modifier
 -                ("\e$,1EYFPFQFTFdEuEw\e(B"       "w"    ?3) ; lowel vowel/modifier
 -                ("\e$,1E`\e(B-\e$,1EiEj\e(B-\e$,1Es\e(B"            "w"     ?6) ; digit
 -                ("\e$,1EKEM\e(B-\e$,1ERETF_\e(B"        "."     ?|) ; line-break char
 -                ("\e$,1EHEKEM\e(B-\e$,1ERETF_E}Et\e(B"  "."     ?>) ; prohibition
 -                ("\e$,1E@\e(B-\e$,1EJE|GAGBFe\e(B"      "."     ?<) ; prohibition
 -                ("\e$,1ESEU\e(B-\e$,1EXEZ\e(B-\e$,1E_EvEx\e(B-\e$,1E{E~E\7fG>G?\e(B-\e$,1GO\e(B" "." ?q) ; others
 +                ("ཀ-ཀྵཪ"         "w"     ?0) ; consonant
 +                ("à¾-ྐྵྺྻྼö€ö€‚"       "w"     ?0) ;
 +                ("ö„š-ö…ž"              "w"     ?0) ;
 +                ("ö…¸-ö‡Œ"              "w"     ?0) ;
 +                ("ིེཻོཽྀ"       "w"       ?2) ; upper vowel
 +                ("ཾྂྃ྆྇ྈྉྊྋ" "w"    ?2) ; upper modifier
 +                ("༙ö‚Žà½±à½´à¾„༵༷"       "w"   ?3) ; lowel vowel/modifier
 +                ("཰"                "w" ?3)             ; invisible vowel a
 +                ("༠-༩༪-༳"             "w"     ?6) ; digit
 +                ("་à¼-༒༔ཿ"        "."     ?|) ; line-break char
 +                ("་à¼à¼à¼à¼‘༔ཿ"            "."     ?|) ;
 +                ("༈་à¼-༒༔ཿ༽༴"  "."     ?>) ; prohibition
 +                ("་à¼à¼à¼à¼‘༔ཿ"            "."     ?>) ;
 +                ("ༀ-༊༼à¿à¿‚྅"      "."     ?<) ; prohibition
 +                ("༓༕-༘༚-༟༶༸-༻༾༿྾྿-à¿" "." ?q) ; others
                  ))
        elm chars len syntax category to ch i)
    (while deflist
  
  ;; Vietnamese character set
  
 -(let ((lower (make-char 'vietnamese-viscii-lower))
 -      (upper (make-char 'vietnamese-viscii-upper)))
 -;;   (modify-syntax-entry lower "w")
 -;;   (modify-syntax-entry upper "w")
 -  (modify-category-entry lower ?v)
 -  (modify-category-entry upper ?v)
 -  (modify-category-entry lower ?l)    ; To make a word with
 -  (modify-category-entry upper ?l)    ; latin characters.
 -  )
 +;; To make a word with Latin characters
 +(map-charset-chars #'modify-category-entry 'vietnamese-viscii-lower ?l)
 +(map-charset-chars #'modify-category-entry 'vietnamese-viscii-lower ?v)
 +
 +(map-charset-chars #'modify-category-entry 'vietnamese-viscii-upper ?l)
 +(map-charset-chars #'modify-category-entry 'vietnamese-viscii-upper ?v)
  
  (let ((tbl (standard-case-table))
        (i 32))
    (while (< i 128)
 -    (set-case-syntax-pair (make-char 'vietnamese-viscii-upper i)
 -                        (make-char 'vietnamese-viscii-lower i)
 -                        tbl)
 +    (let* ((char (decode-char 'vietnamese-viscii-upper i))
 +         (charl (decode-char 'vietnamese-viscii-lower i))
 +         (uc (encode-char char 'ucs))
 +         (lc (encode-char charl 'ucs)))
 +      (set-case-syntax-pair char (decode-char 'vietnamese-viscii-lower i)
 +                          tbl)        
 +      (if uc (modify-category-entry uc ?v))
 +      (if lc (modify-category-entry lc ?v)))
      (setq i (1+ i))))
  
 -;; Unicode (mule-unicode-0100-24ff)
 +
 +;; Latin
 +
 +(modify-category-entry '(#x80 . #x024F) ?l)
  
  (let ((tbl (standard-case-table)) c)
  
 +  ;; Latin-1
 +
 +  ;; Fixme: Some of the non-word syntaxes here perhaps should be
 +  ;; reviewed.  (Note that the following all implicitly have word
 +  ;; syntax: Â¢Â£Â¤Â¥Â¨ÂªÂ¯Â²Â³Â´Â¶Â¸Â¹Âº.)  There should be a well-defined way of
 +  ;; relating Unicode categories to Emacs syntax codes.
 +
 +  ;; NBSP isn't semantically interchangeable with other whitespace chars,
 +  ;; so it's more like punctation.
 +  (set-case-syntax ?  "." tbl)
 +  (set-case-syntax ?¡ "." tbl)
 +  (set-case-syntax ?¦ "_" tbl)
 +  (set-case-syntax ?§ "." tbl)
 +  (set-case-syntax ?© "_" tbl)
 +  (set-case-syntax-delims 171 187 tbl)        ; Â« Â»
 +  (set-case-syntax ?¬ "_" tbl)
 +  (set-case-syntax ?­ "_" tbl)
 +  (set-case-syntax ?® "_" tbl)
 +  (set-case-syntax ?° "_" tbl)
 +  (set-case-syntax ?± "_" tbl)
 +  (set-case-syntax ?µ "_" tbl)
 +  (set-case-syntax ?· "_" tbl)
 +  (set-case-syntax ?¼ "_" tbl)
 +  (set-case-syntax ?½ "_" tbl)
 +  (set-case-syntax ?¾ "_" tbl)
 +  (set-case-syntax ?¿ "." tbl)
 +  (let ((c 192))
 +    (while (<= c 222)
 +      (set-case-syntax-pair c (+ c 32) tbl)
 +      (setq c (1+ c))))
 +  (set-case-syntax ?× "_" tbl)
 +  (set-case-syntax ?ß "w" tbl)
 +  (set-case-syntax ?÷ "_" tbl)
 +  ;; See below for Ã¿.
 +
    ;; Latin Extended-A, Latin Extended-B
    (setq c #x0100)
    (while (<= c #x0233)
 -    (modify-category-entry (decode-char 'ucs c) ?l)
      (and (or (<= c #x012e)
             (and (>= c #x014a) (<= c #x0177)))
         (zerop (% c 2))
 -       (set-case-syntax-pair
 -        (decode-char 'ucs c) (decode-char 'ucs (1+ c)) tbl))
 +       (set-case-syntax-pair c (1+ c) tbl))
      (and (>= c #x013a)
         (<= c #x0148)
         (zerop (% c 2))
 -       (set-case-syntax-pair
 -        (decode-char 'ucs (1- c)) (decode-char 'ucs c) tbl))
 +       (set-case-syntax-pair (1- c) c tbl))
      (setq c (1+ c)))
  
  
    ;; but that makes searches slow.  So now we don't set up either half
    ;; of these correspondences by default.
  
 -  ;;  (set-downcase-syntax  ?\e$,1 P\e(B ?i tbl)
 -  ;;  (set-upcase-syntax    ?I ?\e$,1 Q\e(B tbl)
 +  ;; (set-downcase-syntax  ?Ä° ?i tbl)
 +  ;; (set-upcase-syntax    ?I ?ı tbl)
  
 -  (set-case-syntax-pair ?\e$,1 R\e(B ?\e$,1 S\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1 T\e(B ?\e$,1 U\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1 V\e(B ?\e$,1 W\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!8\e(B ?\e,A\7f\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!9\e(B ?\e$,1!:\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!;\e(B ?\e$,1!<\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!=\e(B ?\e$,1!>\e(B tbl)
 +  (set-case-syntax-pair ?IJ ?ij tbl)
 +  (set-case-syntax-pair ?Ä´ ?ĵ tbl)
 +  (set-case-syntax-pair ?Ķ ?Ä· tbl)
 +  (set-case-syntax-pair ?Ÿ ?ÿ tbl)
 +  (set-case-syntax-pair ?Ź ?ź tbl)
 +  (set-case-syntax-pair ?Å» ?ż tbl)
 +  (set-case-syntax-pair ?Ž ?ž tbl)
  
    ;; Latin Extended-B
 -  (set-case-syntax-pair ?\e$,1!A\e(B ?\e$,1#S\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!B\e(B ?\e$,1!C\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!D\e(B ?\e$,1!E\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!F\e(B ?\e$,1#T\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!G\e(B ?\e$,1!H\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!I\e(B ?\e$,1#V\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!J\e(B ?\e$,1#W\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!K\e(B ?\e$,1!L\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!N\e(B ?\e$,1"=\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!O\e(B ?\e$,1#Y\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!P\e(B ?\e$,1#[\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!Q\e(B ?\e$,1!R\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!S\e(B ?\e$,1#`\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!T\e(B ?\e$,1#c\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!V\e(B ?\e$,1#i\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!W\e(B ?\e$,1#h\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!X\e(B ?\e$,1!Y\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!\\e(B ?\e$,1#o\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!]\e(B ?\e$,1#r\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!_\e(B ?\e$,1#u\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!`\e(B ?\e$,1!a\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!b\e(B ?\e$,1!c\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!d\e(B ?\e$,1!e\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!f\e(B ?\e$,1$ \e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!g\e(B ?\e$,1!h\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!i\e(B ?\e$,1$#\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!l\e(B ?\e$,1!m\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!n\e(B ?\e$,1$(\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!o\e(B ?\e$,1!p\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!q\e(B ?\e$,1$*\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!r\e(B ?\e$,1$+\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!s\e(B ?\e$,1!t\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!u\e(B ?\e$,1!v\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!w\e(B ?\e$,1$2\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!x\e(B ?\e$,1!y\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1!|\e(B ?\e$,1!}\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"$\e(B ?\e$,1"&\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"%\e(B ?\e$,1"&\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"'\e(B ?\e$,1")\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"(\e(B ?\e$,1")\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"*\e(B ?\e$,1",\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"+\e(B ?\e$,1",\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"-\e(B ?\e$,1".\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"/\e(B ?\e$,1"0\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"1\e(B ?\e$,1"2\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"3\e(B ?\e$,1"4\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"5\e(B ?\e$,1"6\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"7\e(B ?\e$,1"8\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"9\e(B ?\e$,1":\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1";\e(B ?\e$,1"<\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1">\e(B ?\e$,1"?\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"@\e(B ?\e$,1"A\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"B\e(B ?\e$,1"C\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"D\e(B ?\e$,1"E\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"F\e(B ?\e$,1"G\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"H\e(B ?\e$,1"I\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"J\e(B ?\e$,1"K\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"L\e(B ?\e$,1"M\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"N\e(B ?\e$,1"O\e(B tbl)
 +  (set-case-syntax-pair ?Æ ?É“ tbl)
 +  (set-case-syntax-pair ?Æ‚ ?ƃ tbl)
 +  (set-case-syntax-pair ?Æ„ ?Æ… tbl)
 +  (set-case-syntax-pair ?Ɔ ?É” tbl)
 +  (set-case-syntax-pair ?Ƈ ?ƈ tbl)
 +  (set-case-syntax-pair ?Ɖ ?É– tbl)
 +  (set-case-syntax-pair ?ÆŠ ?É— tbl)
 +  (set-case-syntax-pair ?Æ‹ ?ÆŒ tbl)
 +  (set-case-syntax-pair ?ÆŽ ?Ç tbl)
 +  (set-case-syntax-pair ?Æ ?É™ tbl)
 +  (set-case-syntax-pair ?Æ ?É› tbl)
 +  (set-case-syntax-pair ?Æ‘ ?Æ’ tbl)
 +  (set-case-syntax-pair ?Æ“ ?É  tbl)
 +  (set-case-syntax-pair ?Æ” ?É£ tbl)
 +  (set-case-syntax-pair ?Æ– ?É© tbl)
 +  (set-case-syntax-pair ?Æ— ?ɨ tbl)
 +  (set-case-syntax-pair ?Ƙ ?Æ™ tbl)
 +  (set-case-syntax-pair ?Æœ ?ɯ tbl)
 +  (set-case-syntax-pair ?Æ ?ɲ tbl)
 +  (set-case-syntax-pair ?ÆŸ ?ɵ tbl)
 +  (set-case-syntax-pair ?Æ  ?Æ¡ tbl)
 +  (set-case-syntax-pair ?Æ¢ ?Æ£ tbl)
 +  (set-case-syntax-pair ?Ƥ ?Æ¥ tbl)
 +  (set-case-syntax-pair ?Ʀ ?Ê€ tbl)
 +  (set-case-syntax-pair ?Ƨ ?ƨ tbl)
 +  (set-case-syntax-pair ?Æ© ?ʃ tbl)
 +  (set-case-syntax-pair ?Ƭ ?Æ­ tbl)
 +  (set-case-syntax-pair ?Æ® ?ʈ tbl)
 +  (set-case-syntax-pair ?Ư ?Æ° tbl)
 +  (set-case-syntax-pair ?Ʊ ?ÊŠ tbl)
 +  (set-case-syntax-pair ?Ʋ ?Ê‹ tbl)
 +  (set-case-syntax-pair ?Ƴ ?Æ´ tbl)
 +  (set-case-syntax-pair ?Ƶ ?ƶ tbl)
 +  (set-case-syntax-pair ?Æ· ?Ê’ tbl)
 +  (set-case-syntax-pair ?Ƹ ?ƹ tbl)
 +  (set-case-syntax-pair ?Ƽ ?ƽ tbl)
 +  (set-case-syntax-pair ?Ç„ ?dž tbl)
 +  (set-case-syntax-pair ?Ç… ?dž tbl)
 +  (set-case-syntax-pair ?LJ ?lj tbl)
 +  (set-case-syntax-pair ?Lj ?lj tbl)
 +  (set-case-syntax-pair ?ÇŠ ?ÇŒ tbl)
 +  (set-case-syntax-pair ?Ç‹ ?ÇŒ tbl)
 +  (set-case-syntax-pair ?Ç ?ÇŽ tbl)
 +  (set-case-syntax-pair ?Ç ?Ç tbl)
 +  (set-case-syntax-pair ?Ç‘ ?Ç’ tbl)
 +  (set-case-syntax-pair ?Ç“ ?Ç” tbl)
 +  (set-case-syntax-pair ?Ç• ?Ç– tbl)
 +  (set-case-syntax-pair ?Ç— ?ǘ tbl)
 +  (set-case-syntax-pair ?Ç™ ?Çš tbl)
 +  (set-case-syntax-pair ?Ç› ?Çœ tbl)
 +  (set-case-syntax-pair ?Çž ?ÇŸ tbl)
 +  (set-case-syntax-pair ?Ç  ?Ç¡ tbl)
 +  (set-case-syntax-pair ?Ç¢ ?Ç£ tbl)
 +  (set-case-syntax-pair ?Ǥ ?Ç¥ tbl)
 +  (set-case-syntax-pair ?Ǧ ?ǧ tbl)
 +  (set-case-syntax-pair ?Ǩ ?Ç© tbl)
 +  (set-case-syntax-pair ?Ǫ ?Ç« tbl)
 +  (set-case-syntax-pair ?Ǭ ?Ç­ tbl)
 +  (set-case-syntax-pair ?Ç® ?ǯ tbl)
    ;; 01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON
 -  (set-case-syntax-pair ?\e$,1"Q\e(B ?\e$,1"S\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"R\e(B ?\e$,1"S\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"T\e(B ?\e$,1"U\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"V\e(B ?\e$,1!U\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"W\e(B ?\e$,1!\7f\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"X\e(B ?\e$,1"Y\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"Z\e(B ?\e$,1"[\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"\\e(B ?\e$,1"]\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"^\e(B ?\e$,1"_\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"`\e(B ?\e$,1"a\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"b\e(B ?\e$,1"c\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"d\e(B ?\e$,1"e\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"f\e(B ?\e$,1"g\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"h\e(B ?\e$,1"i\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"j\e(B ?\e$,1"k\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"l\e(B ?\e$,1"m\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"n\e(B ?\e$,1"o\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"p\e(B ?\e$,1"q\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"r\e(B ?\e$,1"s\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"t\e(B ?\e$,1"u\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"v\e(B ?\e$,1"w\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"x\e(B ?\e$,1"y\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"z\e(B ?\e$,1"{\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"|\e(B ?\e$,1"}\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1"~\e(B ?\e$,1"\7f\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#"\e(B ?\e$,1##\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#$\e(B ?\e$,1#%\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#&\e(B ?\e$,1#'\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#(\e(B ?\e$,1#)\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#*\e(B ?\e$,1#+\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#,\e(B ?\e$,1#-\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#.\e(B ?\e$,1#/\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#0\e(B ?\e$,1#1\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1#2\e(B ?\e$,1#3\e(B tbl)
 +  (set-case-syntax-pair ?DZ ?dz tbl)
 +  (set-case-syntax-pair ?Dz ?dz tbl)
 +  (set-case-syntax-pair ?Ç´ ?ǵ tbl)
 +  (set-case-syntax-pair ?Ƕ ?Æ• tbl)
 +  (set-case-syntax-pair ?Ç· ?Æ¿ tbl)
 +  (set-case-syntax-pair ?Ǹ ?ǹ tbl)
 +  (set-case-syntax-pair ?Ǻ ?Ç» tbl)
 +  (set-case-syntax-pair ?Ǽ ?ǽ tbl)
 +  (set-case-syntax-pair ?Ǿ ?Ç¿ tbl)
 +  (set-case-syntax-pair ?È€ ?È tbl)
 +  (set-case-syntax-pair ?È‚ ?ȃ tbl)
 +  (set-case-syntax-pair ?È„ ?È… tbl)
 +  (set-case-syntax-pair ?Ȇ ?ȇ tbl)
 +  (set-case-syntax-pair ?Ȉ ?ȉ tbl)
 +  (set-case-syntax-pair ?ÈŠ ?È‹ tbl)
 +  (set-case-syntax-pair ?ÈŒ ?È tbl)
 +  (set-case-syntax-pair ?ÈŽ ?È tbl)
 +  (set-case-syntax-pair ?È ?È‘ tbl)
 +  (set-case-syntax-pair ?È’ ?È“ tbl)
 +  (set-case-syntax-pair ?È” ?È• tbl)
 +  (set-case-syntax-pair ?È– ?È— tbl)
 +  (set-case-syntax-pair ?Ș ?È™ tbl)
 +  (set-case-syntax-pair ?Èš ?È› tbl)
 +  (set-case-syntax-pair ?Èœ ?È tbl)
 +  (set-case-syntax-pair ?Èž ?ÈŸ tbl)
 +  (set-case-syntax-pair ?È¢ ?È£ tbl)
 +  (set-case-syntax-pair ?Ȥ ?È¥ tbl)
 +  (set-case-syntax-pair ?Ȧ ?ȧ tbl)
 +  (set-case-syntax-pair ?Ȩ ?È© tbl)
 +  (set-case-syntax-pair ?Ȫ ?È« tbl)
 +  (set-case-syntax-pair ?Ȭ ?È­ tbl)
 +  (set-case-syntax-pair ?È® ?ȯ tbl)
 +  (set-case-syntax-pair ?È° ?ȱ tbl)
 +  (set-case-syntax-pair ?Ȳ ?ȳ tbl)
  
    ;; Latin Extended Additional
 +  (modify-category-entry '(#x1e00 . #x1ef9) ?l)
    (setq c #x1e00)
    (while (<= c #x1ef9)
 -    (modify-category-entry (decode-char 'ucs c) ?l)
      (and (zerop (% c 2))
         (or (<= c #x1e94) (>= c #x1ea0))
 -       (set-case-syntax-pair
 -        (decode-char 'ucs c) (decode-char 'ucs (1+ c)) tbl))
 +       (set-case-syntax-pair c (1+ c) tbl))
      (setq c (1+ c)))
  
    ;; Greek
 +  (modify-category-entry '(#x0370 . #x03ff) ?g)
    (setq c #x0370)
    (while (<= c #x03ff)
 -    (modify-category-entry (decode-char 'ucs c) ?g)
      (if (or (and (>= c #x0391) (<= c #x03a1))
            (and (>= c #x03a3) (<= c #x03ab)))
 -      (set-case-syntax-pair
 -       (decode-char 'ucs c) (decode-char 'ucs (+ c 32)) tbl))
 +      (set-case-syntax-pair c (+ c 32) tbl))
      (and (>= c #x03da)
         (<= c #x03ee)
         (zerop (% c 2))
 -       (set-case-syntax-pair
 -        (decode-char 'ucs c) (decode-char 'ucs (1+ c)) tbl))
 +       (set-case-syntax-pair c (1+ c) tbl))
      (setq c (1+ c)))
 -  (set-case-syntax-pair ?\e$,1&f\e(B ?\e$,1',\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&h\e(B ?\e$,1'-\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&i\e(B ?\e$,1'.\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&j\e(B ?\e$,1'/\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&l\e(B ?\e$,1'L\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&n\e(B ?\e$,1'M\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1&o\e(B ?\e$,1'N\e(B tbl)
 +  (set-case-syntax-pair ?Ά ?ά tbl)
 +  (set-case-syntax-pair ?Έ ?έ tbl)
 +  (set-case-syntax-pair ?Ή ?ή tbl)
 +  (set-case-syntax-pair ?Ί ?ί tbl)
 +  (set-case-syntax-pair ?ÎŒ ?ÏŒ tbl)
 +  (set-case-syntax-pair ?ÎŽ ?Ï tbl)
 +  (set-case-syntax-pair ?Π?ÏŽ tbl)
  
    ;; Armenian
    (setq c #x531)
    (while (<= c #x556)
 -    (set-case-syntax-pair (decode-char 'ucs c)
 -                        (decode-char 'ucs (+ c #x30)) tbl)
 +    (set-case-syntax-pair c (+ c #x30) tbl)
      (setq c (1+ c)))
  
    ;; Greek Extended
 +  (modify-category-entry '(#x1f00 . #x1fff) ?g)
    (setq c #x1f00)
    (while (<= c #x1fff)
 -    (modify-category-entry (decode-char 'ucs c) ?g)
      (and (<= (logand c #x000f) 7)
         (<= c #x1fa7)
         (not (memq c '(#x1f50 #x1f52 #x1f54 #x1f56)))
         (/= (logand c #x00f0) 7)
 -       (set-case-syntax-pair
 -        (decode-char 'ucs (+ c 8)) (decode-char 'ucs c) tbl))
 +       (set-case-syntax-pair (+ c 8) c tbl))
      (setq c (1+ c)))
 -  (set-case-syntax-pair ?\e$,1qx\e(B ?\e$,1qp\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1qy\e(B ?\e$,1qq\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1qz\e(B ?\e$,1q0\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1q{\e(B ?\e$,1q1\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1q|\e(B ?\e$,1qs\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r(\e(B ?\e$,1q2\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r)\e(B ?\e$,1q3\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r*\e(B ?\e$,1q4\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r+\e(B ?\e$,1q5\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r,\e(B ?\e$,1r#\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r8\e(B ?\e$,1r0\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r9\e(B ?\e$,1r1\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r:\e(B ?\e$,1q6\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r;\e(B ?\e$,1q7\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rH\e(B ?\e$,1r@\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rI\e(B ?\e$,1rA\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rJ\e(B ?\e$,1q:\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rK\e(B ?\e$,1q;\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rL\e(B ?\e$,1rE\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rX\e(B ?\e$,1q8\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rY\e(B ?\e$,1q9\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1rZ\e(B ?\e$,1q<\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r[\e(B ?\e$,1q=\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1r\\e(B ?\e$,1rS\e(B tbl)
 +  (set-case-syntax-pair ?Ᾰ ?á¾° tbl)
 +  (set-case-syntax-pair ?á¾¹ ?á¾± tbl)
 +  (set-case-syntax-pair ?Ὰ ?á½° tbl)
 +  (set-case-syntax-pair ?á¾» ?á½± tbl)
 +  (set-case-syntax-pair ?á¾¼ ?á¾³ tbl)
 +  (set-case-syntax-pair ?Ὲ ?á½² tbl)
 +  (set-case-syntax-pair ?Έ ?á½³ tbl)
 +  (set-case-syntax-pair ?á¿Š ?á½´ tbl)
 +  (set-case-syntax-pair ?á¿‹ ?á½µ tbl)
 +  (set-case-syntax-pair ?á¿Œ ?ῃ tbl)
 +  (set-case-syntax-pair ?Ῐ ?á¿ tbl)
 +  (set-case-syntax-pair ?á¿™ ?á¿‘ tbl)
 +  (set-case-syntax-pair ?á¿š ?ὶ tbl)
 +  (set-case-syntax-pair ?á¿› ?á½· tbl)
 +  (set-case-syntax-pair ?Ῠ ?á¿  tbl)
 +  (set-case-syntax-pair ?á¿© ?á¿¡ tbl)
 +  (set-case-syntax-pair ?Ὺ ?ὺ tbl)
 +  (set-case-syntax-pair ?á¿« ?á½» tbl)
 +  (set-case-syntax-pair ?Ῥ ?á¿¥ tbl)
 +  (set-case-syntax-pair ?Ὸ ?ὸ tbl)
 +  (set-case-syntax-pair ?Ό ?á½¹ tbl)
 +  (set-case-syntax-pair ?Ὼ ?á½¼ tbl)
 +  (set-case-syntax-pair ?á¿» ?á½½ tbl)
 +  (set-case-syntax-pair ?ῼ ?ῳ tbl)
  
    ;; cyrillic
 +  (modify-category-entry '(#x0400 . #x04FF) ?y)
    (setq c #x0400)
    (while (<= c #x04ff)
 -    (modify-category-entry (decode-char 'ucs c) ?y)
      (and (>= c #x0400)
         (<= c #x040f)
 -       (set-case-syntax-pair
 -        (decode-char 'ucs c) (decode-char 'ucs (+ c 80)) tbl))
 +       (set-case-syntax-pair c (+ c 80) tbl))
      (and (>= c #x0410)
         (<= c #x042f)
 -       (set-case-syntax-pair
 -        (decode-char 'ucs c) (decode-char 'ucs (+ c 32)) tbl))
 +       (set-case-syntax-pair c (+ c 32) tbl))
      (and (zerop (% c 2))
         (or (and (>= c #x0460) (<= c #x0480))
             (and (>= c #x048c) (<= c #x04be))
             (and (>= c #x04d0) (<= c #x04f4)))
 -       (set-case-syntax-pair
 -        (decode-char 'ucs c) (decode-char 'ucs (1+ c)) tbl))
 +       (set-case-syntax-pair c (1+ c) tbl))
      (setq c (1+ c)))
 -  (set-case-syntax-pair ?\e$,1*!\e(B ?\e$,1*"\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1*#\e(B ?\e$,1*$\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1*'\e(B ?\e$,1*(\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1*+\e(B ?\e$,1*,\e(B tbl)
 -  (set-case-syntax-pair ?\e$,1*X\e(B ?\e$,1*Y\e(B tbl)
 +  (set-case-syntax-pair ?Ó ?Ó‚ tbl)
 +  (set-case-syntax-pair ?Óƒ ?Ó„ tbl)
 +  (set-case-syntax-pair ?Ó‡ ?Óˆ tbl)
 +  (set-case-syntax-pair ?Ó‹ ?ÓŒ tbl)
 +  (set-case-syntax-pair ?Ó¸ ?Ó¹ tbl)
  
    ;; general punctuation
    (setq c #x2000)
    (while (<= c #x200b)
 -    (set-case-syntax (decode-char 'ucs c) " " tbl)
 +    (set-case-syntax c " " tbl)
      (setq c (1+ c)))
 +  (while (<= c #x200F)
 +    (set-case-syntax c "." tbl)
 +    (setq c (1+ c)))
 +  ;; Fixme: These aren't all right:
    (setq c #x2010)
    (while (<= c #x2016)
 -    (set-case-syntax (decode-char 'ucs c) "_" tbl)
 +    (set-case-syntax c "_" tbl)
      (setq c (1+ c)))
    ;; Punctuation syntax for quotation marks (like `)
    (while (<= c #x201f)
 -    (set-case-syntax (decode-char 'ucs c) "." tbl)
 +    (set-case-syntax  c "." tbl)
      (setq c (1+ c)))
 +  ;; Fixme: These aren't all right:
    (while (<= c #x2027)
 -    (set-case-syntax (decode-char 'ucs c) "_" tbl)
 +    (set-case-syntax c "_" tbl)
 +    (setq c (1+ c)))
 +  (while (<= c #x206F)
 +    (set-case-syntax c "." tbl)
      (setq c (1+ c)))
  
    ;; Roman numerals
    (setq c #x2160)
    (while (<= c #x216f)
 -    (set-case-syntax-pair (decode-char 'ucs c)
 -                        (decode-char 'ucs (+ c #x10)) tbl)
 +    (set-case-syntax-pair c (+ c #x10) tbl)
 +    (setq c (1+ c)))
 +
 +  ;; Fixme: The following blocks might be better as symbol rather than
 +  ;; punctuation.
 +  ;; Arrows
 +  (setq c #x2190)
 +  (while (<= c #x21FF)
 +    (set-case-syntax c "." tbl)
 +    (setq c (1+ c)))
 +  ;; Mathematical Operators
 +  (while (<= c #x22FF)
 +    (set-case-syntax c "." tbl)
 +    (setq c (1+ c)))
 +  ;; Miscellaneous Technical
 +  (while (<= c #x23FF)
 +    (set-case-syntax c "." tbl)
 +    (setq c (1+ c)))
 +  ;; Control Pictures
 +  (while (<= c #x243F)
 +    (set-case-syntax c "_" tbl)
      (setq c (1+ c)))
  
    ;; Circled Latin
    (setq c #x24b6)
    (while (<= c #x24cf)
 -    (set-case-syntax-pair (decode-char 'ucs c)
 -                        (decode-char 'ucs (+ c 26)) tbl)
 -    (modify-category-entry (decode-char 'ucs c) ?l)
 -    (modify-category-entry (decode-char 'ucs (+ c 26)) ?l)
 +    (set-case-syntax-pair c (+ c 26) tbl)
 +    (modify-category-entry c ?l)
 +    (modify-category-entry (+ c 26) ?l)
      (setq c (1+ c)))
  
    ;; Fullwidth Latin
    (setq c #xff21)
    (while (<= c #xff3a)
 -    (set-case-syntax-pair (decode-char 'ucs c)
 -                        (decode-char 'ucs (+ c #x20)) tbl)
 -    (modify-category-entry (decode-char 'ucs c) ?l)
 -    (modify-category-entry (decode-char 'ucs (+ c #x20)) ?l)
 +    (set-case-syntax-pair c (+ c #x20) tbl)
 +    (modify-category-entry c ?l)
 +    (modify-category-entry (+ c #x20) ?l)
      (setq c (1+ c)))
  
    ;; Combining diacritics
 -  (setq c #x300)
 -  (while (<= c #x362)
 -    (modify-category-entry (decode-char 'ucs c) ?^)
 -    (setq c (1+ c)))
 -
 +  (modify-category-entry '(#x300 . #x362) ?^)
    ;; Combining marks
 -  (setq c #x20d0)
 -  (while (<= c #x20e3)
 -    (modify-category-entry (decode-char 'ucs c) ?^)
 -    (setq c (1+ c)))
 +  (modify-category-entry '(#x20d0 . #x20e3) ?^)
  
    ;; Fixme: syntax for symbols &c
    )
  
  (let ((pairs
 -       '("\e$,1sEsF\e(B"                                ; U+2045 U+2046
 -       "\e$,1s}s~\e(B"                          ; U+207D U+207E
 -       "\e$,1t-t.\e(B"                          ; U+208D U+208E
 -       "\e$,1{){*\e(B"                          ; U+2329 U+232A
 -       "\e$,1|T|U\e(B"                          ; U+23B4 U+23B5
 -       "\e$,2&H&I\e(B"                          ; U+2768 U+2769
 -       "\e$,2&J&K\e(B"                          ; U+276A U+276B
 -       "\e$,2&L&M\e(B"                          ; U+276C U+276D
 -       "\e$,2&P&Q\e(B"                          ; U+2770 U+2771
 -       "\e$,2&R&S\e(B"                          ; U+2772 U+2773
 -       "\e$,2&T&U\e(B"                          ; U+2774 U+2775
 -       "\e$,2'f'g\e(B"                          ; U+27E6 U+27E7
 -       "\e$,2'h'i\e(B"                          ; U+27E8 U+27E9
 -       "\e$,2'j'k\e(B"                          ; U+27EA U+27EB
 -       "\e$,2,#,$\e(B"                          ; U+2983 U+2984
 -       "\e$,2,%,&\e(B"                          ; U+2985 U+2986
 -       "\e$,2,',(\e(B"                          ; U+2987 U+2988
 -       "\e$,2,),*\e(B"                          ; U+2989 U+298A
 -       "\e$,2,+,,\e(B"                          ; U+298B U+298C
 -       "\e$,2,-,.\e(B"                          ; U+298D U+298E
 -       "\e$,2,/,0\e(B"                          ; U+298F U+2990
 -       "\e$,2,1,2\e(B"                          ; U+2991 U+2992
 -       "\e$,2,3,4\e(B"                          ; U+2993 U+2994
 -       "\e$,2,5,6\e(B"                          ; U+2995 U+2996
 -       "\e$,2,7,8\e(B"                          ; U+2997 U+2998
 -       "\e$,2-<-=\e(B"                          ; U+29FC U+29FD
 -       "\e$,2=H=I\e(B"                          ; U+3008 U+3009
 -       "\e$,2=J=K\e(B"                          ; U+300A U+300B
 -       "\e$,2=L=M\e(B"                          ; U+300C U+300D
 -       "\e$,2=N=O\e(B"                          ; U+300E U+300F
 -       "\e$,2=P=Q\e(B"                          ; U+3010 U+3011
 -       "\e$,2=T=U\e(B"                          ; U+3014 U+3015
 -       "\e$,2=V=W\e(B"                          ; U+3016 U+3017
 -       "\e$,2=X=Y\e(B"                          ; U+3018 U+3019
 -       "\e$,2=Z=[\e(B"                          ; U+301A U+301B
 -       "\e$,3m~m\7f\e(B"                          ; U+FD3E U+FD3F
 -       "\e$,3pUpV\e(B"                          ; U+FE35 U+FE36
 -       "\e$,3pWpX\e(B"                          ; U+FE37 U+FE38
 -       "\e$,3pYpZ\e(B"                          ; U+FE39 U+FE3A
 -       "\e$,3p[p\\e(B"                          ; U+FE3B U+FE3C
 -       "\e$,3p]p^\e(B"                          ; U+FE3D U+FE3E
 -       "\e$,3p_p`\e(B"                          ; U+FE3F U+FE40
 -       "\e$,3papb\e(B"                          ; U+FE41 U+FE42
 -       "\e$,3pcpd\e(B"                          ; U+FE43 U+FE44
 -       "\e$,3pypz\e(B"                          ; U+FE59 U+FE5A
 -       "\e$,3p{p|\e(B"                          ; U+FE5B U+FE5C
 -       "\e$,3p}p~\e(B"                          ; U+FE5D U+FE5E
 -       "\e$,3rhri\e(B"                          ; U+FF08 U+FF09
 -       "\e$,3s;s=\e(B"                          ; U+FF3B U+FF3D
 -       "\e$,3s[s]\e(B"                          ; U+FF5B U+FF5D
 -       "\e$,3s_s`\e(B"                          ; U+FF5F U+FF60
 -       "\e$,3sbsc\e(B"                          ; U+FF62 U+FF63
 +       '("â…â†"                             ; U+2045 U+2046
 +       "â½â¾"                               ; U+207D U+207E
 +       "â‚â‚Ž"                               ; U+208D U+208E
 +       "〈〉"                               ; U+2329 U+232A
 +       "⎴⎵"                               ; U+23B4 U+23B5
 +       "â¨â©"                               ; U+2768 U+2769
 +       "âªâ«"                               ; U+276A U+276B
 +       "â¬â­"                               ; U+276C U+276D
 +       "â°â±"                               ; U+2770 U+2771
 +       "â²â³"                               ; U+2772 U+2773
 +       "â´âµ"                               ; U+2774 U+2775
 +       "⟦⟧"                               ; U+27E6 U+27E7
 +       "⟨⟩"                               ; U+27E8 U+27E9
 +       "⟪⟫"                               ; U+27EA U+27EB
 +       "⦃⦄"                               ; U+2983 U+2984
 +       "⦅⦆"                               ; U+2985 U+2986
 +       "⦇⦈"                               ; U+2987 U+2988
 +       "⦉⦊"                               ; U+2989 U+298A
 +       "⦋⦌"                               ; U+298B U+298C
 +       "â¦â¦Ž"                               ; U+298D U+298E
 +       "â¦â¦"                               ; U+298F U+2990
 +       "⦑⦒"                               ; U+2991 U+2992
 +       "⦓⦔"                               ; U+2993 U+2994
 +       "⦕⦖"                               ; U+2995 U+2996
 +       "⦗⦘"                               ; U+2997 U+2998
 +       "⧼⧽"                               ; U+29FC U+29FD
 +       "〈〉"                               ; U+3008 U+3009
 +       "《》"                               ; U+300A U+300B
 +       "「ã€"                               ; U+300C U+300D
 +       "『ã€"                               ; U+300E U+300F
 +       "ã€ã€‘"                               ; U+3010 U+3011
 +       "〔〕"                               ; U+3014 U+3015
 +       "〖〗"                               ; U+3016 U+3017
 +       "〘〙"                               ; U+3018 U+3019
 +       "〚〛"                               ; U+301A U+301B
 +       "﴾﴿"                               ; U+FD3E U+FD3F
 +       "︵︶"                               ; U+FE35 U+FE36
 +       "︷︸"                               ; U+FE37 U+FE38
 +       "︹︺"                               ; U+FE39 U+FE3A
 +       "︻︼"                               ; U+FE3B U+FE3C
 +       "︽︾"                               ; U+FE3D U+FE3E
 +       "︿﹀"                               ; U+FE3F U+FE40
 +       "ï¹ï¹‚"                               ; U+FE41 U+FE42
 +       "﹃﹄"                               ; U+FE43 U+FE44
 +       "﹙﹚"                               ; U+FE59 U+FE5A
 +       "﹛﹜"                               ; U+FE5B U+FE5C
 +       "ï¹ï¹ž"                               ; U+FE5D U+FE5E
 +       "()"                               ; U+FF08 U+FF09
 +       "[]"                               ; U+FF3B U+FF3D
 +       "ï½›ï½"                               ; U+FF5B U+FF5D
 +       "⦅⦆"                               ; U+FF5F U+FF60
 +       "「」"                               ; U+FF62 U+FF63
         )))
    (dolist (elt pairs)
      (modify-syntax-entry (aref elt 0) (string ?\( (aref elt 1)))
      (modify-syntax-entry (aref elt 1) (string ?\) (aref elt 0)))))
  
 -\f
 -;;; Setting word boundary.
 -
 -(setq word-combining-categories
 -      '((?l . ?l)
 -      (?C . ?C)
 -      (?C . ?H)
 -      (?C . ?K)))
 -
 -(setq word-separating-categories      ;  (2-byte character sets)
 -      '((?A . ?K)                     ; Alpha numeric - Katakana
 -      (?A . ?C)                       ; Alpha numeric - Chinese
 -      (?H . ?A)                       ; Hiragana - Alpha numeric
 -      (?H . ?K)                       ; Hiragana - Katakana
 -      (?H . ?C)                       ; Hiragana - Chinese
 -      (?K . ?A)                       ; Katakana - Alpha numeric
 -      (?K . ?C)                       ; Katakana - Chinese
 -      (?C . ?A)                       ; Chinese - Alpha numeric
 -      (?C . ?K)                       ; Chinese - Katakana
 -      ))
 -
  \f
  ;; For each character set, put the information of the most proper
  ;; coding system to encode it by `preferred-coding-system' property.
  
 +;; Fixme: should this be junked?
  (let ((l '((latin-iso8859-1   . iso-latin-1)
           (latin-iso8859-2     . iso-latin-2)
           (latin-iso8859-3     . iso-latin-3)
           (cyrillic-iso8859-5  . cyrillic-iso-8bit)
           (latin-iso8859-9     . iso-latin-5)
           (japanese-jisx0208-1978 . iso-2022-jp)
 -         (chinese-gb2312      . cn-gb-2312)
 +         (chinese-gb2312      . chinese-iso-8bit)
 +         (chinese-gbk         . chinese-gbk)
 +         (gb18030-2-byte      . chinese-gb18030)
 +         (gb18030-4-byte-bmp  . chinese-gb18030)
 +         (gb18030-4-byte-smp  . chinese-gb18030)
 +         (gb18030-4-byte-ext-1 . chinese-gb18030)
 +         (gb18030-4-byte-ext-2 . chinese-gb18030)
           (japanese-jisx0208   . iso-2022-jp)
           (korean-ksc5601      . iso-2022-kr)
           (japanese-jisx0212   . iso-2022-jp)
 -         (chinese-cns11643-1  . iso-2022-cn)
 -         (chinese-cns11643-2  . iso-2022-cn)
           (chinese-big5-1      . chinese-big5)
           (chinese-big5-2      . chinese-big5)
           (chinese-sisheng     . iso-2022-7bit)
           (vietnamese-viscii-upper . vietnamese-viscii)
           (arabic-digit        . iso-2022-7bit)
           (arabic-1-column     . iso-2022-7bit)
 -         (ascii-right-to-left . iso-2022-7bit)
           (lao                 . lao)
           (arabic-2-column     . iso-2022-7bit)
           (indian-is13194      . devanagari)
           (indian-glyph        . devanagari)
           (tibetan-1-column    . tibetan)
           (ethiopic            . iso-2022-7bit)
 +         (chinese-cns11643-1  . iso-2022-cn)
 +         (chinese-cns11643-2  . iso-2022-cn)
           (chinese-cns11643-3  . iso-2022-cn)
           (chinese-cns11643-4  . iso-2022-cn)
           (chinese-cns11643-5  . iso-2022-cn)
  
  \f
  ;; Setup auto-fill-chars for charsets that should invoke auto-filling.
 -;; SPACE and NEWLINE are already set.  Also put `nospace-between-words'
 -;; property on the charsets.
 -(let ((l '(katakana-jisx0201
 -         japanese-jisx0208 japanese-jisx0212
 -         chinese-gb2312 chinese-big5-1 chinese-big5-2)))
 -  (while l
 -    (aset auto-fill-chars (make-char (car l)) t)
 -    (put-charset-property (car l) 'nospace-between-words t)
 -    (setq l (cdr l))))
 +;; SPACE and NEWLINE are already set.
 +
 +(set-char-table-range auto-fill-chars '(#x3041 . #x30FF) t)
 +(set-char-table-range auto-fill-chars '(#x3400 . #x4DB5) t)
 +(set-char-table-range auto-fill-chars '(#x4e00 . #x9fbb) t)
 +(set-char-table-range auto-fill-chars '(#xF900 . #xFAFF) t)
 +(set-char-table-range auto-fill-chars '(#xFF00 . #xFF9F) t)
 +(set-char-table-range auto-fill-chars '(#x20000 . #x2FFFF) t)
  
  \f
 -(setq utf-translate-cjk-mode saved-utf-translate-cjk-mode)
 -(makunbound 'saved-utf-translate-cjk-mode)
 +;;; Setting char-width-table.  The default is 1.
 +
 +;; 0: non-spacing, enclosing combining, formatting, Hangul Jamo medial
 +;;    and final characters.
 +(let ((l '((#x00AD . #x00AD)
 +         (#x0300 . #x036F)
 +         (#x0483 . #x0489)
 +         (#x0591 . #x05BD)
 +         (#x05BF . #x05BF)
 +         (#x05C1 . #x05C2)
 +         (#x05C4 . #x05C5)
 +         (#x05C7 . #x05C7)
 +         (#x0600 . #x0603)
 +         (#x0610 . #x0615)
 +         (#x064B . #x065E)
 +         (#x0670 . #x0670)
 +         (#x06D6 . #x06E4)
 +         (#x06E7 . #x06E8)
 +         (#x06EA . #x06ED)
 +         (#x070F . #x070F)
 +         (#x0711 . #x0711)
 +         (#x0730 . #x074A)
 +         (#x07A6 . #x07B0)
 +         (#x07EB . #x07F3)
 +         (#x0901 . #x0902)
 +         (#x093C . #x093C)
 +         (#x0941 . #x0948)
 +         (#x094D . #x094D)
 +         (#x0951 . #x0954)
 +         (#x0962 . #x0963)
 +         (#x0981 . #x0981)
 +         (#x09BC . #x09BC)
 +         (#x09C1 . #x09C4)
 +         (#x09CD . #x09CD)
 +         (#x09E2 . #x09E3)
 +         (#x0A01 . #x0A02)
 +         (#x0A3C . #x0A3C)
 +         (#x0A41 . #x0A4D)
 +         (#x0A70 . #x0A71)
 +         (#x0A81 . #x0A82)
 +         (#x0ABC . #x0ABC)
 +         (#x0AC1 . #x0AC8)
 +         (#x0ACD . #x0ACD)
 +         (#x0AE2 . #x0AE3)
 +         (#x0B01 . #x0B01)
 +         (#x0B3C . #x0B3C)
 +         (#x0B3F . #x0B3F)
 +         (#x0B41 . #x0B43)
 +         (#x0B4D . #x0B56)
 +         (#x0B82 . #x0B82)
 +         (#x0BC0 . #x0BC0)
 +         (#x0BCD . #x0BCD)
 +         (#x0C3E . #x0C40)
 +         (#x0C46 . #x0C56)
 +         (#x0CBC . #x0CBC)
 +         (#x0CBF . #x0CBF)
 +         (#x0CC6 . #x0CC6)
 +         (#x0CCC . #x0CCD)
 +         (#x0CE2 . #x0CE3)
 +         (#x0D41 . #x0D43)
 +         (#x0D4D . #x0D4D)
 +         (#x0DCA . #x0DCA)
 +         (#x0DD2 . #x0DD6)
 +         (#x0E31 . #x0E31)
 +         (#x0E34 . #x0E3A)
 +         (#x0E47 . #x0E4E)
 +         (#x0EB1 . #x0EB1)
 +         (#x0EB4 . #x0EBC)
 +         (#x0EC8 . #x0ECD)
 +         (#x0F18 . #x0F19)
 +         (#x0F35 . #x0F35)
 +         (#x0F37 . #x0F37)
 +         (#x0F39 . #x0F39)
 +         (#x0F71 . #x0F7E)
 +         (#x0F80 . #x0F84)
 +         (#x0F86 . #x0F87)
 +         (#x0F90 . #x0FBC)
 +         (#x0FC6 . #x0FC6)
 +         (#x102D . #x1030)
 +         (#x1032 . #x1037)
 +         (#x1039 . #x1039)
 +         (#x1058 . #x1059)
 +         (#x1160 . #x11FF)
 +         (#x135F . #x135F)
 +         (#x1712 . #x1714)
 +         (#x1732 . #x1734)
 +         (#x1752 . #x1753)
 +         (#x1772 . #x1773)
 +         (#x17B4 . #x17B5)
 +         (#x17B7 . #x17BD)
 +         (#x17C6 . #x17C6)
 +         (#x17C9 . #x17D3)
 +         (#x17DD . #x17DD)
 +         (#x180B . #x180D)
 +         (#x18A9 . #x18A9)
 +         (#x1920 . #x1922)
 +         (#x1927 . #x1928)
 +         (#x1932 . #x1932)
 +         (#x1939 . #x193B)
 +         (#x1A17 . #x1A18)
 +         (#x1B00 . #x1B03)
 +         (#x1B34 . #x1B34)
 +         (#x1B36 . #x1B3A)
 +         (#x1B3C . #x1B3C)
 +         (#x1B42 . #x1B42)
 +         (#x1B6B . #x1B73)
 +         (#x1DC0 . #x1DFF)
 +         (#x200B . #x200F)
 +         (#x202A . #x202E)
 +         (#x2060 . #x206F)
 +         (#x20D0 . #x20EF)
 +         (#x302A . #x302F)
 +         (#x3099 . #x309A)
 +         (#xA806 . #xA806)
 +         (#xA80B . #xA80B)
 +         (#xA825 . #xA826)
 +         (#xFB1E . #xFB1E)
 +         (#xFE00 . #xFE0F)
 +         (#xFE20 . #xFE23)
 +         (#xFEFF . #xFEFF)
 +         (#xFFF9 . #xFFFB)
 +         (#x10A01 . #x10A0F)
 +         (#x10A38 . #x10A3F)
 +         (#x1D167 . #x1D169)
 +         (#x1D173 . #x1D182)
 +         (#x1D185 . #x1D18B)
 +         (#x1D1AA . #x1D1AD)
 +         (#x1D242 . #x1D244)
 +         (#xE0001 . #xE01EF))))
 +  (dolist (elt l)
 +    (set-char-table-range char-width-table elt 0)))
 +
 +;; 2: East Asian Wide and Full-width characters.
 +(let ((l '((#x1100 . #x115F)
 +         (#x2329 . #x232A)
 +         (#x2E80 . #x303E)
 +         (#x3040 . #xA4CF)
 +         (#xAC00 . #xD7A3)
 +         (#xF900 . #xFAFF)
 +         (#xFE30 . #xFE6F)
 +         (#xFF01 . #xFF60)
 +         (#xFFE0 . #xFFE6)
 +         (#x20000 . #x2FFFF)
 +         (#x30000 . #x3FFFF))))
 +  (dolist (elt l)
 +    (set-char-table-range char-width-table elt 2)))
 +
 +;; Other double width
 +;;(map-charset-chars
 +;; (lambda (range ignore) (set-char-table-range char-width-table range 2))
 +;; 'ethiopic)
 +;; (map-charset-chars
 +;;  (lambda (range ignore) (set-char-table-range char-width-table range 2))
 +;; 'tibetan)
 +(map-charset-chars
 + (lambda (range ignore) (set-char-table-range char-width-table range 2))
 + 'indian-2-column)
 +(map-charset-chars
 + (lambda (range ignore) (set-char-table-range char-width-table range 2))
 + 'arabic-2-column)
 +
 +(optimize-char-table (standard-case-table))
 +(optimize-char-table (standard-category-table))
 +(optimize-char-table (standard-syntax-table))
 +
 +;; The Unicode blocks actually extend past some of these ranges with
 +;; undefined codepoints.
 +(let ((script-list nil))
 +  (dolist
 +      (elt
 +       '((#x0000 #x007F latin)
 +       (#x00A0 #x036F latin)
 +       (#x0370 #x03E1 greek)
 +       (#x03E2 #x03EF coptic)
 +       (#x03F0 #x03F3 greek)
 +       (#x0400 #x04FF cyrillic)
 +       (#x0530 #x058F armenian)
 +       (#x0590 #x05FF hebrew)
 +       (#x0600 #x06FF arabic)
 +       (#x0700 #x074F syriac)
 +       (#x07C0 #x07FA nko)
 +       (#x0780 #x07BF thaana)
 +       (#x0900 #x097F devanagari)
 +       (#x0980 #x09FF bengali)
 +       (#x0A00 #x0A7F gurmukhi)
 +       (#x0A80 #x0AFF gujarati)
 +       (#x0B00 #x0B7F oriya)
 +       (#x0B80 #x0BFF tamil)
 +       (#x0C00 #x0C7F telugu)
 +       (#x0C80 #x0CFF kannada)
 +       (#x0D00 #x0D7F malayalam)
 +       (#x0D80 #x0DFF sinhala)
 +       (#x0E00 #x0E5F thai)
 +       (#x0E80 #x0EDF lao)
 +       (#x0F00 #x0FFF tibetan)
 +       (#x1000 #x105F myanmar)
 +       (#x10A0 #x10FF georgian)
 +       (#x1100 #x11FF hangul)
 +       (#x1200 #x139F ethiopic)
 +       (#x13A0 #x13FF cherokee)
 +       (#x1400 #x167F canadian-aboriginal)
 +       (#x1680 #x169F ogham)
 +       (#x16A0 #x16FF runic)
 +       (#x1780 #x17FF khmer)
 +       (#x1800 #x18AF mongolian)
 +       (#x1E00 #x1EFF latin)
 +       (#x1F00 #x1FFF greek)
 +       (#x2000 #x27FF symbol)
 +       (#x2800 #x28FF braille)
 +       (#x2D80 #x2DDF ethiopic)
 +       (#x2E80 #x2FDF han)
 +       (#x2FF0 #x2FFF ideographic-description)
 +       (#x3000 #x303F cjk-misc)
 +       (#x3040 #x30FF kana)
 +       (#x3100 #x312F bopomofo)
 +       (#x3130 #x318F hangul)
 +       (#x3190 #x319F kanbun)
 +       (#x31A0 #x31BF bopomofo)
 +       (#x3400 #x9FAF han)
 +       (#xA000 #xA4CF yi)
 +       (#xAC00 #xD7AF hangul)
 +       (#xF900 #xFAFF han)
 +       (#xFB1D #xFB4F hebrew)
 +       (#xFB50 #xFDFF arabic)
 +       (#xFE70 #xFEFC arabic)
 +       (#xFF00 #xFF5F cjk-misc)
 +       (#xFF61 #xFF9F kana)
 +       (#xFFE0 #xFFE6 cjk-misc)
 +       (#x1D000 #x1D0FF byzantine-musical-symbol)
 +       (#x1D100 #x1D1FF musical-symbol)
 +       (#x1D400 #x1D7FF mathematical)
 +       (#x20000 #x2AFFF han)
 +       (#x2F800 #x2FFFF han)))
 +    (set-char-table-range char-script-table
 +                        (cons (car elt) (nth 1 elt)) (nth 2 elt))
 +    (or (memq (nth 2 elt) script-list)
 +      (setq script-list (cons (nth 2 elt) script-list))))
 +  (set-char-table-extra-slot char-script-table 0 (nreverse script-list)))
 +
 +(map-charset-chars
 + #'(lambda (range ignore)
 +     (set-char-table-range char-script-table range 'tibetan))
 + 'tibetan)
 +
 +\f
 +;;; Setting word boundary.
 +
 +(defun next-word-boundary-han (pos limit)
 +  (if (<= pos limit)
 +      (save-excursion
 +      (goto-char pos)
 +      (looking-at "\\cC+")
 +      (goto-char (match-end 0))
 +      (if (looking-at "\\cH+")
 +          (goto-char (match-end 0)))
 +      (point))
 +    (while (and (> pos limit)
 +              (eq (aref char-script-table (char-after (1- pos))) 'han))
 +      (setq pos (1- pos)))
 +    pos))
 +
 +(defun next-word-boundary-kana (pos limit)
 +  (if (<= pos limit)
 +      (save-excursion
 +      (goto-char pos)
 +      (if (looking-at "\\cK+")
 +          (goto-char (match-end 0)))
 +      (if (looking-at "\\cH+")
 +          (goto-char (match-end 0)))
 +      (if (looking-at "\\ck+")
 +          (goto-char (match-end 0)))
 +      (point))
 +    (let ((category-set (char-category-set (char-after pos)))
 +        category)
 +      (if (or (aref category-set ?K) (aref category-set ?k))
 +        (while (and (> pos limit)
 +                    (setq category-set 
 +                          (char-category-set (char-after (1- pos))))
 +                    (or (aref category-set ?K) (aref category-set ?k)))
 +          (setq pos (1- pos)))
 +      (while (and (> pos limit)
 +                  (aref (setq category-set
 +                              (char-category-set (char-after (1- pos)))) ?H))
 +        (setq pos (1- pos)))
 +      (setq category (cond ((aref category-set ?C) ?C)
 +                           ((aref category-set ?K) ?K)
 +                           ((aref category-set ?A) ?A)))
 +      (when category
 +        (setq pos (1- pos))
 +        (while (and (> pos limit)
 +                    (aref (char-category-set (char-after (1- pos)))
 +                          category))
 +          (setq pos (1- pos)))))
 +      pos)))
 +
 +(map-char-table
 + #'(lambda (char script)
 +     (cond ((eq script 'han)
 +          (set-char-table-range find-word-boundary-function-table
 +                                char #'next-word-boundary-han))
 +         ((eq script 'kana)
 +          (set-char-table-range find-word-boundary-function-table
 +                                char #'next-word-boundary-kana))))
 + char-script-table)
 +
 +(setq word-combining-categories
 +      '((?l . ?l)
 +      (?C . ?C)
 +      (?C . ?H)
 +      (?C . ?K)))
 +
 +(setq word-separating-categories      ;  (2-byte character sets)
 +      '((?A . ?K)                     ; Alpha numeric - Katakana
 +      (?A . ?C)                       ; Alpha numeric - Chinese
 +      (?H . ?A)                       ; Hiragana - Alpha numeric
 +      (?H . ?K)                       ; Hiragana - Katakana
 +      (?H . ?C)                       ; Hiragana - Chinese
 +      (?K . ?A)                       ; Katakana - Alpha numeric
 +      (?K . ?C)                       ; Katakana - Chinese
 +      (?C . ?A)                       ; Chinese - Alpha numeric
 +      (?C . ?K)                       ; Chinese - Katakana
 +      ))
  
  ;;; Local Variables:
 -;;; coding: iso-2022-7bit
 +;;; coding: utf-8-emacs
  ;;; End:
  
  ;;; arch-tag: 85889c35-9f4d-4912-9bf5-82de31b0d42d
index ca5500b541587cf6ed6590b646b6d92328427d4e,ff30e4c14c40a6179f3a6f074e1dbc2fc07816f8..4c3f76d470bcbaafa7a2161aee3039be4525abbc
@@@ -1,13 -1,13 +1,13 @@@
  ;;; codepage.el --- MS-DOS/MS-Windows specific coding systems
  
 -;; Copyright (C) 1998, 1999, 2000, 2002  Free Software Foundation, Inc.
 +;; Copyright (C) 1998, 1999, 2000, 2002, 2005  Free Software Foundation, Inc.
- ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  ;; Author: Eli Zaretskii
  ;; Maintainer: FSF
 -;; Keywords: i18n ms-dos ms-windows codepage
 +;; Keywords: i18n ms-dos ms-windows codepage obsolete
  
  ;; This file is part of GNU Emacs.
  
  ;;; Commentary:
  
  ;; Special coding systems for DOS/Windows codepage support.
 -;;
 -;; These coding systems perform conversion from the DOS/Windows
 -;; codepage encoding to one of the ISO-8859 character sets.  Each
 -;; codepage has its corresponding ISO-8859 charset, chosen so as to be
 -;; able to convert all (or most) of the characters.  The idea is that
 -;; Emacs internally works with the usual MULE charsets, and the
 -;; conversion to and from the DOS codepage is performed on I/O only.
 -;; See term/internal.el for the complementary setup of the DOS
 -;; terminal display and input methods.
 -;;
 -;; Thanks to Ken'ichi Handa <handa@etl.go.jp> for writing the CCL
 -;; encoders/decoders, and for help in debugging this code.
 +;; Obsolete.
  
  ;;; Code:
  
  (defvar dos-unsupported-char-glyph)
  
 -(defun cp-coding-system-for-codepage-1 (coding mnemonic iso-name
 -                                             decoder encoder)
 -  "Make coding system CODING for a DOS codepage using translation tables.
 -MNEMONIC is a character to be displayed on mode line for the coding system.
 -ISO-NAME is the name of the ISO-8859 charset which corresponds to this
 -codepage.
 -DECODER is a translation table for converting characters in the DOS codepage
 -encoding to Emacs multibyte characters.
 -ENCODER is a translation table for encoding Emacs multibyte characters into
 -external DOS codepage codes."
 -  (save-match-data
 -    (let* ((coding-name (symbol-name coding))
 -         (undef (if (eq system-type 'ms-dos)
 -                    (if dos-unsupported-char-glyph
 -                        (logand dos-unsupported-char-glyph 255)
 -                      127)
 -                  ??))
 -         (safe-chars (make-char-table 'safe-chars))
 -         (ccl-decoder
 -          (ccl-compile
 -           ;; The 4 here supplies the buf_magnification parameter
 -           ;; for the CCL program.  A multibyte character may take
 -           ;; at most 4-bytes.
 -           `(4 (loop (read r1)
 -                     (if (r1 >= 128)
 -                         ((r0 = ,(charset-id 'ascii))
 -                          (translate-character ,decoder r0 r1)
 -                          (write-multibyte-character r0 r1))
 -                       (write r1))
 -                     (repeat)))))
 -         (ccl-encoder
 -          (ccl-compile
 -           ;; The 2 here supplies the buf_magnification parameter for
 -           ;; the CCL program.  Since the -dos coding system generates
 -           ;; \r\n for each \n, a factor of 2 covers even the worst case
 -           ;; of empty lines with a single \n.
 -           `(2 (loop (read-multibyte-character r0 r1)
 -                     (if (r0 != ,(charset-id 'ascii))
 -                         ((translate-character ,encoder r0 r1)
 -                          (if (r0 == ,(charset-id 'japanese-jisx0208))
 -                              ((r1 = ,undef)
 -                               (write r1)))))
 -                     (write-repeat r1))))))
 -
 -      ;; Set elements of safe multibyte characters for this codepage
 -      ;; to t in the char-table safe-chars.
 -      (let ((tbl (get decoder 'translation-table))
 -          (i 128)
 -          ch)
 -      (while (< i 256)
 -        (setq ch (aref tbl i))
 -        (if ch (aset safe-chars ch t))
 -        (setq i (1+ i))))
 -
 -      ;; Make coding system CODING.
 -      (make-coding-system
 -       coding 4 mnemonic
 -       (concat "8-bit encoding of " (symbol-name iso-name)
 -             " characters using IBM codepage " coding-name)
 -       (cons ccl-decoder ccl-encoder)
 -       `((safe-charsets ascii eight-bit-control eight-bit-graphic ,iso-name)
 -       (safe-chars . ,safe-chars)
 -       (valid-codes (0 . 255)))))))
 -
 -(defun cp-decoding-vector-for-codepage (table charset offset)
 -  "Create a vector for decoding IBM PC characters using conversion table
 -TABLE into an ISO-8859 character set CHARSET whose first non-ASCII
 -character is generated by (make-char CHARSET OFFSET)."
 -  (let* ((len (length table))
 -       (undefined-char
 -        (if (eq system-type 'ms-dos)
 -            (if dos-unsupported-char-glyph
 -                (logand dos-unsupported-char-glyph 255)
 -              127)
 -          32))
 -       (vec1 (make-vector 256 undefined-char))
 -       (i 0))
 -    (while (< i 256)
 -      (aset vec1 i i)
 -      (setq i (1+ i)))
 -    (setq i 0)
 -    (while (< i len)
 -      (if (aref table i)
 -        (aset vec1 (aref table i) (make-char charset (+ i offset))))
 -      (setq i (1+ i)))
 -    vec1))
 -
 -;;; You don't think I created all these tables below by hand, do you?
 -;;; The following Awk script will create the table for cp850-to-Latin-1
 -;;; conversion from the RFC 1345 file (the other tables are left as an
 -;;; excercise):
 -;;; BEGIN { n_pages = 11;
 -;;;         pn["IBM437"] = 0; pn["IBM850"] = 1; pn["IBM851"] = 2;
 -;;;         pn["IBM852"] = 3; pn["IBM855"] = 4; pn["IBM860"] = 5;
 -;;;         pn["IBM861"] = 6; pn["IBM862"] = 7; pn["IBM863"] = 8;
 -;;;         pn["IBM864"] = 9; pn["IBM865"] = 10;
 -;;;       }
 -;;; $1 == "&charset" { charset = $2; }
 -;;; $1 == "&code"    { code = $2; }
 -;;; /^  [^&]/  {
 -;;;   if ((charset ~ /^IBM(437|8(5[0125]|6[0-5]))$/) || (charset ~ /^ISO_8859-1/))
 -;;;     {
 -;;;       for (i = 1; i <= NF; i++)
 -;;;         chars[charset,code++] = $i;
 -;;;     }
 -;;;   }
 -;;;
 -;;; END {
 -;;;   for (i = 160; i < 256; i++)
 -;;;     {
 -;;;       c =  chars["ISO_8859-1:1987",i];
 -;;;       if (c == "??")        # skip unused positions
 -;;;         {
 -;;;           printf " nil";
 -;;;           if ((i - 159)%16 == 0)
 -;;;             printf "\n";
 -;;;           continue;
 -;;;         }
 -;;;       found = 0;
 -;;;       for (j in pn)
 -;;;         map[j] = "nil";
 -;;;       for (combined in chars)
 -;;;         {
 -;;;           candidate = chars[combined];
 -;;;           split (combined, separate, SUBSEP);
 -;;;           if (separate[1] == "IBM850" && candidate == c)
 -;;;             {
 -;;;               found = 1;
 -;;;               map[separate[1]] = separate[2];
 -;;;             }
 -;;;         }
 -;;;       printf " %s", map["IBM850"];
 -;;;       if ((i - 159)%16 == 0)
 -;;;         printf "\n";
 -;;;     }
 -;;; }
 -
 -;;; WARNING WARNING WARNING!!!
 -;;;
 -;;; If you want to get fancy with these tables, remember that the inverse
 -;;; tables, created by `cp-decoding-vector-for-codepage' above, are installed
 -;;; on MS-DOS as nonascii-translation-table (see `dos-codepage-setup' on
 -;;; internal.el).  Therefore, you should NOT put any codes below 128 in
 -;;; these tables!  Otherwise, various Emacs commands and functions will
 -;;; mysteriously fail!  For example, a typical screwup is to map the Latin-N
 -;;; acute accent character to the apostrophe, and have all regexps which
 -;;; end with "\\'" begin to fail (e.g., the automatic setting of the major
 -;;; mode by file name extension will stop working).
 -;;;
 -;;; You HAVE BEEN warned!
 -
 -;; US/English/PC-8/IBM-2.  This doesn't support Latin-1 characters very
 -;; well, but why not use what we can salvage?
 -(defvar cp437-decode-table
 -  ;; Nth element is the code of a cp437 glyph for the multibyte
 -  ;; character created by (make-char 'latin-iso8859-1 (+ N 160)).
 -  ;; The element nil means there's no corresponding cp437 glyph.
 -  [
 -   255 173 155 156 nil 157 179 nil nil nil 166 174 170 196 nil nil
 -   248 241 253 nil nil nil nil 249 nil nil 167 175 172 171 nil 168
 -   nil nil nil nil 142 143 146 128 nil 144 nil nil nil nil nil nil
 -   nil 165 nil nil nil nil 153 nil nil nil nil nil 154 nil nil 225
 -   133 160 131 nil 132 134 145 135 138 130 136 137 141 161 140 139
 -   nil 164 149 162 147 nil 148 246 nil 151 163 150 129 nil nil 152]
 -  "Table for converting ISO-8859-1 characters into codepage 437 glyphs.")
 -(setplist 'cp437-decode-table
 -        '(charset latin-iso8859-1 language "Latin-1" offset 160))
 -
 -;; Multilingual (Latin-1)
 -(defvar cp850-decode-table
 -  ;; Nth element is the code of a cp850 glyph for the multibyte
 -  ;; character created by (make-char 'latin-iso8859-1 (+ N 160)).
 -  ;; The element nil means there's no corresponding cp850 glyph.
 -  [
 -   255 173 189 156 207 190 221 245 249 184 166 174 170 240 169 238
 -   248 241 253 252 239 230 244 250 247 251 167 175 172 171 243 168
 -   183 181 182 199 142 143 146 128 212 144 210 211 222 214 215 216
 -   209 165 227 224 226 229 153 158 157 235 233 234 154 237 232 225
 -   133 160 131 198 132 134 145 135 138 130 136 137 141 161 140 139
 -   208 164 149 162 147 228 148 246 155 151 163 150 129 236 231 152]
 -  "Table for converting ISO-8859-1 characters into codepage 850 glyphs.")
 -(setplist 'cp850-decode-table
 -        '(charset latin-iso8859-1 language "Latin-1" offset 160))
 -
 -;; Multilingual (Latin-9)
 -(defvar cp858-decode-table
 -  ;; Nth element is the code of a cp858 glyph for the multibyte
 -  ;; character created by (make-char 'latin-iso8859-15 (+ N 160)).
 -  ;; The element nil means there's no corresponding cp858 glyph.
 -  [
 -   255 173 189 156 213 190 221 245 249 184 166 174 170 240 169 238
 -   248 241 253 252 239 230 244 250 247 251 167 175 172 171 243 168
 -   183 181 182 199 142 143 146 128 212 144 210 211 222 214 215 216
 -   209 165 227 224 226 229 153 158 157 235 233 234 154 237 232 225
 -   133 160 131 198 132 134 145 135 138 130 136 137 141 161 140 139
 -   208 164 149 162 147 228 148 246 155 151 163 150 129 236 231 152]
 -  "Table for converting ISO-8859-15 characters into codepage 858 glyphs.")
 -(setplist 'cp858-decode-table
 -        '(charset latin-iso8859-15 language "Latin-9" offset 160))
 -
 -;; Greek
 -(defvar cp851-decode-table
 -  [
 -   255 nil nil 156 nil nil nil 245 249 nil nil 174 nil 240 nil nil
 -   248 241 nil nil 239 nil 134 nil 141 143 144 175 146 171 149 152
 -   161 164 165 166 167 168 169 170 172 173 181 182 184 183 189 190
 -   198 199 nil 207 208 209 210 211 212 213 nil nil 155 157 158 159
 -   252 214 215 216 221 222 224 225 226 227 228 229 230 231 232 233
 -   234 235 237 236 238 242 243 244 246 250 160 251 162 163 253 nil]
 -  "Table for converting ISO-8859-7 characters into codepage 851 glyphs.")
 -(setplist 'cp851-decode-table
 -        '(charset greek-iso8859-7 language "Greek" offset 160))
 -
 -;; Slavic/Eastern Europe (Latin-2)
 -(defvar cp852-decode-table
 -  [
 -   255 164 244 157 207 149 151 245 249 230 184 155 141 240 166 189
 -   248 165 247 136 239 150 152 243 242 231 173 156 171 241 167 190
 -   232 181 182 198 142 145 143 128 172 144 168 211 183 214 215 210
 -   209 227 213 224 226 138 153 158 252 222 233 235 154 237 221 225
 -   234 160 131 199 132 146 134 135 159 130 169 137 216 161 140 212
 -   208 228 229 162 147 139 148 246 253 133 163 251 129 236 238 250]
 -  "Table for converting ISO-8859-2 characters into codepage 852 glyphs.")
 -(setplist 'cp852-decode-table
 -        '(charset latin-iso8859-2 language "Latin-2" offset 160))
 -
 -;; Russian
 -(defvar cp855-decode-table
 -  [
 -   255 133 129 131 135 137 139 141 143 145 147 149 151 240 153 155
 -   161 163 236 173 167 169 234 244 184 190 199 209 211 213 215 221
 -   226 228 230 232 171 182 165 252 246 250 159 242 238 248 157 224
 -   160 162 235 172 166 168 233 243 183 189 198 208 210 212 214 216
 -   225 227 229 231 170 181 164 251 245 249 158 241 237 247 156 222
 -   239 132 128 130 134 136 138 140 142 144 146 148 150 253 152 154]
 -  "Table for converting ISO-8859-5 characters into codepage 855 glyphs.")
 -(setplist 'cp855-decode-table
 -        '(charset cyrillic-iso8859-5 language "Cyrillic-ISO" offset 160))
 -
 -;; Turkish
 -(defvar cp857-decode-table
 -  [
 -   255 nil nil 156 207 nil 245 249 152 158 166 nil 240 nil
 -   248 nil 253 252 239 nil nil nil nil 141 159 167 nil 171 nil
 -   183 181 182 142 nil nil 128 212 144 210 211 222 214 215 216
 -   165 227 224 226 nil 153 232 nil 235 233 234 154 nil nil 225
 -   133 160 131 132 nil nil 135 138 130 136 137 236 161 140 139
 -   164 149 162 147 nil 148 246 nil 151 163 150 129 nil nil 250]
 -  "Table for converting ISO-8859-3 characters into codepage 857 glyphs.")
 -(setplist 'cp857-decode-table
 -        '(charset latin-iso8859-3 language "Latin-3" offset 160))
 -
 -;; Portuguese
 -(defvar cp860-decode-table
 -  [
 -   255 173 155 156 nil nil 179 nil nil nil 166 174 170 nil nil nil
 -   nil 241 253 nil nil nil nil 249 nil nil 167 175 172 171 nil 168
 -   145 134 143 142 nil nil nil 128 146 144 137 nil 152 nil 139 nil
 -   nil 165 159 169 140 153 nil nil nil 157 150 nil 154 nil nil nil
 -   133 160 131 132 nil nil nil 135 138 130 136 nil 141 161 nil nil
 -   nil 164 149 162 147 148 nil 246 nil 151 163 nil 129 nil nil nil]
 -  "Table for converting ISO-8859-1 characters into codepage 860 glyphs.")
 -(setplist 'cp860-decode-table
 -        '(charset latin-iso8859-1 language "Latin-1" offset 160))
 -
 -;; Icelandic
 -(defvar cp861-decode-table
 -  [
 -   255 173 nil 156 nil nil nil nil nil nil nil 174 170 nil nil nil
 -   nil 241 253 nil nil nil nil 249 nil nil nil 175 172 171 nil 168
 -   nil 164 nil nil 142 143 146 128 nil 144 nil nil nil 165 nil nil
 -   139 nil 159 166 nil nil 153 nil 157 nil 167 nil 154 151 141 nil
 -   133 160 131 nil 132 134 145 135 138 130 136 137 nil 161 nil nil
 -   140 nil nil 162 147 nil 148 246 155 nil 163 150 129 152 149 nil]
 -  "Table for converting ISO-8859-1 characters into codepage 861 glyphs.")
 -(setplist 'cp861-decode-table
 -        '(charset latin-iso8859-1 language "Latin-1" offset 160))
 -
 -;; Hebrew
 -(defvar cp862-decode-table
 -  ;; Nth element is the code of a cp862 glyph for the multibyte
 -  ;; character created by (make-char 'hebrew-iso8859-8 (+ N 160)).
 -  ;; The element nil means there's no corresponding cp862 glyph.
 -  [
 -   255 173 155 156 nil 157 179 nil nil nil nil 174 170 196 nil nil
 -   248 241 253 nil nil 230 nil 249 nil nil 246 175 172 171 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil 205
 -   128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
 -   144 145 146 147 148 149 150 151 152 153 154 nil nil nil nil nil]
 -  "Table for converting ISO-8859-8 characters into codepage 862 glyphs.")
 -(setplist 'cp862-decode-table
 -        '(charset hebrew-iso8859-8 language "Hebrew" offset 160))
 -
 -;; French Canadian
 -(defvar cp863-decode-table
 -  [
 -   255 nil 155 156 152 nil 160 143 164 nil nil 174 170 nil nil 167
 -   nil 241 253 166 161 nil 134 249 165 nil nil 175 172 171 173 nil
 -   142 nil 132 nil nil nil nil 128 145 144 146 148 nil nil 168 149
 -   nil nil nil nil 153 nil nil nil nil 157 nil 158 154 nil nil nil
 -   133 nil 131 nil nil nil nil 135 138 130 136 137 141 nil 140 139
 -   nil nil nil 162 147 nil nil 246 nil 151 163 150 129 nil nil nil]
 -  "Table for converting ISO-8859-1 characters into codepage 863 glyphs.")
 -(setplist 'cp863-decode-table
 -        '(charset latin-iso8859-1 language "Latin-1" offset 160))
 -
 -;; Arabic
 -;; FIXME: Emacs doesn't seem to support the "Arabic" language
 -;; environment yet.  So this is only partially usable, for now
 -(defvar cp864-decode-table
 -  [
 -   255 nil nil nil 164 nil nil nil nil nil nil nil 172 161 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil 187 nil nil nil 191
 -   nil 193 194 195 196 nil 198 199 169 201 170 171 173 174 175 207
 -   208 209 210 188 189 190 235 215 216 223 238 nil nil nil nil nil
 -   224 247 248 252 251 239 242 243 232 233 253 nil nil nil nil nil
 -   nil 241 nil nil nil nil nil nil nil nil nil nil nil nil nil nil]
 -  "Table for converting ISO-8859-6 characters into codepage 864 glyphs.")
 -(setplist 'cp864-decode-table
 -        '(charset arabic-iso8859-6 language nil offset 160))
 -
 -;; Arabic OEM codepage used by Windows
 -;; FIXME: Emacs doesn't seem to support the "Arabic" language
 -;; environment yet.  So this is only partially usable, for now
 -(defvar cp720-decode-table
 -  [
 -   255 nil nil nil 148 nil nil nil nil nil nil nil nil 196 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
 -   nil 152 153 154 155 157 158 159 160 161 162 163 164 165 166 167
 -   168 169 170 171 172 173 224 225 226 227 228 nil nil nil nil nil
 -   149 229 231 232 233 234 235 236 237 238 239 241 242 243 244 245
 -   246 145 146 nil nil nil nil nil nil nil nil nil nil nil nil nil]
 -  "Table for converting ISO-8859-6 characters into codepage 720 glyphs.")
 -(setplist 'cp720-decode-table
 -        '(charset arabic-iso8859-6 language nil offset 160))
 -
 -
 -;; Nordic (Norwegian/Danish)
 -(defvar cp865-decode-table
 -  [
 -   255 173 nil 156 nil nil nil nil nil nil 166 174 170 nil nil nil
 -   nil 241 253 nil nil nil nil 249 nil nil 167 175 172 171 nil 168
 -   nil nil nil nil 142 143 146 128 nil 144 nil nil nil nil nil nil
 -   nil 165 nil nil nil nil 153 nil 157 nil nil nil 154 nil nil nil
 -   133 160 131 nil 132 134 145 135 138 130 136 137 141 161 140 139
 -   nil 164 149 162 147 nil 148 246 155 151 163 150 129 nil nil 152]
 -  "Table for converting ISO-8859-1 characters into codepage 865 glyphs.")
 -(setplist 'cp865-decode-table
 -        '(charset latin-iso8859-1 language "Latin-1" offset 160))
 -
 -;; Russian (Yes, another one!  This one's supposed to be used
 -;; on Windows as the Russian OEM code page.)
 -(defvar cp866-decode-table
 -  [
 -   255 240 nil nil 242 nil nil 244 nil nil nil nil nil nil 246 nil
 -   128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
 -   144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
 -   160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
 -   224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
 -   252 241 nil nil 243 nil nil 245 nil nil nil nil nil nil 247 nil]
 -  "Table for converting ISO-8859-5 characters into codepage 866 glyphs.")
 -(setplist 'cp866-decode-table
 -        '(charset cyrillic-iso8859-5 language "Cyrillic-ISO" offset 160))
 -
 -;; Greek (yes, another one!)
 -(defvar cp869-decode-table
 -  [
 -   255 139 140 156 nil nil 138 245 249 151 nil 174 137 240 nil 142
 -   248 241 153 154 239 247 134 136 141 143 144 175 146 171 149 152
 -   161 164 165 166 167 168 169 170 172 173 181 182 183 184 189 190
 -   198 199 nil 207 208 209 210 211 212 213 145 150 155 157 158 159
 -   252 214 215 216 221 222 224 225 226 227 228 229 230 231 232 233
 -   234 235 237 236 238 242 243 244 246 250 160 251 162 163 253 nil]
 -  "Table for converting ISO-8859-7 characters into codepage 869 glyphs.")
 -(setplist 'cp869-decode-table
 -        '(charset greek-iso8859-7 language "Greek" offset 160))
 -
 -;; Greek OEM codepage used by Windows
 -(defvar cp737-decode-table
 -  [
 -   255 nil nil nil nil nil 179 nil nil nil nil nil nil 196 nil nil
 -   248 241 253 nil nil nil 234 250 235 236 237 nil 238 nil 239 240
 -   nil 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
 -   143 144 nil 145 146 147 148 149 150 151 244 245 225 226 227 229
 -   nil 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
 -   167 168 170 169 171 172 173 174 175 224 228 232 230 231 233 nil]
 -  "Table for converting ISO-8859-7 characters into codepage 737 glyphs.")
 -(setplist 'cp737-decode-table
 -        '(charset greek-iso8859-7 language "Greek" offset 160))
 -
 -;; Conversion from codepages 770-775 to Latin-4 for Baltic countries.
 -;; FIXME: Once we support Latin-7, these should be remapped into it.
 -(defvar cp770-decode-table
 -  [
 -   255 143 nil nil 155 nil 156 nil 157 159 137 168 nil 196 146 nil
 -   248 133 nil nil nil nil 134 nil nil 158 136 152 nil nil 145 nil
 -   160 nil nil nil 142 nil nil 173 128 nil 139 nil 144 nil nil 161
 -   nil nil nil 163 nil 149 153 nil nil 167 nil nil 154 nil 166 225
 -   131 nil nil nil 132 nil nil 141 135 nil 138 nil 130 nil nil 140
 -   nil nil nil 162 nil 147 148 247 nil 151 nil nil 129 nil 150 nil]
 -  "Table for converting ISO-8859-4 characters into codepage 770 glyphs.")
 -(setplist 'cp770-decode-table
 -        '(charset latin-iso8859-4 language "Latin-4" offset 160))
 -
 -(defvar cp773-decode-table
 -  [
 -   255 220 nil 138 150 nil 234 190 166 246 237 149 173 196 252 nil
 -   208 nil nil 139 239 nil 235 nil nil 247 137 133 136 nil 253 nil
 -   160 nil nil nil 142 143 146 244 222 144 240 nil 242 nil nil 161
 -   nil 238 226 232 nil 229 153 158 157 248 nil nil 154 nil 250 225
 -   131 nil nil nil 132 134 145 245 223 130 241 nil 243 nil nil 140
 -   nil 236 147 233 nil 228 148 198 155 249 nil nil 129 nil 251 nil]
 -  "Table for converting ISO-8859-4 characters into codepage 773 glyphs.")
 -(setplist 'cp773-decode-table
 -        '(charset latin-iso8859-4 language "Latin-4" offset 160))
 -
 -(defvar cp774-decode-table
 -  [
 -   255 181 nil nil 155 nil nil nil 245 190 nil nil nil 196 207 nil
 -   248 208 nil nil nil nil nil nil nil 213 nil nil nil nil 216 nil
 -   nil nil nil nil 142 143 146 189 182 144 183 nil 184 nil nil nil
 -   nil nil nil nil nil nil 153 nil nil 198 nil nil 154 nil 199 225
 -   nil 160 nil nil 132 134 145 212 209 130 210 137 211 161 140 nil
 -   nil nil nil nil 147 nil 148 246 237 214 163 150 129 nil 215 248]
 -  "Table for converting ISO-8859-4 characters into codepage 774 glyphs.")
 -(setplist 'cp774-decode-table
 -        '(charset latin-iso8859-4 language "Latin-4" offset 160))
 -
 -(defvar cp775-decode-table
 -  [
 -   255 181 nil 138 150 nil 234 245 166 190 237 149 173 240 207 nil
 -   248 208 nil 139 239 nil 235 nil nil 213 137 133 136 nil 216 nil
 -   160 nil nil nil 142 143 146 189 182 144 183 nil 184 nil nil 161
 -   nil 238 226 232 nil 229 153 158 157 198 nil nil 154 nil 199 225
 -   131 nil nil nil 132 134 145 212 209 130 210 nil 211 nil nil 140
 -   nil 236 147 233 nil 228 148 247 155 214 nil nil 129 nil 215 nil]
 -  "Table for converting ISO-8859-4 characters into codepage 775 glyphs.")
 -(setplist 'cp775-decode-table
 -        '(charset latin-iso8859-4 language "Latin-4" offset 160))
 -
 -;; Support for the Windows 12xx series of codepages that MS has
 -;; butchered from the ISO-8859 specs. This does not add support for
 -;; the extended characters that MS has added in the 128 - 159 coding
 -;; range, only translates those characters that can be expressed in
 -;; the corresponding iso-8859 charset.
 -
 -;; Codepage Mapping:
 -;;
 -;; Windows-1250: ISO-8859-2 (Central Europe) - differs in some positions
 -;; Windows-1251: ISO-8859-5 (Cyrillic)       - differs wildly
 -;; Windows-1252: ISO-8859-1 (West Europe)    - exact match
 -;; Windows-1253: ISO-8859-7 (Greek)          - differs in some positions
 -;; Windows-1254: ISO-8859-9 (Turkish)        - exact match
 -;; Windows-1255: ISO-8859-8 (Hebrew)         - exact match
 -;; Windows-1256: ISO-8859-6 (Arabic)         - half match
 -;; Windows-1257: ISO-8859-4 (Baltic)         - differs, future Latin-7
 -;; Windows-1258: VISCII (Vietnamese)         - Completely different
 -
 -(defvar cp1250-decode-table
 -  [
 -    160 165 162 163 164 188 140 167 168 138 170 141 143 173 142 175
 -    176 185 178 179 180 190 156 161 184 154 186 157 159 189 158 191
 -    192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
 -    208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
 -    224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
 -    240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 ]
 -  "ISO-8859-2 to Windows-1250 (Central Europe) codepage decoding table.")
 -(setplist 'cp1250-decode-table
 -          '(charset latin-iso8859-2 language "Latin-2" offset 160))
 -
 -(defvar cp1251-decode-table
 -  [
 -    160 168 128 129 170 189 178 175 163 138 140 142 141 173 161 143
 -    192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
 -    208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
 -    224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
 -    240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
 -    185 184 144 131 186 190 179 191 188 154 156 158 157 167 162 159 ]
 -  "ISO-8859-5 to Windows-1251 (Cyrillic) codepage decoding table.")
 -(setplist 'cp1251-decode-table
 -          '(charset cyrillic-iso8859-5 language "Cyrillic-ISO" offset 160))
 -
 -;; cp1253 is missing nbsp so we cannot quite translate perfectly. It
 -;; also has two micro/mu characters which would require more complex
 -;; processing to accomodate.
 -(defvar cp1253-decode-table
 -  [
 -    nil 145 146 163 nil nil 166 167 168 169 nil 171 172 173 nil 151
 -    176 177 178 179 180 161 162 183 184 185 186 187 188 189 190 191
 -    192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
 -    208 209 nil 211 212 213 214 215 216 217 218 219 220 221 222 223
 -    224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
 -    240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 nil ]
 -  "ISO-8859-7 to Windows-1253 (Greek) codepage decoding table.")
 -(setplist 'cp1253-decode-table
 -          '(charset greek-iso8859-7 language "Greek" offset 160))
 -
 -;; Since Latin-7 is not yet official, and Emacs does not support it,
 -;; provide translation between Windows-1257 and Latin-4 the best we
 -;; can.
 -(defvar cp1257-decode-table
 -  [
 -    160 192 nil 170 164 nil 207 167 nil 208 199 204 nil 173 222 nil
 -    176 224 nil 186 nil nil 239 nil nil 240 231 236 nil nil 254 nil
 -    194 nil nil nil 196 197 175 193 200 201 198 nil 203 nil nil 206
 -    nil 210 212 205 nil 213 214 215 168 216 nil nil 220 nil 219 223
 -    226 nil nil nil 228 229 191 225 232 233 230 nil 235 nil nil 238
 -    nil 242 244 237 nil 245 246 247 184 248 nil nil 252 nil 251 nil ]
 -  "ISO-8859-4 to Windows-1257 (Baltic) codepage decoding table.")
 -(setplist 'cp1257-decode-table
 -          '(charset latin-iso8859-4 language "Latin-4" offset 160))
 -
 -;;;###autoload
 -(defun cp-make-coding-systems-for-codepage (codepage iso-name offset)
 -  "Create a coding system to convert IBM CODEPAGE into charset ISO-NAME
 -whose first character is at offset OFFSET from the beginning of 8-bit
 -ASCII table.
 -
 -The created coding system has the usual 3 subsidiary systems: for Unix-,
 -DOS- and Mac-style EOL conversion.  However, unlike built-in coding
 -systems, the Mac-style EOL conversion is currently not supported by the
 -decoder and encoder created by this function."
 -  (let* ((decode-table (intern (format "%s-decode-table" codepage)))
 -       (nonascii-table
 -        (intern (format "%s-nonascii-translation-table" codepage)))
 -       (decode-translation
 -        (intern (format "%s-decode-translation-table" codepage)))
 -       (encode-translation
 -        (intern (format "%s-encode-translation-table" codepage))))
 -    (set nonascii-table
 -       (make-translation-table-from-vector
 -        (cp-decoding-vector-for-codepage
 -         (symbol-value decode-table) iso-name offset)))
 -    (define-translation-table encode-translation
 -      (char-table-extra-slot (symbol-value nonascii-table) 0))
 -    ;; For charsets other than ascii, eight-bit-* and ISO-NAME, set
 -    ;; `?' for one-column charsets, and some Japanese character for
 -    ;; wide-column charsets.  CCL encoder convert that Japanese
 -    ;; character to either dos-unsupported-char-glyph or "??".
 -    (let ((tbl (char-table-extra-slot (symbol-value nonascii-table) 0))
 -        (undef (if (eq system-type 'ms-dos)
 -                   (if dos-unsupported-char-glyph
 -                       (logand dos-unsupported-char-glyph 255)
 -                     127)
 -                 ??))
 -        (charsets (delq 'ascii
 -                        (delq 'eight-bit-control
 -                              (delq 'eight-bit-graphic
 -                                    (delq iso-name
 -                                          (copy-sequence charset-list))))))
 -        (wide-column-char (make-char 'japanese-jisx0208 32 32)))
 -      (while charsets
 -      (aset tbl (make-char (car charsets))
 -            (if (= (charset-width (car charsets)) 1) undef wide-column-char))
 -      (setq charsets (cdr charsets))))
 -    (define-translation-table decode-translation
 -      (symbol-value nonascii-table))
 -    (cp-coding-system-for-codepage-1
 -     (intern codepage) ?D iso-name decode-translation encode-translation)
 -    ))
 -
 -(defun cp-codepage-decoder (codepage)
 -  "If CODEPAGE is the name of a supported codepage, return its decode table.
 -Otherwise return nil."
 -  (let ((cp (if (symbolp codepage) (symbol-name codepage) codepage)))
 -    (cond
 -     ((stringp cp)
 -      (intern-soft (format "%s-decode-table" cp)))
 -     (t nil))))
 +;; I doubt we need compatibility versions of any of these autoloaded
 +;; functions apart from codepage-setup, which users may call.
 +
 +;; ;;;###autoload
 +;; (defun cp-make-coding-systems-for-codepage (codepage iso-name offset)
 +;;   "Create a coding system to convert IBM CODEPAGE into charset ISO-NAME
 +;; whose first character is at offset OFFSET from the beginning of 8-bit
 +;; ASCII table.
 +
 +;; The created coding system has the usual 3 subsidiary systems: for Unix-,
 +;; DOS- and Mac-style EOL conversion.  However, unlike built-in coding
 +;; systems, the Mac-style EOL conversion is currently not supported by the
 +;; decoder and encoder created by this function."
 +;;   (let* ((decode-table (intern (format "%s-decode-table" codepage)))
 +;;     (nonascii-table
 +;;      (intern (format "%s-nonascii-translation-table" codepage)))
 +;;     (decode-translation
 +;;      (intern (format "%s-decode-translation-table" codepage)))
 +;;     (encode-translation
 +;;      (intern (format "%s-encode-translation-table" codepage))))
 +;;     (set nonascii-table
 +;;     (make-translation-table-from-vector
 +;;      (cp-decoding-vector-for-codepage
 +;;       (symbol-value decode-table) iso-name offset)))
 +;;     (define-translation-table encode-translation
 +;;       (char-table-extra-slot (symbol-value nonascii-table) 0))
 +;;     ;; For charsets other than ascii, eight-bit-* and ISO-NAME, set
 +;;     ;; `?' for one-column charsets, and some Japanese character for
 +;;     ;; wide-column charsets.  CCL encoder convert that Japanese
 +;;     ;; character to either dos-unsupported-char-glyph or "??".
 +;;     (let ((tbl (char-table-extra-slot (symbol-value nonascii-table) 0))
 +;;      (undef (if (eq system-type 'ms-dos)
 +;;                 (if dos-unsupported-char-glyph
 +;;                     (logand dos-unsupported-char-glyph 255)
 +;;                   127)
 +;;               ??))
 +;;      (charsets (delq 'ascii
 +;;                      (delq 'eight-bit-control
 +;;                            (delq 'eight-bit-graphic
 +;;                                  (delq iso-name
 +;;                                        (copy-sequence charset-list))))))
 +;;      (wide-column-char (make-char 'japanese-jisx0208 32 32)))
 +;;       (while charsets
 +;;    (aset tbl (make-char (car charsets))
 +;;          (if (= (charset-width (car charsets)) 1) undef wide-column-char))
 +;;    (setq charsets (cdr charsets))))
 +;;     (define-translation-table decode-translation
 +;;       (symbol-value nonascii-table))
 +;;     (cp-coding-system-for-codepage-1
 +;;      (intern codepage) ?D iso-name decode-translation encode-translation)
 +;;     ))
 +
 +;; ;;;###autoload
 +;; (defun cp-charset-for-codepage (codepage)
 +;;   "Return the charset for which there is a translation table to DOS CODEPAGE.
 +;; CODEPAGE must be the name of a DOS codepage, a string."
 +;;   (let ((cp-decoder (cp-codepage-decoder codepage)))
 +;;     (if (null cp-decoder)
 +;;    (error "Unsupported codepage %s" codepage)
 +;;       (get cp-decoder 'charset))))
 +
 +;; ;;;###autoload
 +;; (defun cp-language-for-codepage (codepage)
 +;;   "Return the name of the MULE language environment for CODEPAGE.
 +;; CODEPAGE must be the name of a DOS codepage, a string."
 +;;   (let ((cp-decoder (cp-codepage-decoder codepage)))
 +;;     (if (null cp-decoder)
 +;;    (error "Unsupported codepage %s" codepage)
 +;;       (get cp-decoder 'language))))
 +
 +;; ;;;###autoload
 +;; (defun cp-offset-for-codepage (codepage)
 +;;   "Return the offset to be used in setting up coding systems for CODEPAGE.
 +;; CODEPAGE must be the name of a DOS codepage, a string."
 +;;   (let ((cp-decoder (cp-codepage-decoder codepage)))
 +;;     (if (null cp-decoder)
 +;;    (error "Unsupported codepage %s" codepage)
 +;;       (get cp-decoder 'offset))))
 +
 +;; ;;;###autoload
 +;; (defun cp-supported-codepages ()
 +;;   "Return an alist of supported codepages.
 +
 +;; Each association in the alist has the form (NNN . CHARSET), where NNN is the
 +;; codepage number, and CHARSET is the MULE charset which is the closest match
 +;; for the character set supported by that codepage.
 +
 +;; A codepage NNN is supported if a variable called `cpNNN-decode-table' exists,
 +;; is a vector, and has a charset property."
 +;;   (save-match-data
 +;;     (let (alist chset sname)
 +;;       (mapatoms
 +;;        (function
 +;;    (lambda (sym)
 +;;      (if (and (boundp sym)
 +;;               (string-match "\\`cp\\([1-9][0-9][0-9][0-9]?\\)-decode-table\\'"
 +;;                             (setq sname (symbol-name sym)))
 +;;               (vectorp (symbol-value sym))
 +;;               (setq chset (get sym 'charset)))
 +;;          (setq alist
 +;;                (cons (cons (match-string 1 sname) chset) alist))))))
 +;;       alist)))
  
  ;;;###autoload
 -(defun cp-charset-for-codepage (codepage)
 -  "Return the charset for which there is a translation table to DOS CODEPAGE.
 -CODEPAGE must be the name of a DOS codepage, a string."
 -  (let ((cp-decoder (cp-codepage-decoder codepage)))
 -    (if (null cp-decoder)
 -      (error "Unsupported codepage %s" codepage)
 -      (get cp-decoder 'charset))))
 -
 -;;;###autoload
 -(defun cp-language-for-codepage (codepage)
 -  "Return the name of the MULE language environment for CODEPAGE.
 -CODEPAGE must be the name of a DOS codepage, a string."
 -  (let ((cp-decoder (cp-codepage-decoder codepage)))
 -    (if (null cp-decoder)
 -      (error "Unsupported codepage %s" codepage)
 -      (get cp-decoder 'language))))
 -
 -;;;###autoload
 -(defun cp-offset-for-codepage (codepage)
 -  "Return the offset to be used in setting up coding systems for CODEPAGE.
 -CODEPAGE must be the name of a DOS codepage, a string."
 -  (let ((cp-decoder (cp-codepage-decoder codepage)))
 -    (if (null cp-decoder)
 -      (error "Unsupported codepage %s" codepage)
 -      (get cp-decoder 'offset))))
 -
 -;;;###autoload
 -(defun cp-supported-codepages ()
 -  "Return an alist of supported codepages.
 -
 -Each association in the alist has the form (NNN . CHARSET), where NNN is the
 -codepage number, and CHARSET is the MULE charset which is the closest match
 -for the character set supported by that codepage.
 -
 -A codepage NNN is supported if a variable called `cpNNN-decode-table' exists,
 -is a vector, and has a charset property."
 -  (save-match-data
 -    (let (alist chset sname)
 -      (mapatoms
 -       (function
 -      (lambda (sym)
 -        (if (and (boundp sym)
 -                 (string-match "\\`cp\\([1-9][0-9][0-9][0-9]?\\)-decode-table\\'"
 -                               (setq sname (symbol-name sym)))
 -                 (vectorp (symbol-value sym))
 -                 (setq chset (get sym 'charset)))
 -            (setq alist
 -                  (cons (cons (match-string 1 sname) chset) alist))))))
 -      alist)))
 -
 -;;;###autoload
 -(defun codepage-setup (codepage)
 -  "Create a coding system cpCODEPAGE to support the IBM codepage CODEPAGE.
 -
 -These coding systems are meant for encoding and decoding 8-bit non-ASCII
 -characters used by the IBM codepages, typically in conjunction with files
 -read/written by MS-DOS software, or for display on the MS-DOS terminal."
 -  (interactive
 -   (let ((completion-ignore-case t)
 -       (candidates (cp-supported-codepages)))
 -     (list (completing-read "Setup DOS Codepage (default 437): " candidates
 -                          nil t nil nil "437"))))
 -  (let* ((cp (format "cp%s" codepage))
 -       (cp-defined (intern-soft cp)))
 -    (or (and cp-defined  ;; avoid defining if already defined
 -           (coding-system-p cp-defined))
 -      (cp-make-coding-systems-for-codepage
 -       cp (cp-charset-for-codepage cp) (cp-offset-for-codepage cp)))))
 -
 -;; Add DOS codepages to `non-iso-charset-alist'.
 -(eval-after-load "mule-diag"
 -  '(let ((tail (cp-supported-codepages))
 -       elt)
 -     (while tail
 -       (setq elt (car tail) tail (cdr tail))
 -       ;; Now ELT is (CODEPAGE . CHARSET), where CODEPAGE is a string
 -       ;; (e.g. "850"), CHARSET is a charset that characters in CODEPAGE
 -       ;; are mapped to.
 -       (unless (assq (intern (concat "cp" (car elt))) non-iso-charset-alist)
 -       (setq non-iso-charset-alist
 -             (cons (list (intern (concat "cp" (car elt)))
 -                         (list 'ascii (cdr elt))
 -                         `(lambda (code)
 -                            (decode-codepage-char ,(string-to-int (car elt))
 -                                                  code))
 -                         (list (list 0 255)))
 -                   non-iso-charset-alist))))))
 +(defun codepage-setup (&optional codepage)
 +  "Obsolete.  All coding systems are set up initially."
 +  (interactive))
 +(make-obsolete 'codepage-setup "no longer relevant" "23.1")
  
  (provide 'codepage)
  
index 8456eb3c1754c0666178b412c550de9e8939575b,6d89b7306687edb7ae6cd1e3e1f056f0b83dc1fa..5f61c7ca65e27f383dedf56595437880484e8d0d
@@@ -1,14 -1,11 +1,14 @@@
  ;;; encoded-kb.el --- handler to input multibyte characters encoded somehow
  
- ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; This file is part of GNU Emacs.
  
@@@ -170,7 -167,7 +170,7 @@@ The following key sequence may cause mu
  
  (defun encoded-kbd-self-insert-ccl (ignore)
    (let ((str (char-to-string (encoded-kbd-last-key)))
 -      (ccl (car (aref (coding-system-spec (keyboard-coding-system)) 4)))
 +      (ccl (coding-system-get (keyboard-coding-system) :ccl-decoder))
        (vec [nil nil nil nil nil nil nil nil nil])
        result)
      (while (= (length (setq result (ccl-execute-on-string ccl vec str t))) 0)
        (setq str (format "%s%c" str (read-char-exclusive))))
      (vector (aref result 0))))
  
 +
 +;; Decode list of codes in CODE-LIST by CHARSET and return the decoded
 +;; characters.  If CODE-LIST is too short for the dimension of
 +;; CHARSET, read new codes and append them to the tail of CODE-LIST.
 +;; Return nil if CODE-LIST can't be decoded.
 +
 +(defun encoded-kbd-decode-code-list (charset code-list)
 +  (let ((dimension (charset-dimension charset))
 +      code)
 +    (while (> dimension (length code-list))
 +      (nconc code-list (list (read-char-exclusive))))
 +    (setq code (car code-list))
 +    (if (= dimension 1)
 +      (decode-char charset code)
 +      (setq code-list (cdr code-list)
 +          code (logior (lsh code 8) (car code-list)))
 +      (if (= dimension 2)
 +        (decode-char charset code)
 +      (setq code-list (cdr code-list)
 +            code (logior (lsh code 8) (car code-list)))
 +      (if (= dimension 3)
 +          (decode-char charset code)
 +        ;; As Emacs can't handle full 32-bit integer, we must give a
 +        ;; cons of higher and lower 16-bit codes to decode-char.
 +        (setq code (cons (lsh code -8)
 +                         (logior (lsh (car code-list) 8) (cadr code-list))))
 +        (decode-char charset code))))))
 +
 +(defun encoded-kbd-self-insert-charset (ignore)
 +  (let ((charset-list
 +       (coding-system-get (keyboard-coding-system) :charset-list))
 +      (code-list (list (encoded-kbd-last-key)))
 +      tail char)
 +    (while (and charset-list (not char))
 +      (setq char (encoded-kbd-decode-code-list (car charset-list) code-list)
 +          charset-list (cdr charset-list)))
 +    (if char
 +      (vector char)
 +      (setq unread-command-events (cdr code-list))
 +      (vector (car code-list)))))
 +
 +(defun encoded-kbd-self-insert-utf-8 (arg)
 +  (interactive "p")
 +  (let ((char (encoded-kbd-last-key))
 +      len)
 +    (cond ((< char #xE0)
 +         (setq len 1 char (logand char #x1F)))
 +        ((< char #xF0)
 +         (setq len 2 char (logand char #x0F)))
 +        ((< char #xF8)
 +         (setq len 3 char (logand char #x07)))
 +        (t
 +         (setq len 4 char 0)))
 +    (while (> len 0)
 +      (setq char (logior (lsh char 6) (logand (read-char-exclusive) #x3F))
 +          len (1- len)))
 +    (vector char)))
 +
  (defun encoded-kbd-setup-keymap (coding)
    ;; At first, reset the keymap.
    (define-key encoded-kbd-mode-map "\e" nil)
    ;; Then setup the keymap according to the keyboard coding system.
    (cond
 -   ((eq (coding-system-type coding) 1)        ; SJIS
 +   ((eq (coding-system-type coding) 'shift-jis)
      (let ((i 128))
        (while (< i 256)
        (define-key key-translation-map
        (setq i (1+ i))))
      8)
  
 -   ((eq (coding-system-type coding) 3)        ; Big5
 -    (let ((i 161))
 -      (while (< i 255)
 -      (define-key key-translation-map
 -        (vector i) 'encoded-kbd-self-insert-big5)
 -      (setq i (1+ i))))
 +   ((eq (coding-system-type coding) 'charset)
 +    (dolist (elt (mapcar
 +                #'(lambda (x) 
 +                    (let ((dim (charset-dimension x))
 +                          (code-space (get-charset-property x :code-space)))
 +                      (cons (aref code-space (* (1- dim) 2))
 +                            (aref code-space (1+ (* (1- dim) 2))))))
 +                (coding-system-get coding :charset-list)))
 +      (let ((from (max (car elt) 128))
 +          (to (cdr elt)))
 +      (while (<= from to)
 +        (define-key key-translation-map
 +          (vector from) 'encoded-kbd-self-insert-charset)
 +        (setq from (1+ from)))))
      8)
  
 -   ((eq (coding-system-type coding) 2) ; ISO-2022
 -    (let ((flags (coding-system-flags coding))
 -        use-designation)
 -      (if (aref flags 8)
 +   ((eq (coding-system-type coding) 'iso-2022)
 +    (let ((flags (coding-system-get coding :flags))
 +        (designation (coding-system-get coding :designation)))
 +      (if (memq 'locking-shift flags)
          nil                           ; Don't support locking-shift.
        (setq encoded-kbd-iso2022-designations (make-vector 4 nil)
              encoded-kbd-iso2022-invocations (make-vector 3 nil))
        (dotimes (i 4)
 -        (if (aref flags i)
 -            (if (charsetp (aref flags i))
 +        (if (aref designation i)
 +            (if (charsetp (aref designation i))
                  (aset encoded-kbd-iso2022-designations
 -                      i (aref flags i))
 -              (setq use-designation t)
 -              (if (charsetp (car-safe (aref flags i)))
 +                      i (aref designation i))
 +              (if (charsetp (car-safe (aref designation i)))
                    (aset encoded-kbd-iso2022-designations
 -                        i (car (aref flags i)))))))
 +                        i (car (aref designation i)))))))
        (aset encoded-kbd-iso2022-invocations 0 0)
        (if (aref encoded-kbd-iso2022-designations 1)
            (aset encoded-kbd-iso2022-invocations 1 1))
 -      (when use-designation
 +      (when (memq 'designation flags)
          (define-key encoded-kbd-mode-map "\e" 'encoded-kbd-iso2022-esc-prefix)
          (define-key key-translation-map "\e" 'encoded-kbd-iso2022-esc-prefix))
 -      (when (or (aref flags 2) (aref flags 3))
 +      (when (or (aref designation 2) (aref designation 3))
          (define-key key-translation-map
            [?\216] 'encoded-kbd-iso2022-single-shift)
          (define-key key-translation-map
            [?\217] 'encoded-kbd-iso2022-single-shift))
 -      (or (eq (aref flags 0) 'ascii)
 +      (or (eq (aref designation 0) 'ascii)
            (dotimes (i 96)
              (define-key key-translation-map
                (vector (+ 32 i)) 'encoded-kbd-self-insert-iso2022-7bit)))
 -      (if (aref flags 7)
 +      (if (memq '7-bit flags)
            t
          (dotimes (i 96)
            (define-key key-translation-map
          8))))
  
     ((eq (coding-system-type coding) 4)        ; CCL-base
 -    (let ((valid-codes (or (coding-system-get coding 'valid-codes)
 +    (let ((valid-codes (or (coding-system-get coding :valid)
                           '((128 . 255))))
          elt from to valid)
        (while valid-codes
          (setq from (1+ from))))
        8))
  
 +   ((eq (coding-system-type coding) 'utf-8)
 +    (let ((i #xC0))
 +      (while (< i 256)
 +      (define-key key-translation-map
 +        (vector i) 'encoded-kbd-self-insert-utf-8)
 +      (setq i (1+ i))))
 +    8)
 +
     (t
      nil)))
  
@@@ -378,11 -302,10 +378,11 @@@ as a multilingual text encoded in a cod
                 coding)))
  
      ;; We are turning off Encoded-kbd mode.
 -    (setq key-translation-map saved-key-translation-map
 -        saved-key-translation-map nil)
 -    (apply 'set-input-mode saved-input-mode)
 -    (setq saved-input-mode nil)))
 +    (when saved-input-mode
 +      (setq key-translation-map saved-key-translation-map
 +          saved-key-translation-map nil)
 +      (apply 'set-input-mode saved-input-mode)
 +      (setq saved-input-mode nil))))
  
  (provide 'encoded-kb)
  
index e62583bb2b7cab5fda59f4351b058e679629f18e,81665ffd1ce2b312c5e83ea17600b3b49ed94e0d..2913a10dcdb743d67c4874235ab97c839d14f133
@@@ -1,16 -1,13 +1,16 @@@
  ;;; fontset.el --- commands for handling fontset
  
  ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006  Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007  Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003, 2006
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
 -;; Keywords: mule, multilingual, fontset
 +;; Keywords: mule, i18n, fontset
  
  ;; This file is part of GNU Emacs.
  
  
  ;;; Code:
  
 +;; Setup font-encoding-alist for all known encodings.
 +
 +(setq font-encoding-alist
 +      '(("iso8859-1$" . iso-8859-1)
 +      ("iso8859-2$" . iso-8859-2)
 +      ("iso8859-3$" . iso-8859-3)
 +      ("iso8859-4$" . iso-8859-4)
 +      ("iso8859-5$" . iso-8859-5)
 +      ("iso8859-6$" . iso-8859-6)
 +      ("iso8859-7$" . iso-8859-7)
 +      ("iso8859-8$" . iso-8859-8)
 +      ("iso8859-9$" . iso-8859-9)
 +      ("iso8859-10$" . iso-8859-10)
 +      ("iso8859-11$" . iso-8859-11)
 +      ("iso8859-13$" . iso-8859-13)
 +      ("iso8859-14$" . iso-8859-14)
 +      ("iso8859-15$" . iso-8859-15)
 +      ("gb2312.1980" . chinese-gb2312)
 +      ("gbk" . chinese-gbk)
 +      ("gb18030" . gb18030)
 +      ("jisx0208.1978" . japanese-jisx0208-1978)
 +      ("jisx0208" . japanese-jisx0208)
 +      ("jisx0201" . jisx0201)
 +      ("jisx0212" . japanese-jisx0212)
 +      ("ksc5601.1987" . korean-ksc5601)
 +      ("cns11643.1992.*1" . chinese-cns11643-1)
 +      ("cns11643.1992.*2" . chinese-cns11643-2)
 +      ("cns11643.1992.*3" . chinese-cns11643-3)
 +      ("cns11643.1992.*4" . chinese-cns11643-4)
 +      ("cns11643.1992.*5" . chinese-cns11643-5)
 +      ("cns11643.1992.*6" . chinese-cns11643-6)
 +      ("cns11643.1992.*7" . chinese-cns11643-7)
 +      ("cns11643.92p1-0" . chinese-cns11643-1)
 +      ("cns11643.92p2-0" . chinese-cns11643-2)
 +      ("cns11643.92p3-0" . chinese-cns11643-3)
 +      ("cns11643.92p4-0" . chinese-cns11643-4)
 +      ("cns11643.92p5-0" . chinese-cns11643-5)
 +      ("cns11643.92p6-0" . chinese-cns11643-6)
 +      ("cns11643.92p7-0" . chinese-cns11643-7)
 +      ("big5" . big5)
 +      ("sisheng_cwnn" . chinese-sisheng)
 +      ("viscii" . viscii)
 +      ("tis620" . tis620-2533)
 +      ("microsoft-cp1251" . windows-1251)
 +      ("koi8-r" . koi8-r)
 +      ("mulearabic-0" . arabic-digit)
 +      ("mulearabic-1" . arabic-1-column)
 +      ("mulearabic-2" . arabic-2-column)
 +      ("muleipa" . ipa)
 +      ("ethiopic-unicode" . (unicode-bmp . ethiopic))
 +      ("is13194-devanagari" . indian-is13194)
 +      ("Devanagari-CDAC" . devanagari-cdac)
 +      ("Sanskrit-CDAC" . sanskrit-cdac)
 +      ("Bengali-CDAC" . bengali-cdac)
 +      ("Assamese-CDAC" . assamese-cdac)
 +      ("Punjabi-CDAC" . punjabi-cdac)
 +      ("Gujarati-CDAC" . gujarati-cdac)
 +      ("Oriya-CDAC" . oriya-cdac)
 +      ("Tamil-CDAC" . tamil-cdac)
 +      ("Telugu-CDAC" . telugu-cdac)
 +      ("Kannada-CDAC" . kannada-cdac)
 +      ("Malayalam-CDAC" . malayalam-cdac)
 +      ("Devanagari-Akruti" . devanagari-akruti)
 +      ("Bengali-Akruti" . bengali-akruti)
 +      ("Punjabi-Akruti" . punjabi-akruti)
 +      ("Gujarati-Akruti" . gujarati-akruti)
 +      ("Oriya-Akruti" . oriya-akruti)
 +      ("Tamil-Akruti" . tamil-akruti)
 +      ("Telugu-Akruti" . telugu-akruti)
 +      ("Kannada-Akruti" . kannada-akruti)
 +      ("Malayalam-Akruti" . malayalam-akruti)
 +      ("muleindian-2" . indian-2-column)
 +      ("muleindian-1" . indian-1-column)
 +      ("mulelao-1" . mule-lao)
 +      ("muletibetan-2" . tibetan)
 +      ("muletibetan-1" . tibetan-1-column)
 +      ("jisx0213.2000-1" . japanese-jisx0213-1)
 +      ("jisx0213.2000-2" . japanese-jisx0213-2)
 +      ("jisx0213.2004-1" . japanese-jisx0213.2004-1)
 +      ("abobe-symbol" . symbol)
 +      ("iso10646-1$" . (unicode-bmp . nil))
 +      ("iso10646.indian-1" . (unicode-bmp . nil))))
 +
 +(setq script-representative-chars
 +      '((latin ?A ?Z ?a ?z)
 +      (greek #x3A9)
 +      (coptic #x3E2)
 +      (cyrillic #x42F)
 +      (armenian #x531)
 +      (hebrew #x5D0)
 +      (arabic #x628)
 +      (syriac #x710)
 +      (thaana #x78C)
 +      (devanagari #x915)
 +      (bengali #x995)
 +      (gurmukhi #xA15)
 +      (gujarati #xA95)
 +      (oriya #xB15)
 +      (tamil #xB95)
 +      (telugu #xC15)
 +      (kannada #xC95)
 +      (malayalam #xD15)
 +      (sinhala #xD95)
 +      (thai #xE17)
 +      (lao #xEA5)
 +      (tibetan #xF40)
 +      (myanmar #x1000)
 +      (georgian #x10D3)
 +      (ethiopic #x1208)
 +      (cherokee #x13B6)
 +      (canadian-aboriginal #x14C0)
 +      (ogham #x168F)
 +      (runic #x16A0)
 +      (khmer #x1780)
 +      (mongolian #x1826)
 +      (braille #x2800)
 +      (ideographic-description #x2FF0)
 +      (cjk-misc #x300E)
 +      (kana #x304B)
 +      (bopomofo #x3105)
 +      (kanbun #x319D)
 +      (han #x5B57)
 +      (yi #xA288)
 +      (hangul #xAC00)))
 +
 +(setq otf-script-alist
 +      '((arab . arabic)
 +      (armn . armenian)
 +      (bali . balinese)
 +      (beng . bengali)
 +      (bopo . bopomofo)
 +      (brai . braille)
 +      (bugi . buginese)
 +      (buhd . buhid)
 +      (byzm . byzantine-musical-symbol)
 +      (cans . canadian_aboliginal)
 +      (cher . cherokee)
 +      (copt . coptic)
 +      (xsux . cuneiform)
 +      (cyrl . cyrillic)
 +      (cprt . cypriot)
 +      (dsrt . deseret)
 +      (deva . devanagari)
 +      (ethi . ethiopic)
 +      (geor . georgian)
 +      (glag . glagolitic)
 +      (goth . gothic)
 +      (grek . greek)
 +      (gujr . gujarati)
 +      (guru . gurmukhi)
 +      (hani . han)
 +      (hang . hangul)
 +      (hano . hanunoo)
 +      (hebr . hebrew)
 +      (kana . kana)
 +      (knda . kannada)
 +      (khar . kharoshthi)
 +      (khmr . khmer)
 +      (lao  . lao)
 +      (latn . latin)
 +      (limb . limbu)
 +      (linb . linear_b)
 +      (mlym . malayalam)
 +      (math . mathematical)
 +      (mong . mongolian)
 +      (musc . musical-symbol)
 +      (mymr . myanmar)
 +      (nko  . nko)
 +      (ogam . ogham)
 +      (ital . old_italic)
 +      (xpeo . old_persian)
 +      (orya . oriya)
 +      (osma . osmanya)
 +      (phag . phags-pa)
 +      (phnx . phoenician)
 +      (runr . runic)
 +      (shaw . shavian)
 +      (sinh . sinhala)
 +      (sylo . syloti_nagri)
 +      (syrc . syriac)
 +      (tglg . tagalog)
 +      (tagb . tagbanwa)
 +      (taml . tamil)
 +      (tale . tai_le)
 +      (telu . telugu)
 +      (thaa . thaana)
 +      (thai . thai)
 +      (tibt . tibetan)
 +      (tfng . tifinagh)
 +      (ugar . ugaritic)
 +      (yi   . yi)))
 +
  ;; Set standard fontname specification of characters in the default
 -;; fontset to find an appropriate font for each charset.  This is used
 -;; to generate a font name for a fontset if the fontset doesn't
 -;; specify a font name for a specific character.  The specification
 -;; has the form (FAMILY . REGISTRY).  FAMILY may be nil, in which
 -;; case, the family name of default face is used.  If REGISTRY
 +;; fontset to find an appropriate font for each script/charset.  The
 +;; specification has the form ((SCRIPT FONT-SPEC ...) ...), where
 +;; FONT-SPEC is:
 +;;    a vector [ FAMILY WEIGHT SLANT ADSTYLE REGISTRY ],
 +;;    or a cons (FAMILY . REGISTRY),
 +;;    or a string FONT-NAME.
 +;;
 +;; FAMILY, WEIGHT, SLANT, and ADSTYLE may be nil, in which case, the
 +;; the corresponding name of default face is used.  If REGISTRY
  ;; contains a character `-', the string before that is embedded in
  ;; `CHARSET_REGISTRY' field, and the string after that is embedded in
  ;; `CHARSET_ENCODING' field.  If it does not contain `-', the whole
  ;; string is embedded in `CHARSET_REGISTRY' field, and a wild card
 -;; character `*' is embedded in `CHARSET_ENCODING' field.  The
 -;; REGISTRY for ASCII characters are predefined as "ISO8859-1".
 +;; character `*' is embedded in `CHARSET_ENCODING' field.
 +;;
 +;; SCRIPT is a symbol that appears as an element of the char table
 +;; `char-script-table'.  SCRIPT may be a charset specifying the range
 +;; of characters.
  
  (defun setup-default-fontset ()
    "Setup the default fontset."
 -  (dolist (elt
 -         `((latin-iso8859-1 . (nil . "ISO8859-1"))
 -           (latin-iso8859-2 . (nil . "ISO8859-2"))
 -           (latin-iso8859-3 . (nil . "ISO8859-3"))
 -           (latin-iso8859-4 . (nil . "ISO8859-4"))
 -           ;; Setting "*" family is for a workaround of the problem
 -           ;; that a font of wrong size is preferred if the font
 -           ;; family matches with a requested one.
 -           (thai-tis620 . ("*" . "TIS620"))
 -           (greek-iso8859-7 . (nil . "ISO8859-7"))
 -           (arabic-iso8859-6 . (nil . "ISO8859-6"))
 -           (hebrew-iso8859-8 . (nil . "ISO8859-8"))
 -           (katakana-jisx0201 . (nil . "JISX0201"))
 -           (latin-jisx0201 . (nil . "JISX0201"))
 -           (cyrillic-iso8859-5 . (nil . "ISO8859-5"))
 -           (latin-iso8859-9 . (nil . "ISO8859-9"))
 -           (japanese-jisx0208-1978 . (nil . "JISX0208.1978"))
 -           (chinese-gb2312 . (nil . "GB2312.1980"))
 -           (japanese-jisx0208 . (nil . "JISX0208.1990"))
 -           (korean-ksc5601 . (nil . "KSC5601.1989"))
 -           (japanese-jisx0212 . (nil . "JISX0212"))
 -           (chinese-cns11643-1 . (nil . "CNS11643.1992-1"))
 -           (chinese-cns11643-2 . (nil . "CNS11643.1992-2"))
 -           (chinese-cns11643-3 . (nil . "CNS11643.1992-3"))
 -           (chinese-cns11643-4 . (nil . "CNS11643.1992-4"))
 -           (chinese-cns11643-5 . (nil . "CNS11643.1992-5"))
 -           (chinese-cns11643-6 . (nil . "CNS11643.1992-6"))
 -           (chinese-cns11643-7 . (nil . "CNS11643.1992-7"))
 -           (chinese-big5-1 . (nil . "Big5"))
 -           (chinese-big5-2 . (nil . "Big5"))
 -           (chinese-sisheng . (nil . "sisheng_cwnn"))
 -           (vietnamese-viscii-lower . (nil . "VISCII1.1"))
 -           (vietnamese-viscii-upper . (nil . "VISCII1.1"))
 -           (arabic-digit . (nil . "MuleArabic-0"))
 -           (arabic-1-column . (nil . "MuleArabic-1"))
 -           (arabic-2-column . (nil . "MuleArabic-2"))
 -           (ipa . (nil . "MuleIPA"))
 -           (ethiopic . (nil . "Ethiopic-Unicode"))
 -           (ascii-right-to-left . (nil . "ISO8859-1"))
 -           (indian-is13194 . (nil . "IS13194-Devanagari"))
 -           (indian-2-column . (nil . "MuleIndian-2"))
 -           (lao . (nil . "MuleLao-1"))
 -           (tibetan . ("proportional" . "MuleTibetan-2"))
 -           (tibetan-1-column . (nil . "MuleTibetan-1"))
 -           (latin-iso8859-14 . (nil . "ISO8859-14"))
 -           (latin-iso8859-15 . (nil . "ISO8859-15"))
 -           (mule-unicode-0100-24ff . (nil . "ISO10646-1"))
 -           (mule-unicode-2500-33ff . (nil . "ISO10646-1"))
 -           (mule-unicode-e000-ffff . (nil . "ISO10646-1"))
 -           (japanese-jisx0213-1 . (nil . "JISX0213.2000-1"))
 -           (japanese-jisx0213-2 . (nil . "JISX0213.2000-2"))
 -           ;; unicode
 -           ((,(decode-char 'ucs #x0900) . ,(decode-char 'ucs #x097F))
 -            . (nil . "ISO10646.indian-1"))
 -           ;; Indian CDAC
 -           (,(indian-font-char-range 'cdac:dv-ttsurekh)
 -            . (nil . "Devanagari-CDAC"))
 -           (,(indian-font-char-range 'cdac:sd-ttsurekh)
 -            . (nil . "Sanskrit-CDAC"))
 -           (,(indian-font-char-range 'cdac:bn-ttdurga)
 -            . (nil . "Bengali-CDAC"))
 -           (,(indian-font-char-range 'cdac:as-ttdurga)
 -            . (nil . "Assamese-CDAC"))
 -           (,(indian-font-char-range 'cdac:pn-ttamar)
 -            . (nil . "Punjabi-CDAC"))
 -           (,(indian-font-char-range 'cdac:gj-ttavantika)
 -            . (nil . "Gujarati-CDAC"))
 -           (,(indian-font-char-range 'cdac:or-ttsarala)
 -            . (nil . "Oriya-CDAC"))
 -           (,(indian-font-char-range 'cdac:tm-ttvalluvar)
 -            . (nil . "Tamil-CDAC"))
 -           (,(indian-font-char-range 'cdac:tl-tthemalatha)
 -            . (nil . "Telugu-CDAC"))
 -           (,(indian-font-char-range 'cdac:kn-ttuma)
 -            . (nil . "Kannada-CDAC"))
 -           (,(indian-font-char-range 'cdac:ml-ttkarthika)
 -            . (nil . "Malayalam-CDAC"))
 -           ;; Indian AKRUTI
 -           (,(indian-font-char-range 'akruti:dev)
 -            . (nil . "Devanagari-Akruti"))
 -           (,(indian-font-char-range 'akruti:bng)
 -            . (nil . "Bengali-Akruti"))
 -           (,(indian-font-char-range 'akruti:pnj)
 -            . (nil . "Punjabi-Akruti"))
 -           (,(indian-font-char-range 'akruti:guj)
 -            . (nil . "Gujarati-Akruti"))
 -           (,(indian-font-char-range 'akruti:ori)
 -            . (nil . "Oriya-Akruti"))
 -           (,(indian-font-char-range 'akruti:tml)
 -            . (nil . "Tamil-Akruti"))
 -           (,(indian-font-char-range 'akruti:tlg)
 -            . (nil . "Telugu-Akruti"))
 -           (,(indian-font-char-range 'akruti:knd)
 -            . (nil . "Kannada-Akruti"))
 -           (,(indian-font-char-range 'akruti:mal)
 -            . (nil . "Malayalam-Akruti"))
 -           ))
 -    (set-fontset-font "fontset-default" (car elt) (cdr elt))))
 -
 -;; Set arguments in `font-encoding-alist' (which see).
 -(defun set-font-encoding (pattern charset encoding)
 +  (new-fontset
 +   "fontset-default"
 +   '(;; for each script
 +     (latin (nil . "ISO8859-1")
 +          (nil . "ISO8859-2")
 +          (nil . "ISO8859-3")
 +          (nil . "ISO8859-4")
 +          (nil . "ISO8859-9")
 +          (nil . "ISO8859-10")
 +          (nil . "ISO8859-13")
 +          (nil . "ISO8859-14")
 +          (nil . "ISO8859-15")
 +          (nil . "VISCII1.1-1"))
 +
 +     (thai (nil . "TIS620*")
 +         (nil . "ISO8859-11"))
 +
 +     (devanagari (nil . "iso10646.indian-1"))
 +
 +     (lao  (nil . "MuleLao-1"))
 +
 +     ;; both for script and charset.
 +     (tibetan (nil . "muletibetan-2"))
 +
 +     ;; both for script and charset.
 +     (ethiopic (nil . "ethiopic-unicode"))
 +
 +     (greek (nil . "ISO8859-7"))
 +
 +     (cyrillic (nil . "ISO8859-5")
 +             (nil . "microsoft-cp1251")
 +             (nil . "koi8-r"))
 +
 +     (arabic (nil . "MuleArabic-0")
 +           (nil . "MuleArabic-1")
 +           (nil . "MuleArabic-2")
 +           (nil . "ISO8859-6"))
 +
 +     (hebrew (nil . "ISO8859-8"))
 +
 +     (kana (nil . "JISX0208*")
 +         (nil . "GB2312.1980-0")
 +         (nil . "KSC5601.1987*")
 +         (nil . "JISX0201*")
 +         (nil . "JISX0213.2000-1")
 +         (nil . "JISX0213.2004-1"))
 +
 +     (bopomofo (nil . "sisheng_cwnn-0"))
 +
 +     (han (nil . "GB2312.1980-0")
 +        (nil . "JISX0208*")
 +        (nil . "JISX0212*")
 +        (nil . "big5*")
 +        (nil . "KSC5601.1987*")
 +        (nil . "CNS11643.1992-1")
 +        (nil . "CNS11643.1992-2")
 +        (nil . "CNS11643.1992-3")
 +        (nil . "CNS11643.1992-4")
 +        (nil . "CNS11643.1992-5")
 +        (nil . "CNS11643.1992-6")
 +        (nil . "CNS11643.1992-7")
 +        (nil . "gbk-0")
 +        (nil . "gb18030")
 +        (nil . "JISX0213.2000-1")
 +        (nil . "JISX0213.2000-2")
 +        (nil . "JISX0213.2004-1"))
 +
 +     (cjk-misc (nil . "GB2312.1980-0")
 +             (nil . "JISX0208*")
 +             (nil . "JISX0212*")
 +             (nil . "big5*")
 +             (nil . "KSC5601.1987*")
 +             (nil . "CNS11643.1992-1")
 +             (nil . "CNS11643.1992-2")
 +             (nil . "CNS11643.1992-3")
 +             (nil . "CNS11643.1992-4")
 +             (nil . "CNS11643.1992-5")
 +             (nil . "CNS11643.1992-6")
 +             (nil . "CNS11643.1992-7")
 +             (nil . "gbk-0")
 +             (nil . "gb18030")
 +             (nil . "JISX0213.2000-1")
 +             (nil . "JISX0213.2000-2"))
 +
 +     (hangul (nil . "KSC5601.1987-0"))
 +
 +     ;; for each charset
 +     (ascii (nil . "ISO8859-1"))
 +     (arabic-digit ("*" . "MuleArabic-0"))
 +     (arabic-1-column ("*" . "MuleArabic-1"))
 +     (arabic-2-column ("*" . "MuleArabic-2"))
 +     (indian-is13194 (nil . "is13194-devanagari"))
 +     (indian-1-column ("*" . "muleindian-2"))
 +     ;; Indian CDAC
 +     (devanagari-cdac (nil . "Devanagari-CDAC"))
 +     (sanskrit-cdac (nil . "Sanskrit-CDAC"))
 +     (bengali-cdac (nil . "Bengali-CDAC"))
 +     (assamese-cdac (nil . "Assamese-CDAC"))
 +     (punjabi-cdac (nil . "Punjabi-CDAC"))
 +     (gujarati-cdac (nil . "Gujarati-CDAC"))
 +     (oriya-cdac (nil . "Oriya-CDAC"))
 +     (tamil-cdac (nil . "Tamil-CDAC"))
 +     (telugu-cdac (nil . "Telugu-CDAC"))
 +     (kannada-cdac (nil . "Kannada-CDAC"))
 +     (malayalam-cdac (nil . "Malayalam-CDAC"))
 +     ;; Indian AKRUTI
 +     (devanagari-akruti (nil . "Devanagari-Akruti"))
 +     (bengali-akruti (nil . "Bengali-Akruti"))
 +     (punjabi-akruti (nil . "Punjabi-Akruti"))
 +     (gujarati-akruti (nil . "Gujarati-Akruti"))
 +     (oriya-akruti (nil . "Oriya-Akruti"))
 +     (tamil-akruti (nil . "Tamil-Akruti"))
 +     (telugu-akruti (nil . "Telugu-Akruti"))
 +     (kannada-akruti (nil . "Kannada-Akruti"))
 +     (malayalam-akruti (nil . "Malayalam-Akruti"))
 +     ;;(devanagari-glyph ("altsys-dv_ttsurekh" . "devanagari-cdac"))
 +     ;;(malayalam-glyph ("altsys-ml_ttkarthika" . "malayalam-cdac"))
 +     (ipa (nil . "MuleIPA-1"))
 +
 +     ;; Fallback fonts
 +     (nil (nil . "gb2312.1980")
 +        (nil . "gbk-0")
 +        (nil . "gb18030")
 +        (nil . "jisx0208")
 +        (nil . "ksc5601.1987")
 +        (nil . "CNS11643.1992-1")
 +        (nil . "CNS11643.1992-2")
 +        (nil . "CNS11643.1992-3")
 +        (nil . "CNS11643.1992-4")
 +        (nil . "CNS11643.1992-5")
 +        (nil . "CNS11643.1992-6")
 +        (nil . "CNS11643.1992-7")
 +        (nil . "big5")
 +        (nil . "jisx0213.2000-1")
 +        (nil . "jisx0213.2004-1")
 +        (nil . "jisx0212"))
 +     ))
 +
 +  ;; Append Unicode fonts.
 +  ;; This may find fonts with more variants (bold, italic) but which
 +  ;; don't cover many characters.
 +  (set-fontset-font "fontset-default" nil
 +                  '(nil . "iso10646-1") nil 'append)
 +  ;; These may find fonts that cover many characters but with fewer
 +  ;; variants.
 +  (set-fontset-font "fontset-default" nil
 +                  '("gnu-unifont" . "iso10646-1") nil 'append)
 +  (set-fontset-font "fontset-default" nil
 +                  '("mutt-clearlyu" . "iso10646-1") nil 'append))
 +
 +;; These are the registered registries/encodings from
 +;; ftp://ftp.x.org/pub/DOCS/registry 2001/06/01
 +
 +;; Name                                            Reference
 +;; ----                                            ---------
 +;; "DEC"                                           [27]
 +;;         registry prefix
 +;; "DEC.CNS11643.1986-2"                           [53]
 +;;         CNS11643 2-plane using the encoding
 +;;         suggested in that standard
 +;; "DEC.DTSCS.1990-2"                              [54]
 +;;         DEC Taiwan Supplemental Character Set
 +;; "fujitsu.u90x01.1991-0"                         [87]
 +;; "fujitsu.u90x03.1991-0"                         [87]
 +;; "GB2312.1980-0"                                 [39],[12]
 +;;         China (PRC) Hanzi, GL encoding
 +;; "GB2312.1980-1"                                 [39]
 +;;         (deprecated)
 +;;         China (PRC) Hanzi, GR encoding
 +;; "HP-Arabic8"                                    [36]
 +;;         HPARABIC8 8-bit character set
 +;; "HP-East8"                                      [36]
 +;;         HPEAST8 8-bit character set
 +;; "HP-Greek8"                                     [36]
 +;;         HPGREEK8 8-bit character set
 +;; "HP-Hebrew8"                                    [36]
 +;;         HPHEBREW8 8-bit character set
 +;; "HP-Japanese15"                                 [36]
 +;;         HPJAPAN15 15-bit characer set,
 +;;         modified from industry defacto
 +;;         standard Shift-JIS
 +;; "HP-Kana8"                                      [36]
 +;;         HPKANA8 8-bit character set
 +;; "HP-Korean15"                                   [36]
 +;;         HPKOREAN15 15-bit character set
 +;; "HP-Roman8"                                     [36]
 +;;         HPROMAN8 8-bit character set
 +;; "HP-SChinese15"                                 [36]
 +;;         HPSCHINA15 15-bit character set for
 +;;         support of Simplified Chinese
 +;; "HP-TChinese15"                                 [36]
 +;;         HPTCHINA15 15-bit character set for
 +;;         support of Traditional Chinese
 +;; "HP-Turkish8"                                   [36]
 +;;         HPTURKISH8 8-bit character set
 +;; "IPSYS"                                         [59]
 +;;         registry prefix
 +;; "IPSYS.IE-1"                                    [59]
 +;; "ISO2022"<REG>"-"<ENC>                          [44]
 +;; "ISO646.1991-IRV"                               [107]
 +;;         ISO 646 International Reference Version
 +;; "ISO8859-1"                                     [15],[12]
 +;;         ISO Latin alphabet No. 1
 +;; "ISO8859-2"                                     [15],[12]
 +;;         ISO Latin alphabet No. 2
 +;; "ISO8859-3"                                     [15],[12]
 +;;         ISO Latin alphabet No. 3
 +;; "ISO8859-4"                                     [15],[12]
 +;;         ISO Latin alphabet No. 4
 +;; "ISO8859-5"                                     [15],[12]
 +;;         ISO Latin/Cyrillic alphabet
 +;; "ISO8859-6"                                     [15],[12]
 +;;         ISO Latin/Arabic alphabet
 +;; "ISO8859-7"                                     [15],[12]
 +;;         ISO Latin/Greek alphabet
 +;; "ISO8859-8"                                     [15],[12]
 +;;         ISO Latin/Hebrew alphabet
 +;; "ISO8859-9"                                     [15],[12]
 +;;         ISO Latin alphabet No. 5
 +;; "ISO8859-10"                                    [15],[12]
 +;;         ISO Latin alphabet No. 6
 +;; "ISO8859-13"                                    [15],[12]
 +;;         ISO Latin alphabet No. 7
 +;; "ISO8859-14"                                    [15],[12]
 +;;         ISO Latin alphabet No. 8
 +;; "ISO8859-15"                                    [15],[12]
 +;;         ISO Latin alphabet No. 9
 +;; "FCD8859-15"                                    [7]
 +;;         (deprecated)
 +;;         ISO Latin alphabet No. 9, Final Committee Draft
 +;; "ISO10646-1"                                    [133]
 +;;         Unicode Universal Multiple-Octet Coded Character Set
 +;; "ISO10646-MES"                                  [133]
 +;;         (deprecated)
 +;;         Unicode Minimum European Subset
 +;; "JISX0201.1976-0"                               [38],[12]
 +;;         8-Bit Alphanumeric-Katakana Code
 +;; "JISX0208.1983-0"                               [40],[12]
 +;;         Japanese Graphic Character Set,
 +;;         GL encoding
 +;; "JISX0208.1990-0"                               [71]
 +;;         Japanese Graphic Character Set,
 +;;         GL encoding
 +;; "JISX0208.1983-1"                               [40]
 +;;         (deprecated)
 +;;         Japanese Graphic Character Set,
 +;;         GR encoding
 +;; "JISX0212.1990-0"                               [72]
 +;;         Supplementary Japanese Graphic Character Set,
 +;;         GL encoding
 +;; "KOI8-R"                                        [119]
 +;;         Cyrillic alphabet
 +;; "KSC5601.1987-0"                                [41],[12]
 +;;         Korean Graphic Character Set,
 +;;         GL encoding
 +;; "KSC5601.1987-1"                                [41]
 +;;         (deprecated)
 +;;         Korean Graphic Character Set,
 +;;         GR encoding
 +;; "omron_CNS11643-0"                              [45]
 +;; "omron_CNS11643-1"                              [45]
 +;; "omron_BIG5-0"                                  [45]
 +;; "omron_BIG5-1"                                  [45]
 +;; "wn.tamil.1993"                                 [103]
 +
 +(defun set-font-encoding (pattern charset)
 +  "Set arguments in `font-encoding-alist' (which see)."
    (let ((slot (assoc pattern font-encoding-alist)))
      (if slot
 -      (let ((place (assq charset (cdr slot))))
 -        (if place
 -            (setcdr place encoding)
 -          (setcdr slot (cons (cons charset encoding) (cdr slot)))))
 +      (setcdr slot charset)
        (setq font-encoding-alist
 -          (cons (list pattern (cons charset encoding)) font-encoding-alist)))
 -    ))
 -
 -;; Allow display of arbitrary characters with an iso-10646-encoded
 -;; (`Unicode') font.
 -(define-translation-table 'ucs-mule-to-mule-unicode
 -  ucs-mule-to-mule-unicode)
 -(define-translation-hash-table 'ucs-mule-cjk-to-unicode
 -  ucs-mule-cjk-to-unicode)
 -
 -(define-ccl-program ccl-encode-unicode-font
 -  `(0
 -    ;; r0: charset-id
 -    ;; r1: 1st position code
 -    ;; r2: 2nd position code (if r0 is 2D charset)
 -    ((if (r0 == ,(charset-id 'ascii))
 -       ((r2 = r1)
 -        (r1 = 0))
 -       ;; At first, try to get a Unicode code point directly.
 -       ((if (r2 >= 0)
 -          ;; This is a 2D charset.
 -          (r1 = ((r1 << 7) | r2)))
 -      (lookup-character utf-subst-table-for-encode r0 r1)
 -      (if r7
 -          ;; We got it!
 -          ((r1 = (r0 >> 8))
 -           (r2 = (r0 & #xFF)))
 -        ;; Look for a translation for non-ASCII chars.
 -        ((translate-character ucs-mule-to-mule-unicode r0 r1)
 -         (if (r0 == ,(charset-id 'ascii))
 -             ((r2 = r1)
 -              (r1 = 0))
 -           ((if (r0 == ,(charset-id 'latin-iso8859-1))
 -                ((r2 = (r1 + 128))
 -                 (r1 = 0))
 -              ((r2 = (r1 & #x7F))
 -               (r1 >>= 7)
 -               (if (r0 == ,(charset-id 'mule-unicode-0100-24ff))
 -                   ((r1 *= 96)
 -                    (r1 += r2)
 -                    (r1 += ,(- #x100 (* 32 96) 32))
 -                    (r1 >8= 0)
 -                    (r2 = r7))
 -                 (if (r0 == ,(charset-id 'mule-unicode-2500-33ff))
 -                     ((r1 *= 96)
 -                      (r1 += r2)
 -                      (r1 += ,(- #x2500 (* 32 96) 32))
 -                      (r1 >8= 0)
 -                      (r2 = r7))
 -                   (if (r0 == ,(charset-id 'mule-unicode-e000-ffff))
 -                       ((r1 *= 96)
 -                        (r1 += r2)
 -                        (r1 += ,(- #xe000 (* 32 96) 32))
 -                        (r1 >8= 0)
 -                        (r2 = r7))
 -                     ;; No way, use the glyph for U+FFFD.
 -                     ((r1 = #xFF)
 -                      (r2 = #xFD)))))))))))))))
 -  "Encode characters for display with iso10646 font.
 -Translate through the translation-hash-table named
 -`ucs-mule-cjk-to-unicode' and the translation-table named
 -`ucs-mule-to-mule-unicode' initially.")
 -
 -;; Use the above CCL encoder for Unicode fonts.  Please note that the
 -;; regexp is not simply "ISO10646-1" because there exists, for
 -;; instance, the following Devanagari Unicode fonts:
 -;;    -misc-fixed-medium-r-normal--24-240-72-72-c-120-iso10646.indian-1
 -;;    -sibal-devanagari-medium-r-normal--24-240-75-75-P--iso10646-dev
 -(setq font-ccl-encoder-alist
 -      (cons '("ISO10646.*-*" . ccl-encode-unicode-font)
 -          font-ccl-encoder-alist))
 +          (cons (cons pattern charset) font-encoding-alist)))))
  
  ;; Setting for suppressing XLoadQueryFont on big fonts.
  (setq x-pixel-size-width-font-regexp
 -      "gb2312\\|jisx0208\\|ksc5601\\|cns11643\\|big5")
 +      "gb2312\\|gbk\\|gb18030\\|jisx0208\\|ksc5601\\|cns11643\\|big5")
  
  ;; These fonts require vertical centering.
  (setq vertical-centering-font-regexp
 -      "gb2312\\|jisx0208\\|jisx0212\\|ksc5601\\|cns11643\\|big5")
 +      "gb2312\\|gbk\\|gb18030\\|jisx0208\\|jisx0212\\|ksc5601\\|cns11643\\|big5")
  
  ;; CDAC fonts are actually smaller than their design sizes.
  (setq face-font-rescale-alist
        '(("-cdac$" . 1.3)))
  
 -(defvar x-font-name-charset-alist
 -  '(("iso8859-1" ascii latin-iso8859-1)
 -    ("iso8859-2" ascii latin-iso8859-2)
 -    ("iso8859-3" ascii latin-iso8859-3)
 -    ("iso8859-4" ascii latin-iso8859-4)
 -    ("iso8859-5" ascii cyrillic-iso8859-5)
 -    ("iso8859-6" ascii arabic-iso8859-6)
 -    ("iso8859-7" ascii greek-iso8859-7)
 -    ("iso8859-8" ascii hebrew-iso8859-8)
 -    ("iso8859-14" ascii latin-iso8859-14)
 -    ("iso8859-15" ascii latin-iso8859-15)
 -    ("tis620" ascii thai-tis620)
 -    ("koi8" ascii cyrillic-iso8859-5)
 -    ("viscii" ascii vietnamese-viscii-upper vietnamese-viscii-lower)
 -    ("vscii" ascii vietnamese-viscii-upper vietnamese-viscii-lower)
 -    ("mulelao-1" ascii lao)
 -    ("iso10646-1" ascii latin-iso8859-1 mule-unicode-0100-24ff
 -     mule-unicode-2500-33ff mule-unicode-e000-ffff))
 -  "Alist of font names vs list of charsets the font can display.
 -
 -When a font name which matches some element of this alist is given as
 -`-fn' command line argument or is specified by X resource, a fontset
 -which uses the specified font for the corresponding charsets are
 -created and used for the initial frame.")
 +(defvar x-font-name-charset-alist nil
 +  "This variable has no meaning now.  Just kept for backward compatibility.")
  
  ;;; XLFD (X Logical Font Description) format handler.
  
  ;; Define XLFD's field index numbers.         ; field name
 -(defconst xlfd-regexp-foundry-subnum 0)               ; FOUNDRY
 -(defconst xlfd-regexp-family-subnum 1)                ; FAMILY_NAME
 -(defconst xlfd-regexp-weight-subnum 2)                ; WEIGHT_NAME
 -(defconst xlfd-regexp-slant-subnum 3)         ; SLANT
 -(defconst xlfd-regexp-swidth-subnum 4)                ; SETWIDTH_NAME
 -(defconst xlfd-regexp-adstyle-subnum 5)               ; ADD_STYLE_NAME
 -(defconst xlfd-regexp-pixelsize-subnum 6)     ; PIXEL_SIZE
 -(defconst xlfd-regexp-pointsize-subnum 7)     ; POINT_SIZE
 -(defconst xlfd-regexp-resx-subnum 8)          ; RESOLUTION_X
 -(defconst xlfd-regexp-resy-subnum 9)          ; RESOLUTION_Y
 -(defconst xlfd-regexp-spacing-subnum 10)      ; SPACING
 -(defconst xlfd-regexp-avgwidth-subnum 11)     ; AVERAGE_WIDTH
 -(defconst xlfd-regexp-registry-subnum 12)     ; CHARSET_REGISTRY
 -(defconst xlfd-regexp-encoding-subnum 13)     ; CHARSET_ENCODING
 +(defconst xlfd-regexp-family-subnum 0)                ; FOUNDRY and FAMILY
 +(defconst xlfd-regexp-weight-subnum 1)                ; WEIGHT_NAME
 +(defconst xlfd-regexp-slant-subnum 2)         ; SLANT
 +(defconst xlfd-regexp-swidth-subnum 3)                ; SETWIDTH_NAME
 +(defconst xlfd-regexp-adstyle-subnum 4)               ; ADD_STYLE_NAME
 +(defconst xlfd-regexp-pixelsize-subnum 5)     ; PIXEL_SIZE
 +(defconst xlfd-regexp-pointsize-subnum 6)     ; POINT_SIZE
 +(defconst xlfd-regexp-resx-subnum 7)          ; RESOLUTION_X
 +(defconst xlfd-regexp-resy-subnum 8)          ; RESOLUTION_Y
 +(defconst xlfd-regexp-spacing-subnum 8)               ; SPACING
 +(defconst xlfd-regexp-avgwidth-subnum 10)     ; AVERAGE_WIDTH
 +(defconst xlfd-regexp-registry-subnum 11)     ; REGISTRY and ENCODING
  
  ;; Regular expression matching against a fontname which conforms to
  ;; XLFD (X Logical Font Description).  All fields in XLFD should be
  ;; not be omitted (but can be a wild card) to be matched.
  (defconst xlfd-tight-regexp
    "^\
 +-\\([^-]*-[^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)\
  -\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)\
 --\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)\
 --\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)$")
 +-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*-[^-]*\\)$")
 +
 +;; Regular expression matching against a fontname which conforms to
 +;; XLFD (X Logical Font Description).  All fields in XLFD from FOUNDRY
 +;; to ADSTYLE, REGISTRY, and ENCODING should be not be omitted (but
 +;; can be a wild card) to be matched.
 +(defconst xlfd-style-regexp
 +  "^\
 +-\\([^-]*-[^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-\\([^-]*\\)-.*\
 +-\\([^-]*-[^-]*\\)$")
  
  ;; List of field numbers of XLFD whose values are numeric.
  (defconst xlfd-regexp-numeric-subnums
 -  (list xlfd-regexp-pixelsize-subnum  ;6
 -      xlfd-regexp-pointsize-subnum    ;7
 -      xlfd-regexp-resx-subnum         ;8
 -      xlfd-regexp-resy-subnum         ;9
 -      xlfd-regexp-avgwidth-subnum     ;11
 +  (list xlfd-regexp-pixelsize-subnum  ;5
 +      xlfd-regexp-pointsize-subnum    ;6
 +      xlfd-regexp-resx-subnum         ;7
 +      xlfd-regexp-resy-subnum         ;8
 +      xlfd-regexp-avgwidth-subnum     ;10
        ))
  
  (defun x-decompose-font-name (pattern)
 -  "Decompose PATTERN into XLFD's fields and return vector of the fields.
 -The length of the vector is 14.
 -
 -If PATTERN doesn't conform to XLFD, try to get a full XLFD name from
 -X server and use the information of the full name to decompose
 -PATTERN.  If no full XLFD name is gotten, return nil."
 -  (let (xlfd-fields fontname)
 -    (if (string-match xlfd-tight-regexp pattern)
 -      (let ((i 0))
 -        (setq xlfd-fields (make-vector 14 nil))
 -        (while (< i 14)
 -          (aset xlfd-fields i (match-string (1+ i) pattern))
 -          (setq i (1+ i)))
 -        xlfd-fields)
 -      (setq fontname (condition-case nil
 -                       (x-resolve-font-name pattern)
 -                     (error)))
 -      (if (and fontname
 -             (string-match xlfd-tight-regexp fontname))
 -        ;; We get a full XLFD name.
 -        (let ((len (length pattern))
 -              (i 0)
 -              l)
 -          ;; Setup xlfd-fields by the full XLFD name.  Each element
 -          ;; should be a cons of matched index and matched string.
 -          (setq xlfd-fields (make-vector 14 nil))
 -          (while (< i 14)
 -            (aset xlfd-fields i
 -                  (cons (match-beginning (1+ i))
 -                        (match-string (1+ i) fontname)))
 -            (setq i (1+ i)))
 -
 -          ;; Replace wild cards in PATTERN by regexp codes.
 -          (setq i 0)
 -          (while (< i len)
 -            (let ((ch (aref pattern i)))
 -              (if (= ch ??)
 -                  (setq pattern (concat (substring pattern 0 i)
 -                                        "\\(.\\)"
 -                                        (substring pattern (1+ i)))
 -                        len (+ len 4)
 -                        i (+ i 4))
 -                (if (= ch ?*)
 -                    (setq pattern (concat (substring pattern 0 i)
 -                                          "\\(.*\\)"
 -                                          (substring pattern (1+ i)))
 -                          len (+ len 5)
 -                          i (+ i 5))
 -                  (setq i (1+ i))))))
 -
 -          ;; Set each element of xlfd-fields to proper strings.
 -          (if (string-match pattern fontname)
 -              ;; The regular expression PATTERN matchs the full XLFD
 -              ;; name.  Set elements that correspond to a wild card
 -              ;; in PATTERN to "*", set the other elements to the
 -              ;; exact strings in PATTERN.
 -              (let ((l (cdr (cdr (match-data)))))
 -                (setq i 0)
 -                (while (< i 14)
 -                  (if (or (null l) (< (car (aref xlfd-fields i)) (car l)))
 -                      (progn
 -                        (aset xlfd-fields i (cdr (aref xlfd-fields i)))
 -                        (setq i (1+ i)))
 -                    (if (< (car (aref xlfd-fields i)) (car (cdr l)))
 -                        (progn
 -                          (aset xlfd-fields i "*")
 -                          (setq i (1+ i)))
 -                      (setq l (cdr (cdr l)))))))
 -            ;; Set each element of xlfd-fields to the exact string
 -            ;; in the corresonding fields in full XLFD name.
 -            (setq i 0)
 -            (while (< i 14)
 -              (aset xlfd-fields i (cdr (aref xlfd-fields i)))
 -              (setq i (1+ i))))
 -          xlfd-fields)))))
 -
 -;; Replace consecutive wild-cards (`*') in NAME to one.
 -;; Ex. (x-reduce-font-name "-*-*-*-iso8859-1") => "-*-iso8859-1"
 -(defsubst x-reduce-font-name (name)
 -  (while (string-match "-\\*-\\(\\*-\\)+" name)
 -    (setq name (replace-match "-*-" t t name)))
 -  name)
 +  "Decompose PATTERN into XLFD fields and return a vector of the fields.
 +The length of the vector is 12.
 +The FOUNDRY and FAMILY fields are concatinated and stored in the first
 +element of the vector.
 +The REGISTRY and ENCODING fields are concatinated and stored in the last
 +element of the vector.
 +
 +Return nil if PATTERN doesn't conform to XLFD."
 +  (if (string-match xlfd-tight-regexp pattern)
 +      (let ((xlfd-fields (make-vector 12 nil)))
 +      (dotimes (i 12)
 +        (aset xlfd-fields i (match-string (1+ i) pattern)))
 +      (dotimes (i 12)
 +        (if (string-match "^[*-]+$" (aref xlfd-fields i))
 +            (aset xlfd-fields i nil)))
 +      xlfd-fields)))
  
  (defun x-compose-font-name (fields &optional reduce)
 -  "Compose X's fontname from FIELDS.
 -FIELDS is a vector of XLFD fields, of length 14.
 +  "Compose X fontname from FIELDS.
 +FIELDS is a vector of XLFD fields, of length 12.
  If a field is nil, wild-card letter `*' is embedded.
  Optional argument REDUCE exists just for backward compatibility,
  and is always ignored."
@@@ -612,7 -398,7 +612,7 @@@ If no font matching XLFD-FIELDS is avai
  parts of the font name pattern with \"*\" until some font is found.
  Value is name of that font."
    (let ((ascii-font nil) (index 0))
 -    (while (and (null ascii-font) (<= index xlfd-regexp-encoding-subnum))
 +    (while (and (null ascii-font) (<= index xlfd-regexp-registry-subnum))
        (let ((pattern (x-compose-font-name xlfd-fields)))
        (condition-case nil
            (setq ascii-font (x-resolve-font-name pattern))
  
  
  (defun x-complement-fontset-spec (xlfd-fields fontlist)
 -  "Complement FONTLIST for charsets based on XLFD-FIELDS and return it.
 +  "Complement elements of FONTLIST based on XLFD-FIELDS.
  XLFD-FIELDS is a vector of XLFD (X Logical Font Description) fields.
 -FONTLIST is an alist of charsets vs the corresponding font names.
 -
 -The fonts are complemented as below.
 -
 -If FONTLIST doesn't specify a font for ASCII charset, generate a font
 -name for the charset from XLFD-FIELDS, and add that information to
 -FONTLIST.
 -
 -If a font specifid for ASCII supports the other charsets (see the
 -variable `x-font-name-charset-alist'), add that information to FONTLIST."
 -  (let* ((slot (assq 'ascii fontlist))
 -       (ascii-font (cdr slot))
 -       ascii-font-spec)
 -    (if ascii-font
 -      (setcdr slot (setq ascii-font (x-resolve-font-name ascii-font)))
 -      ;; If font for ASCII is not specified, add it.
 -      (aset xlfd-fields xlfd-regexp-registry-subnum "iso8859")
 -      (aset xlfd-fields xlfd-regexp-encoding-subnum "1")
 -      (setq ascii-font (x-must-resolve-font-name xlfd-fields))
 -      (setq fontlist (cons (cons 'ascii ascii-font) fontlist)))
 -
 -    ;; If the font for ASCII also supports the other charsets, and
 -    ;; they are not specified in FONTLIST, add them.
 -    (setq xlfd-fields (x-decompose-font-name ascii-font))
 -    (if (not xlfd-fields)
 -      (setq ascii-font-spec ascii-font)
 -      (setq ascii-font-spec
 -          (cons (format "%s-%s"
 -                        (aref xlfd-fields xlfd-regexp-foundry-subnum)
 -                        (aref xlfd-fields xlfd-regexp-family-subnum))
 -                (format "%s-%s"
 -                        (aref xlfd-fields xlfd-regexp-registry-subnum)
 -                        (aref xlfd-fields xlfd-regexp-encoding-subnum)))))
 -    (let ((tail x-font-name-charset-alist)
 -        elt)
 -      (while tail
 -      (setq elt (car tail) tail (cdr tail))
 -      (if (string-match (car elt) ascii-font)
 -          (let ((charsets (cdr elt))
 -                charset)
 -            (while charsets
 -              (setq charset (car charsets) charsets (cdr charsets))
 -              (or (assq charset fontlist)
 -                  (setq fontlist
 -                        (cons (cons charset ascii-font-spec) fontlist))))))))
 +FONTLIST is an alist of script names vs the corresponding font names.
 +
 +The font names are complemented as below.
 +
 +If a font name matches `xlfd-style-regexp', each field of wild card is
 +replaced by the corresponding fields in XLFD-FIELDS."
 +  (let ((default-spec (vector (aref xlfd-fields xlfd-regexp-family-subnum)
 +                            (aref xlfd-fields xlfd-regexp-weight-subnum)
 +                            (aref xlfd-fields xlfd-regexp-slant-subnum)
 +                            (aref xlfd-fields xlfd-regexp-swidth-subnum)
 +                            (aref xlfd-fields xlfd-regexp-adstyle-subnum)
 +                            (aref xlfd-fields xlfd-regexp-registry-subnum))))
 +    (dolist (elt fontlist)
 +      (let ((name (cadr elt))
 +          font-spec)
 +      (when (or (string-match xlfd-style-regexp name)
 +                (and (setq name (car (x-list-fonts name nil nil 1)))
 +                     (string-match xlfd-style-regexp name)))
 +        (setq font-spec (make-vector 6 nil))
 +        (dotimes (i 6)
 +          (aset font-spec i (match-string (1+ i) name)))
 +        (dotimes (i 5)
 +          (if (string-match "^[*-]+$" (aref font-spec i))
 +              (aset font-spec i (aref default-spec i))))
 +        (setcar (cdr elt) font-spec))))
  
      fontlist))
  
@@@ -664,15 -470,17 +664,15 @@@ with \"fontset\" in `<CHARSET_REGISTRY>
         (string= (match-string (1+ xlfd-regexp-registry-subnum) fontset)
                "fontset")))
  
 -;; Return a list to be appended to `x-fixed-font-alist' when
 -;; `mouse-set-font' is called.
  (defun generate-fontset-menu ()
 -  (let ((fontsets (fontset-list))
 -      fontset-name
 -      l)
 -    (while fontsets
 -      (setq fontset-name (car fontsets) fontsets (cdr fontsets))
 -      (setq l (cons (list (fontset-plain-name fontset-name) fontset-name) l)))
 +  "Return list to be appended to `x-fixed-font-alist'.
 +Done when `mouse-set-font' is called."
 +  (let (l)
 +    (dolist (fontset (fontset-list))
 +      (or (string-match "fontset-default$" fontset)
 +        (push (list (fontset-plain-name fontset) fontset) l)))
      (cons "Fontset"
 -        (sort l (function (lambda (x y) (string< (car x) (car y))))))))
 +        (sort l #'(lambda (x y) (string< (car x) (car y)))))))
  
  (defun fontset-plain-name (fontset)
    "Return a plain and descriptive name of FONTSET."
        (error "Invalid fontset: %s" fontset))
    (let ((xlfd-fields (x-decompose-font-name fontset)))
      (if xlfd-fields
 -      (let ((weight (aref xlfd-fields xlfd-regexp-weight-subnum))
 +      (let ((family (aref xlfd-fields xlfd-regexp-family-subnum))
 +            (weight (aref xlfd-fields xlfd-regexp-weight-subnum))
              (slant  (aref xlfd-fields xlfd-regexp-slant-subnum))
              (swidth (aref xlfd-fields xlfd-regexp-swidth-subnum))
              (size   (aref xlfd-fields xlfd-regexp-pixelsize-subnum))
 -            (charset (aref xlfd-fields xlfd-regexp-registry-subnum))
 -            (nickname (aref xlfd-fields xlfd-regexp-encoding-subnum))
 +            (nickname (aref xlfd-fields xlfd-regexp-registry-subnum))
              name)
 -        (if (not (string= "fontset" charset))
 -            fontset
 -          (if (> (string-to-number size) 0)
 -              (setq name (format "%s: %s-dot" nickname size))
 -            (setq name nickname))
 -          (cond ((string-match "^medium$" weight)
 -                 (setq name (concat name " " "medium")))
 -                ((string-match "^bold$\\|^demibold$" weight)
 -                 (setq name (concat name " " weight))))
 -          (cond ((string-match "^i$" slant)
 -                 (setq name (concat name " " "italic")))
 -                ((string-match "^o$" slant)
 -                 (setq name (concat name " " "slant")))
 -                ((string-match "^ri$" slant)
 -                 (setq name (concat name " " "reverse italic")))
 -                ((string-match "^ro$" slant)
 -                 (setq name (concat name " " "reverse slant"))))
 -          name))
 +        (if (not (string-match "^fontset-\\(.*\\)$" nickname))
 +            (setq nickname family)
 +          (setq nickname (match-string 1 nickname)))
 +        (if (and size (> (string-to-number size) 0))
 +            (setq name (format "%s: %s-dot" nickname size))
 +          (setq name nickname))
 +        (and weight
 +             (cond ((string-match "^medium$" weight)
 +                    (setq name (concat name " " "medium")))
 +                   ((string-match "^bold$\\|^demibold$" weight)
 +                    (setq name (concat name " " weight)))))
 +        (and slant
 +             (cond ((string-match "^i$" slant)
 +                    (setq name (concat name " " "italic")))
 +                   ((string-match "^o$" slant)
 +                    (setq name (concat name " " "slant")))
 +                   ((string-match "^ri$" slant)
 +                    (setq name (concat name " " "reverse italic")))
 +                   ((string-match "^ro$" slant)
 +                    (setq name (concat name " " "reverse slant")))))
 +        name)
        fontset)))
  
 +(defvar charset-script-alist
 +  '((ascii . latin)
 +    (latin-iso8859-1 . latin)
 +    (latin-iso8859-2 . latin)
 +    (latin-iso8859-3 . latin)
 +    (latin-iso8859-4 . latin)
 +    (latin-iso8859-9 . latin)
 +    (latin-iso8859-10 . latin)
 +    (latin-iso8859-13 . latin)
 +    (latin-iso8859-14 . latin)
 +    (latin-iso8859-15 . latin)
 +    (latin-iso8859-16 . latin)
 +    (latin-jisx0201 . latin)
 +    (thai-tis620 . thai)
 +    (cyrillic-iso8859-5 . cyrillic)
 +    (arabic-iso8859-6 . arabic)
 +    (greek-iso8859-7 . latin)
 +    (hebrew-iso8859-8 . latin)
 +    (katakana-jisx0201 . kana)
 +    (chinese-gb2312 . han)
 +    (chinese-gbk . han)
 +    (gb18030-2-byte . han)
 +    (gb18030-4-byte-bmp . han)
 +    (gb18030-4-byte-ext-1 . han)
 +    (gb18030-4-byte-ext-2 . han)
 +    (gb18030-4-byte-smp . han)
 +    (chinese-big5-1 . han)
 +    (chinese-big5-2 . han)
 +    (chinese-cns11643-1 . han)
 +    (chinese-cns11643-2 . han)
 +    (chinese-cns11643-3 . han)
 +    (chinese-cns11643-4 . han)
 +    (chinese-cns11643-5 . han)
 +    (chinese-cns11643-6 . han)
 +    (chinese-cns11643-7 . han)
 +    (japanese-jisx0208 . han)
 +    (japanese-jisx0208-1978 . han)
 +    (japanese-jisx0212 . han)
 +    (japanese-jisx0213-1 . han)
 +    (japanese-jisx0213-2 . han)
 +    (korean-ksc5601 . hangul)
 +    (chinese-sisheng . bopomofo)
 +    (vietnamese-viscii-lower . latin)
 +    (vietnamese-viscii-upper . latin)
 +    (arabic-digit . arabic)
 +    (arabic-1-column . arabic)
 +    (arabic-2-column . arabic)
 +    (indian-is13194 . devanagari)
 +    (indian-glyph . devanagari)
 +    (indian-1-column . devanagari)
 +    (indian-2-column . devanagari)
 +    (tibetan-1-column . tibetan))
 +  "Alist of charsets vs the corresponding most appropriate scripts.
 +
 +This alist is used by the function `create-fontset-from-fontset-spec'
 +to map charsets to scripts.")
  
  (defun create-fontset-from-fontset-spec (fontset-spec
                                         &optional style-variant noerror)
    "Create a fontset from fontset specification string FONTSET-SPEC.
  FONTSET-SPEC is a string of the format:
 -      FONTSET-NAME,CHARSET0:FONT0,CHARSET1:FONT1, ...
 +      FONTSET-NAME,SCRIPT0:FONT0,SCRIPT1:FONT1, ...
  Any number of SPACE, TAB, and NEWLINE can be put before and after commas.
  
 -Optional 2nd arg exists just for backward compatibility, and is ignored.
 +When a frame uses the fontset as the `font' parameter, the frame's
 +default font name is derived from FONTSET-NAME by substituting
 +\"iso8859-1\" for the tail part \"fontset-XXX\".  But, if SCRIPT-NAMEn
 +is \"ascii\", use the corresponding FONT-NAMEn as the default font
 +name.
  
 -If this function attempts to create already existing fontset, an error is
 -signaled unless the optional 3rd argument NOERROR is non-nil.
 +Optional 2nd and 3rd arguments exist just for backward compatibility,
 +and are ignored.
  
 -It returns a name of the created fontset."
 -  (if (not (string-match "^[^,]+" fontset-spec))
 +It returns a name of the created fontset.
 +
 +For backward compatibility, SCRIPT-NAME may be a charset name, in
 +which case, the corresponding script is decided by the variable
 +`charset-script-alist' (which see)."
 +  (or (string-match "^[^,]+" fontset-spec)
        (error "Invalid fontset spec: %s" fontset-spec))
 -  (setq fontset-spec (downcase fontset-spec))
    (let ((idx (match-end 0))
        (name (match-string 0 fontset-spec))
 -      xlfd-fields charset fontlist ascii-font)
 -    (if (query-fontset name)
 -      (or noerror
 -          (error "Fontset \"%s\" already exists" name))
 -      (setq xlfd-fields (x-decompose-font-name name))
 -      (or xlfd-fields
 -        (error "Fontset \"%s\" not conforming to XLFD" name))
 -
 -      ;; At first, extract pairs of charset and fontname from FONTSET-SPEC.
 -      (while (string-match "[, \t\n]*\\([^:]+\\):[ \t]*\\([^,]+\\)"
 -                         fontset-spec idx)
 -      (setq idx (match-end 0))
 -      (setq charset (intern (match-string 1 fontset-spec)))
 -      (if (charsetp charset)
 -          (setq fontlist (cons (cons charset (match-string 2 fontset-spec))
 -                               fontlist))))
 -      (setq ascii-font (cdr (assq 'ascii fontlist)))
 -
 -      ;; Complement FONTLIST.
 -      (setq fontlist (x-complement-fontset-spec xlfd-fields fontlist))
 -
 -      (new-fontset name fontlist)
 -
 -      ;; Define the short name alias.
 -      (if (and (string-match "fontset-.*$" name)
 -             (not (assoc name fontset-alias-alist)))
 -        (let ((alias (match-string 0 name)))
 -          (or (rassoc alias fontset-alias-alist)
 -              (setq fontset-alias-alist
 -                    (cons (cons name alias) fontset-alias-alist)))))
 -
 -      ;; Define the ASCII font name alias.
 -      (or ascii-font
 -        (setq ascii-font (cdr (assq 'ascii fontlist))))
 -      (or (rassoc ascii-font fontset-alias-alist)
 -        (setq fontset-alias-alist
 -              (cons (cons name ascii-font)
 -                    fontset-alias-alist))))
 -
 -    name))
 +      xlfd-fields target script fontlist)
 +    (setq xlfd-fields (x-decompose-font-name name))
 +    (or xlfd-fields
 +      (error "Fontset name \"%s\" not conforming to XLFD" name))
 +
 +    ;; At first, extract pairs of charset and fontname from FONTSET-SPEC.
 +    (while (string-match "[, \t\n]*\\([^:]+\\):[ \t]*\\([^,]+\\)" 
 +                       fontset-spec idx)
 +      (setq idx (match-end 0))
 +      (setq target (intern (match-string 1 fontset-spec)))
 +      (cond ((or (eq target 'ascii)
 +               (memq target (char-table-extra-slot char-script-table 0)))
 +           (push (list target (match-string 2 fontset-spec)) fontlist))
 +          ((setq script (cdr (assq target charset-script-alist)))
 +           (push (list script (match-string 2 fontset-spec)) fontlist))
 +          ((charsetp target)
 +           (push (list target (match-string 2 fontset-spec)) fontlist))))
 +
 +    ;; Complement FONTLIST.
 +    (setq fontlist (x-complement-fontset-spec xlfd-fields fontlist))
 +
 +    ;; Create a fontset.
 +    (new-fontset name (nreverse fontlist))))
  
  (defun create-fontset-from-ascii-font (font &optional resolved-font
                                            fontset-name)
@@@ -830,19 -589,23 +830,19 @@@ an appropriate name is generated automa
  
  It returns a name of the created fontset."
    (setq font (downcase font))
 -  (if resolved-font
 -      (setq resolved-font (downcase resolved-font))
 -    (setq resolved-font (downcase (x-resolve-font-name font))))
 -  (let ((xlfd (x-decompose-font-name font))
 -      (resolved-xlfd (x-decompose-font-name resolved-font))
 -      fontset fontset-spec)
 -    (aset xlfd xlfd-regexp-foundry-subnum nil)
 -    (aset xlfd xlfd-regexp-family-subnum nil)
 -    (aset xlfd xlfd-regexp-registry-subnum "fontset")
 +  (setq resolved-font
 +      (downcase (or resolved-font (x-resolve-font-name font))))
 +  (let ((xlfd (x-decompose-font-name resolved-font))
 +      fontset)
      (if fontset-name
        (setq fontset-name (downcase fontset-name))
 -      (setq fontset-name
 -          (format "%s_%s_%s"
 -                  (aref resolved-xlfd xlfd-regexp-registry-subnum)
 -                  (aref resolved-xlfd xlfd-regexp-encoding-subnum)
 -                  (aref resolved-xlfd xlfd-regexp-pixelsize-subnum))))
 -    (aset xlfd xlfd-regexp-encoding-subnum fontset-name)
 +      (if (query-fontset "fontset-startup")
 +        (setq fontset-name
 +              (subst-char-in-string
 +               ?- ?_ (aref xlfd xlfd-regexp-registry-subnum) t))
 +      (setq fontset-name "startup")))
 +    (aset xlfd xlfd-regexp-registry-subnum
 +        (format "fontset-%s" fontset-name))
      (setq fontset (x-compose-font-name xlfd))
      (or (query-fontset fontset)
        (create-fontset-from-fontset-spec (concat fontset ", ascii:" font)))))
  ;; specified here because FAMILY of those fonts are not "fixed" in
  ;; many cases.
  (defvar standard-fontset-spec
 -  (purecopy "-*-fixed-medium-r-normal-*-16-*-*-*-*-*-fontset-standard,
 -      chinese-gb2312:-*-medium-r-normal-*-16-*-gb2312*-*,
 -      korean-ksc5601:-*-medium-r-normal-*-16-*-ksc5601*-*,
 -      chinese-cns11643-1:-*-medium-r-normal-*-16-*-cns11643*-1,
 -      chinese-cns11643-2:-*-medium-r-normal-*-16-*-cns11643*-2,
 -      chinese-cns11643-3:-*-medium-r-normal-*-16-*-cns11643*-3,
 -      chinese-cns11643-4:-*-medium-r-normal-*-16-*-cns11643*-4,
 -      chinese-cns11643-5:-*-medium-r-normal-*-16-*-cns11643*-5,
 -      chinese-cns11643-6:-*-medium-r-normal-*-16-*-cns11643*-6,
 -      chinese-cns11643-7:-*-medium-r-normal-*-16-*-cns11643*-7")
 +  (purecopy "-*-fixed-medium-r-normal-*-16-*-*-*-*-*-fontset-standard")
    "String of fontset spec of the standard fontset.
  You have the biggest chance to display international characters
  with correct glyphs by using the standard fontset.
  See the documentation of `create-fontset-from-fontset-spec' for the format.")
  
 +
  ;; Create fontsets from X resources of the name `fontset-N (class
  ;; Fontset-N)' where N is integer 0, 1, ...
  ;; The values of the resources the string of the same format as
index 711b1342d7f222a9971ed5d8b790738e96947f03,babfc5bacf79f35bdce97ae420ca7850bdef54dc..f6aa892aafec2c9071fcfc9816b28ffe6ecc64ca
@@@ -1,7 -1,7 +1,7 @@@
  ;;; ja-dic-cnv.el --- convert a Japanese dictionary (SKK-JISYO.L) to Emacs Lisp
  
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  (defvar ja-dic-filename "ja-dic.el")
  
  ;; To make a generated ja-dic.el smaller.
 -(make-coding-system
 - 'iso-2022-7bit-short
 - 2 ?J
 +(define-coding-system 'iso-2022-7bit-short
   "Like `iso-2022-7bit' but no ASCII designation before SPC."
 - '(ascii nil nil nil t t nil t)
 - '((safe-charsets . t)))
 +  :coding-type 'iso-2022
 +  :mnemonic ?J
 +  :charset-list 'iso-2022
 +  :designation [(ascii t) nil nil nil]
 +  :flags '(short 7-bit designation))
  
  (defun skkdic-convert-okuri-ari (skkbuf buf)
    (message "Processing OKURI-ARI entries ...")
@@@ -366,7 -365,7 +366,7 @@@ The name of generated file is specifie
              ";;\tGenerated by the command `skkdic-convert'\n"
              ";;\tDate: " (current-time-string) "\n"
              ";;\tOriginal SKK dictionary file: "
-             (file-name-nondirectory filename)
+             (file-relative-name (expand-file-name filename) dirname)
              "\n\n"
              ";; This file is part of GNU Emacs.\n\n"
              ";;; Commentary:\n\n"
@@@ -479,7 -478,7 +479,7 @@@ To get complete usage, invoke
                (- ch)                  ;  represented by a negative code.
              (if (= ch ?\e$B!<\e(B)              ; `\e$B!<\e(B' is represented by 0.
                  0
 -              (- (nth 2 (split-char ch)) 32))))
 +              (- (logand (encode-char ch 'japanese-jisx0208) #xFF) 32))))
        (setq i (1+ i)))
      vec))
  
index 4c01ed5d75d2c2f63e5ffb604e81f3704eccbaa2,3b16c14dc4ea972ff2630ddad5af9b67a8b8617c..3fd81d6e4f7371327307ec229e840de3371b4241
@@@ -1,7 -1,7 +1,7 @@@
  ;;; ja-dic-utl.el --- utilities for handling Japanese dictionary (SKK-JISYO.L)
  
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
@@@ -90,9 -90,7 +90,9 @@@
        (setq heads (cdr heads)))
      l))
  
 -(defconst skkdic-jisx0208-hiragana-block (nth 1 (split-char ?\e$B$"\e(B)))
 +(defconst skkdic-jisx0208-hiragana-block
 +  (cons (decode-char 'japanese-jisx0208 #x2421)
 +      (decode-char 'japanese-jisx0208 #x247E)))
  
  (defun skkdic-lookup-key (seq len &optional postfix prefer-noun)
    "Return a list of conversion string for sequence SEQ of length LEN.
@@@ -132,17 -130,14 +132,17 @@@ LEIM is available from the same ftp dir
      ;;   else VEC[N] is 128.
      (while (< i len)
        (let ((ch (aref seq i))
 -          elts)
 -      (if (= ch ?\e$B!<\e(B)
 -          (aset vec i 0)
 -        (setq elts (split-char ch))
 -        (if (and (eq (car elts) 'japanese-jisx0208)
 -                 (= (nth 1 elts) skkdic-jisx0208-hiragana-block))
 -            (aset vec i (- (nth 2 elts) 32))
 -          (aset vec i 128))))
 +          code)
 +      (cond ((= ch ?\e$B!<\e(B)
 +             (aset vec i 0))
 +            ((and (>= ch (car skkdic-jisx0208-hiragana-block))
 +                  (<= ch (cdr skkdic-jisx0208-hiragana-block)))
 +             (setq code (encode-char ch 'japanese-jisx0208))
 +             (if code
 +                 (aset vec i (- (logand code #xFF) 32))
 +               (aset vec i 128)))
 +            (t
 +             (aset vec i 128))))
        (setq i (1+ i)))
  
      ;; Search OKURI-NASI entries.
index 6c7500ce9506855fb371e0acfeb0f97f1b41ce83,eff277887d4bd726c1e43bd584b2f7b95ff98168..f45c41f46b5eab0ea3434cf41183a6e5b7ac35d2
@@@ -1,16 -1,13 +1,16 @@@
  ;;; mule-cmds.el --- commands for mulitilingual environment -*-coding: iso-2022-7bit -*-
  
  ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- ;;   2006  Free Software Foundation, Inc.
+ ;;   2006, 2007  Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
 -;; Keywords: mule, multilingual
 +;; Keywords: mule, i18n
  
  ;; This file is part of GNU Emacs.
  
@@@ -279,7 -276,7 +279,7 @@@ wrong, use this command again to toggl
    (interactive
     (let ((default (and buffer-file-coding-system
                       (not (eq (coding-system-type buffer-file-coding-system)
 -                              t))
 +                              'undecided))
                       buffer-file-coding-system)))
       (list (read-coding-system
            (if default
@@@ -346,13 -343,15 +346,13 @@@ This also sets the following values
        (setq default-file-name-coding-system 'utf-8)
      (if (and default-enable-multibyte-characters
             (or (not coding-system)
 -               (not (coding-system-get coding-system 'ascii-incompatible))))
 +               (coding-system-get coding-system 'ascii-compatible-p)))
        (setq default-file-name-coding-system coding-system)))
    ;; If coding-system is nil, honor that on MS-DOS as well, so
    ;; that they could reset the terminal coding system.
    (unless (and (eq window-system 'pc) coding-system)
      (setq default-terminal-coding-system coding-system))
 -  (if (or (not coding-system)
 -        (not (coding-system-get coding-system 'ascii-incompatible)))
 -      (setq default-keyboard-coding-system coding-system))
 +  (setq default-keyboard-coding-system coding-system)
    ;; Preserve eol-type from existing default-process-coding-systems.
    ;; On non-unix-like systems in particular, these may have been set
    ;; carefully by the user, or by the startup code, to deal with the
@@@ -386,24 -385,33 +386,24 @@@ system, and Emacs automatically sets th
  startup.
  
  A coding system that requires automatic detection of text
 -encoding (e.g. undecided, unix) can't be preferred.
 -
 -See also `coding-category-list' and `coding-system-category'."
 ++encoding (e.g. undecided, unix) can't be preferred.."
    (interactive "zPrefer coding system: ")
    (if (not (and coding-system (coding-system-p coding-system)))
        (error "Invalid coding system `%s'" coding-system))
 -  (let ((coding-category (coding-system-category coding-system))
 -      (base (coding-system-base coding-system))
 +  (if (memq (coding-system-type coding-system) '(raw-text undecided))
 +      (error "Can't prefer the coding system `%s'" coding-system))
 +  (let ((base (coding-system-base coding-system))
        (eol-type (coding-system-eol-type coding-system)))
 -    (if (not coding-category)
 -      ;; CODING-SYSTEM is no-conversion or undecided.
 -      (error "Can't prefer the coding system `%s'" coding-system))
 -    (set coding-category (or base coding-system))
 -    ;; Changing the binding of a coding category requires this call.
 -    (update-coding-systems-internal)
 -    (or (eq coding-category (car coding-category-list))
 -      ;; We must change the order.
 -      (set-coding-priority (list coding-category)))
 -    (if (and base (interactive-p))
 -      (message "Highest priority is set to %s (base of %s)"
 -               base coding-system))
 +    (set-coding-system-priority base)
 +    (and (interactive-p)
 +       (or (eq base coding-system)
 +           (message "Highest priority is set to %s (base of %s)"
 +                    base coding-system)))
      ;; If they asked for specific EOL conversion, honor that.
      (if (memq eol-type '(0 1 2))
 -      (setq coding-system
 -            (coding-system-change-eol-conversion base eol-type))
 -      (setq coding-system base))
 -    (set-default-coding-systems coding-system)))
 +      (setq base
 +            (coding-system-change-eol-conversion base eol-type)))
 +    (set-default-coding-systems base)))
  
  (defvar sort-coding-systems-predicate nil
    "If non-nil, a predicate function to sort coding systems.
@@@ -427,8 -435,9 +427,8 @@@ If the variable `sort-coding-systems-pr
  non-nil, it is used to sort CODINGS in the different way than above."
    (if sort-coding-systems-predicate
        (sort codings sort-coding-systems-predicate)
 -    (let* ((from-categories (mapcar #'(lambda (x) (symbol-value x))
 -                                  coding-category-list))
 -         (most-preferred (car from-categories))
 +    (let* ((from-priority (coding-system-priority-list))
 +         (most-preferred (car from-priority))
           (lang-preferred (get-language-info current-language-environment
                                              'coding-system))
           (func (function
                      (logior
                       (lsh (if (eq base most-preferred) 1 0) 7)
                       (lsh
 -                      (let ((mime (coding-system-get base 'mime-charset)))
 +                      (let ((mime (coding-system-get base :mime-charset)))
                           ;; Prefer coding systems corresponding to a
                           ;; MIME charset.
                           (if mime
                             0))
                        5)
                       (lsh (if (memq base lang-preferred) 1 0) 4)
 -                     (lsh (if (memq base from-categories) 1 0) 3)
 +                     (lsh (if (memq base from-priority) 1 0) 3)
                       (lsh (if (string-match "-with-esc\\'"
                                              (symbol-name base))
                                0 1) 2)
 -                     (if (eq (coding-system-type base) 2)
 -                         ;; For ISO based coding systems, prefer
 -                         ;; one that doesn't use escape sequences.
 -                         (let ((flags (coding-system-flags base)))
 -                           (if (or (consp (aref flags 0))
 -                                   (consp (aref flags 1))
 -                                   (consp (aref flags 2))
 -                                   (consp (aref flags 3)))
 -                               (if (or (aref flags 8) (aref flags 9))
 -                                   0
 -                                 1)
 -                             2))
 -                       1)))))))
 +                     (if (eq (coding-system-type base) 'iso-2022)
 +                         (let ((category (coding-system-category base)))
 +                           ;; For ISO based coding systems, prefer
 +                           ;; one that doesn't use designation nor
 +                           ;; locking/single shifting.
 +                             (cond
 +                              ((or (eq category 'coding-category-iso-8-1)
 +                                   (eq category 'coding-category-iso-8-2))
 +                               2)
 +                              ((or (eq category 'coding-category-iso-7-tight)
 +                                   (eq category 'coding-category-iso-7))
 +                               1)
 +                              (t
 +                               0)))
 +                         1)
 +                       ))))))
        (sort codings (function (lambda (x y)
                                (> (funcall func x) (funcall func y))))))))
  
  (defun find-coding-systems-region (from to)
    "Return a list of proper coding systems to encode a text between FROM and TO.
 +
  If FROM is a string, find coding systems in that instead of the buffer.
  All coding systems in the list can safely encode any multibyte characters
  in the text.
@@@ -513,38 -518,43 +513,38 @@@ element `undecided'.
  (defun find-coding-systems-for-charsets (charsets)
    "Return a list of proper coding systems to encode characters of CHARSETS.
  CHARSETS is a list of character sets.
 -It actually checks at most the first 96 characters of each charset.
 -So, if a charset of dimension two is included in CHARSETS, the value may
 -contain a coding system that can't encode all characters of the charset."
 +
 +This only finds coding systems of type `charset', whose
 +`:charset-list' property includes all of CHARSETS (plus `ascii' for
 +ascii-compatible coding systems).  It was used in older versions of
 +Emacs, but is unlikely to be what you really want now."
 +  ;; Deal with aliases.
 +  (setq charsets (mapcar (lambda (c)
 +                         (get-charset-property c :name))
 +                       charsets))
    (cond ((or (null charsets)
             (and (= (length charsets) 1)
                  (eq 'ascii (car charsets))))
         '(undecided))
        ((or (memq 'eight-bit-control charsets)
             (memq 'eight-bit-graphic charsets))
 -       '(raw-text emacs-mule))
 +       '(raw-text utf-8-emacs))
        (t
 -       (let ((codings t)
 -             charset l str)
 -         (while (and codings charsets)
 -           (setq charset (car charsets) charsets (cdr charsets))
 -           (unless (eq charset 'ascii)
 -             (setq str (make-string 96 32))
 -             (if (= (charset-dimension charset) 1)
 -                 (if (= (charset-chars charset) 96)
 -                     (dotimes (i 96)
 -                       (aset str i (make-char charset (+ i 32))))
 -                   (dotimes (i 94)
 -                     (aset str i (make-char charset (+ i 33)))))
 -               (if (= (charset-chars charset) 96)
 -                   (dotimes (i 96)
 -                     (aset str i (make-char charset 32 (+ i 32))))
 -                 (dotimes (i 94)
 -                   (aset str i (make-char charset 33 (+ i 33))))))
 -             (setq l (find-coding-systems-string str))
 -             (if (eq codings t)
 -                 (setq codings l)
 -               (let ((ll nil))
 -                 (dolist (elt codings)
 -                   (if (memq elt l)
 -                       (setq ll (cons elt ll))))
 -                 (setq codings ll)))))
 -         codings))))
 +       (let (codings)
 +         (dolist (cs (coding-system-list t))
 +           (let ((cs-charsets (and (eq (coding-system-type cs) 'charset)
 +                                   (coding-system-charset-list cs)))
 +                 (charsets charsets))
 +             (if (coding-system-get cs :ascii-compatible-p)
 +                 (add-to-list 'cs-charsets 'ascii))
 +             (if (catch 'ok
 +                   (when cs-charsets
 +                     (while charsets
 +                       (unless (memq (pop charsets) cs-charsets)
 +                         (throw 'ok nil)))
 +                     t))
 +                 (push cs codings))))
 +         (nreverse codings)))))
  
  (defun find-multibyte-characters (from to &optional maxcount excludes)
    "Find multibyte characters in the region specified by FROM and TO.
@@@ -556,42 -566,50 +556,42 @@@ wher
    COUNT is a number of characters,
    CHARs are the characters found from the character set.
  Optional 3rd arg MAXCOUNT limits how many CHARs are put in the above list.
 -Optional 4th arg EXCLUDE is a list of character sets to be ignored.
 -
 -For invalid characters, CHARs are actually strings."
 +Optional 4th arg EXCLUDE is a list of character sets to be ignored."
    (let ((chars nil)
        charset char)
      (if (stringp from)
 -      (let ((idx 0))
 -        (while (setq idx (string-match "[^\000-\177]" from idx))
 -          (setq char (aref from idx)
 -                charset (char-charset char))
 -          (if (eq charset 'unknown)
 -              (setq char (match-string 0)))
 -          (if (or (memq charset '(unknown
 -                                  eight-bit-control eight-bit-graphic))
 -                  (not (or (eq excludes t) (memq charset excludes))))
 +      (if (multibyte-string-p from)
 +          (let ((idx 0))
 +            (while (setq idx (string-match "[^\000-\177]" from idx))
 +              (setq char (aref from idx)
 +                    charset (char-charset char))
 +              (unless (memq charset excludes)
 +                (let ((slot (assq charset chars)))
 +                  (if slot
 +                      (if (not (memq char (nthcdr 2 slot)))
 +                          (let ((count (nth 1 slot)))
 +                            (setcar (cdr slot) (1+ count))
 +                            (if (or (not maxcount) (< count maxcount))
 +                                (nconc slot (list char)))))
 +                    (setq chars (cons (list charset 1 char) chars)))))
 +              (setq idx (1+ idx)))))
 +      (if enable-multibyte-characters
 +        (save-excursion
 +          (goto-char from)
 +          (while (re-search-forward "[^\000-\177]" to t)
 +            (setq char (preceding-char)
 +                  charset (char-charset char))
 +            (unless (memq charset excludes)
                (let ((slot (assq charset chars)))
                  (if slot
 -                    (if (not (memq char (nthcdr 2 slot)))
 +                    (if (not (member char (nthcdr 2 slot)))
                          (let ((count (nth 1 slot)))
                            (setcar (cdr slot) (1+ count))
                            (if (or (not maxcount) (< count maxcount))
                                (nconc slot (list char)))))
 -                  (setq chars (cons (list charset 1 char) chars)))))
 -          (setq idx (1+ idx))))
 -      (save-excursion
 -      (goto-char from)
 -      (while (re-search-forward "[^\000-\177]" to t)
 -        (setq char (preceding-char)
 -              charset (char-charset char))
 -        (if (eq charset 'unknown)
 -            (setq char (match-string 0)))
 -        (if (or (memq charset '(unknown eight-bit-control eight-bit-graphic))
 -                (not (or (eq excludes t) (memq charset excludes))))
 -            (let ((slot (assq charset chars)))
 -              (if slot
 -                  (if (not (member char (nthcdr 2 slot)))
 -                      (let ((count (nth 1 slot)))
 -                        (setcar (cdr slot) (1+ count))
 -                        (if (or (not maxcount) (< count maxcount))
 -                            (nconc slot (list char)))))
 -                (setq chars (cons (list charset 1 char) chars))))))))
 +                  (setq chars (cons (list charset 1 char) chars)))))))))
      (nreverse chars)))
  
 -
  (defun search-unencodable-char (coding-system)
    "Search forward from point for a character that is not encodable.
  It asks which coding system to check.
@@@ -611,6 -629,7 +611,6 @@@ or nil if all characters are encodable.
        (message "All following characters are encodable by %s" coding-system))
      pos))
  
 -
  (defvar last-coding-system-specified nil
    "Most recent coding system explicitly specified by the user when asked.
  This variable is set whenever Emacs asks the user which coding system
@@@ -661,9 -680,8 +661,9 @@@ DEFAULT is the coding system to use by 
    (let ((l codings)
        mime-charset)
      (while l
 -      (setq mime-charset (coding-system-get (car l) 'mime-charset))
 -      (if (and mime-charset (coding-system-p mime-charset))
 +      (setq mime-charset (coding-system-get (car l) :mime-charset))
 +      (if (and mime-charset (coding-system-p mime-charset)
 +             (coding-system-equal (car l) mime-charset))
          (setcar l mime-charset))
        (setq l (cdr l))))
  
@@@ -770,10 -788,10 +770,10 @@@ e.g., for sending an email message.\n "
                                          (car coding)))))
                    (setq i (1+ i))))
                (insert "\n"))
-             (insert "\
+             (insert (substitute-command-keys "\
  
- Click on a character to jump to the place it appears,\n"
                    (substitute-command-keys "\
+ Click on a character (or switch to this window by `\\[other-window]'\n\
and select the characters by RET) to jump to the place it appears,\n\
  where `\\[universal-argument] \\[what-cursor-position]' will give information about it.\n"))))
          (insert (substitute-command-keys "\nSelect \
  one of the safe coding systems listed below,\n\
@@@ -914,11 -932,13 +914,11 @@@ It is highly recommended to fix it befo
  
        ;; If the most preferred coding system has the property mime-charset,
        ;; append it to the defaults.
 -      (let ((tail coding-category-list)
 -          preferred base)
 -      (while (and tail (not (setq preferred (symbol-value (car tail)))))
 -        (setq tail (cdr tail)))
 +      (let ((preferred (coding-system-priority-list t))
 +          base)
        (and (coding-system-p preferred)
             (setq base (coding-system-base preferred))
 -           (coding-system-get preferred 'mime-charset)
 +           (coding-system-get preferred :mime-charset)
             (not (rassq base default-coding-system))
             (setq default-coding-system
                   (append default-coding-system
  
        ;; Classify the defaults into safe, rejected, and unsafe.
        (dolist (elt default-coding-system)
 -        (if (memq (cdr elt) codings)
 +        (if (or (eq (car codings) 'undecided)
 +                (memq (cdr elt) codings))
              (if (and (functionp accept-default-p)
                       (not (funcall accept-default-p (cdr elt))))
                  (push (car elt) rejected)
@@@ -1035,10 -1054,19 +1035,10 @@@ it asks the user to select a proper cod
        ;; We should never use no-conversion for outgoing mail.
        (setq coding nil))
      (if (fboundp select-safe-coding-system-function)
 -      (setq coding
 -            (funcall select-safe-coding-system-function
 -                     (point-min) (point-max) coding
 -                     (function (lambda (x)
 -                                 (coding-system-get x 'mime-charset))))))
 -    (if coding
 -      ;; Be sure to use LF for end-of-line.
 -      (setq coding (coding-system-change-eol-conversion coding 'unix))
 -      ;; No coding system is decided.  Usually this is the case that
 -      ;; the current buffer contains only ASCII.  So, we hope
 -      ;; iso-8859-1 works.
 -      (setq coding 'iso-8859-1-unix))
 -    coding))
 +      (funcall select-safe-coding-system-function
 +               (point-min) (point-max) coding
 +               (function (lambda (x) (coding-system-get x :mime-charset))))
 +      coding)))
  \f
  ;;; Language support stuff.
  
@@@ -1053,8 -1081,8 +1053,8 @@@ Meaningful values for KEY includ
  
    documentation      value is documentation of what this language environment
                        is meant for, and how to use it.
 -  charset          value is a list of the character sets used by this
 -                      language environment.
 +  charset          value is a list of the character sets mainly used
 +                      by this language environment.
    sample-text      value is an expression which is evalled to generate
                          a line of text written using characters appropriate
                          for this language environment.
                        This is used to set up the coding system priority
                        list when you switch to this language environment.
    nonascii-translation
 -                   value is a translation table to be set in the
 -                      variable `nonascii-translation-table' in this
 -                      language environment, or a character set from
 -                      which `nonascii-insert-offset' is calculated.
 +                   value is a charset of dimension one to use for
 +                      converting a unibyte character to multibyte
 +                      and vice versa.
    input-method       value is a default input method for this language
                        environment.
    features           value is a list of features requested in this
@@@ -1089,6 -1118,10 +1089,6 @@@ The following keys take effect only whe
  globally disabled, i.e. the value of `default-enable-multibyte-characters'
  is nil.
  
 -  unibyte-syntax     value is a library name to load to set
 -                      unibyte 8-bit character syntaxes for this
 -                      language environment.
 -
    unibyte-display    value is a coding system to encode characters
                        for the terminal.  Characters in the range
                        of 160 to 255 display not as octal escapes,
@@@ -1120,14 -1153,15 +1120,14 @@@ see `language-info-alist'.
    (set-language-info-internal lang-env key info)
    (if (equal lang-env current-language-environment)
        (cond ((eq key 'coding-priority)
 -           (set-language-environment-coding-systems lang-env))
 +           (set-language-environment-coding-systems lang-env)
 +           (set-language-environment-charset lang-env))
            ((eq key 'input-method)
             (set-language-environment-input-method lang-env))
            ((eq key 'nonascii-translation)
             (set-language-environment-nonascii-translation lang-env))
            ((eq key 'charset)
             (set-language-environment-charset lang-env))
 -          ((eq key 'overriding-fontspec)
 -           (set-language-environment-fontset lang-env))
            ((and (not default-enable-multibyte-characters)
                  (or (eq key 'unibyte-syntax) (eq key 'unibyte-display)))
             (set-language-environment-unibyte lang-env)))))
@@@ -1496,8 -1530,6 +1496,8 @@@ which marks the variable `default-input
          (when interactive
            (customize-mark-as-set 'default-input-method)))))))
  
 +(eval-when-compile (autoload 'help-buffer "help-mode"))
 +
  (defun describe-input-method (input-method)
    "Describe input method INPUT-METHOD."
    (interactive
@@@ -1597,26 -1629,20 +1597,26 @@@ See also the variable `input-method-ver
    :type 'boolean
    :group 'mule)
  
 -(defvar input-method-activate-hook nil
 +(defcustom input-method-activate-hook nil
    "Normal hook run just after an input method is activated.
  
  The variable `current-input-method' keeps the input method name
 -just activated.")
 +just activated."
 +  :type 'hook
 +  :group 'mule)
  
 -(defvar input-method-inactivate-hook nil
 +(defcustom input-method-inactivate-hook nil
    "Normal hook run just after an input method is inactivated.
  
  The variable `current-input-method' still keeps the input method name
 -just inactivated.")
 +just inactivated."
 +  :type 'hook
 +  :group 'mule)
  
 -(defvar input-method-after-insert-chunk-hook nil
 -  "Normal hook run just after an input method insert some chunk of text.")
 +(defcustom input-method-after-insert-chunk-hook nil
 +  "Normal hook run just after an input method insert some chunk of text."
 +  :type 'hook
 +  :group 'mule)
  
  (defvar input-method-exit-on-first-char nil
    "This flag controls when an input method returns.
@@@ -1625,14 -1651,12 +1625,14 @@@ that it may find a different translatio
  But, it this flag is non-nil, the input method returns as soon as
  the current key sequence gets long enough to have some valid translation.")
  
 -(defvar input-method-use-echo-area nil
 +(defcustom input-method-use-echo-area nil
    "This flag controls how an input method shows an intermediate key sequence.
  Usually, the input method inserts the intermediate key sequence,
  or candidate translations corresponding to the sequence,
  at point in the current buffer.
 -But, if this flag is non-nil, it displays them in echo area instead.")
 +But, if this flag is non-nil, it displays them in echo area instead."
 +  :type 'hook
 +  :group 'mule)
  
  (defvar input-method-exit-on-invalid-key nil
    "This flag controls the behavior of an input method on invalid key input.
@@@ -1642,25 -1666,21 +1642,25 @@@ input method temporarily.  After that k
  But, if this flag is non-nil, the input method is never back on.")
  
  \f
 -(defvar set-language-environment-hook nil
 +(defcustom set-language-environment-hook nil
    "Normal hook run after some language environment is set.
  
  When you set some hook function here, that effect usually should not
  be inherited to another language environment.  So, you had better set
  another function in `exit-language-environment-hook' (which see) to
 -cancel the effect.")
 +cancel the effect."
 +  :type 'hook
 +  :group 'mule)
  
 -(defvar exit-language-environment-hook nil
 +(defcustom exit-language-environment-hook nil
    "Normal hook run after exiting from some language environment.
  When this hook is run, the variable `current-language-environment'
  is still bound to the language environment being exited.
  
  This hook is mainly used for canceling the effect of
 -`set-language-environment-hook' (which-see).")
 +`set-language-environment-hook' (which-see)."
 +  :type 'hook
 +  :group 'mule)
  
  (put 'setup-specified-language-environment 'apropos-inhibit t)
  
@@@ -1710,26 -1730,64 +1710,26 @@@ The default status is as follows
    The default value for the command `set-terminal-coding-system' is nil.
    The default value for the command `set-keyboard-coding-system' is nil.
  
 -  The order of priorities of coding categories and the coding system
 -  bound to each category are as follows
 -      coding category                 coding system
 -      --------------------------------------------------
 -      coding-category-iso-8-1         iso-latin-1
 -      coding-category-iso-8-2         iso-latin-1
 -      coding-category-utf-8           mule-utf-8
 -      coding-category-utf-16-be       mule-utf-16be-with-signature
 -      coding-category-utf-16-le       mule-utf-16le-with-signature
 -      coding-category-iso-7-tight     iso-2022-jp
 -      coding-category-iso-7           iso-2022-7bit
 -      coding-category-iso-7-else      iso-2022-7bit-lock
 -      coding-category-iso-8-else      iso-2022-8bit-ss2
 -      coding-category-emacs-mule      emacs-mule
 -      coding-category-raw-text        raw-text
 -      coding-category-sjis            japanese-shift-jis
 -      coding-category-big5            chinese-big5
 -      coding-category-ccl             nil
 -      coding-category-binary          no-conversion"
 +  The order of priorities of coding systems are as follows:
 +      utf-8
 +      iso-2022-7bit
 +      iso-latin-1
 +      iso-2022-7bit-lock
 +      iso-2022-8bit-ss2
 +      emacs-mule
 +      raw-text"
    (interactive)
    ;; This function formerly set default-enable-multibyte-characters to t,
    ;; but that is incorrect.  It should not alter the unibyte/multibyte choice.
  
 -  (setq coding-category-iso-7-tight   'iso-2022-jp
 -      coding-category-iso-7           'iso-2022-7bit
 -      coding-category-iso-8-1         'iso-latin-1
 -      coding-category-iso-8-2         'iso-latin-1
 -      coding-category-iso-7-else      'iso-2022-7bit-lock
 -      coding-category-iso-8-else      'iso-2022-8bit-ss2
 -      coding-category-emacs-mule      'emacs-mule
 -      coding-category-raw-text        'raw-text
 -      coding-category-sjis            'japanese-shift-jis
 -      coding-category-big5            'chinese-big5
 -      coding-category-utf-16-be       'mule-utf-16be-with-signature
 -      coding-category-utf-16-le       'mule-utf-16le-with-signature
 -      coding-category-utf-8           'mule-utf-8
 -      coding-category-ccl             nil
 -      coding-category-binary          'no-conversion)
 -
 -  (set-coding-priority
 -   '(coding-category-iso-8-1
 -     coding-category-iso-8-2
 -     coding-category-utf-8
 -     coding-category-utf-16-be
 -     coding-category-utf-16-le
 -     coding-category-iso-7-tight
 -     coding-category-iso-7
 -     coding-category-iso-7-else
 -     coding-category-iso-8-else
 -     coding-category-emacs-mule
 -     coding-category-raw-text
 -     coding-category-sjis
 -     coding-category-big5
 -     coding-category-ccl
 -     coding-category-binary))
 -
 -  ;; Changing the binding of a coding category requires this call.
 -  (update-coding-systems-internal)
 +  (set-coding-system-priority
 +   'utf-8
 +   'iso-2022-7bit
 +   'iso-latin-1
 +   'iso-2022-7bit-lock
 +   'iso-2022-8bit-ss2
 +   'emacs-mule
 +   'raw-text)
  
    (set-default-coding-systems nil)
    (setq default-sendmail-coding-system 'iso-latin-1)
    ;; (set-terminal-coding-system-internal nil)
    ;; (set-keyboard-coding-system-internal nil)
  
 -  (setq nonascii-translation-table nil
 -      nonascii-insert-offset 0)
 -
 -  ;; Don't invoke fontset-related functions if fontsets aren't
 -  ;; supported in this build of Emacs.
 -  (and (fboundp 'fontset-list)
 -       (set-overriding-fontspec-internal nil)))
 +  (set-unibyte-charset 'iso-8859-1))
  
  (reset-language-environment)
  
@@@ -1820,6 -1884,7 +1820,6 @@@ specifies the character set for the maj
    (set-language-environment-input-method language-name)
    (set-language-environment-nonascii-translation language-name)
    (set-language-environment-charset language-name)
 -  (set-language-environment-fontset language-name)
    ;; Unibyte setups if necessary.
    (unless default-enable-multibyte-characters
      (set-language-environment-unibyte language-name))
    (run-hooks 'set-language-environment-hook)
    (force-mode-line-update t))
  
 +(define-widget 'charset 'symbol
 +  "An Emacs charset."
 +  :tag "Charset"
 +  :complete-function (lambda ()
 +                     (interactive)
 +                     (lisp-complete-symbol 'charsetp))
 +  :completion-ignore-case t
 +  :value 'ascii
 +  :validate (lambda (widget)
 +            (unless (charsetp (widget-value widget))
 +              (widget-put widget :error (format "Invalid charset: %S"
 +                                                (widget-value widget)))
 +              widget))
 +  :prompt-history 'charset-history)
 +
 +(defcustom language-info-custom-alist nil
 +  "Customizations of language environment parameters.
 +Value is an alist with elements like those of `language-info-alist'.
 +These are used to set values in `language-info-alist' which replace
 +the defaults.  A typical use is replacing the default input method for
 +the environment.  Use \\[describe-language-environment] to find the environment's settings.
 +
 +This option is intended for use at startup.  Removing items doesn't
 +remove them from the language info until you next restart Emacs.
 +
 +Setting this variable directly does not take effect.  See
 +`set-language-info-alist' for use in programs."
 +  :group 'mule
 +  :version "23.1"
 +  :set (lambda (s v)
 +       (custom-set-default s v)
 +       ;; Can't do this before language environments are set up.
 +       (when v
 +         ;; modify language-info-alist
 +         (dolist (elt v)
 +           (set-language-info-alist (car elt) (cdr elt)))
 +         ;; re-set the environment in case its parameters changed
 +         (set-language-environment current-language-environment)))
 +  :type `(alist
 +        :key-type (string :tag "Language environment"
 +                          :completion-ignore-case t
 +                          :complete-function widget-string-complete
 +                          :completion-alist language-info-alist)
 +        :value-type
 +        (alist :key-type symbol
 +               :options ((documentation string)
 +                         (charset (repeat charset))
 +                         (sample-text string)
 +                         (setup-function function)
 +                         (exit-function function)
 +                         (coding-system (repeat coding-system))
 +                         (coding-priority (repeat coding-system))
 +                         (nonascii-translation charset)
 +                         (input-method
 +                          (string
 +                           :completion-ignore-case t
 +                           :complete-function widget-string-complete
 +                           :completion-alist input-method-alist
 +                           :prompt-history input-method-history))
 +                         (features (repeat symbol))
 +                         (unibyte-display coding-system)))))
 +
  (defun standard-display-european-internal ()
    ;; Actually set up direct output of non-ASCII characters.
    (standard-display-8bit (if (eq window-system 'pc) 128 160) 255)
    (let* ((priority (get-language-info language-name 'coding-priority))
         (default-coding (car priority))
         (eol-type (coding-system-eol-type default-buffer-file-coding-system)))
 -    (if priority
 -      (let ((categories (mapcar 'coding-system-category priority)))
 -        (set-default-coding-systems
 -         (if (memq eol-type '(0 1 2 unix dos mac))
 -             (coding-system-change-eol-conversion default-coding eol-type)
 -           default-coding))
 -        (setq default-sendmail-coding-system default-coding)
 -        (set-coding-priority categories)
 -        (while priority
 -          (set (car categories) (car priority))
 -          (setq priority (cdr priority) categories (cdr categories)))
 -        ;; Changing the binding of a coding category requires this call.
 -        (update-coding-systems-internal)))))
 +    (when priority
 +      (set-default-coding-systems
 +       (if (memq eol-type '(0 1 2 unix dos mac))
 +         (coding-system-change-eol-conversion default-coding eol-type)
 +       default-coding))
 +      (setq default-sendmail-coding-system default-coding)
 +      (apply 'set-coding-system-priority priority))))
  
  (defun set-language-environment-input-method (language-name)
    "Do various input method setups for language environment LANGUAGE-NAME."
  
  (defun set-language-environment-nonascii-translation (language-name)
    "Do unibyte/multibyte translation setup for language environment LANGUAGE-NAME."
 -  (let ((nonascii (get-language-info language-name 'nonascii-translation))
 -      (dos-table
 -       (if (eq window-system 'pc)
 -           (intern
 -            (format "cp%d-nonascii-translation-table" dos-codepage)))))
 -    (cond
 -     ((char-table-p nonascii)
 -      (setq nonascii-translation-table nonascii))
 -     ((and (eq window-system 'pc) (boundp dos-table))
 -      ;; DOS terminals' default is to use a special non-ASCII translation
 -      ;; table as appropriate for the installed codepage.
 -      (setq nonascii-translation-table (symbol-value dos-table)))
 -     ((charsetp nonascii)
 -      (setq nonascii-insert-offset (- (make-char nonascii) 128))))))
 +  ;; Note: For DOS, we assumed that the charset cpXXX is already
 +  ;; defined.
 +  (let ((nonascii (get-language-info language-name 'nonascii-translation)))
 +    (if (eq window-system 'pc)
 +      (setq nonascii (intern "cp%d" dos-codepage)))
 +    (or (and (charsetp nonascii)
 +           (get-charset-property nonascii :ascii-compatible-p))
 +      (setq nonascii 'iso-8859-1))
 +    (set-unibyte-charset nonascii)))
  
  (defun set-language-environment-charset (language-name)
    "Do various charset setups for language environment LANGUAGE-NAME."
 -  (if (and utf-translate-cjk-mode
 -         (not (eq utf-translate-cjk-lang-env language-name))
 -         (catch 'tag
 -           (dolist (charset (get-language-info language-name 'charset))
 -             (if (memq charset utf-translate-cjk-charsets)
 -                 (throw 'tag t)))
 -           nil))
 -      (utf-translate-cjk-load-tables)))
 -
 -(defun set-language-environment-fontset (language-name)
 -  "Do various fontset setups for language environment LANGUAGE-NAME."
 -  ;; Don't invoke fontset-related functions if fontsets aren't
 -  ;; supported in this build of Emacs.
 -  (if (fboundp 'fontset-list)
 -      (set-overriding-fontspec-internal
 -       (get-language-info language-name 'overriding-fontspec))))
 +  ;; Put higher priorities to such charsets that are supported by the
 +  ;; coding systems of higher priorities in this environment.
 +  (let ((charsets (get-language-info language-name 'charset)))
 +    (dolist (coding (get-language-info language-name 'coding-priority))
 +      (setq charsets (append charsets (coding-system-charset-list coding))))
 +    (if charsets
 +      (apply 'set-charset-priority charsets))))
  
  (defun set-language-environment-unibyte (language-name)
    "Do various unibyte-mode setups for language environment LANGUAGE-NAME."
 -  ;; Syntax and case table.
 -  (let ((syntax (get-language-info language-name 'unibyte-syntax)))
 -    (if syntax
 -      (let ((set-case-syntax-set-multibyte nil))
 -        (load syntax nil t))
 -      ;; No information for syntax and case.  Reset to the defaults.
 -      (let ((syntax-table (standard-syntax-table))
 -          (standard-table (standard-case-table))
 -          (case-table (make-char-table 'case-table))
 -          (ch (if (eq window-system 'pc) 128 160)))
 -      (while (< ch 256)
 -        (modify-syntax-entry ch " " syntax-table)
 -        (setq ch (1+ ch)))
 -      (dotimes (i 128)
 -        (aset case-table i (aref standard-table i)))
 -      (set-char-table-extra-slot case-table 0 nil)
 -      (set-char-table-extra-slot case-table 1 nil)
 -      (set-char-table-extra-slot case-table 2 nil)
 -      (set-standard-case-table case-table))
 -      (let ((list (buffer-list)))
 -      (while list
 -        (with-current-buffer (car list)
 -          (set-case-table (standard-case-table)))
 -        (setq list (cdr list))))))
    (set-display-table-and-terminal-coding-system language-name))
  
  (defsubst princ-list (&rest args)
            (setq l (cons input-method (delete input-method l))))
          (insert ":\n")
          (while l
 -          (when (string= language-name (nth 1 (car l)))
 +          (when (eq t (compare-strings language-name nil nil
 +                                       (nth 1 (car l)) nil nil t))
              (insert "  " (car (car l)))
              (search-backward (car (car l)))
              (help-xref-button 0 'help-input-method (car (car l)))
                      "' in mode line):\n\t"
                      (coding-system-doc-string (car l))
                      "\n")
 -            (let ((aliases (coding-system-get (car l)
 -                                              'alias-coding-systems)))
 +            (let ((aliases (coding-system-aliases (car l))))
                (when aliases
                  (insert "\t(alias:")
                  (while aliases
      ("so_ET" "UTF-8") ; Somali
      ("so" "Latin-1") ; Somali
      ("sq" . "Latin-1") ; Albanian
 -    ("sr_YU@cyrillic" . "Cyrillic-ISO")       ; Serbian (Cyrillic alphabet)
      ("sr" . "Latin-2") ; Serbian (Latin alphabet)
      ; ss Siswati
      ("st" . "Latin-1") ;  Sesotho
      ; yo Yoruba
      ; za Zhuang
      ("zh_HK" . "Chinese-Big5")
 +    ; zh_HK/BIG5-HKSCS \
      ("zh_TW" . "Chinese-Big5")
 +    ("zh_CN.GB2312" "Chinese-GB")
 +    ("zh_CN.GBK" "Chinese-GBK")
 +    ("zh_CN.GB18030" "Chinese-GB18030")
 +    ("zh_CN.UTF-8" . "Chinese-GBK")
      ("zh_CN" . "Chinese-GB")
      ("zh" . "Chinese-GB")
 -    ; zh_CN.GB18030/GB18030 \
 -    ; zh_CN.GBK/GBK \
 -    ; zh_HK/BIG5-HKSCS \
      ("zu" . "Latin-1") ; Zulu
  
      ;; ISO standard locales
      ("sp" . "Cyrillic-ISO") ; Serbian (Cyrillic alphabet), e.g. X11R6.4
      ("su" . "Latin-1") ; Finnish, e.g. Solaris 2.6
      ("jp" . "Japanese") ; e.g. MS Windows
 -    ("chs" . "Chinese-GB") ; MS Windows Chinese Simplified
 +    ("chs" . "Chinese-GBK") ; MS Windows Chinese Simplified
      ("cht" . "Chinese-BIG5") ; MS Windows Chinese Traditional
      ("gbz" . "UTF-8") ; MS Windows Dari Persian
      ("div" . "UTF-8") ; MS Windows Divehi (Maldives)
@@@ -2344,13 -2390,14 +2344,13 @@@ This language name is used if the local
       ("koi8-?r" . koi8-r)
       ("koi8-?u" . koi8-u)
       ("tcvn" . tcvn)
 +     ("big5[-_]?hkscs" . big5-hkscs)
       ("big5" . big5)
       ("euc-?tw" . euc-tw)
 -     ;; We don't support GBK, but as it is upper compatible with
 -     ;; GB-2312, we setup the default coding system to gb2312.
 -     ("gbk" . gb2312)
 -     ;; We don't support BIG5-HKSCS, but as it is upper compatible with
 -     ;; BIG5, we setup the default coding system to big5.
 -     ("big5hkscs" . big5)
 +     ("euc-?cn" .euc-cn)
 +     ("gb2312" . gb2312)
 +     ("gbk" . gbk)
 +     ("gb18030" . gb18030)
       ("ja.*[._]euc" . japanese-iso-8bit)
       ("ja.*[._]jis7" . iso-2022-jp)
       ("ja.*[._]pck" . japanese-shift-jis)
@@@ -2477,7 -2524,6 +2477,7 @@@ See also `locale-charset-language-names
        ;; using the translation file that many systems have.
        (when locale-translation-file-name
        (with-temp-buffer
 +        (set-buffer-multibyte nil)
          (insert-file-contents locale-translation-file-name)
          (when (re-search-forward
                 (concat "^" (regexp-quote locale) ":?[ \t]+") nil t)
          ;; Fixme: perhaps prefer-coding-system should set this too.
          ;; But it's not the time to do such a fundamental change.
          (setq default-sendmail-coding-system coding-system)
 -        (setq locale-coding-system coding-system))))
 +        (setq locale-coding-system coding-system))
 +
 +      (when (get-language-info current-language-environment 'coding-priority)
 +        (let ((codeset (locale-info 'codeset))
 +              (coding-system (car (coding-system-priority-list))))
 +          (when codeset
 +            (let ((cs (coding-system-aliases coding-system))
 +                  result)
 +              (while (and cs (not result))
 +                (setq result
 +                      (locale-charset-match-p (symbol-name (pop cs))
 +                                              (locale-info 'codeset))))
 +              (unless result
 +                (message "Warning: Default coding system `%s' disagrees with
 +system codeset `%s' for this locale." coding-system codeset))))))))
  
      ;; On Windows, override locale-coding-system,
      ;; keyboard-coding-system with system codepage.  Note:
                    'a4))))))
    nil)
  \f
 -;;; Charset property
 -
 -(defun get-charset-property (charset propname)
 -  "Return the value of CHARSET's PROPNAME property.
 -This is the last value stored with
 - (put-charset-property CHARSET PROPNAME VALUE)."
 -  (and (not (eq charset 'composition))
 -       (plist-get (charset-plist charset) propname)))
 -
 -(defun put-charset-property (charset propname value)
 -  "Store CHARSETS's PROPNAME property with value VALUE.
 -It can be retrieved with `(get-charset-property CHARSET PROPNAME)'."
 -  (or (eq charset 'composition)
 -      (set-charset-plist charset
 -                       (plist-put (charset-plist charset) propname value))))
 +;;; Character property
 +
 +;; Each element has the form (PROP . TABLE).
 +;; PROP is a symbol representing a character property.
 +;; TABLE is a char-table containing the property value for each character.
 +;; TABLE may be a name of file to load to build a char-table.
 +;; Don't modify this variable directly but use `define-char-code-property'.
 +
 +(defvar char-code-property-alist nil
 +  "Alist of character property name vs char-table containing property values.
 +Internal use only.")
 +
 +(put 'char-code-property-table 'char-table-extra-slots 5)
 +
 +(defun define-char-code-property (name table &optional docstring)
 +  "Define NAME as a character code property given by TABLE.
 +TABLE is a char-table of purpose `char-code-property-table' with
 +these extra slots:
 +  1st: NAME.
 +  2nd: Function to call to get a property value of a character.
 +    It is called with three arugments CHAR, VAL, and TABLE, where
 +    CHAR is a character, VAL is the value of (aref TABLE CHAR).
 +  3rd: Function to call to put a property value of a character.
 +    It is called with the same arguments as above.
 +  4th: Function to call to get a description string of a property value.
 +    It is called with one argument VALUE, a property value.
 +  5th: Data used by the above functions.
 +
 +TABLE may be a name of file to load to build a char-table.  The
 +file should contain a call of `define-char-code-property' with a
 +char-table of the above format as the argument TABLE.
 +
 +TABLE may also be nil, in which case no property value is pre-assigned.
 +
 +Optional 3rd argment DOCSTRING is a documentation string of the property.
  
 -;;; Character code property
 -(put 'char-code-property-table 'char-table-extra-slots 0)
 +See also the documentation of `get-char-code-property' and
 +`put-char-code-property'."
 +  (or (symbolp name)
 +      (error "Not a symbol: %s" name))
 +  (if (char-table-p table)
 +      (or (and (eq (char-table-subtype table) 'char-code-property-table)
 +             (eq (char-table-extra-slot table 0) name))
 +        (error "Invalid char-table: %s" table))
 +    (or (stringp table)
 +      (error "Not a char-table nor a file name: %s" table)))
 +  (let ((slot (assq name char-code-property-alist)))
 +    (if slot
 +      (setcdr slot table)
 +      (setq char-code-property-alist
 +          (cons (cons name table) char-code-property-alist))))
 +  (put name 'char-code-property-documentation docstring))
  
  (defvar char-code-property-table
    (make-char-table 'char-code-property-table)
    "Char-table containing a property list of each character code.
 -
 +This table is used for properties not listed in `char-code-property-alist'.
  See also the documentation of `get-char-code-property' and
  `put-char-code-property'.")
  
  (defun get-char-code-property (char propname)
 -  "Return the value of CHAR's PROPNAME property in `char-code-property-table'."
 -  (let ((plist (aref char-code-property-table char)))
 -    (if (listp plist)
 -      (car (cdr (memq propname plist))))))
 +  "Return the value of CHAR's PROPNAME property."
 +  (let ((slot (assq propname char-code-property-alist)))
 +    (if slot
 +      (let (table value func)
 +        (if (stringp (cdr slot))
 +            (load (cdr slot)))
 +        (setq table (cdr slot)
 +              value (aref table char)
 +              func (char-table-extra-slot table 1))
 +        (if (functionp func)
 +            (setq value (funcall func char value table)))
 +        value)
 +      (plist-get (aref char-code-property-table char) propname))))
  
  (defun put-char-code-property (char propname value)
 -  "Store CHAR's PROPNAME property with VALUE in `char-code-property-table'.
 +  "Store CHAR's PROPNAME property with VALUE.
  It can be retrieved with `(get-char-code-property CHAR PROPNAME)'."
 -  (let ((plist (aref char-code-property-table char)))
 -    (if plist
 -      (let ((slot (memq propname plist)))
 -        (if slot
 -            (setcar (cdr slot) value)
 -          (nconc plist (list propname value))))
 -      (aset char-code-property-table char (list propname value)))))
 +  (let ((slot (assq propname char-code-property-alist)))
 +    (if slot
 +      (let (table func)
 +        (if (stringp (cdr slot))
 +            (load (cdr slot)))
 +        (setq table (cdr slot)
 +              func (char-table-extra-slot table 2))
 +        (if (functionp func)
 +            (funcall func char value table)
 +          (aset table char value)))
 +      (let* ((plist (aref char-code-property-table char))
 +           (x (plist-put plist propname value)))
 +      (or (eq x plist)
 +          (aset char-code-property-table char x))))
 +    value))
 +
 +(defun char-code-property-description (prop value)
 +  "Return a description string of character property PROP's value VALUE.
 +If there's no description string for VALUE, return nil."
 +  (let ((slot (assq prop char-code-property-alist)))
 +    (if slot
 +      (let (table func)
 +        (if (stringp (cdr slot))
 +            (load (cdr slot)))
 +        (setq table (cdr slot)
 +              func (char-table-extra-slot table 3))
 +        (if (functionp func)
 +            (funcall func value))))))
  
  \f
  ;; Pretty description of encoded string
    "Return a pretty description of STR that is encoded by CODING-SYSTEM."
    (setq str (string-as-unibyte str))
    (mapconcat
 -   (if (and coding-system (eq (coding-system-type coding-system) 2))
 +   (if (and coding-system (eq (coding-system-type coding-system) 'iso-2022))
         ;; Try to get a pretty description for ISO 2022 escape sequences.
         (function (lambda (x) (or (cdr (assq x iso-2022-control-alist))
                                 (format "#x%02X" x))))
  (defun encode-coding-char (char coding-system)
    "Encode CHAR by CODING-SYSTEM and return the resulting string.
  If CODING-SYSTEM can't safely encode CHAR, return nil."
 -  (let ((str1 (string-as-multibyte (char-to-string char)))
 -      (str2 (string-as-multibyte (make-string 2 char)))
 -      (safe-chars (and coding-system
 -                       (coding-system-get coding-system 'safe-chars)))
 -      (charset (char-charset char))
 +  (let ((str1 (string-as-multibyte (string char)))
 +      (str2 (string-as-multibyte (string char char)))
        enc1 enc2 i1 i2)
 -    (when (or (eq safe-chars t)
 -            (eq charset 'ascii)
 -            (and safe-chars (aref safe-chars char)))
 +    (when (memq (coding-system-base coding-system)
 +              (find-coding-systems-string str1))
        ;; We must find the encoded string of CHAR.  But, just encoding
        ;; CHAR will put extra control sequences (usually to designate
        ;; ASCII charset) at the tail if type of CODING is ISO 2022.
        ;; exclude.
        (substring enc2 0 i2))))
  
 +;; Backwards compatibility.  These might be better with :init-value t,
 +;; but that breaks loadup.
 +(define-minor-mode unify-8859-on-encoding-mode
 +  "Obsolete."
 +  :group 'mule
 +  :global t)
 +(define-minor-mode unify-8859-on-decoding-mode
 +  "Obsolete."
 +  :group 'mule
 +  :global t)
 +
 +(defvar nonascii-insert-offset 0 "This variable is obsolete.")
 +(defvar nonascii-translation-table nil "This variable is obsolete.")
 +
 +(defun ucs-insert (arg)
 +  "Insert a character of the given Unicode code point.
 +Interactively, prompts for a hex string giving the code."
 +  (interactive "sUnicode (hex): ")
 +  (or (integerp arg)
 +      (setq arg (string-to-number arg 16)))
 +  (if (or (< arg 0) (> arg #x10FFFF))
 +      (error "Not a Unicode character code: 0x%X" arg))
 +  (insert arg))
 +
  
  ;; arch-tag: b382c432-4b36-460e-bf4c-05efd0bb18dc
  ;;; mule-cmds.el ends here
index e10f776b33aef14d140101f138400707798d0fb2,05f259b038fac914dd77caa60e17f4372f9ec376..bf224c9d8136f8521dd2618a5c526b82ce3dcda5
@@@ -1,15 -1,12 +1,15 @@@
 -;;; mule-conf.el --- configure multilingual environment -*- no-byte-compile: t -*-
 +;;; mule-conf.el --- configure multilingual environment
  
  ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- ;;   2004, 2005, 2006  Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;;   2004, 2005, 2006, 2007  Free Software Foundation, Inc.
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
 -;; Keywords: mule, multilingual, character set, coding system
 +;; Keywords: i18n, mule, multilingual, character set, coding system
  
  ;; This file is part of GNU Emacs.
  
  
  ;;; Commentary:
  
 -;; Don't byte-compile this file.
 +;; This file defines the Emacs charsets and some basic coding systems.
 +;; Other coding systems are defined in the files in directory
 +;; lisp/language.
  
  ;;; Code:
  
 +;;; Remarks
 +
 +;; The ISO-IR registry is at http://www.itscj.ipsj.or.jp/ISO-IR/.
 +;; Standards docs equivalent to iso-2022 and iso-8859 are at
 +;; http://www.ecma.ch/.
 +
 +;; FWIW, http://www.microsoft.com/globaldev/ lists the following for
 +;; MS Windows, which are presumably the only charsets we really need
 +;; to worry about on such systems:
 +;; `OEM codepages': 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866
 +;; `Windows codepages': 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257,
 +;;                      1258, 874, 932, 936, 949, 950
 +
  ;;; Definitions of character sets.
  
 -;; Basic (official) character sets.  These character sets are treated
 -;; efficiently with respect to buffer memory.
 -
 -;; Syntax:
 -;; (define-charset CHARSET-ID CHARSET
 -;;   [ DIMENSION CHARS WIDTH DIRECTION ISO-FINAL-CHAR ISO-GRAPHIC-PLANE
 -;;     SHORT-NAME LONG-NAME DESCRIPTION ])
 -;; ASCII charset is defined in src/charset.c as below.
 -;; (define-charset 0 ascii
 -;;    [1 94 1 0 ?B 0 "ASCII" "ASCII" "ASCII (ISO646 IRV)"])
 -
 -;; 1-byte charsets.  Valid range of CHARSET-ID is 128..143.
 -
 -;; CHARSET-ID 128 is not used.
 -
 -(define-charset 129 'latin-iso8859-1
 -  [1 96 1 0 ?A 1 "RHP of Latin-1" "RHP of Latin-1 (ISO 8859-1): ISO-IR-100"
 -     "Right-Hand Part of Latin Alphabet 1 (ISO/IEC 8859-1): ISO-IR-100."])
 -(define-charset 130 'latin-iso8859-2
 -  [1 96 1 0 ?B 1 "RHP of Latin-2" "RHP of Latin-2 (ISO 8859-2): ISO-IR-101"
 -     "Right-Hand Part of Latin Alphabet 2 (ISO/IEC 8859-2): ISO-IR-101."])
 -(define-charset 131 'latin-iso8859-3
 -  [1 96 1 0 ?C 1 "RHP of Latin-3" "RHP of Latin-3 (ISO 8859-3): ISO-IR-109"
 -     "Right-Hand Part of Latin Alphabet 3 (ISO/IEC 8859-3): ISO-IR-109."])
 -(define-charset 132 'latin-iso8859-4
 -  [1 96 1 0 ?D 1 "RHP of Latin-4" "RHP of Latin-4 (ISO 8859-4): ISO-IR-110"
 -     "Right-Hand Part of Latin Alphabet 4 (ISO/IEC 8859-4): ISO-IR-110."])
 -(define-charset 133 'thai-tis620
 -  [1 96 1 0 ?T 1 "RHP of TIS620" "RHP of Thai (TIS620): ISO-IR-166"
 -     "Right-Hand Part of TIS620.2533 (Thai): ISO-IR-166."])
 -(define-charset 134 'greek-iso8859-7
 -  [1 96 1 0 ?F 1 "RHP of ISO8859/7" "RHP of Greek (ISO 8859-7): ISO-IR-126"
 -     "Right-Hand Part of Latin/Greek Alphabet (ISO/IEC 8859-7): ISO-IR-126."])
 -(define-charset 135 'arabic-iso8859-6
 -  [1 96 1 1 ?G 1 "RHP of ISO8859/6" "RHP of Arabic (ISO 8859-6): ISO-IR-127"
 -     "Right-Hand Part of Latin/Arabic Alphabet (ISO/IEC 8859-6): ISO-IR-127."])
 -(define-charset 136 'hebrew-iso8859-8
 -  [1 96 1 1 ?H 1 "RHP of ISO8859/8" "RHP of Hebrew (ISO 8859-8): ISO-IR-138"
 -     "Right-Hand Part of Latin/Hebrew Alphabet (ISO/IEC 8859-8): ISO-IR-138."])
 -(define-charset 137 'katakana-jisx0201
 -  [1 94 1 0 ?I 1 "JISX0201 Katakana" "Japanese Katakana (JISX0201.1976)"
 -     "Katakana Part of JISX0201.1976."])
 -(define-charset 138 'latin-jisx0201
 -  [1 94 1 0 ?J 0 "JISX0201 Roman" "Japanese Roman (JISX0201.1976)"
 -     "Roman Part of JISX0201.1976."])
 -
 -;; CHARSET-ID is not used 139.
 -
 -(define-charset 140 'cyrillic-iso8859-5
 -  [1 96 1 0 ?L 1 "RHP of ISO8859/5" "RHP of Cyrillic (ISO 8859-5): ISO-IR-144"
 -     "Right-Hand Part of Latin/Cyrillic Alphabet (ISO/IEC 8859-5): ISO-IR-144."])
 -(define-charset 141 'latin-iso8859-9
 -  [1 96 1 0 ?M 1 "RHP of Latin-5" "RHP of Latin-5 (ISO 8859-9): ISO-IR-148"
 -     "Right-Hand Part of Latin Alphabet 5 (ISO/IEC 8859-9): ISO-IR-148."])
 -(define-charset 142 'latin-iso8859-15
 -  [1 96 1 0 ?b 1 "RHP of Latin-9" "RHP of Latin-9 (ISO 8859-15): ISO-IR-203"
 -     "Right-Hand Part of Latin Alphabet 9 (ISO/IEC 8859-15): ISO-IR-203."])
 -(define-charset 143 'latin-iso8859-14
 -  [1 96 1 0 ?_ 1 "RHP of Latin-8" "RHP of Latin-8 (ISO 8859-14): ISO-IR-199"
 -     "Right-Hand Part of Latin Alphabet 8 (ISO/IEC 8859-14): ISO-IR-199."])
 -
 -;; 2-byte charsets.  Valid range of CHARSET-ID is 144..153.
 -
 -(define-charset 144 'japanese-jisx0208-1978
 -  [2 94 2 0 ?@ 0 "JISX0208.1978" "JISX0208.1978 (Japanese): ISO-IR-42"
 -     "JISX0208.1978 Japanese Kanji (so called \"old JIS\"): ISO-IR-42."])
 -(define-charset 145 'chinese-gb2312
 -  [2 94 2 0 ?A 0 "GB2312" "GB2312: ISO-IR-58"
 -     "GB2312 Chinese simplified: ISO-IR-58."])
 -(define-charset 146 'japanese-jisx0208
 -  [2 94 2 0 ?B 0 "JISX0208" "JISX0208.1983/1990 (Japanese): ISO-IR-87"
 -     "JISX0208.1983/1990 Japanese Kanji: ISO-IR-87."])
 -(define-charset 147 'korean-ksc5601
 -  [2 94 2 0 ?C 0 "KSC5601" "KSC5601 (Korean): ISO-IR-149"
 -     "KSC5601 Korean Hangul and Hanja: ISO-IR-149."])
 -(define-charset 148 'japanese-jisx0212
 -  [2 94 2 0 ?D 0 "JISX0212" "JISX0212 (Japanese): ISO-IR-159"
 -     "JISX0212 Japanese supplement: ISO-IR-159."])
 -(define-charset 149 'chinese-cns11643-1
 -  [2 94 2 0 ?G 0 "CNS11643-1" "CNS11643-1 (Chinese traditional): ISO-IR-171"
 -     "CNS11643 Plane 1 Chinese traditional: ISO-IR-171."])
 -(define-charset 150 'chinese-cns11643-2
 -  [2 94 2 0 ?H 0 "CNS11643-2" "CNS11643-2 (Chinese traditional): ISO-IR-172"
 -     "CNS11643 Plane 2 Chinese traditional: ISO-IR-172."])
 -(define-charset 151 'japanese-jisx0213-1
 -  [2 94 2 0 ?O 0 "JISX0213-1" "JISX0213-1" "JISX0213 Plane 1 (Japanese)"])
 -(define-charset 152 'chinese-big5-1
 -  [2 94 2 0 ?0 0 "Big5 (Level-1)" "Big5 (Level-1) A141-C67F"
 -     "Frequently used part (A141-C67F) of Big5 (Chinese traditional)."])
 -(define-charset 153 'chinese-big5-2
 -  [2 94 2 0 ?1 0 "Big5 (Level-2)" "Big5 (Level-2) C940-FEFE"
 -     "Less frequently used part (C940-FEFE) of Big5 (Chinese traditional)."])
 -
 -;; Additional (private) character sets.  These character sets are
 -;; treated less space-efficiently in the buffer.
 -
 -;; Syntax:
 -;; (define-charset CHARSET-ID CHARSET
 -;;   [ DIMENSION CHARS WIDTH DIRECTION ISO-FINAL-CHAR ISO-GRAPHIC-PLANE
 -;;     SHORT-NAME LONG-NAME DESCRIPTION ])
 -
 -;; ISO-2022 allows a use of character sets not registered in ISO with
 -;; final characters `0' (0x30) through `?' (0x3F).  Among them, Emacs
 -;; reserves `0' through `9' to support several private character sets.
 -;; The remaining final characters `:' through `?' are for users.
 -
 -;; 1-byte 1-column charsets.  Valid range of CHARSET-ID is 160..223.
 -
 -(define-charset 160 'chinese-sisheng
 -  [1 94 1 0 ?0 0 "SiSheng" "SiSheng (PinYin/ZhuYin)"
 -     "Sisheng characters (vowels with tone marks) for Pinyin/Zhuyin."])
 -
 -;; IPA characters for phonetic symbols.
 -(define-charset 161 'ipa
 -  [1 96 1 0 ?0 1 "IPA" "IPA"
 -     "IPA (International Phonetic Association) characters."])
 -
 -;; Vietnamese VISCII.  VISCII is 1-byte character set which contains
 -;; more than 96 characters.  Since Emacs can't handle it as one
 -;; character set, it is divided into two: lower case letters and upper
 -;; case letters.
 -(define-charset 162 'vietnamese-viscii-lower
 -  [1 96 1 0 ?1 1 "VISCII lower" "VISCII lower-case"
 -     "Vietnamese VISCII1.1 lower-case characters."])
 -(define-charset 163 'vietnamese-viscii-upper
 -  [1 96 1 0 ?2 1 "VISCII upper" "VISCII upper-case"
 -     "Vietnamese VISCII1.1 upper-case characters."])
 +;; The charsets `ascii', `unicode' and `eight-bit' are already defined
 +;; in charset.c as below:
 +;;
 +;; (define-charset 'ascii
 +;;   ""
 +;;   :dimension 1
 +;;   :code-space [0 127]
 +;;   :iso-final-char ?B
 +;;   :ascii-compatible-p t
 +;;   :emacs-mule-id 0
 +;;   :code-offset 0)
 +;;
 +;; (define-charset 'unicode
 +;;   ""
 +;;   :dimension 3
 +;;   :code-space [0 255 0 255 0 16]
 +;;   :ascii-compatible-p t
 +;;   :code-offset 0)
 +;;
 +;; (define-charset 'eight-bit
 +;;   ""
 +;;   :dimension 1
 +;;   :code-space [128 255]
 +;;   :code-offset #x3FFF80)
 +;;
 +;; We now set :docstring, :short-name, and :long-name properties.
 +
 +(put-charset-property
 + 'ascii :docstring "ASCII (ISO646 IRV)")
 +(put-charset-property
 + 'ascii :short-name "ASCII")
 +(put-charset-property
 + 'ascii :long-name "ASCII (ISO646 IRV)")
 +(put-charset-property
 + 'iso-8859-1 :docstring "Latin-1 (ISO/IEC 8859-1)")
 +(put-charset-property
 + 'iso-8859-1 :short-name "Latin-1")
 +(put-charset-property
 + 'iso-8859-1 :long-name "Latin-1")
 +(put-charset-property
 + 'unicode :docstring "Unicode (ISO10646)")
 +(put-charset-property
 + 'unicode :short-name "Unicode")
 +(put-charset-property
 + 'unicode :long-name "Unicode (ISO10646)")
 +(put-charset-property 'eight-bit :docstring "Raw bytes 0-255")
 +(put-charset-property 'eight-bit :short-name "Raw bytes")
 +
 +(define-charset-alias 'ucs 'unicode)
 +
 +(define-charset 'emacs
 +  "Full Emacs characters"
 +  :ascii-compatible-p t
 +  :code-space [ 0 255 0 255 0 63 ]
 +  :code-offset 0
 +  :supplementary-p t)
 +
 +(define-charset 'latin-iso8859-1
 +  "Right-Hand Part of ISO/IEC 8859/1 (Latin-1): ISO-IR-100"
 +  :short-name "RHP of Latin-1"
 +  :long-name "RHP of ISO/IEC 8859/1 (Latin-1): ISO-IR-100"
 +  :iso-final-char ?A
 +  :emacs-mule-id 129
 +  :code-space [32 127]
 +  :code-offset 160)
 +
 +;; Name perhaps not ideal, but is XEmacs-compatible.
 +(define-charset 'control-1
 +  "8-bit control code (0x80..0x9F)"
 +  :short-name "8-bit control code"
 +  :code-space [128 159]
 +  :code-offset 128)
 +
 +(define-charset 'eight-bit-control
 +  "Raw bytes in the range 0x80..0x9F (usually produced from invalid encodings)"
 +  :short-name "Raw bytes 0x80..0x9F"
 +  :code-space [128 159]
 +  :code-offset #x3FFF80)              ; see character.h
 +
 +(define-charset 'eight-bit-graphic
 +  "Raw bytes in the range 0xA0..0xFF (usually produced from invalid encodings)"
 +  :short-name "Raw bytes 0xA0..0xFF"
 +  :code-space [160 255]
 +  :code-offset #x3FFFA0)              ; see character.h
 +
 +(defmacro define-iso-single-byte-charset (symbol iso-symbol name nickname
 +                                               iso-ir iso-final
 +                                               emacs-mule-id map)
 +  `(progn
 +     (define-charset ,symbol
 +       ,name
 +       :short-name ,nickname
 +       :long-name ,name
 +       :ascii-compatible-p t
 +       :code-space [0 255]
 +       :map ,map)
 +     (if ,iso-symbol
 +       (define-charset ,iso-symbol
 +         (if ,iso-ir
 +             (format "Right-Hand Part of %s (%s): ISO-IR-%d"
 +                     ,name ,nickname ,iso-ir)
 +           (format "Right-Hand Part of %s (%s)" ,name ,nickname))
 +         :short-name (format "RHP of %s" ,name)
 +         :long-name (format "RHP of %s (%s)" ,name ,nickname)
 +         :iso-final-char ,iso-final
 +         :emacs-mule-id ,emacs-mule-id
 +         :code-space [32 127]
 +         :subset (list ,symbol 160 255 -128)))))
 +
 +(define-iso-single-byte-charset 'iso-8859-2 'latin-iso8859-2
 +  "ISO/IEC 8859/2" "Latin-2" 101 ?B 130 "8859-2")
 +
 +(define-iso-single-byte-charset 'iso-8859-3 'latin-iso8859-3
 +  "ISO/IEC 8859/3" "Latin-3" 109 ?C 131 "8859-3")
 +
 +(define-iso-single-byte-charset 'iso-8859-4 'latin-iso8859-4
 +  "ISO/IEC 8859/4" "Latin-4" 110 ?D 132 "8859-4")
 +
 +(define-iso-single-byte-charset 'iso-8859-5 'cyrillic-iso8859-5
 +  "ISO/IEC 8859/5" "Latin/Cyrillic" 144 ?L 140 "8859-5")
 +
 +(define-iso-single-byte-charset 'iso-8859-6 'arabic-iso8859-6
 +  "ISO/IEC 8859/6" "Latin/Arabic" 127 ?G 135 "8859-6")
 +
 +(define-iso-single-byte-charset 'iso-8859-7 'greek-iso8859-7
 +  "ISO/IEC 8859/7" "Latin/Greek" 126 ?F 134 "8859-7")
 +
 +(define-iso-single-byte-charset 'iso-8859-8 'hebrew-iso8859-8
 +  "ISO/IEC 8859/8" "Latin/Hebrew" 138 ?H 136 "8859-8")
 +
 +(define-iso-single-byte-charset 'iso-8859-9 'latin-iso8859-9
 +  "ISO/IEC 8859/9" "Latin-5" 148 ?M 141 "8859-9")
 +
 +(define-iso-single-byte-charset 'iso-8859-10 'latin-iso8859-10
 +  "ISO/IEC 8859/10" "Latin-6" 157 ?V nil "8859-10")
 +
 +;; http://www.nectec.or.th/it-standards/iso8859-11/
 +;; http://www.cwi.nl/~dik/english/codes/8859.html says this is tis-620
 +;; plus nbsp
 +(define-iso-single-byte-charset 'iso-8859-11 'thai-iso8859-11
 +  "ISO/IEC 8859/11" "Latin/Thai" 166 ?T nil "8859-11")
 +
 +;; 8859-12 doesn't (yet?) exist.
 +
 +(define-iso-single-byte-charset 'iso-8859-13 'latin-iso8859-13
 +  "ISO/IEC 8859/13" "Latin-7" 179 ?Y nil "8859-13")
 +
 +(define-iso-single-byte-charset 'iso-8859-14 'latin-iso8859-14
 +  "ISO/IEC 8859/14" "Latin-8" 199 ?_ 143 "8859-14")
 +
 +(define-iso-single-byte-charset 'iso-8859-15 'latin-iso8859-15
 +  "ISO/IEC 8859/15" "Latin-9" 203 ?b 142 "8859-15")
 +
 +(define-iso-single-byte-charset 'iso-8859-16 'latin-iso8859-16
 +  "ISO/IEC 8859/16" "Latin-10" 226 ?f nil "8859-16")
 +
 +;; No point in keeping it around.
 +(fmakunbound 'define-iso-single-byte-charset)
 +
 +;; Can this be shared with 8859-11?
 +;; N.b. not all of these are defined unicodes.
 +(define-charset 'thai-tis620
 +  "TIS620.2533"
 +  :short-name "TIS620.2533"
 +  :iso-final-char ?T
 +  :emacs-mule-id 133
 +  :code-space [32 127]
 +  :code-offset #x0E00)
 +
 +;; Fixme: doc for this, c.f. above
 +(define-charset 'tis620-2533
 +  "TIS620.2533"
 +  :short-name "TIS620.2533"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :superset '(ascii eight-bit-control (thai-tis620 . 128)))
 +
 +(define-charset 'jisx0201
 +  "JISX0201"
 +  :short-name "JISX0201"
 +  :code-space [0 #xDF]
 +  :map "JISX0201")
 +
 +(define-charset 'latin-jisx0201
 +  "Roman Part of JISX0201.1976"
 +  :short-name "JISX0201 Roman"
 +  :long-name "Japanese Roman (JISX0201.1976)"
 +  :iso-final-char ?J
 +  :emacs-mule-id  138
 +  :code-space [33 126]
 +  :subset '(jisx0201 33 126 0))
 +
 +(define-charset 'katakana-jisx0201
 +  "Katakana Part of JISX0201.1976"
 +  :short-name "JISX0201 Katakana"
 +  :long-name "Japanese Katakana (JISX0201.1976)"
 +  :iso-final-char ?I
 +  :emacs-mule-id  137
 +  :code-space [33 126]
 +  :subset '(jisx0201 161 254 -128))
 +
 +(define-charset 'chinese-gb2312
 +  "GB2312 Chinese simplified: ISO-IR-58"
 +  :short-name "GB2312"
 +  :long-name "GB2312: ISO-IR-58"
 +  :iso-final-char ?A
 +  :emacs-mule-id 145
 +  :code-space [33 126 33 126]
 +  :code-offset #x110000
 +  :unify-map "GB2312")
 +
 +(define-charset 'chinese-gbk
 +  "GBK Chinese simplified."
 +  :short-name "GBK"
 +  :code-space [#x40 #xFE #x81 #xFE]
 +  :code-offset #x160000
 +  :unify-map "GBK")
 +(define-charset-alias 'cp936 'chinese-gbk)
 +(define-charset-alias 'windows-936 'chinese-gbk)
 +
 +(define-charset 'chinese-cns11643-1
 +  "CNS11643 Plane 1 Chinese traditional: ISO-IR-171"
 +  :short-name "CNS11643-1"
 +  :long-name "CNS11643-1 (Chinese traditional): ISO-IR-171"
 +  :iso-final-char ?G
 +  :emacs-mule-id  149
 +  :code-space [33 126 33 126]
 +  :code-offset #x114000
 +  :unify-map "CNS-1")
 +
 +(define-charset 'chinese-cns11643-2
 +  "CNS11643 Plane 2 Chinese traditional: ISO-IR-172"
 +  :short-name "CNS11643-2"
 +  :long-name "CNS11643-2 (Chinese traditional): ISO-IR-172"
 +  :iso-final-char ?H
 +  :emacs-mule-id  150
 +  :code-space [33 126 33 126]
 +  :code-offset #x118000
 +  :unify-map "CNS-2")
 +
 +(define-charset 'chinese-cns11643-3
 +  "CNS11643 Plane 3 Chinese Traditional: ISO-IR-183"
 +  :short-name  "CNS11643-3"
 +  :long-name "CNS11643-3 (Chinese traditional): ISO-IR-183"
 +  :iso-final-char ?I
 +  :code-space [33 126 33 126]
 +  :emacs-mule-id  246
 +  :code-offset #x11C000
 +  :unify-map "CNS-3")
 +
 +(define-charset 'chinese-cns11643-4
 +  "CNS11643 Plane 4 Chinese Traditional: ISO-IR-184"
 +  :short-name  "CNS11643-4"
 +  :long-name "CNS11643-4 (Chinese traditional): ISO-IR-184"
 +  :iso-final-char ?J
 +  :emacs-mule-id  247
 +  :code-space [33 126 33 126]
 +  :code-offset #x120000
 +  :unify-map "CNS-4")
 +
 +(define-charset 'chinese-cns11643-5
 +  "CNS11643 Plane 5 Chinese Traditional: ISO-IR-185"
 +  :short-name  "CNS11643-5"
 +  :long-name "CNS11643-5 (Chinese traditional): ISO-IR-185"
 +  :iso-final-char ?K
 +  :emacs-mule-id  248
 +  :code-space [33 126 33 126]
 +  :code-offset #x124000
 +  :unify-map "CNS-5")
 +
 +(define-charset 'chinese-cns11643-6
 +  "CNS11643 Plane 6 Chinese Traditional: ISO-IR-186"
 +  :short-name  "CNS11643-6"
 +  :long-name "CNS11643-6 (Chinese traditional): ISO-IR-186"
 +  :iso-final-char ?L
 +  :emacs-mule-id 249
 +  :code-space [33 126 33 126]
 +  :code-offset #x128000
 +  :unify-map "CNS-6")
 +
 +(define-charset 'chinese-cns11643-7
 +  "CNS11643 Plane 7 Chinese Traditional: ISO-IR-187"
 +  :short-name  "CNS11643-7"
 +  :long-name "CNS11643-7 (Chinese traditional): ISO-IR-187"
 +  :iso-final-char ?M
 +  :emacs-mule-id 250
 +  :code-space [33 126 33 126]
 +  :code-offset #x12C000
 +  :unify-map "CNS-7")
 +
 +(define-charset 'big5
 +  "Big5 (Chinese traditional)"
 +  :short-name "Big5"
 +  :code-space [#x40 #xFE #xA1 #xFE]
 +  :code-offset #x130000
 +  :unify-map "BIG5")
 +;; Fixme: AKA cp950 according to
 +;; <URL:http://www.microsoft.com/globaldev/reference/WinCP.asp>.  Is
 +;; that correct?
 +
 +(define-charset 'chinese-big5-1
 +  "Frequently used part (A141-C67E) of Big5 (Chinese traditional)"
 +  :short-name "Big5 (Level-1)"
 +  :long-name "Big5 (Level-1) A141-C67F"
 +  :iso-final-char ?0
 +  :emacs-mule-id 152
 +  :code-space [#x21 #x7E #x21 #x7E]
 +  :code-offset #x135000
 +  :unify-map "BIG5-1")
 +
 +(define-charset 'chinese-big5-2
 +  "Less frequently used part (C940-FEFE) of Big5 (Chinese traditional)"
 +  :short-name "Big5 (Level-2)"
 +  :long-name "Big5 (Level-2) C940-FEFE"
 +  :iso-final-char ?1
 +  :emacs-mule-id  153
 +  :code-space [#x21 #x7E #x21 #x7E]
 +  :code-offset #x137800
 +  :unify-map "BIG5-2")
 +
 +(define-charset 'japanese-jisx0208
 +  "JISX0208.1983/1990 Japanese Kanji: ISO-IR-87"
 +  :short-name "JISX0208"
 +  :long-name "JISX0208.1983/1990 (Japanese): ISO-IR-87"
 +  :iso-final-char ?B
 +  :emacs-mule-id 146
 +  :code-space [33 126 33 126]
 +  :code-offset #x140000
 +  :unify-map "JISX0208")
 +
 +(define-charset 'japanese-jisx0208-1978
 +  "JISX0208.1978 Japanese Kanji (so called \"old JIS\"): ISO-IR-42"
 +  :short-name "JISX0208.1978"
 +  :long-name  "JISX0208.1978 (JISC6226.1978): ISO-IR-42"
 +  :iso-final-char ?@
 +  :emacs-mule-id  144
 +  :code-space [33 126 33 126]
 +  :code-offset #x144000
 +  :unify-map "JISC6226")
 +
 +(define-charset 'japanese-jisx0212
 +  "JISX0212 Japanese supplement: ISO-IR-159"
 +  :short-name "JISX0212"
 +  :long-name "JISX0212 (Japanese): ISO-IR-159"
 +  :iso-final-char ?D
 +  :emacs-mule-id 148
 +  :code-space [33 126 33 126]
 +  :code-offset #x148000
 +  :unify-map "JISX0212")
 +
 +;; Note that jisx0213 contains characters not in Unicode (3.2?).  It's
 +;; arguable whether it should have a unify-map.
 +(define-charset 'japanese-jisx0213-1
 +  "JISX0213.2000 Plane 1 (Japanese)"
 +  :short-name "JISX0213-1"
 +  :iso-final-char ?O
 +  :emacs-mule-id  151
 +  :unify-map "JISX2131"
 +  :code-space [33 126 33 126]
 +  :code-offset #x14C000)
 +
 +(define-charset 'japanese-jisx0213-2
 +  "JISX0213.2000 Plane 2 (Japanese)"
 +  :short-name "JISX0213-2"
 +  :iso-final-char ?P
 +  :emacs-mule-id 254
 +  :unify-map "JISX2132"
 +  :code-space [33 126 33 126]
 +  :code-offset #x150000)
 +
 +(define-charset 'japanese-jisx0213-a
 +  "JISX0213.2004 adds these characters to JISX0213.2000."
 +  :short-name "JISX0213A"
 +  :dimension 2
 +  :code-space [33 126 33 126]
 +  :supplementary-p t
 +  :map "JISX213A")
 +
 +(define-charset 'japanese-jisx0213.2004-1
 +  "JISX0213.2004 Plane1 (Japanese)"
 +  :short-name "JISX0213.2004-1"
 +  :dimension 2
 +  :code-space [33 126 33 126]
 +  :iso-final-char ?Q
 +  :superset '(japanese-jisx0213-a japanese-jisx0213-1))
 +
 +(define-charset 'katakana-sjis
 +  "Katakana part of Shift-JIS"
 +  :dimension 1
 +  :code-space [#xA1 #xDF]
 +  :subset '(jisx0201 #xA1 #xDF 0)
 +  :supplementary-p t)
 +
 +(define-charset 'cp932-2-byte
 +  "2-byte part of CP932"
 +  :dimension 2
 +  :map "CP932-2BYTE"
 +  :code-space [#x40 #xFC #x81 #xFC]
 +  :supplementary-p t)
 +
 +(define-charset 'cp932
 +  "CP932 (Microsoft shift-jis)"
 +  :code-space [#x00 #xFF #x00 #xFE]
 +  :short-name "CP932"
 +  :superset '(ascii katakana-sjis cp932-2-byte))
 +
 +(define-charset 'korean-ksc5601
 +  "KSC5601 Korean Hangul and Hanja: ISO-IR-149"
 +  :short-name "KSC5601"
 +  :long-name "KSC5601 (Korean): ISO-IR-149"
 +  :iso-final-char ?C
 +  :emacs-mule-id 147
 +  :code-space [33 126 33 126]
 +  :code-offset #x279f94                       ; ... #x27c217
 +  :unify-map "KSC5601")
 +
 +(define-charset 'big5-hkscs
 +  "Big5-HKSCS (Chinese traditional, Hong Kong supplement)"
 +  :short-name "Big5"
 +  :code-space [#x40 #xFE #xA1 #xFE]
 +  :code-offset #x27c218                       ; ... #x280839
 +  :unify-map "BIG5-HKSCS")
 +
 +;; Fixme: Korean cp949/UHC
 +
 +(define-charset 'chinese-sisheng
 +  "SiSheng characters for PinYin/ZhuYin"
 +  :short-name "SiSheng"
 +  :long-name "SiSheng (PinYin/ZhuYin)"
 +  :iso-final-char ?0
 +  :emacs-mule-id 160
 +  :code-space [33 126]
 +  :unify-map "MULE-sisheng"
 +  :code-offset #x200000)
 +
 +;; A subset of the 1989 version of IPA.  It consists of the consonant
 +;; signs used in English, French, German and Italian, and all vowels
 +;; signs in the table.  [says old MULE doc]
 +(define-charset 'ipa
 +  "IPA (International Phonetic Association)"
 +  :short-name "IPA"
 +  :iso-final-char ?0
 +  :emacs-mule-id  161
 +  :unify-map "MULE-ipa"
 +  :code-space [32 127]
 +  :code-offset #x200080)
 +
 +(define-charset 'viscii
 +  "VISCII1.1"
 +  :short-name "VISCII"
 +  :long-name "VISCII 1.1"
 +  :code-space [0 255]
 +  :map "VISCII")
 +
 +(define-charset 'vietnamese-viscii-lower
 +  "VISCII1.1 lower-case"
 +  :short-name "VISCII lower"
 +  :long-name "VISCII lower-case"
 +  :iso-final-char ?1
 +  :emacs-mule-id  162
 +  :code-space [32 127]
 +  :code-offset #x200200
 +  :unify-map "MULE-lviscii")
 +
 +(define-charset 'vietnamese-viscii-upper
 +  "VISCII1.1 upper-case"
 +  :short-name "VISCII upper"
 +  :long-name "VISCII upper-case"
 +  :iso-final-char ?2
 +  :emacs-mule-id  163
 +  :code-space [32 127]
 +  :code-offset #x200280
 +  :unify-map "MULE-uviscii")
 +
 +(define-charset 'vscii
 +  "VSCII1.1 (TCVN-5712 VN1)"
 +  :short-name "VSCII"
 +  :code-space [0 255]
 +  :map "VSCII")
 +
 +(define-charset-alias 'tcvn-5712 'vscii)
 +
 +;; Fixme: see note in tcvn.map about combining characters
 +(define-charset 'vscii-2
 +  "VSCII-2 (TCVN-5712 VN2)"
 +  :code-space [0 255]
 +  :map "VSCII-2")
 +
 +(define-charset 'koi8-r
 +  "KOI8-R"
 +  :short-name "KOI8-R"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "KOI8-R")
 +
 +(define-charset-alias 'koi8 'koi8-r)
 +
 +(define-charset 'alternativnyj
 +  "ALTERNATIVNYJ"
 +  :short-name "alternativnyj"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "ALTERNATIVNYJ")
 +
 +(define-charset 'cp866
 +  "CP866"
 +  :short-name "cp866"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "IBM866")
 +(define-charset-alias 'ibm866 'cp866)
 +
 +(define-charset 'koi8-u
 +  "KOI8-U"
 +  :short-name "KOI8-U"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "KOI8-U")
 +
 +(define-charset 'koi8-t
 +  "KOI8-T"
 +  :short-name "KOI8-T"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "KOI8-T")
 +
 +(define-charset 'georgian-ps
 +  "GEORGIAN-PS"
 +  :short-name "GEORGIAN-PS"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "KA-PS")
 +
 +(define-charset 'georgian-academy
 +  "GEORGIAN-ACADEMY"
 +  :short-name "GEORGIAN-ACADEMY"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "KA-ACADEMY")
 +
 +(define-charset 'windows-1250
 +  "WINDOWS-1250 (Central Europe)"
 +  :short-name "WINDOWS-1250"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1250")
 +(define-charset-alias 'cp1250 'windows-1250)
 +
 +(define-charset 'windows-1251
 +  "WINDOWS-1251 (Cyrillic)"
 +  :short-name "WINDOWS-1251"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1251")
 +(define-charset-alias 'cp1251 'windows-1251)
 +
 +(define-charset 'windows-1252
 +  "WINDOWS-1252 (Latin I)"
 +  :short-name "WINDOWS-1252"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1252")
 +(define-charset-alias 'cp1252 'windows-1252)
 +
 +(define-charset 'windows-1253
 +  "WINDOWS-1253 (Greek)"
 +  :short-name "WINDOWS-1253"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1253")
 +(define-charset-alias 'cp1253 'windows-1253)
 +
 +(define-charset 'windows-1254
 +  "WINDOWS-1254 (Turkish)"
 +  :short-name "WINDOWS-1254"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1254")
 +(define-charset-alias 'cp1254 'windows-1254)
 +
 +(define-charset 'windows-1255
 +  "WINDOWS-1255 (Hebrew)"
 +  :short-name "WINDOWS-1255"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1255")
 +(define-charset-alias 'cp1255 'windows-1255)
 +
 +(define-charset 'windows-1256
 +  "WINDOWS-1256 (Arabic)"
 +  :short-name "WINDOWS-1256"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1256")
 +(define-charset-alias 'cp1256 'windows-1256)
 +
 +(define-charset 'windows-1257
 +  "WINDOWS-1257 (Baltic)"
 +  :short-name "WINDOWS-1257"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1257")
 +(define-charset-alias 'cp1257 'windows-1257)
 +
 +(define-charset 'windows-1258
 +  "WINDOWS-1258 (Viet Nam)"
 +  :short-name "WINDOWS-1258"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "CP1258")
 +(define-charset-alias 'cp1258 'windows-1258)
 +
 +(define-charset 'next
 +  "NEXT"
 +  :short-name "NEXT"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "NEXTSTEP")
 +
 +(define-charset 'cp1125
 +  "CP1125"
 +  :short-name "CP1125"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "CP1125")
 +(define-charset-alias 'ruscii 'cp1125)
 +;; Original name for cp1125, says Serhii Hlodin <hlodin@lutsk.bank.gov.ua>
 +(define-charset-alias 'cp866u 'cp1125)
 +
 +;; Fixme: C.f. iconv, http://czyborra.com/charsets/codepages.html
 +;; shows this as not ASCII comptaible, with various graphics in
 +;; 0x01-0x1F.
 +(define-charset 'cp437
 +  "CP437 (MS-DOS United States, Australia, New Zealand, South Africa)"
 +  :short-name "CP437"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM437")
 +
 +(define-charset 'cp720
 +  "CP720 (Arabic)"
 +  :short-name "CP720"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "CP720")
 +
 +(define-charset 'cp737
 +  "CP737 (PC Greek)"
 +  :short-name "CP737"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "CP737")
 +
 +(define-charset 'cp775
 +  "CP775 (PC Baltic)"
 +  :short-name "CP775"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "CP775")
 +
 +(define-charset 'cp851
 +  "CP851 (Greek)"
 +  :short-name "CP851"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM851")
 +
 +(define-charset 'cp852
 +  "CP852 (MS-DOS Latin-2)"
 +  :short-name "CP852"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM852")
 +
 +(define-charset 'cp855
 +  "CP855 (IBM Cyrillic)"
 +  :short-name "CP855"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM855")
 +
 +(define-charset 'cp857
 +  "CP857 (IBM Turkish)"
 +  :short-name "CP857"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM857")
 +
 +(define-charset 'cp858
 +  "CP858 (Multilingual Latin I + Euro)"
 +  :short-name "CP858"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "CP858")
 +(define-charset-alias 'cp00858 'cp858)        ; IANA has IBM00858/CP00858
 +
 +(define-charset 'cp860
 +  "CP860 (MS-DOS Portuguese)"
 +  :short-name "CP860"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM860")
 +
 +(define-charset 'cp861
 +  "CP861 (MS-DOS Icelandic)"
 +  :short-name "CP861"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM861")
 +
 +(define-charset 'cp862
 +  "CP862 (PC Hebrew)"
 +  :short-name "CP862"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM862")
 +
 +(define-charset 'cp863
 +  "CP863 (MS-DOS Canadian French)"
 +  :short-name "CP863"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM863")
 +
 +(define-charset 'cp864
 +  "CP864 (PC Arabic)"
 +  :short-name "CP864"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM864")
 +
 +(define-charset 'cp865
 +  "CP865 (MS-DOS Nordic)"
 +  :short-name "CP865"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM865")
 +
 +(define-charset 'cp869
 +  "CP869 (IBM Modern Greek)"
 +  :short-name "CP869"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM869")
 +
 +(define-charset 'cp874
 +  "CP874 (IBM Thai)"
 +  :short-name "CP874"
 +  :code-space [0 255]
 +  :ascii-compatible-p t
 +  :map "IBM874")
  
  ;; For Arabic, we need three different types of character sets.
  ;; Digits are of direction left-to-right and of width 1-column.
  ;; Others are of direction right-to-left and of width 1-column or
  ;; 2-column.
 -(define-charset 164 'arabic-digit
 -  [1 94 1 0 ?2 0 "Arabic digit" "Arabic digit"
 -     "Arabic digits."])
 -(define-charset 165 'arabic-1-column
 -  [1 94 1 1 ?3 0 "Arabic 1-col" "Arabic 1-column"
 -     "Arabic 1-column width glyphs."])
 -
 -;; ASCII with right-to-left direction.
 -(define-charset 166 'ascii-right-to-left
 -  [1 94 1 1 ?B 0 "rev ASCII" "ASCII with right-to-left direction"
 -     "ASCII (left half of ISO 8859-1) with right-to-left direction."])
 +(define-charset 'arabic-digit
 +  "Arabic digit"
 +  :short-name "Arabic digit"
 +  :iso-final-char ?2
 +  :emacs-mule-id 164
 +  :code-space [34 42]
 +  :code-offset #x0600)
 +
 +(define-charset 'arabic-1-column
 +  "Arabic 1-column"
 +  :short-name "Arabic 1-col"
 +  :long-name "Arabic 1-column"
 +  :iso-final-char ?3
 +  :emacs-mule-id 165
 +  :code-space [33 126]
 +  :code-offset #x200100)
 +
 +(define-charset 'arabic-2-column
 +  "Arabic 2-column"
 +  :short-name "Arabic 2-col"
 +  :long-name "Arabic 2-column"
 +  :iso-final-char ?4
 +  :emacs-mule-id 224
 +  :code-space [33 126]
 +  :code-offset #x200180)
  
  ;; Lao script.
 -;; ISO10646's 0x0E80..0x0EDF are mapped to 0x20..0x7F.
 -(define-charset 167 'lao
 -  [1 94 1 0 ?1 0 "Lao" "Lao"
 -     "Lao characters (U+0E80..U+0EDF)."])
 -
 -;; CHARSET-IDs 168..223 are not used.
 -
 -;; 1-byte 2-column charsets.  Valid range of CHARSET-ID is 224..239.
 +;; Codes 0x21..0x7E are mapped to Unicode U+0E81..U+0EDF.
 +;; Not all of them are defined unicodes.
 +(define-charset 'lao
 +  "Lao characters (ISO10646 0E81..0EDF)"
 +  :short-name "Lao"
 +  :iso-final-char ?1
 +  :emacs-mule-id 167
 +  :code-space [33 126]
 +  :code-offset #x0E81)
 +
 +(define-charset 'mule-lao
 +  "Lao characters (ISO10646 0E81..0EDF)"
 +  :short-name "Lao"
 +  :code-space [0 255]
 +  :superset '(ascii eight-bit-control (lao . 128)))
  
 -(define-charset 224 'arabic-2-column
 -  [1 94 2 1 ?4 0 "Arabic 2-col" "Arabic 2-column"
 -     "Arabic 2-column glyphs."])
  
  ;; Indian scripts.  Symbolic charset for data exchange.  Glyphs are
  ;; not assigned.  They are automatically converted to each Indian
  ;; script which IS-13194 supports.
  
 -(define-charset 225 'indian-is13194
 -  [1 94 2 0 ?5 1 "IS 13194" "Indian IS 13194"
 -     "Generic Indian character set for data exchange with IS 13194."])
 -
 -;; CHARSET-IDs 226..239 are not used.
 -
 -(define-charset 240  'indian-glyph
 -  [2 96 1 0 ?4 0 "Indian glyph" "Indian glyph"
 -     "Glyphs for Indian characters."])
 -;; 240 used to be [2 94 1 0 ?6 0 "Indian 1-col" "Indian 1 Column"]
 -
 -;; 2-byte 1-column charsets.  Valid range of CHARSET-ID is 240..244.
 +(define-charset 'indian-is13194
 +  "Generic Indian charset for data exchange with IS 13194"
 +  :short-name "IS 13194"
 +  :long-name "Indian IS 13194"
 +  :iso-final-char ?5
 +  :emacs-mule-id 225
 +  :code-space [33 126]
 +  :code-offset #x180000)
 +
 +(let ((code-offset #x180100))
 +  (dolist (script '(devanagari sanskrit bengali tamil telugu assamese
 +                             oriya kannada malayalam gujarati punjabi))
 +    (define-charset (intern (format "%s-cdac" script))
 +      (format "Glyphs of %s script for CDAC font.  Subset of `indian-glyph'."
 +            (capitalize (symbol-name script)))
 +      :short-name (format "CDAC %s glyphs" (capitalize (symbol-name script)))
 +      :code-space [0 255]
 +      :code-offset code-offset)
 +    (setq code-offset (+ code-offset #x100)))
 +
 +  (dolist (script '(devanagari bengali punjabi gujarati
 +                             oriya tamil telugu kannada malayalam))
 +    (define-charset (intern (format "%s-akruti" script))
 +      (format "Glyphs of %s script for AKRUTI font.  Subset of `indian-glyph'."
 +            (capitalize (symbol-name script)))
 +      :short-name (format "AKRUTI %s glyphs" (capitalize (symbol-name script)))
 +      :code-space [0 255]
 +      :code-offset code-offset)
 +    (setq code-offset (+ code-offset #x100))))
 +
 +(define-charset 'indian-glyph
 +  "Glyphs for Indian characters."
 +  :short-name "Indian glyph"
 +  :iso-final-char ?4
 +  :emacs-mule-id 240
 +  :code-space [32 127 32 127]
 +  :code-offset #x180100)
  
  ;; Actual Glyph for 1-column width.
 -(define-charset 241 'tibetan-1-column
 -  [2 94 1 0 ?8 0 "Tibetan 1-col" "Tibetan 1 column"
 -     "Tibetan 1-column glyphs."])
 -
 -;; Subsets of Unicode.
 -
 -(define-charset 242 'mule-unicode-2500-33ff
 -  [2 96 1 0 ?2 0 "Unicode subset 2" "Unicode subset (U+2500..U+33FF)"
 -     "Unicode characters of the range U+2500..U+33FF."])
 -
 -(define-charset 243 'mule-unicode-e000-ffff
 -  [2 96 1 0 ?3 0 "Unicode subset 3" "Unicode subset (U+E000+FFFF)"
 -     "Unicode characters of the range U+E000..U+FFFF."])
 -
 -(define-charset 244 'mule-unicode-0100-24ff
 -  [2 96 1 0 ?1 0 "Unicode subset" "Unicode subset (U+0100..U+24FF)"
 -     "Unicode characters of the range U+0100..U+24FF."])
 -
 -;; 2-byte 2-column charsets.  Valid range of CHARSET-ID is 245..254.
 -
 -;; Ethiopic characters (Amharic and Tigrigna).
 -(define-charset 245 'ethiopic
 -  [2 94 2 0 ?3 0 "Ethiopic" "Ethiopic characters"
 -     "Ethiopic characters."])
 -
 -;; Chinese CNS11643 Plane3 thru Plane7.  Although these are official
 -;; character sets, the use is rare and don't have to be treated
 -;; space-efficiently in the buffer.
 -(define-charset 246 'chinese-cns11643-3
 -  [2 94 2 0 ?I 0 "CNS11643-3" "CNS11643-3 (Chinese traditional): ISO-IR-183"
 -     "CNS11643 Plane 3 Chinese Traditional: ISO-IR-183."])
 -(define-charset 247 'chinese-cns11643-4
 -  [2 94 2 0 ?J 0 "CNS11643-4" "CNS11643-4 (Chinese traditional): ISO-IR-184"
 -     "CNS11643 Plane 4 Chinese Traditional: ISO-IR-184."])
 -(define-charset 248 'chinese-cns11643-5
 -  [2 94 2 0 ?K 0 "CNS11643-5" "CNS11643-5 (Chinese traditional): ISO-IR-185"
 -     "CNS11643 Plane 5 Chinese Traditional: ISO-IR-185."])
 -(define-charset 249 'chinese-cns11643-6
 -  [2 94 2 0 ?L 0 "CNS11643-6" "CNS11643-6 (Chinese traditional): ISO-IR-186"
 -     "CNS11643 Plane 6 Chinese Traditional: ISO-IR-186."])
 -(define-charset 250 'chinese-cns11643-7
 -  [2 94 2 0 ?M 0 "CNS11643-7" "CNS11643-7 (Chinese traditional): ISO-IR-187"
 -     "CNS11643 Plane 7 Chinese Traditional: ISO-IR-187."])
 +(define-charset 'indian-1-column
 +  "Indian charset for 1-column width glyphs."
 +  :short-name "Indian 1-col"
 +  :long-name "Indian 1 Column"
 +  :iso-final-char ?6
 +  :emacs-mule-id  251
 +  :code-space [33 126 33 126]
 +  :code-offset #x184000)
  
  ;; Actual Glyph for 2-column width.
 -(define-charset 251 'indian-2-column
 -  [2 94 2 0 ?5 0 "Indian 2-col" "Indian 2 Column"
 -     "Indian character set for 2-column width glyphs."])
 -  ;; old indian-1-column characters will be translated to indian-2-column.
 -(declare-equiv-charset 2 94 ?6 'indian-2-column)
 +(define-charset 'indian-2-column
 +  "Indian charset for 2-column width glyphs."
 +  :short-name "Indian 2-col"
 +  :long-name "Indian 2 Column"
 +  :iso-final-char ?5
 +  :emacs-mule-id  251
 +  :code-space [33 126 33 126]
 +  :code-offset #x184000)
 +
 +(define-charset 'tibetan
 +  "Tibetan characters"
 +  :iso-final-char ?7
 +  :short-name "Tibetan 2-col"
 +  :long-name "Tibetan 2 column"
 +  :iso-final-char ?7
 +  :emacs-mule-id 252
 +  :unify-map "MULE-tibetan"
 +  :code-space [33 126 33 37]
 +  :code-offset #x190000)
 +
 +(define-charset 'tibetan-1-column
 +  "Tibetan 1 column glyph"
 +  :short-name "Tibetan 1-col"
 +  :long-name "Tibetan 1 column"
 +  :iso-final-char ?8
 +  :emacs-mule-id 241
 +  :code-space [33 126 33 37]
 +  :code-offset #x190000)
  
 -;; Tibetan script.
 -(define-charset 252 'tibetan
 -  [2 94 2 0 ?7 0 "Tibetan 2-col" "Tibetan 2 column"
 -     "Tibetan 2-column width glyphs."])
 -
 -;; CHARSET-ID 253 is not used.
 -
 -;; JISX0213 Plane 2
 -(define-charset 254 'japanese-jisx0213-2
 -  [2 94 2 0 ?P 0 "JISX0213-2" "JISX0213-2"
 -     "JISX0213 Plane 2 (Japanese)."])
 -
 -;; Tell C code charset ID's of several charsets.
 -(setup-special-charsets)
 +;; Subsets of Unicode.
 +(define-charset 'mule-unicode-2500-33ff
 +  "Unicode characters of the range U+2500..U+33FF."
 +  :short-name "Unicode subset 2"
 +  :long-name "Unicode subset (U+2500..U+33FF)"
 +  :iso-final-char ?2
 +  :emacs-mule-id 242
 +  :code-space [#x20 #x7f #x20 #x47]
 +  :code-offset #x2500)
 +
 +(define-charset 'mule-unicode-e000-ffff
 +  "Unicode characters of the range U+E000..U+FFFF."
 +  :short-name "Unicode subset 3"
 +  :long-name "Unicode subset (U+E000+FFFF)"
 +  :iso-final-char ?3
 +  :emacs-mule-id 243
 +  :code-space [#x20 #x7F #x20 #x75]
 +  :code-offset #xE000
 +  :max-code 30015)                    ; U+FFFF
 +
 +(define-charset 'mule-unicode-0100-24ff
 +  "Unicode characters of the range U+0100..U+24FF."
 +  :short-name "Unicode subset"
 +  :long-name "Unicode subset (U+0100..U+24FF)"
 +  :iso-final-char ?1
 +  :emacs-mule-id 244
 +  :code-space [#x20 #x7F #x20 #x7F]
 +  :code-offset #x100)
 +
 +(define-charset 'unicode-bmp
 +  "Unicode Basic Multilingual Plane (U+0000..U+FFFF)"
 +  :short-name "Unicode BMP"
 +  :code-space [0 255 0 255]
 +  :code-offset 0)
 +
 +(define-charset 'unicode-smp
 +  "Unicode Supplementary Multilingual Plane (U+10000..U+1FFFF)"
 +  :short-name "Unicode SMP "
 +  :code-space [0 255 0 255]
 +  :code-offset #x10000)
 +
 +(define-charset 'unicode-sip
 +  "Unicode Supplementary Ideographic Plane (U+20000..U+2FFFF)"
 +  :short-name "Unicode SIP"
 +  :code-space [0 255 0 255]
 +  :code-offset #x20000)
 +
 +(define-charset 'unicode-ssp
 +  "Unicode Supplementary Special-purpose Plane (U+E0000..U+EFFFF)"
 +  :short-name "Unicode SSP"
 +  :code-space [0 255 0 255]
 +  :code-offset #xE0000)
 +
 +(define-charset 'ethiopic
 +  "Ethiopic characters for Amharic and Tigrigna."
 +  :short-name "Ethiopic"
 +  :long-name "Ethiopic characters"
 +  :iso-final-char ?3
 +  :emacs-mule-id  245
 +  :unify-map "MULE-ethiopic"
 +  :code-space [33 126 33 126]
 +  :code-offset #x1A0000)
 +
 +(define-charset 'mac-roman
 +  "Mac Roman charset"
 +  :short-name "Mac Roman"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "MACINTOSH")
 +
 +;; Fixme: modern EBCDIC variants, e.g. IBM00924?
 +(define-charset 'ebcdic-us
 +  "US version of EBCDIC"
 +  :short-name "EBCDIC-US"
 +  :code-space [0 255]
 +  :mime-charset 'ebcdic-us
 +  :map "EBCDICUS")
 +
 +(define-charset 'ebcdic-uk
 +  "UK version of EBCDIC"
 +  :short-name "EBCDIC-UK"
 +  :code-space [0 255]
 +  :mime-charset 'ebcdic-uk
 +  :map "EBCDICUK")
 +
 +(define-charset 'ibm1047
 +  ;; Says groff:
 +  "IBM1047, `EBCDIC Latin 1/Open Systems' used by OS/390 Unix."
 +  :short-name "IBM1047"
 +  :code-space [0 255]
 +  :mime-charset 'ibm1047
 +  :map "IBM1047")
 +(define-charset-alias 'cp1047 'ibm1047)
 +
 +(define-charset 'hp-roman8
 +  "Encoding used by Hewlet-Packard printer software"
 +  :short-name "HP-ROMAN8"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "HP-ROMAN8")
 +
 +;; To make a coding system with this, a pre-write-conversion should
 +;; account for the commented-out multi-valued code points in
 +;; stdenc.map.
 +(define-charset 'adobe-standard-encoding
 +  "Adobe `standard encoding' used in PostScript"
 +  :short-name "ADOBE-STANDARD-ENCODING"
 +  :code-space [#x20 255]
 +  :map "stdenc")
 +
 +(define-charset 'symbol
 +  "Adobe symbol encoding used in PostScript"
 +  :short-name "ADOBE-SYMBOL"
 +  :code-space [#x20 255]
 +  :map "symbol")
 +
 +(define-charset 'ibm850
 +  "DOS codepage 850 (Latin-1)"
 +  :short-name "IBM850"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "IBM850")
 +(define-charset-alias 'cp850 'ibm850)
 +
 +(define-charset 'mik
 +  "Bulgarian DOS codepage"
 +  :short-name "MIK"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map "MIK")
 +
 +(define-charset 'ptcp154
 +  "`Paratype' codepage (Asian Cyrillic)"
 +  :short-name "PT154"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :mime-charset 'pt154
 +  :map "PTCP154")
 +(define-charset-alias 'pt154 'ptcp154)
 +(define-charset-alias 'cp154 'ptcp154)
 +
 +(define-charset 'gb18030-2-byte
 +  "GB18030 2-byte (0x814E..0xFEFE)"
 +  :code-space [#x40 #xFE #x81 #xFE]
 +  :supplementary-p t
 +  :map "GB180302")
 +
 +(define-charset 'gb18030-4-byte-bmp
 +  "GB18030 4-byte for BMP (0x81308130-0x8431A439)"
 +  :code-space [#x30 #x39 #x81 #xFE #x30 #x39 #x81 #x84]
 +  :supplementary-p t
 +  :map "GB180304")
 +
 +(define-charset 'gb18030-4-byte-smp
 +  "GB18030 4-byte for SMP (0x90308130-0xE3329A35)"
 +  :code-space [#x30 #x39 #x81 #xFE #x30 #x39 #x90 #xE3]
 +  :min-code '(#x9030 . #x8130)
 +  :max-code '(#xE332 . #x9A35)
 +  :supplementary-p t
 +  :code-offset #x10000)
 +
 +(define-charset 'gb18030-4-byte-ext-1
 +  "GB18030 4-byte (0x8431A530-0x8F39FE39)"
 +  :code-space [#x30 #x39 #x81 #xFE #x30 #x39 #x84 #x8F]
 +  :min-code '(#x8431 . #xA530)
 +  :max-code '(#x8F39 . #xFE39)
 +  :supplementary-p t
 +  :code-offset #x200000                       ; ... #x22484B
 +  )
 +
 +(define-charset 'gb18030-4-byte-ext-2
 +  "GB18030 4-byte (0xE3329A36-0xFE39FE39)"
 +  :code-space [#x30 #x39 #x81 #xFE #x30 #x39 #xE3 #xFE]
 +  :min-code '(#xE332 . #x9A36)
 +  :max-code '(#xFE39 . #xFE39)
 +  :supplementary-p t
 +  :code-offset #x22484C                       ; ... #x279f93
 +  )
 +
 +(define-charset 'gb18030
 +  "GB18030"
 +  :code-space [#x00 #xFF #x00 #xFE #x00 #xFE #x00 #xFE]
 +  :min-code 0
 +  :max-code '(#xFE39 . #xFE39)
 +  :superset '(ascii gb18030-2-byte
 +                  gb18030-4-byte-bmp gb18030-4-byte-smp
 +                  gb18030-4-byte-ext-1 gb18030-4-byte-ext-2))
 +
 +(define-charset 'chinese-cns11643-15
 +  "CNS11643 Plane 15 Chinese Traditional"
 +  :short-name  "CNS11643-15"
 +  :long-name "CNS11643-15 (Chinese traditional)"
 +  :code-space [33 126 33 126]
 +  :code-offset #x27A000)
 +
 +(unify-charset 'chinese-gb2312)
 +(unify-charset 'chinese-gbk)
 +(unify-charset 'chinese-cns11643-1)
 +(unify-charset 'chinese-cns11643-2)
 +(unify-charset 'chinese-cns11643-3)
 +(unify-charset 'chinese-cns11643-4)
 +(unify-charset 'chinese-cns11643-5)
 +(unify-charset 'chinese-cns11643-6)
 +(unify-charset 'chinese-cns11643-7)
 +(unify-charset 'big5)
 +(unify-charset 'chinese-big5-1)
 +(unify-charset 'chinese-big5-2)
 +(unify-charset 'big5-hkscs)
 +(unify-charset 'korean-ksc5601)
 +(unify-charset 'vietnamese-viscii-lower)
 +(unify-charset 'vietnamese-viscii-upper)
 +(unify-charset 'chinese-sisheng)
 +(unify-charset 'ipa)
 +(unify-charset 'tibetan)
 +(unify-charset 'ethiopic)
 +(unify-charset 'japanese-jisx0208-1978)
 +(unify-charset 'japanese-jisx0208)
 +(unify-charset 'japanese-jisx0212)
 +(unify-charset 'japanese-jisx0213-1)
 +(unify-charset 'japanese-jisx0213-2)
  
  \f
  ;; These are tables for translating characters on decoding and
  ;; encoding.
 -(define-translation-table
 -  'oldjis-newjis-jisroman-ascii
 -  (list (cons (make-char 'japanese-jisx0208-1978)
 -            (make-char 'japanese-jisx0208))
 -      (cons (make-char 'latin-jisx0201) (make-char 'ascii))))
 -(aset (get 'oldjis-newjis-jisroman-ascii 'translation-table)
 -      (make-char 'latin-jisx0201 92) (make-char 'latin-jisx0201 92))
 -(aset (get 'oldjis-newjis-jisroman-ascii 'translation-table)
 -      (make-char 'latin-jisx0201 126) (make-char 'latin-jisx0201 126))
 -
 -(setq standard-translation-table-for-decode
 -      (get 'oldjis-newjis-jisroman-ascii 'translation-table))
 +;; Fixme: these aren't used now -- should they be?
 +(setq standard-translation-table-for-decode nil)
  
  (setq standard-translation-table-for-encode nil)
  \f
  ;;; Make fundamental coding systems.
  
 -;; Miscellaneous coding systems which can't be made by
 -;; `make-coding-system'.
 -
 -(put 'no-conversion 'coding-system
 -     (vector nil ?= "Do no conversion.
 -
 -When you visit a file with this coding, the file is read into a
 -unibyte buffer as is, thus each byte of a file is treated as a
 -character."
 -           (list 'coding-category 'coding-category-binary
 -                 'alias-coding-systems '(no-conversion)
 -                 'safe-charsets t 'safe-chars t)
 -           nil))
 -(put 'no-conversion 'eol-type 0)
 -(put 'coding-category-binary 'coding-systems '(no-conversion))
 -(setq coding-system-list '(no-conversion))
 -(setq coding-system-alist '(("no-conversion")))
 -(define-coding-system-internal 'no-conversion)
 +;; The coding system `no-conversion' and `undecided' are already
 +;; defined in coding.c as below:
 +;;
 +;; (define-coding-system 'no-conversion
 +;;   "..."
 +;;   :coding-type 'raw-text
 +;;   ...)
 +;; (define-coding-system 'undecided
 +;;   "..."
 +;;   :coding-type 'undecided
 +;;   ...)
  
  (define-coding-system-alias 'binary 'no-conversion)
 -
 -(put 'undecided 'coding-system
 -     (vector t ?- "No conversion on encoding, automatic conversion on decoding"
 -           (list 'alias-coding-systems '(undecided)
 -                 'safe-charsets '(ascii))
 -           nil))
 -(setq coding-system-list (cons 'undecided coding-system-list))
 -(setq coding-system-alist (cons '("undecided") coding-system-alist))
 -(put 'undecided 'eol-type
 -     (make-subsidiary-coding-system 'undecided))
 -
  (define-coding-system-alias 'unix 'undecided-unix)
  (define-coding-system-alias 'dos 'undecided-dos)
  (define-coding-system-alias 'mac 'undecided-mac)
  
 -;; Coding systems not specific to each language environment.
 -
 -(make-coding-system
 - 'emacs-mule 0 ?=
 - "Emacs internal format used in buffer and string.
 -
 -Encoding text with this coding system produces the actual byte
 -sequence of the text in buffers and strings.  An exception is made for
 -eight-bit-control characters.  Each of them is encoded into a single
 -byte."
 - nil
 - '((safe-charsets . t)
 -   (composition . t)))
 -
 -(make-coding-system
 - 'raw-text 5 ?t
 - "Raw text, which means text contains random 8-bit codes.
 +(define-coding-system 'raw-text
 +  "Raw text, which means text contains random 8-bit codes.
  Encoding text with this coding system produces the actual byte
  sequence of the text in buffers and strings.  An exception is made for
  eight-bit-control characters.  Each of them is encoded into a single
  When you visit a file with this coding, the file is read into a
  unibyte buffer as is (except for EOL format), thus each byte of a file
  is treated as a character."
 - nil
 - '((safe-charsets . t)))
 -
 -(make-coding-system
 - 'iso-2022-7bit 2 ?J
 - "ISO 2022 based 7-bit encoding using only G0"
 - '((ascii t) nil nil nil
 -   short ascii-eol ascii-cntl seven)
 - '((safe-charsets . t)
 -   (composition . t)))
 -
 -(make-coding-system
 - 'iso-2022-7bit-ss2 2 ?$
 - "ISO 2022 based 7-bit encoding using SS2 for 96-charset"
 - '((ascii t) nil t nil
 -   short ascii-eol ascii-cntl seven nil single-shift)
 - '((safe-charsets . t)
 -   (composition . t)))
 -
 -(make-coding-system
 - 'iso-2022-7bit-lock 2 ?&
 - "ISO-2022 coding system using Locking-Shift for 96-charset"
 - '((ascii t) t nil nil
 -   nil ascii-eol ascii-cntl seven locking-shift)
 - '((safe-charsets . t)
 -   (composition . t)))
 +  :coding-type 'raw-text
 +  :for-unibyte t
 +  :mnemonic ?t)
 +
 +(define-coding-system 'no-conversion-multibyte
 +  "Like `no-conversion' but don't read a file into a unibyte buffer."
 +  :coding-type 'raw-text
 +  :eol-type 'unix
 +  :mnemonic ?=)
 +  
 +(define-coding-system 'iso-latin-1
 +  "ISO 2022 based 8-bit encoding for Latin-1 (MIME:ISO-8859-1)."
 +  :coding-type 'charset
 +  :mnemonic ?1
 +  :charset-list '(iso-8859-1)
 +  :mime-charset 'iso-8859-1)
  
 -(define-coding-system-alias 'iso-2022-int-1 'iso-2022-7bit-lock)
 +(define-coding-system-alias 'iso-8859-1 'iso-latin-1)
 +(define-coding-system-alias 'latin-1 'iso-latin-1)
  
 -(make-coding-system
 - 'iso-2022-7bit-lock-ss2 2 ?i
 - "Mixture of ISO-2022-JP, ISO-2022-KR, and ISO-2022-CN"
 - '((ascii t)
 -   (nil korean-ksc5601 chinese-gb2312 chinese-cns11643-1 t)
 -   (nil chinese-cns11643-2)
 -   (nil chinese-cns11643-3 chinese-cns11643-4 chinese-cns11643-5
 -      chinese-cns11643-6 chinese-cns11643-7)
 -   short ascii-eol ascii-cntl seven locking-shift single-shift nil nil nil
 -   init-bol)
 - '((safe-charsets ascii japanese-jisx0208 japanese-jisx0208-1978 latin-jisx0201
 -                korean-ksc5601 chinese-gb2312 chinese-cns11643-1
 -                chinese-cns11643-2 chinese-cns11643-3 chinese-cns11643-4
 -                chinese-cns11643-5 chinese-cns11643-6 chinese-cns11643-7)
 -   (composition . t)))
 +;; Coding systems not specific to each language environment.
  
 -(define-coding-system-alias 'iso-2022-cjk 'iso-2022-7bit-lock-ss2)
 +(define-coding-system 'emacs-mule
 + "Emacs 21 internal format used in buffer and string."
 + :coding-type 'emacs-mule
 + :charset-list 'emacs-mule
 + :mnemonic ?M)
 +
 +(define-coding-system 'utf-8
 +  "UTF-8."
 +  :coding-type 'utf-8
 +  :mnemonic ?U
 +  :charset-list '(unicode)
 +  :mime-charset 'utf-8)
 +
 +(define-coding-system-alias 'mule-utf-8 'utf-8)
 +
 +(define-coding-system 'utf-8-emacs
 +  "Support for all Emacs characters (including non-Unicode characters)."
 +  :coding-type 'utf-8
 +  :mnemonic ?U
 +  :charset-list '(emacs))
 +
 +(define-coding-system 'utf-16le
 +  "UTF-16LE (little endian, no signature (BOM))."
 +  :coding-type 'utf-16
 +  :mnemonic ?U
 +  :charset-list '(unicode)
 +  :endian 'little
 +  :mime-text-unsuitable t
 +  :mime-charset 'utf-16le)
 +
 +(define-coding-system 'utf-16be
 +  "UTF-16BE (big endian, no signature (BOM))."
 +  :coding-type 'utf-16
 +  :mnemonic ?U
 +  :charset-list '(unicode)
 +  :endian 'big
 +  :mime-text-unsuitable t
 +  :mime-charset 'utf-16be)
 +
 +(define-coding-system 'utf-16le-with-signature
 +  "UTF-16 (little endian, with signature (BOM))."
 +  :coding-type 'utf-16
 +  :mnemonic ?U
 +  :charset-list '(unicode)
 +  :bom t
 +  :endian 'little
 +  :mime-text-unsuitable t
 +  :mime-charset 'utf-16)
 +
 +(define-coding-system 'utf-16be-with-signature
 +  "UTF-16 (big endian, with signature)."
 +  :coding-type 'utf-16
 +  :mnemonic ?U
 +  :charset-list '(unicode)
 +  :bom t
 +  :endian 'big
 +  :mime-text-unsuitable t
 +  :mime-charset 'utf-16)
 +
 +(define-coding-system 'utf-16
 +  "UTF-16 (detect endian on decoding, use big endian on encoding with BOM)."
 +  :coding-type 'utf-16
 +  :mnemonic ?U
 +  :charset-list '(unicode)
 +  :bom '(utf-16le-with-signature . utf-16be-with-signature)
 +  :endian 'big
 +  :mime-text-unsuitable t
 +  :mime-charset 'utf-16)
 +
 +;; Backwards compatibility (old names, also used by Mule-UCS).  We
 +;; prefer the MIME names.
 +(define-coding-system-alias 'utf-16-le 'utf-16le-with-signature)
 +(define-coding-system-alias 'utf-16-be 'utf-16be-with-signature)
 +
 +
 +(define-coding-system 'iso-2022-7bit
 +  "ISO 2022 based 7-bit encoding using only G0."
 +  :coding-type 'iso-2022
 +  :mnemonic ?J
 +  :charset-list 'iso-2022
 +  :designation [(ascii t) nil nil nil]
 +  :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation composition))
 +
 +(define-coding-system 'iso-2022-7bit-ss2
 +  "ISO 2022 based 7-bit encoding using SS2 for 96-charset."
 +  :coding-type 'iso-2022
 +  :mnemonic ?$
 +  :charset-list 'iso-2022
 +  :designation [(ascii 94) nil (nil 96) nil]
 +  :flags '(short ascii-at-eol ascii-at-cntl 7-bit
 +               designation single-shift composition))
 +
 +(define-coding-system 'iso-2022-7bit-lock
 +  "ISO-2022 coding system using Locking-Shift for 96-charset."
 +  :coding-type 'iso-2022
 +  :mnemonic ?&
 +  :charset-list 'iso-2022
 +  :designation [(ascii 94) (nil 96) nil nil]
 +  :flags '(ascii-at-eol ascii-at-cntl 7-bit
 +                      designation locking-shift composition))
 +
 +(define-coding-system-alias 'iso-2022-int-1 'iso-2022-7bit-lock)
  
 -(make-coding-system
 - 'iso-2022-8bit-ss2 2 ?@
 - "ISO 2022 based 8-bit encoding using SS2 for 96-charset"
 - '((ascii t) nil t nil
 -   nil ascii-eol ascii-cntl nil nil single-shift)
 - '((safe-charsets . t)
 -   (composition . t)))
 +(define-coding-system 'iso-2022-7bit-lock-ss2
 +  "Mixture of ISO-2022-JP, ISO-2022-KR, and ISO-2022-CN."
 +  :coding-type 'iso-2022
 +  :mnemonic ?i
 +  :charset-list '(ascii
 +                japanese-jisx0208 japanese-jisx0208-1978 latin-jisx0201
 +                korean-ksc5601
 +                chinese-gb2312
 +                chinese-cns11643-1 chinese-cns11643-2 chinese-cns11643-3
 +                chinese-cns11643-4 chinese-cns11643-5 chinese-cns11643-6
 +                chinese-cns11643-7)
 +  :designation [(ascii 94)
 +              (nil korean-ksc5601 chinese-gb2312 chinese-cns11643-1 96)
 +              (nil chinese-cns11643-2)
 +              (nil chinese-cns11643-3 chinese-cns11643-4 chinese-cns11643-5
 +                   chinese-cns11643-6 chinese-cns11643-7)]
 +  :flags '(short ascii-at-eol ascii-at-cntl 7-bit locking-shift
 +               single-shift init-bol))
  
 -(make-coding-system
 - 'compound-text 2 ?x
 - "Compound text based generic encoding for decoding unknown messages.
 +(define-coding-system-alias 'iso-2022-cjk 'iso-2022-7bit-lock-ss2)
  
 -This coding system does not support extended segments."
 - '((ascii t) (latin-iso8859-1 katakana-jisx0201 t) t t
 -   nil ascii-eol ascii-cntl nil locking-shift single-shift nil nil nil
 -   init-bol nil nil)
 - '((safe-charsets . t)
 -   (mime-charset . x-ctext)
 -   (composition . t)))
 +(define-coding-system 'iso-2022-8bit-ss2
 +  "ISO 2022 based 8-bit encoding using SS2 for 96-charset."
 +  :coding-type 'iso-2022
 +  :mnemonic ?@
 +  :charset-list 'iso-2022
 +  :designation [(ascii 94) nil (nil 96) nil]
 +  :flags '(ascii-at-eol ascii-at-cntl designation single-shift composition))
 +
 +(define-coding-system 'compound-text
 +  "Compound text based generic encoding for decoding unknown messages.
 +
 +This coding system does not support extended segments of CTEXT."
 +  :coding-type 'iso-2022
 +  :mnemonic ?x
 +  :charset-list 'iso-2022
 +  :designation [(ascii 94) (latin-iso8859-1 katakana-jisx0201 96) nil nil]
 +  :flags '(ascii-at-eol ascii-at-cntl long-form
 +                      designation locking-shift single-shift composition)
 +  ;; Fixme: this isn't a valid MIME charset and has to be
 +  ;; special-cased elsewhere  -- fx
 +  :mime-charset 'x-ctext)
  
  (define-coding-system-alias  'x-ctext 'compound-text)
  (define-coding-system-alias  'ctext 'compound-text)
  ;; compound-text-with-extensions, see mule.el.  Note that this should
  ;; not have a mime-charset property, to prevent it from showing up
  ;; close to the beginning of coding systems ordered by priority.
 -(make-coding-system
 - 'ctext-no-compositions 2 ?x
 +(define-coding-system 'ctext-no-compositions
   "Compound text based generic encoding for decoding unknown messages.
  
  Like `compound-text', but does not produce escape sequences for compositions."
 - '((ascii t) (latin-iso8859-1 katakana-jisx0201 t) t t
 -   nil ascii-eol ascii-cntl nil locking-shift single-shift nil nil nil
 -   init-bol nil nil)
 - '((safe-charsets . t)))
 +  :coding-type 'iso-2022
 +  :mnemonic ?x
 +  :charset-list 'iso-2022
 +  :designation [(ascii 94) (latin-iso8859-1 katakana-jisx0201 96) nil nil]
 +  :flags '(ascii-at-eol ascii-at-cntl
 +                      designation locking-shift single-shift))
  
 -(make-coding-system
 - 'compound-text-with-extensions 2 ?x
 - "Compound text encoding with extended segments.
 +(define-coding-system 'compound-text-with-extensions
 + "Compound text encoding with ICCCM Extended Segment extensions.
  
  See the variable `ctext-non-standard-encodings-alist' for the
  detail about how extended segments are handled.
  
  This coding system should be used only for X selections.  It is inappropriate
  for decoding and encoding files, process I/O, etc."
 - '((ascii t) (latin-iso8859-1 katakana-jisx0201 t) t t
 -   nil ascii-eol ascii-cntl)
 - '((post-read-conversion . ctext-post-read-conversion)
 -   (pre-write-conversion . ctext-pre-write-conversion)))
 +  :coding-type 'iso-2022
 +  :mnemonic ?x
 +  :charset-list 'iso-2022
 +  :designation [(ascii 94) (latin-iso8859-1 katakana-jisx0201 96) nil nil]
 +  :flags '(ascii-at-eol ascii-at-cntl long-form
 +                      designation locking-shift single-shift)
 +  :post-read-conversion 'ctext-post-read-conversion
 +  :pre-write-conversion 'ctext-pre-write-conversion)
  
  (define-coding-system-alias
    'x-ctext-with-extensions 'compound-text-with-extensions)
  (define-coding-system-alias
    'ctext-with-extensions 'compound-text-with-extensions)
  
 -(make-coding-system
 - 'iso-safe 2 ?-
 - "Encode ASCII asis and encode non-ASCII characters to `?'."
 - '(ascii nil nil nil
 -   nil ascii-eol ascii-cntl nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii)))
 -
 -(define-coding-system-alias
 -  'us-ascii 'iso-safe)
 -
 -(make-coding-system
 - 'iso-latin-1 2 ?1
 - "ISO 2022 based 8-bit encoding for Latin-1 (MIME:ISO-8859-1)."
 - '(ascii latin-iso8859-1 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t t)
 - '((safe-charsets ascii latin-iso8859-1)
 -   (mime-charset . iso-8859-1)))
 -
 -(define-coding-system-alias 'iso-8859-1 'iso-latin-1)
 -(define-coding-system-alias 'latin-1 'iso-latin-1)
 -
 -;; Use iso-safe for terminal output if some other coding system is not
 +(define-coding-system 'us-ascii
 +  "Encode ASCII as-is and encode non-ASCII characters to `?'."
 +  :coding-type 'charset
 +  :mnemonic ?-
 +  :charset-list '(ascii)
 +  :default-char ??
 +  :mime-charset 'us-ascii)
 +
 +(define-coding-system-alias 'iso-safe 'us-ascii)
 +
 +(define-coding-system 'utf-7
 +  "UTF-7 encoding of Unicode (RFC 2152)."
 +  :coding-type 'utf-8
 +  :mnemonic ?U
 +  :mime-charset 'utf-7
 +  :charset-list '(unicode)
 +  :pre-write-conversion 'utf-7-pre-write-conversion
 +  :post-read-conversion 'utf-7-post-read-conversion)
 +
 +;; Use us-ascii for terminal output if some other coding system is not
  ;; specified explicitly.
 -(set-safe-terminal-coding-system-internal 'iso-safe)
 +(set-safe-terminal-coding-system-internal 'us-ascii)
  
  ;; The other coding-systems are defined in each language specific
 -;; section of languages.el.
 +;; files under lisp/language.
  
  ;; Normally, set coding system to `undecided' before reading a file.
  ;; Compiled Emacs Lisp files (*.elc) are not decoded at all,
  ;; Tar files are not decoded at all, but we treat them as raw bytes.
  
  (setq file-coding-system-alist
 -      '(("\\.elc\\'" . (emacs-mule . emacs-mule))
 +      '(("\\.elc\\'" . utf-8-emacs)
        ("\\.utf\\(-8\\)?\\'" . utf-8)
 +      ;; This is the defined default for XML documents.  It may be
 +      ;; overridden by a charset specification in the header.  That
 +      ;; should be grokked by the auto-coding mechanism, but rms
 +      ;; vetoed that.  -- fx
 +      ("\\.xml\\'" . utf-8)
        ;; We use raw-text for reading loaddefs.el so that if it
        ;; happens to have DOS or Mac EOLs, they are converted to
        ;; newlines.  This is required to make the special treatment
  ;; values are set by the command `set-language-environment' for each
  ;; language environment.
  
 -(setq coding-category-emacs-mule      'emacs-mule
 -      coding-category-sjis            'japanese-shift-jis
 -      coding-category-iso-7           'iso-2022-7bit
 -      coding-category-iso-7-tight     'iso-2022-jp
 -      coding-category-iso-8-1         'iso-latin-1
 -      coding-category-iso-8-2         'iso-latin-1
 -      coding-category-iso-7-else      'iso-2022-7bit-lock
 -      coding-category-iso-8-else      'iso-2022-8bit-ss2
 -      coding-category-ccl             nil
 -      coding-category-utf-8           'mule-utf-8
 -      coding-category-utf-16-be         'mule-utf-16be-with-signature
 -      coding-category-utf-16-le         'mule-utf-16le-with-signature
 -      coding-category-big5            'chinese-big5
 -      coding-category-raw-text                'raw-text
 -      coding-category-binary          'no-conversion)
 -
 -(set-coding-priority
 - '(coding-category-iso-8-1
 -   coding-category-iso-8-2
 -   coding-category-utf-8
 -   coding-category-utf-16-be
 -   coding-category-utf-16-le
 -   coding-category-iso-7-tight
 -   coding-category-iso-7
 -   coding-category-iso-7-else
 -   coding-category-iso-8-else
 -   coding-category-emacs-mule
 -   coding-category-raw-text
 -   coding-category-sjis
 -   coding-category-big5
 -   coding-category-ccl
 -   coding-category-binary
 -   ))
 +(set-coding-system-priority
 + 'iso-latin-1
 + 'utf-8
 + 'iso-2022-7bit
 + )
  
  \f
  ;;; Miscellaneous settings.
 +
 +;; Make all multibyte characters self-insert.
 +(set-char-table-range (nth 1 global-map)
 +                    (cons 128 (max-char))
 +                    'self-insert-command)
 +
  (aset latin-extra-code-table ?\221 t)
  (aset latin-extra-code-table ?\222 t)
  (aset latin-extra-code-table ?\223 t)
  (aset latin-extra-code-table ?\225 t)
  (aset latin-extra-code-table ?\226 t)
  
 -(update-coding-systems-internal)
 +;; Move least specific charsets to end of priority list
 +
 +(apply #'set-charset-priority
 +       (delq 'unicode (delq 'emacs (charset-priority-list))))
 +
 +;; The old code-pages library is obsoleted by coding systems based on
 +;; the charsets defined in this file but might be required by user
 +;; code.
 +(provide 'code-pages)
 +
 +;; Local variables:
 +;; no-byte-compile: t
 +;; End:
  
  ;; arch-tag: 7d5fed55-b6df-42f6-8d3d-0011190551f5
  ;;; mule-conf.el ends here
index a67b021341678efbe97613dfbb3d9d8baaaab09c,80bfd2dbfa31a2c3419014ed64bb03ef7d4095ff..286a6410fdfaa64ce8e3c2105ae9759b3ee2c81c
@@@ -1,14 -1,11 +1,14 @@@
  ;;; mule-diag.el --- show diagnosis of multilingual environment (Mule)
  
  ;; Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006  Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007  Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multilingual, charset, coding system, fontset, diagnosis, i18n
  
@@@ -38,8 -35,8 +38,8 @@@
  
  ;;; General utility function
  
 -;; Print all arguments with single space separator in one line.
  (defun print-list (&rest args)
 +  "Print all arguments with single space separator in one line."
    (while (cdr args)
      (when (car args)
        (princ (car args))
    (princ (car args))
    (princ "\n"))
  
 -;; Re-order the elements of charset-list.
 -(defun sort-charset-list ()
 -  (setq charset-list
 -      (sort charset-list
 -            (lambda (x y) (< (charset-id x) (charset-id y))))))
 -
  ;;; CHARSET
  
  (define-button-type 'sort-listed-character-sets
    'help-function #'list-charset-chars
    'help-echo "mouse-2, RET: show table of characters for this character set")
  
 -;;;###autoload
 -(defvar non-iso-charset-alist
 -  `((mac-roman
 -     (ascii latin-iso8859-1 mule-unicode-2500-33ff
 -          mule-unicode-0100-24ff mule-unicode-e000-ffff)
 -     mac-roman-decoder
 -     ((0 255)))
 -    (viscii
 -     (ascii vietnamese-viscii-lower vietnamese-viscii-upper)
 -     viet-viscii-nonascii-translation-table
 -     ((0 255)))
 -    (vietnamese-tcvn
 -     (ascii vietnamese-viscii-lower vietnamese-viscii-upper)
 -     viet-tcvn-nonascii-translation-table
 -     ((0 255)))
 -    (koi8-r
 -     (ascii cyrillic-iso8859-5)
 -     cyrillic-koi8-r-nonascii-translation-table
 -     ((32 255)))
 -    (alternativnyj
 -     (ascii cyrillic-iso8859-5)
 -     cyrillic-alternativnyj-nonascii-translation-table
 -     ((32 255)))
 -    (koi8-u
 -     (ascii cyrillic-iso8859-5 mule-unicode-0100-24ff)
 -     cyrillic-koi8-u-nonascii-translation-table
 -     ((32 255)))
 -    (big5
 -     (ascii chinese-big5-1 chinese-big5-2)
 -     decode-big5-char
 -     ((32 127)
 -      ((?\xA1 ?\xFE) . (?\x40 ?\x7E ?\xA1 ?\xFE))))
 -    (sjis
 -     (ascii katakana-jisx0201 japanese-jisx0208)
 -     decode-sjis-char
 -     ((32 127 ?\xA1 ?\xDF)
 -      ((?\x81 ?\x9F ?\xE0 ?\xEF) . (?\x40 ?\x7E ?\x80 ?\xFC)))))
 -  "Alist of charset names vs the corresponding information.
 -This is mis-named for historical reasons.  The charsets are actually
 -non-built-in ones.  They correspond to Emacs coding systems, not Emacs
 -charsets, i.e. what Emacs can read (or write) by mapping to (or
 -from) Emacs internal charsets that typically correspond to a limited
 -set of ISO charsets.
 -
 -Each element has the following format:
 -  (CHARSET CHARSET-LIST TRANSLATION-METHOD [ CODE-RANGE ])
 -
 -CHARSET is the name (symbol) of the charset.
 -
 -CHARSET-LIST is a list of Emacs charsets into which characters of
 -CHARSET are mapped.
 -
 -TRANSLATION-METHOD is a translation table (symbol) to translate a
 -character code of CHARSET to the corresponding Emacs character
 -code.  It can also be a function to call with one argument, a
 -character code in CHARSET.
 -
 -CODE-RANGE specifies the valid code ranges of CHARSET.
 -It is a list of RANGEs, where each RANGE is of the form:
 -  (FROM1 TO1 FROM2 TO2 ...)
 -or
 -  ((FROM1-1 TO1-1 FROM1-2 TO1-2 ...) . (FROM2-1 TO2-1 FROM2-2 TO2-2 ...))
 -In the first form, valid codes are between FROM1 and TO1, or FROM2 and
 -TO2, or...
 -The second form is used for 2-byte codes.  The car part is the ranges
 -of the first byte, and the cdr part is the ranges of the second byte.")
 -
  ;;;###autoload
  (defun list-character-sets (arg)
    "Display a list of all character sets.
  
 -The ID-NUM column contains a charset identification number for
 -internal Emacs use.
 -
 -The MULTIBYTE-FORM column contains the format of the buffer and string
 -multibyte sequence of characters in the charset using one to four
 -hexadecimal digits.
 -  `xx' stands for any byte in the range 0..127.
 -  `XX' stands for any byte in the range 160..255.
 -
  The D column contains the dimension of this character set.  The CH
  column contains the number of characters in a block of this character
  set.  The FINAL-CHAR column contains an ISO-2022 <final-char> to use
@@@ -79,20 -158,22 +79,20 @@@ but still shows the full information.
        (if arg
          (list-character-sets-2)
        ;; Insert header.
 -      (insert "Indirectly supported character sets are shown below.\n")
 +      (insert "Supplementary character sets are shown below.\n")
        (insert
         (substitute-command-keys
          (concat "Use "
                  (if (display-mouse-p) "\\[help-follow-mouse] or ")
                  "\\[help-follow]:\n")))
        (insert "  on a column title to sort by that title,")
 -      (indent-to 56)
 +      (indent-to 48)
        (insert "+----DIMENSION\n")
        (insert "  on a charset name to list characters.")
 -      (indent-to 56)
 +      (indent-to 48)
        (insert "| +--CHARS\n")
 -      (let ((columns '(("ID-NUM" . id) "\t"
 -                       ("CHARSET-NAME" . name) "\t\t\t"
 -                       ("MULTIBYTE-FORM" . id) "\t"
 -                       ("D CH FINAL-CHAR" . iso-spec)))
 +      (let ((columns '(("CHARSET-NAME" . name) "\t\t\t\t\t"
 +                       ("D CH  FINAL-CHAR" . iso-spec)))
              pos)
          (while columns
            (if (stringp (car columns))
              (goto-char (point-max)))
            (setq columns (cdr columns)))
          (insert "\n"))
 -      (insert "------\t------------\t\t\t--------------\t- -- ----------\n")
 +      (insert "------------\t\t\t\t\t- --- ----------\n")
  
        ;; Insert body sorted by charset IDs.
 -      (list-character-sets-1 'id)
 -
 -      ;; Insert non-directly-supported charsets.
 -      (insert-char ?- 72)
 -      (insert "\n\nINDIRECTLY SUPPORTED CHARSETS SETS:\n\n"
 -              (propertize "CHARSET NAME\tMAPPED TO" 'face 'bold)
 -              "\n------------\t---------\n")
 -      (dolist (elt non-iso-charset-alist)
 -        (insert-text-button (symbol-name (car elt))
 -                            :type 'list-charset-chars
 -                            'help-args (list (car elt)))
 -        (indent-to 16)
 -        (dolist (e (nth 1 elt))
 -          (when (>= (+ (current-column) 1 (string-width (symbol-name e)))
 -                    ;; This is an approximate value.  We don't know
 -                    ;; the correct window width of this buffer yet.
 -                    78)
 -            (insert "\n")
 -            (indent-to 16))
 -
 -          (insert (format "%s " e)))
 -        (insert "\n"))))))
 +      (list-character-sets-1 'name)))))
  
  (defun sort-listed-character-sets (sort-key)
    (if sort-key
        (save-excursion
 -      (help-setup-xref (list #'list-character-sets nil) t)
        (let ((buffer-read-only nil))
          (goto-char (point-min))
 -        (re-search-forward "[0-9][0-9][0-9]")
 -        (beginning-of-line)
 -        (let ((pos (point)))
 -          (search-forward "----------")
 -          (beginning-of-line)
 -          (save-restriction
 -            (narrow-to-region pos (point))
 -            (delete-region (point-min) (point-max))
 -            (list-character-sets-1 sort-key)))))))
 -
 -(defun charset-multibyte-form-string (charset)
 -  (let ((info (charset-info charset)))
 -    (cond ((eq charset 'ascii)
 -         "xx")
 -        ((eq charset 'eight-bit-control)
 -         (format "%2X Xx" (aref info 6)))
 -        ((eq charset 'eight-bit-graphic)
 -         "XX")
 -        (t
 -         (let ((str (format "%2X" (aref info 6))))
 -           (if (> (aref info 7) 0)
 -               (setq str (format "%s %2X"
 -                                 str (aref info 7))))
 -           (setq str (concat str " XX"))
 -           (if (> (aref info 2) 1)
 -               (setq str (concat str " XX")))
 -           str)))))
 -
 -;; Insert a list of character sets sorted by SORT-KEY.  SORT-KEY
 -;; should be one of `id', `name', and `iso-spec'.  If SORT-KEY is nil,
 -;; it defaults to `id'.
 +        (search-forward "\n-")
 +        (forward-line 1)
 +        (delete-region (point) (point-max))
 +        (list-character-sets-1 sort-key)))))
  
  (defun list-character-sets-1 (sort-key)
 +  "Insert a list of character sets sorted by SORT-KEY.
 +SORT-KEY should be `name' or `iso-spec' (default `name')."
    (or sort-key
 -      (setq sort-key 'id))
 -  (let ((tail (charset-list))
 -      charset-info-list elt charset info sort-func)
 -    (while tail
 -      (setq charset (car tail) tail (cdr tail)
 -          info (charset-info charset))
 -
 +      (setq sort-key 'name))
 +  (let ((tail charset-list)
 +      charset-info-list supplementary-list charset sort-func)
 +    (dolist (charset charset-list)
        ;; Generate a list that contains all information to display.
 -      (setq charset-info-list
 -          (cons (list (charset-id charset)    ; ID-NUM
 -                      charset                 ; CHARSET-NAME
 -                      (charset-multibyte-form-string charset); MULTIBYTE-FORM
 -                      (aref info 2)           ; DIMENSION
 -                      (aref info 3)           ; CHARS
 -                      (aref info 8)           ; FINAL-CHAR
 -                      )
 -                charset-info-list)))
 +      (let ((elt (list charset
 +                     (charset-dimension charset)
 +                     (charset-chars charset)
 +                     (charset-iso-final-char charset))))
 +      (if (plist-get (charset-plist charset) :supplementary-p)
 +          (push elt supplementary-list)
 +        (push elt charset-info-list))))
  
      ;; Determine a predicate for `sort' by SORT-KEY.
      (setq sort-func
 -        (cond ((eq sort-key 'id)
 -               (lambda (x y) (< (car x) (car y))))
 -
 -              ((eq sort-key 'name)
 -               (lambda (x y) (string< (nth 1 x) (nth 1 y))))
 +        (cond ((eq sort-key 'name)
 +               (lambda (x y) (string< (car x) (car y))))
  
                ((eq sort-key 'iso-spec)
                 ;; Sort by DIMENSION CHARS FINAL-CHAR
 -               (lambda (x y)
 -                 (or (< (nth 3 x) (nth 3 y))
 -                     (and (= (nth 3 x) (nth 3 y))
 -                          (or (< (nth 4 x) (nth 4 y))
 -                              (and (= (nth 4 x) (nth 4 y))
 -                                   (< (nth 5 x) (nth 5 y))))))))
 +               (function
 +                (lambda (x y)
 +                  (or (< (nth 1 x) (nth 1 y))
 +                      (and (= (nth 1 x) (nth 1 y))
 +                           (or (< (nth 2 x) (nth 2 y))
 +                               (and (= (nth 2 x) (nth 2 y))
 +                                    (< (nth 3 x) (nth 3 y)))))))))
                (t
                 (error "Invalid charset sort key: %s" sort-key))))
  
      (setq charset-info-list (sort charset-info-list sort-func))
 +    (setq supplementary-list (sort supplementary-list sort-func))
  
      ;; Insert information of character sets.
 -    (while charset-info-list
 -      (setq elt (car charset-info-list)
 -          charset-info-list (cdr charset-info-list))
 -      (insert (format "%03d(%02X)" (car elt) (car elt))) ; ID-NUM
 -      (indent-to 8)
 -      (insert-text-button (symbol-name (nth 1 elt))
 -                        :type 'list-charset-chars
 -                        'help-args (list (nth 1 elt)))
 -      (goto-char (point-max))
 -      (insert "\t")
 -      (indent-to 40)
 -      (insert (nth 2 elt))            ; MULTIBYTE-FORM
 -      (indent-to 56)
 -      (insert (format "%d %2d " (nth 3 elt) (nth 4 elt)) ; DIMENSION and CHARS
 -            (if (< (nth 5 elt) 0) "none" (nth 5 elt))) ; FINAL-CHAR
 +    (dolist (elt (append charset-info-list (list t) supplementary-list))
 +      (if (eq elt t)
 +        (insert "-------------- Supplementary Character Sets --------------")
 +      (insert-text-button (symbol-name (car elt)) ; NAME
 +                          :type 'list-charset-chars
 +                          'help-args (list (car elt)))
 +      (goto-char (point-max))
 +      (insert "\t")
 +      (indent-to 48)
 +      (insert (format "%d %3d "
 +                      (nth 1 elt) (nth 2 elt)) ; DIMENSION and CHARS
 +              (if (< (nth 3 elt) 0)
 +                  "none"
 +                (nth 3 elt))))        ; FINAL-CHAR
        (insert "\n"))))
  
  
  ## Each line corresponds to one charset.
  ## The following attributes are listed in this order
  ## separated by a colon `:' in one line.
 -##    CHARSET-ID,
  ##    CHARSET-SYMBOL-NAME,
  ##    DIMENSION (1 or 2)
  ##    CHARS (94 or 96)
 -##    BYTES (of multibyte form: 1, 2, 3, or 4),
  ##    WIDTH (occupied column numbers: 1 or 2),
  ##    DIRECTION (0:left-to-right, 1:right-to-left),
  ##    ISO-FINAL-CHAR (character code of ISO-2022's final character)
        charset)
      (while l
        (setq charset (car l) l (cdr l))
 -      (princ (format "%03d:%s:%d:%d:%d:%d:%d:%d:%d:%s\n"
 -                   (charset-id charset)
 +      (princ (format "%s:%d:%d:%d:%d:%s\n"
                     charset
                     (charset-dimension charset)
                     (charset-chars charset)
 -                   (charset-bytes charset)
 -                   (charset-width charset)
 -                   (charset-direction charset)
 +                   (aref char-width-table (make-char charset))
 +;;;                (charset-direction charset)
                     (charset-iso-final-char charset)
 -                   (charset-iso-graphic-plane charset)
 +;;;                (charset-iso-graphic-plane charset)
                     (charset-description charset))))))
  
 +(defvar non-iso-charset-alist nil
 +  "Obsolete.")
 +(make-obsolete-variable 'non-iso-charset-alist "no longer relevant" "23.1")
 +
  (defun decode-codepage-char (codepage code)
    "Decode a character that has code CODE in CODEPAGE.
  Return a decoded character string.  Each CODEPAGE corresponds to a
 -coding system cpCODEPAGE."
 -  (let ((coding-system (intern (format "cp%d" codepage))))
 -    (or (coding-system-p coding-system)
 -      (codepage-setup codepage))
 -    (string-to-char
 -     (decode-coding-string (char-to-string code) coding-system))))
 +coding system cpCODEPAGE.  This function is obsolete."
 +  (decode-char (intern (format "cp%d" codepage)) code))
 +(make-obsolete 'decode-codepage-char 'decode-char "23.1")
  
  ;; A variable to hold charset input history.
  (defvar charset-history nil)
  ;;;###autoload
  (defun read-charset (prompt &optional default-value initial-input)
    "Read a character set from the minibuffer, prompting with string PROMPT.
 -It must be an Emacs character set listed in the variable `charset-list'
 -or a non-ISO character set listed in the variable
 -`non-iso-charset-alist'.
 +It must be an Emacs character set listed in the variable `charset-list'.
  
  Optional arguments are DEFAULT-VALUE and INITIAL-INPUT.
  DEFAULT-VALUE, if non-nil, is the default value.
  INITIAL-INPUT, if non-nil, is a string inserted in the minibuffer initially.
  See the documentation of the function `completing-read' for the
  detailed meanings of these arguments."
 -  (let* ((table (append (mapcar (lambda (x) (list (symbol-name x)))
 -                              charset-list)
 -                      (mapcar (lambda (x) (list (symbol-name (car x))))
 -                              non-iso-charset-alist)))
 +  (let* ((table (mapcar (lambda (x) (list (symbol-name x))) charset-list))
         (charset (completing-read prompt table
                                   nil t initial-input 'charset-history
                                   default-value)))
      (if (> (length charset) 0)
        (intern charset))))
  
 -
  ;; List characters of the range MIN and MAX of CHARSET.  If dimension
  ;; of CHARSET is two (i.e. 2-byte charset), ROW is the first byte
  ;; (block index) of the characters, and MIN and MAX are the second
  ;; bytes of the characters.  If the dimension is one, ROW should be 0.
 -;; For a non-ISO charset, CHARSET is a translation table (symbol) or a
 -;; function to get Emacs' character codes that corresponds to the
 -;; characters to list.
  
  (defun list-block-of-chars (charset row min max)
    (let (i ch)
 -    (insert-char ?- (+ 4 (* 3 16)))
 -    (insert "\n    ")
 +    (insert-char ?- (+ 7 (* 4 16)))
 +    (insert "\n     ")
      (setq i 0)
      (while (< i 16)
 -      (insert (format "%3X" i))
 +      (insert (format "%4X" i))
        (setq i (1+ i)))
      (setq i (* (/ min 16) 16))
      (while (<= i max)
        (if (= (% i 16) 0)
 -        (insert (format "\n%3Xx" (/ (+ (* row 256) i) 16))))
 -      (setq ch (cond ((< i min)
 -                    32)
 -                   ((charsetp charset)
 -                    (if (= row 0)
 -                        (make-char charset i)
 -                      (make-char charset row i)))
 -                   ((and (symbolp charset) (get charset 'translation-table))
 -                    (aref (get charset 'translation-table) i))
 -                   (t (funcall charset (+ (* row 256) i)))))
 -      (if (and (char-table-p charset)
 -             (or (< ch 32) (and (>= ch 127) (<= ch 255))))
 -        ;; Don't insert a control code.
 -        (setq ch 32))
 -      (unless ch (setq ch 32))
 -      (if (eq ch ?\t)
 -        ;; Make it visible.
 -        (setq ch (propertize "\t" 'display "^I")))
 -      ;; This doesn't DTRT.  Maybe it's better to insert "^J" and not
 -      ;; worry about the buffer contents not being correct.
 -;;;       (if (eq ch ?\n)
 -;;;   (setq ch (propertize "\n" 'display "^J")))
 -      (indent-to (+ (* (% i 16) 3) 6))
 -      (insert ch)
 +        (insert (format "\n%6Xx" (/ (+ (* row 256) i) 16))))
 +      (setq ch (if (< i min)
 +                 32
 +               (or (decode-char charset (+ (* row 256) i))
 +                   32)))              ; gap in mapping
 +      ;; Don't insert a control code.
 +      (if (or (< ch 32) (= ch 127))
 +        (setq ch (single-key-description ch))
 +      (if (and (>= ch 128) (< ch 160))
 +          (setq ch (format "%02Xh" ch))))
 +      (insert "\t" ch)
        (setq i (1+ i))))
    (insert "\n"))
  
 -(defun list-iso-charset-chars (charset)
 -  (let ((dim (charset-dimension charset))
 -      (chars (charset-chars charset))
 -      (plane (charset-iso-graphic-plane charset))
 -      min max)
 -    (insert (format "Characters in the coded character set %s.\n" charset))
 -
 -    (cond ((eq charset 'eight-bit-control)
 -         (setq min 128 max 159))
 -        ((eq charset 'eight-bit-graphic)
 -         (setq min 160 max 255))
 -        (t
 -         (if (= chars 94)
 -             (setq min 33 max 126)
 -           (setq min 32 max 127))
 -         (or (= plane 0)
 -             (setq min (+ min 128) max (+ max 128)))))
 -
 -    (if (= dim 1)
 -      (list-block-of-chars charset 0 min max)
 -      (let ((i min))
 -      (while (<= i max)
 -        (list-block-of-chars charset i min max)
 -        (setq i (1+ i)))))))
 -
 -(defun list-non-iso-charset-chars (charset)
 -  "List all characters in non-built-in coded character set CHARSET."
 -  (let* ((slot (assq charset non-iso-charset-alist))
 -       (charsets (nth 1 slot))
 -       (translate-method (nth 2 slot))
 -       (ranges (nth 3 slot))
 -       range)
 -    (or slot
 -      (error "Unknown character set: %s" charset))
 -    (insert (format "Characters in the coded character set %s.\n" charset))
 -    (if charsets
 -      (insert "They are mapped to: "
 -              (mapconcat #'symbol-name charsets ", ")
 -              "\n"))
 -    (while ranges
 -      (setq range (pop ranges))
 -      (if (integerp (car range))
 -        ;; The form of RANGES is (FROM1 TO1 FROM2 TO2 ...).
 -        (if (and (not (functionp translate-method))
 -                 (< (car (last range)) 256))
 -            ;; Do it all in one block to avoid the listing being
 -            ;; broken up at gaps in the range.  Don't do that for
 -            ;; function translate-method, since not all codes in
 -            ;; that range may be valid.
 -            (list-block-of-chars translate-method
 -                                 0 (car range) (car (last range)))
 -          (while range
 -            (list-block-of-chars translate-method
 -                                 0 (car range) (nth 1 range))
 -            (setq range (nthcdr 2 range))))
 -      ;; The form of RANGES is ((FROM1-1 TO1-1 ...) . (FROM2-1 TO2-1 ...)).
 -      (let ((row-range (car range))
 -            row row-max
 -            col-range col col-max)
 -        (while row-range
 -          (setq row (car row-range) row-max (nth 1 row-range)
 -                row-range (nthcdr 2 row-range))
 -          (while (<= row row-max)
 -            (setq col-range (cdr range))
 -            (while col-range
 -              (setq col (car col-range) col-max (nth 1 col-range)
 -                    col-range (nthcdr 2 col-range))
 -              (list-block-of-chars translate-method row col col-max))
 -            (setq row (1+ row)))))))))
 -
 -
  ;;;###autoload
  (defun list-charset-chars (charset)
 -  "Display a list of characters in the specified character set.
 -This can list both Emacs `official' (ISO standard) charsets and the
 -characters encoded by various Emacs coding systems which correspond to
 -PC `codepages' and other coded character sets.  See `non-iso-charset-alist'."
 +  "Display a list of characters in character set CHARSET."
    (interactive (list (read-charset "Character set: ")))
 +  (or (charsetp charset)
 +      (error "Invalid character set: %s" charset))
    (with-output-to-temp-buffer "*Character List*"
      (with-current-buffer standard-output
 +      (if (coding-system-p charset)
 +        ;; Useful to be able to do C-u C-x = to find file code, for
 +        ;; instance:
 +        (set-buffer-file-coding-system charset))
        (setq mode-line-format (copy-sequence mode-line-format))
        (let ((slot (memq 'mode-line-buffer-identification mode-line-format)))
        (if slot
            (setcdr slot
                    (cons (format " (%s)" charset)
                          (cdr slot)))))
 -      (setq indent-tabs-mode nil)
 +      (setq tab-width 4)
        (set-buffer-multibyte t)
 -      (cond ((charsetp charset)
 -           (list-iso-charset-chars charset))
 -          ((assq charset non-iso-charset-alist)
 -           (list-non-iso-charset-chars charset))
 -          (t
 -           (error "Invalid character set %s" charset))))))
 +      (let ((dim (charset-dimension charset))
 +          (chars (charset-chars charset))
 +          ;;  (plane (charset-iso-graphic-plane charset))
 +          (plane 1)
 +          (range (plist-get (charset-plist charset) :code-space))
 +          min max min2 max2)
 +      (if (> dim 2)
 +          (error "Can only list 1- and 2-dimensional charsets"))
 +      (insert (format "Characters in the coded character set %s.\n" charset))
 +      (narrow-to-region (point) (point))
 +      (setq min (aref range 0)
 +            max (aref range 1))
 +      (if (= dim 1)
 +          (list-block-of-chars charset 0 min max)
 +        (setq min2 (aref range 2)
 +              max2 (aref range 3))
 +        (let ((i min2))
 +          (while (<= i max2)
 +            (list-block-of-chars charset i min max)
 +            (setq i (1+ i)))))
 +      (put-text-property (point-min) (point-max) 'charset charset)
 +      (widen)))))
  
  
  ;;;###autoload
  (defun describe-character-set (charset)
    "Display information about built-in character set CHARSET."
 -  (interactive (list (let ((non-iso-charset-alist nil))
 -                     (read-charset "Charset: "))))
 +  (interactive (list (read-charset "Charset: ")))
    (or (charsetp charset)
        (error "Invalid charset: %S" charset))
 -  (let ((info (charset-info charset)))
 -    (help-setup-xref (list #'describe-character-set charset) (interactive-p))
 -    (with-output-to-temp-buffer (help-buffer)
 -      (with-current-buffer standard-output
 -      (insert "Character set: " (symbol-name charset)
 -              (format " (ID:%d)\n\n" (aref info 0)))
 -      (insert (aref info 13) "\n\n")  ; description
 -      (insert "Number of contained characters: "
 -              (if (= (aref info 2) 1)
 -                  (format "%d\n" (aref info 3))
 -                (format "%dx%d\n" (aref info 3) (aref info 3))))
 -      (insert "Final char of ISO2022 designation sequence: ")
 -      (if (>= (aref info 8) 0)
 -          (insert (format "`%c'\n" (aref info 8)))
 -        (insert "not assigned\n"))
 -      (insert (format "Width (how many columns on screen): %d\n"
 -                      (aref info 4)))
 -      (insert (format "Internal multibyte sequence: %s\n"
 -                      (charset-multibyte-form-string charset)))
 -      (let ((coding (plist-get (aref info 14) 'preferred-coding-system)))
 -        (when coding
 -          (insert (format "Preferred coding system: %s\n" coding))
 -          (search-backward (symbol-name coding))
 -          (help-xref-button 0 'help-coding-system coding)))))))
 +  (help-setup-xref (list #'describe-character-set charset) (interactive-p))
 +  (with-output-to-temp-buffer (help-buffer)
 +    (with-current-buffer standard-output
 +      (insert "Character set: " (symbol-name charset))
 +      (let ((name (get-charset-property charset :name)))
 +      (if (not (eq name charset))
 +          (insert " (alias of " (symbol-name name) ?\))))
 +      (insert "\n\n" (charset-description charset) "\n\n")
 +      (insert "Number of contained characters: ")
 +      (dotimes (i (charset-dimension charset))
 +      (unless (= i 0)
 +        (insert ?x))
 +      (insert (format "%d" (charset-chars charset (1+ i)))))
 +      (insert ?\n)
 +      (let ((char (charset-iso-final-char charset)))
 +      (when (> char 0)
 +        (insert "Final char of ISO2022 designation sequence: ")
 +        (insert (format "`%c'\n" char))))
 +      (insert (format "Width (how many columns on screen): %d\n"
 +                    (aref char-width-table (make-char charset))))
 +      (let (aliases)
 +      (dolist (c charset-list)
 +        (if (and (not (eq c charset))
 +                 (eq charset (get-charset-property c :name)))
 +            (push c aliases)))
 +      (if aliases
 +          (insert "Aliases: " (mapconcat #'symbol-name aliases ", ") ?\n)))
 +      
 +      (dolist (elt `((:ascii-compatible-p "ASCII compatible." nil)
 +                   (:map "Map file: " identity)
 +                   (:unify-map "Unification map file: " identity)
 +                   (:invalid-code
 +                    nil
 +                    ,(lambda (c)
 +                       (format "Invalid character: %c (code %d)" c c)))
 +                   (:emacs-mule-id "Id in emacs-mule coding system: "
 +                                   number-to-string)
 +                   (:parents "Parents: "
 +                             (lambda (parents)
 +                               (mapconcat ,(lambda (elt)
 +                                             (format "%s" elt))
 +                                          parents
 +                                          ", ")))
 +                   (:code-space "Code space: " ,(lambda (c)
 +                                                  (format "%s" c)))
 +                   (:code-offset "Code offset: " number-to-string)
 +                   (:iso-revision-number "ISO revision number: "
 +                                         number-to-string)
 +                   (:supplementary-p
 +                    "Used only as a parent of some other charset." nil)))
 +      (let ((val (get-charset-property charset (car elt))))
 +        (when val
 +          (if (cadr elt) (insert (cadr elt)))
 +          (if (nth 2 elt)
 +              (insert (funcall (nth 2 elt) val)))
 +          (insert ?\n)))))))
  \f
  ;;; CODING-SYSTEM
  
 -;; Print information of designation of each graphic register in FLAGS
 -;; in human readable format.  See the documentation of
 -;; `make-coding-system' for the meaning of FLAGS.
 -(defun print-designation (flags)
 -  (let ((graphic-register 0)
 -      charset)
 -    (while (< graphic-register 4)
 -      (setq charset (aref flags graphic-register))
 +(eval-when-compile                    ; dynamic bondage
 +  (defvar graphic-register))
 +
 +;; Print information about designation of each graphic register in
 +;; DESIGNATIONS in human readable format.  See the documentation of
 +;; `define-coding-system' for the meaning of DESIGNATIONS
 +;; (`:designation' property).
 +(defun print-designation (designations)
 +  (let (charset)
 +    (dotimes (graphic-register 4)
 +      (setq charset (aref designations graphic-register))
        (princ (format
              "  G%d -- %s\n"
              graphic-register
                                (charset-description (car charset)))))
                (t
                 "invalid designation information"))
 -        (setq charset (cdr charset))))
 -      (setq graphic-register (1+ graphic-register)))))
 +        (setq charset (cdr charset)))))))
  
  ;;;###autoload
  (defun describe-coding-system (coding-system)
                     (interactive-p))
      (with-output-to-temp-buffer (help-buffer)
        (print-coding-system-briefly coding-system 'doc-string)
 -      (princ "\n")
 -      (let ((vars (coding-system-get coding-system 'dependency)))
 -      (when vars
 -        (princ "See also the documentation of these customizable variables
 -which alter the behavior of this coding system.\n")
 -        (dolist (v vars)
 -          (princ "  `")
 -          (princ v)
 -          (princ "'\n"))
 -        (princ "\n")))
 -
 -      (princ "Type: ")
        (let ((type (coding-system-type coding-system))
 -          (flags (coding-system-flags coding-system)))
 +          ;; Fixme: use this
 +          (extra-spec (coding-system-plist coding-system)))
 +      (princ "Type: ")
        (princ type)
 -      (cond ((eq type nil)
 -             (princ " (do no conversion)"))
 -            ((eq type t)
 +      (cond ((eq type 'undecided)
               (princ " (do automatic conversion)"))
 -            ((eq type 0)
 -             (princ " (Emacs internal multibyte form)"))
 -            ((eq type 1)
 +            ((eq type 'utf-8)
 +             (princ " (UTF-8: Emacs internal multibyte form)"))
 +            ((eq type 'utf-16)
 +             ;; (princ " (UTF-16)")
 +             )
 +            ((eq type 'shift-jis)
               (princ " (Shift-JIS, MS-KANJI)"))
 -            ((eq type 2)
 +            ((eq type 'iso-2022)
               (princ " (variant of ISO-2022)\n")
               (princ "Initial designations:\n")
 -             (print-designation flags)
 -             (princ "Other Form: \n  ")
 -             (princ (if (aref flags 4) "short-form" "long-form"))
 -             (if (aref flags 5) (princ ", ASCII@EOL"))
 -             (if (aref flags 6) (princ ", ASCII@CNTL"))
 -             (princ (if (aref flags 7) ", 7-bit" ", 8-bit"))
 -             (if (aref flags 8) (princ ", use-locking-shift"))
 -             (if (aref flags 9) (princ ", use-single-shift"))
 -             (if (aref flags 10) (princ ", use-roman"))
 -             (if (aref flags 11) (princ ", use-old-jis"))
 -             (if (aref flags 12) (princ ", no-ISO6429"))
 -             (if (aref flags 13) (princ ", init-bol"))
 -             (if (aref flags 14) (princ ", designation-bol"))
 -             (if (aref flags 15) (princ ", convert-unsafe"))
 -             (if (aref flags 16) (princ ", accept-latin-extra-code"))
 -             (princ "."))
 -            ((eq type 3)
 -             (princ " (Big5)"))
 -            ((eq type 4)
 +             (print-designation (coding-system-get coding-system
 +                                                   :designation))
 +
 +             (when (coding-system-get coding-system :flags)
 +               (princ "Other specifications: \n  ")
 +               (apply #'print-list
 +                      (coding-system-get coding-system :flags))))
 +            ((eq type 'charset)
 +             (princ " (charset)"))
 +            ((eq type 'ccl)
               (princ " (do conversion by CCL program)"))
 -            ((eq type 5)
 +            ((eq type 'raw-text)
               (princ " (text with random binary characters)"))
 -            (t (princ ": invalid coding-system."))))
 -      (princ "\nEOL type: ")
 -      (let ((eol-type (coding-system-eol-type coding-system)))
 -      (cond ((vectorp eol-type)
 -             (princ "Automatic selection from:\n\t")
 -             (princ eol-type)
 -             (princ "\n"))
 -            ((or (null eol-type) (eq eol-type 0)) (princ "LF\n"))
 -            ((eq eol-type 1) (princ "CRLF\n"))
 -            ((eq eol-type 2) (princ "CR\n"))
 -            (t (princ "invalid\n"))))
 -      (let ((postread (coding-system-get coding-system 'post-read-conversion)))
 +            ((eq type 'emacs-mule)
 +             (princ " (Emacs 21 internal encoding)"))
 +            (t (princ ": invalid coding-system.")))
 +      (princ "\nEOL type: ")
 +      (let ((eol-type (coding-system-eol-type coding-system)))
 +        (cond ((vectorp eol-type)
 +               (princ "Automatic selection from:\n\t")
 +               (princ eol-type)
 +               (princ "\n"))
 +              ((or (null eol-type) (eq eol-type 0)) (princ "LF\n"))
 +              ((eq eol-type 1) (princ "CRLF\n"))
 +              ((eq eol-type 2) (princ "CR\n"))
 +              (t (princ "invalid\n")))))
 +      (let ((postread (coding-system-get coding-system :post-read-conversion)))
        (when postread
          (princ "After decoding text normally,")
          (princ " perform post-conversion using the function: ")
          (princ "\n  ")
          (princ postread)
          (princ "\n")))
 -      (let ((prewrite (coding-system-get coding-system 'pre-write-conversion)))
 +      (let ((prewrite (coding-system-get coding-system :pre-write-conversion)))
        (when prewrite
          (princ "Before encoding text normally,")
          (princ " perform pre-conversion using the function: ")
          (princ prewrite)
          (princ "\n")))
        (with-current-buffer standard-output
 -      (let ((charsets (coding-system-get coding-system 'safe-charsets)))
 -        (when (and (not (memq (coding-system-base coding-system)
 -                              '(raw-text emacs-mule)))
 +      (let ((charsets (coding-system-charset-list coding-system)))
 +        (when (and (not (eq (coding-system-base coding-system) 'raw-text))
                     charsets)
 -          (if (eq charsets t)
 -              (insert "This coding system can encode all charsets except for
 -eight-bit-control and eight-bit-graphic.\n")
 +          (cond
 +           ((eq charsets 'iso-2022)
 +            (insert "This coding system can encode all ISO 2022 charsets."))
 +           ((eq charsets 'emacs-mule)
 +            (insert "This coding system can encode all emacs-mule charsets\
 +."""))
 +           (t
              (insert "This coding system encodes the following charsets:\n ")
              (while charsets
                (insert " " (symbol-name (car charsets)))
                (search-backward (symbol-name (car charsets)))
                (help-xref-button 0 'help-character-set (car charsets))
                (goto-char (point-max))
 -              (setq charsets (cdr charsets))))))))))
 -
 +              (setq charsets (cdr charsets)))))))))))
  
  ;;;###autoload
  (defun describe-current-coding-system-briefly ()
@@@ -549,17 -742,18 +549,17 @@@ in place of `..'
       (coding-system-eol-type-mnemonic (cdr default-process-coding-system))
       )))
  
 -;; Print symbol name and mnemonic letter of CODING-SYSTEM with `princ'.
 -;; If DOC-STRING is non-nil, print also the docstring of CODING-SYSTEM.
 -;; If DOC-STRING is `tightly', don't print an empty line before the
 -;; docstring, and print only the first line of the docstring.
 -
  (defun print-coding-system-briefly (coding-system &optional doc-string)
 +  "Print symbol name and mnemonic letter of CODING-SYSTEM with `princ'.
 +If DOC-STRING is non-nil, print also the docstring of CODING-SYSTEM.
 +If DOC-STRING is `tightly', don't print an empty line before the
 +docstring, and print only the first line of the docstring."
    (if (not coding-system)
        (princ "nil\n")
      (princ (format "%c -- %s"
                   (coding-system-mnemonic coding-system)
                   coding-system))
 -    (let ((aliases (coding-system-get coding-system 'alias-coding-systems)))
 +    (let ((aliases (coding-system-aliases coding-system)))
        (cond ((eq coding-system (car aliases))
             (if (cdr aliases)
                 (princ (format " %S" (cons 'alias: (cdr aliases))))))
        (print-coding-system-briefly (keyboard-coding-system))
        (princ "Coding system for terminal output:\n  ")
        (print-coding-system-briefly (terminal-coding-system))
 +      (princ "Coding system for inter-client cut and paste:\n  ")
 +      (print-coding-system-briefly selection-coding-system)
        (when (get-buffer-process (current-buffer))
        (princ "Coding systems for process I/O:\n")
        (princ "  encoding input to the process: ")
  
        (princ "
  Priority order for recognizing coding systems when reading files:\n")
 -      (let ((l coding-category-list)
 -          (i 1)
 -          (coding-list nil)
 -          coding aliases)
 -      (while l
 -        (setq coding (symbol-value (car l)))
 -        ;; Do not list up the same coding system twice.
 -        (when (and coding (not (memq coding coding-list)))
 -          (setq coding-list (cons coding coding-list))
 -          (princ (format "  %d. %s " i coding))
 -          (setq aliases (coding-system-get coding 'alias-coding-systems))
 -          (if (eq coding (car aliases))
 +      (let ((i 1))
 +      (dolist (elt (coding-system-priority-list))
 +        (princ (format "  %d. %s " i elt))
 +        (let ((aliases (coding-system-aliases elt)))
 +          (if (eq elt (car aliases))
                (if (cdr aliases)
                    (princ (cons 'alias: (cdr aliases))))
 -            (if (memq coding aliases)
 -                (princ (list 'alias 'of (car aliases)))))
 +            (princ (list 'alias 'of (car aliases))))
            (terpri)
 -          (setq i (1+ i)))
 -        (setq l (cdr l))))
 +          (setq i (1+ i)))))
  
        (princ "\n  Other coding systems cannot be distinguished automatically
    from these, and therefore cannot be recognized automatically
    with the present coding system priorities.\n\n")
  
 +      ;; Fixme: should this be replaced or junked?
 +      (if nil
        (let ((categories '(coding-category-iso-7 coding-category-iso-7-else))
            coding-system codings)
        (while categories
          (mapcar
           (lambda (x)
             (if (and (not (eq x coding-system))
 -                    (coding-system-get x 'no-initial-designation)
 -                    (let ((flags (coding-system-flags x)))
 -                      (not (or (aref flags 10) (aref flags 11)))))
 +                     (let ((flags (coding-system-get :flags)))
 +                       (not (or (memq 'use-roman flags)
 +                                (memq 'use-oldjis flags)))))
                 (setq codings (cons x codings))))
           (get (car categories) 'coding-systems))
          (if codings
                    (goto-char (point-max)))
                  (setq codings (cdr codings)))
                (insert "\n\n")))
 -        (setq categories (cdr categories))))
 +        (setq categories (cdr categories)))))
  
        (princ "Particular coding systems specified for certain file names:\n")
        (terpri)
        (funcall func "Network I/O" network-coding-system-alist))
        (help-mode))))
  
 -;; Print detailed information on CODING-SYSTEM.
  (defun print-coding-system (coding-system)
 +  "Print detailed information on CODING-SYSTEM."
    (let ((type (coding-system-type coding-system))
        (eol-type (coding-system-eol-type coding-system))
 -      (flags (coding-system-flags coding-system))
 -      (aliases (coding-system-get coding-system 'alias-coding-systems)))
 +      (flags (coding-system-get coding-system :flags))
 +      (aliases (coding-system-aliases coding-system)))
      (if (not (eq (car aliases) coding-system))
        (princ (format "%s (alias of %s)\n" coding-system (car aliases)))
        (princ coding-system)
                     type
                     (coding-system-mnemonic coding-system)
                     (if (integerp eol-type) eol-type 3)))
 -      (cond ((eq type 2)              ; ISO-2022
 +      (cond ((eq type 'iso2022)
             (let ((idx 0)
                   charset)
               (while (< idx 4)
                 (princ ",")
                 (setq idx (1+ idx)))
               (princ (if (aref flags idx) 1 0))))
 -          ((eq type 4)                ; CCL
 +          ((eq type 'ccl)
             (let (i len)
               (if (symbolp (car flags))
                   (princ (format " %s" (car flags)))
@@@ -800,9 -999,19 +800,9 @@@ but still contains full information abo
    (dolist (coding-system (sort-coding-systems (coding-system-list 'base-only)))
      (if (null arg)
        (print-coding-system-briefly coding-system 'tightly)
 -      (print-coding-system coding-system)))
 -  (let ((first t))
 -    (dolist (elt coding-system-alist)
 -      (unless (memq (intern (car elt)) coding-system-list)
 -      (when first
 -        (princ "\
 -####################################################
 -# The following coding systems are not yet loaded. #
 -####################################################
 -")
 -        (setq first nil))
 -      (princ-list (car elt))))))
 +      (print-coding-system coding-system))))
  
 +;; Fixme: delete?
  ;;;###autoload
  (defun list-coding-categories ()
    "Display a list of all coding categories."
  \f
  ;;; FONT
  
 -;; Print information of a font in FONTINFO.
  (defun describe-font-internal (font-info &optional verbose)
 +  "Print information about a font in FONT-INFO."
    (print-list "name (opened by):" (aref font-info 0))
    (print-list "       full name:" (aref font-info 1))
    (print-list "            size:" (format "%2d" (aref font-info 2)))
@@@ -856,69 -1065,76 +856,69 @@@ The font must be already used by Emacs.
        (with-output-to-temp-buffer "*Help*"
        (describe-font-internal font-info 'verbose)))))
  
 -(defun print-fontset (fontset &optional print-fonts)
 +(defun print-fontset-element (val)
 +  ;; VAL has this format:
 +  ;;  ((REQUESTED-FONT-NAME OPENED-FONT-NAME ...) ...)
 +  ;; CHAR RANGE is already inserted.  Get character codes from
 +  ;; the current line.
 +  (beginning-of-line)
 +  (let ((from (following-char))
 +      (to (if (looking-at "[^.]*[.]* ")
 +              (char-after (match-end 0)))))
 +    (if (re-search-forward "[ \t]*$" nil t)
 +      (delete-region (match-beginning 0) (match-end 0)))
 +
 +    ;; For non-ASCII characters, insert also CODE RANGE.
 +    (if (or (>= from 128) (and to (>= to 128)))
 +      (if to
 +          (insert (format " (#x%02X .. #x%02X)" from to))
 +        (insert (format " (#x%02X)" from))))
 +
 +    ;; Insert a requested font name.
 +    (dolist (elt val)
 +      (let ((requested (car elt)))
 +      (if (stringp requested)
 +          (insert "\n    " requested)
 +        (let ((family (aref requested 0))
 +              (registry (aref requested 5)))
 +          (if (not family)
 +              (setq family "*-*")
 +            (or (string-match "-" family)
 +                (setq family (concat "*-" family))))
 +          (or (string-match "-" registry)
 +              (= (aref registry (1- (length registry))) ?*)
 +              (setq registry (concat registry "*")))
 +          (insert "\n    -" family
 +                  ?- (or (aref requested 1) ?*) ; weight
 +                  ?- (or (aref requested 2) ?*) ; slant
 +                  ?- (or (aref requested 3) ?*) ; width
 +                  ?- (or (aref requested 4) ?*) ; adstyle
 +                  "-*-*-*-*-*-*-" registry))))
 +
 +      ;; Insert opened font names (if any).
 +      (if (and (boundp 'print-opened) (symbol-value 'print-opened))
 +        (dolist (opened (cdr elt))
 +          (insert "\n\t[" opened "]"))))))
 +
 +(defun print-fontset (fontset &optional print-opened)
    "Print information about FONTSET.
  If FONTSET is nil, print information about the default fontset.
 -If optional arg PRINT-FONTS is non-nil, also print names of all opened
 +If optional arg PRINT-OPENED is non-nil, also print names of all opened
  fonts for FONTSET.  This function actually inserts the information in
  the current buffer."
    (or fontset
        (setq fontset (query-fontset "fontset-default")))
 -  (let ((tail (aref (fontset-info fontset) 2))
 -      elt chars font-spec opened prev-charset charset from to)
 -    (beginning-of-line)
 -    (insert "Fontset: " fontset "\n")
 -    (insert "CHARSET or CHAR RANGE")
 -    (indent-to 24)
 -    (insert "FONT NAME\n")
 -    (insert "---------------------")
 -    (indent-to 24)
 -    (insert "---------")
 -    (insert "\n")
 -    (while tail
 -      (setq elt (car tail) tail (cdr tail))
 -      (setq chars (car elt) font-spec (car (cdr elt)) opened (cdr (cdr elt)))
 -      (if (symbolp chars)
 -        (setq charset chars from nil to nil)
 -      (if (integerp chars)
 -          (setq charset (char-charset chars) from chars to chars)
 -        (setq charset (char-charset (car chars))
 -              from (car chars) to (cdr chars))))
 -      (unless (eq charset prev-charset)
 -      (insert (symbol-name charset))
 -      (if from
 -          (insert "\n")))
 -      (when from
 -      (let ((split (split-char from)))
 -        (if (and (= (charset-dimension charset) 2)
 -                 (= (nth 2 split) 0))
 -            (setq from
 -                  (make-char charset (nth 1 split)
 -                             (if (= (charset-chars charset) 94) 33 32))))
 -        (insert "  " from))
 -      (when (/= from to)
 -        (insert "-")
 -        (let ((split (split-char to)))
 -          (if (and (= (charset-dimension charset) 2)
 -                   (= (nth 2 split) 0))
 -              (setq to
 -                    (make-char charset (nth 1 split)
 -                               (if (= (charset-chars charset) 94) 126 127))))
 -          (insert to))))
 -      (indent-to 24)
 -      (if (stringp font-spec)
 -        (insert font-spec)
 -      (if (car font-spec)
 -          (if (string-match "-" (car font-spec))
 -              (insert "-" (car font-spec) "-*-")
 -            (insert "-*-" (car font-spec) "-*-"))
 -        (insert "-*-"))
 -      (if (cdr font-spec)
 -          (if (string-match "-" (cdr font-spec))
 -              (insert (cdr font-spec))
 -            (insert (cdr font-spec) "-*"))
 -        (insert "*")))
 -      (insert "\n")
 -      (when print-fonts
 -      (while opened
 -        (indent-to 5)
 -        (insert "[" (car opened) "]\n")
 -        (setq opened (cdr opened))))
 -      (setq prev-charset charset)
 -      )))
 +  (beginning-of-line)
 +  (insert "Fontset: " fontset "\n")
 +  (insert (propertize "CHAR RANGE" 'face 'underline)
 +         " (" (propertize "CODE RANGE" 'face 'underline) ")\n")
 +  (insert "    " (propertize "FONT NAME" 'face 'underline)
 +        " (" (propertize "REQUESTED" 'face 'underline)
 +        " and [" (propertize "OPENED" 'face 'underline) "])")
 +  (let ((info (fontset-info fontset)))
 +    (describe-vector info 'print-fontset-element)
 +    (insert "\n  ---<fallback to the default fontset>---")
 +    (describe-vector (char-table-extra-slot info 0) 'print-fontset-element)))
  
  ;;;###autoload
  (defun describe-fontset (fontset)
@@@ -1075,6 -1291,16 +1075,6 @@@ system which uses fontsets).
  
        (insert-section 4 "Coding systems")
        (list-coding-systems-1 t)
 -      (princ "\
 -############################
 -## LIST OF CODING CATEGORIES (ordered by priority)
 -## CATEGORY:CODING-SYSTEM
 -##
 -")
 -      (let ((l coding-category-list))
 -      (while l
 -        (princ (format "%s:%s\n" (car l) (symbol-value (car l))))
 -        (setq l (cdr l))))
        (insert "\n")
  
        (insert-section 5 "Character sets")
            (setq fontsets (cdr fontsets)))))
        (print-help-return-message))))
  
 +;;;###autoload
 +(defcustom unicodedata-file nil
 +  "Location of UnicodeData file.
 +This is the UnicodeData.txt file from the Unicode consortium, used for
 +diagnostics.  If it is non-nil `describe-char-after' will print data
 +looked up from it."
 +  :group 'mule
 +  :type '(choice (const :tag "None" nil)
 +               file))
 +
 +;; We could convert the unidata file into a Lispy form once-for-all
 +;; and distribute it for loading on demand.  It might be made more
 +;; space-efficient by splitting strings word-wise and replacing them
 +;; with lists of symbols interned in a private obarray, e.g.
 +;; "LATIN SMALL LETTER A" => '(LATIN SMALL LETTER A).
 +
 +;;;###autoload
 +(defun unicode-data (char)
 +  "Return a list of Unicode data for unicode CHAR.
 +Each element is a list of a property description and the property value.
 +The list is null if CHAR isn't found in `unicodedata-file'."
 +  (when unicodedata-file
 +    (unless (file-exists-p unicodedata-file)
 +      (error "`unicodedata-file' %s not found" unicodedata-file))
 +    (save-excursion
 +      (set-buffer (find-file-noselect unicodedata-file t t))
 +      (goto-char (point-min))
 +      (let ((hex (format "%04X" char))
 +          found first last)
 +      (if (re-search-forward (concat "^" hex) nil t)
 +          (setq found t)
 +        ;; It's not listed explicitly.  Look for ranges, e.g. CJK
 +        ;; ideographs, and check whether it's in one of them.
 +        (while (and (re-search-forward "^\\([^;]+\\);[^;]+First>;" nil t)
 +                    (>= char (setq first
 +                                   (string-to-number (match-string 1) 16)))
 +                    (progn
 +                      (forward-line 1)
 +                      (looking-at "^\\([^;]+\\);[^;]+Last>;")
 +                      (> char
 +                         (setq last
 +                               (string-to-number (match-string 1) 16))))))
 +        (if (and (>= char first)
 +                 (<= char last))
 +            (setq found t)))
 +      (if found
 +          (let ((fields (mapcar (lambda (elt)
 +                                  (if (> (length elt) 0)
 +                                      elt))
 +                                (cdr (split-string
 +                                      (buffer-substring
 +                                       (line-beginning-position)
 +                                       (line-end-position))
 +                                      ";")))))
 +            ;; The length depends on whether the last field was empty.
 +            (unless (or (= 13 (length fields))
 +                        (= 14 (length fields)))
 +              (error "Invalid contents in %s" unicodedata-file))
 +            ;; The field names and values lists are slightly
 +            ;; modified from Mule-UCS unidata.el.
 +            (list
 +             (list "Name" (let ((name (nth 0 fields)))
 +                            ;; Check for <..., First>, <..., Last>
 +                            (if (string-match "\\`\\(<[^,]+\\)," name)
 +                                (concat (match-string 1 name) ">")
 +                              name)))
 +             (list "Category"
 +                   (cdr (assoc
 +                         (nth 1 fields)
 +                         '(("Lu" . "uppercase letter")
 +                           ("Ll" . "lowercase letter")
 +                           ("Lt" . "titlecase letter")
 +                           ("Mn" . "non-spacing mark")
 +                           ("Mc" . "spacing-combining mark")
 +                           ("Me" . "enclosing mark")
 +                           ("Nd" . "decimal digit")
 +                           ("Nl" . "letter number")
 +                           ("No" . "other number")
 +                           ("Zs" . "space separator")
 +                           ("Zl" . "line separator")
 +                           ("Zp" . "paragraph separator")
 +                           ("Cc" . "other control")
 +                           ("Cf" . "other format")
 +                           ("Cs" . "surrogate")
 +                           ("Co" . "private use")
 +                           ("Cn" . "not assigned")
 +                           ("Lm" . "modifier letter")
 +                           ("Lo" . "other letter")
 +                           ("Pc" . "connector punctuation")
 +                           ("Pd" . "dash punctuation")
 +                           ("Ps" . "open punctuation")
 +                           ("Pe" . "close punctuation")
 +                           ("Pi" . "initial-quotation punctuation")
 +                           ("Pf" . "final-quotation punctuation")
 +                           ("Po" . "other punctuation")
 +                           ("Sm" . "math symbol")
 +                           ("Sc" . "currency symbol")
 +                           ("Sk" . "modifier symbol")
 +                           ("So" . "other symbol")))))
 +             (list "Combining class"
 +                   (cdr (assoc
 +                         (string-to-number (nth 2 fields))
 +                         '((0 . "Spacing")
 +                           (1 . "Overlays and interior")
 +                           (7 . "Nuktas") 
 +                           (8 . "Hiragana/Katakana voicing marks")
 +                           (9 . "Viramas")
 +                           (10 . "Start of fixed position classes")
 +                           (199 . "End of fixed position classes")
 +                           (200 . "Below left attached")
 +                           (202 . "Below attached")
 +                           (204 . "Below right attached")
 +                           (208 . "Left attached (reordrant around \
 +single base character)")
 +                           (210 . "Right attached")
 +                           (212 . "Above left attached")
 +                           (214 . "Above attached")
 +                           (216 . "Above right attached")
 +                           (218 . "Below left")
 +                           (220 . "Below")
 +                           (222 . "Below right")
 +                           (224 . "Left (reordrant around single base \
 +character)")
 +                           (226 . "Right")
 +                           (228 . "Above left")
 +                           (230 . "Above")
 +                           (232 . "Above right")
 +                           (233 . "Double below")
 +                           (234 . "Double above")
 +                           (240 . "Below (iota subscript)")))))
 +             (list "Bidi category"
 +                   (cdr (assoc
 +                         (nth 3 fields)
 +                         '(("L" . "Left-to-Right")
 +                           ("LRE" . "Left-to-Right Embedding")
 +                           ("LRO" . "Left-to-Right Override")
 +                           ("R" . "Right-to-Left")
 +                           ("AL" . "Right-to-Left Arabic")
 +                           ("RLE" . "Right-to-Left Embedding")
 +                           ("RLO" . "Right-to-Left Override")
 +                           ("PDF" . "Pop Directional Format")
 +                           ("EN" . "European Number")
 +                           ("ES" . "European Number Separator")
 +                           ("ET" . "European Number Terminator")
 +                           ("AN" . "Arabic Number")
 +                           ("CS" . "Common Number Separator")
 +                           ("NSM" . "Non-Spacing Mark")
 +                           ("BN" . "Boundary Neutral")
 +                           ("B" . "Paragraph Separator")
 +                           ("S" . "Segment Separator")
 +                           ("WS" . "Whitespace")
 +                           ("ON" . "Other Neutrals")))))
 +             (list "Decomposition"
 +                   (if (nth 4 fields)
 +                       (let* ((parts (split-string (nth 4 fields)))
 +                              (info (car parts)))
 +                         (if (string-match "\\`<\\(.+\\)>\\'" info)
 +                             (setq info (match-string 1 info))
 +                           (setq info nil))
 +                         (if info (setq parts (cdr parts)))
 +                         (setq parts (mapconcat
 +                                      (lambda (arg)
 +                                        (string (string-to-number arg 16)))
 +                                      parts " "))
 +                         (concat info parts))))
 +             (list "Decimal digit value"
 +                   (nth 5 fields))
 +             (list "Digit value"
 +                   (nth 6 fields))
 +             (list "Numeric value"
 +                   (nth 7 fields))
 +             (list "Mirrored"
 +                   (if (equal "Y" (nth 8 fields))
 +                       "yes"))
 +             (list "Old name" (nth 9 fields))
 +             (list "ISO 10646 comment" (nth 10 fields))
 +             (list "Uppercase" (and (nth 11 fields)
 +                                    (string (string-to-number
 +                                             (nth 11 fields) 16))))
 +             (list "Lowercase" (and (nth 12 fields)
 +                                    (string (string-to-number
 +                                             (nth 12 fields) 16))))
 +             (list "Titlecase" (and (nth 13 fields)
 +                                    (string (string-to-number
 +                                             (nth 13 fields) 16)))))))))))
 +
  (provide 'mule-diag)
  
  ;;; arch-tag: cd3b607c-2893-45a0-a4fa-a6535754dbee
index 4d1ec5ec7f3ff89fbcf5988591e7bd1b6a95e71e,78ef30a56de7749269ebb62365776935340a02ed..10b9426aee2c91bce840bb1003b419b263d60c62
@@@ -1,14 -1,11 +1,14 @@@
  ;;; mule-util.el --- utility functions for mulitilingual environment (mule)
  
  ;; Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006  Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007  Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: mule, multilingual
  
@@@ -188,18 -185,18 +188,18 @@@ defaults to \"...\".
  ;;            (("foobarbaz" 6 nil nil "...") . "foo...")
  ;;            (("foobarbaz" 7 2 nil "...") . "ob...")
  ;;            (("foobarbaz" 9 3 nil "...") . "barbaz")
 -;;            (("\e$B$3\e(Bh\e$B$s\e(Be\e$B$K\e(Bl\e$B$A\e(Bl\e$B$O\e(Bo" 15 1 ?  t) . " h\e$B$s\e(Be\e$B$K\e(Bl\e$B$A\e(Bl\e$B$O\e(Bo")
 -;;            (("\e$B$3\e(Bh\e$B$s\e(Be\e$B$K\e(Bl\e$B$A\e(Bl\e$B$O\e(Bo" 14 1 ?  t) . " h\e$B$s\e(Be\e$B$K\e(Bl\e$B$A\e(B...")
 -;;            (("x" 3 nil nil "\e$(0GnM$\e(B") . "x")
 -;;            (("\e$AVP\e(B" 2 nil nil "\e$(0GnM$\e(B") . "\e$AVP\e(B")
 -;;            (("\e$AVP\e(B" 1 nil ?x "\e$(0GnM$\e(B") . "x") ;; XEmacs error
 -;;            (("\e$AVPND\e(B" 3 nil ?  "\e$(0GnM$\e(B") . "\e$AVP\e(B ") ;; XEmacs error
 -;;            (("foobarbaz" 4 nil nil  "\e$(0GnM$\e(B") . "\e$(0GnM$\e(B")
 -;;            (("foobarbaz" 5 nil nil  "\e$(0GnM$\e(B") . "f\e$(0GnM$\e(B")
 -;;            (("foobarbaz" 6 nil nil  "\e$(0GnM$\e(B") . "fo\e$(0GnM$\e(B")
 -;;            (("foobarbaz" 8 3 nil "\e$(0GnM$\e(B") . "b\e$(0GnM$\e(B")
 -;;            (("\e$B$3\e(Bh\e$B$s\e(Be\e$B$K\e(Bl\e$B$A\e(Bl\e$B$O\e(Bo" 14 4 ?x "\e$BF|K\8l\e(B") . "xe\e$B$KF|K\8l\e(B")
 -;;            (("\e$B$3\e(Bh\e$B$s\e(Be\e$B$K\e(Bl\e$B$A\e(Bl\e$B$O\e(Bo" 13 4 ?x "\e$BF|K\8l\e(B") . "xex\e$BF|K\8l\e(B")
 +;;            (("\e$A$3\e(Bh\e$A$s\e(Be\e$A$K\e(Bl\e$A$A\e(Bl\e$A$O\e(Bo" 15 1 ?  t) . " h\e$A$s\e(Be\e$A$K\e(Bl\e$A$A\e(Bl\e$A$O\e(Bo")
 +;;            (("\e$A$3\e(Bh\e$A$s\e(Be\e$A$K\e(Bl\e$A$A\e(Bl\e$A$O\e(Bo" 14 1 ?  t) . " h\e$A$s\e(Be\e$A$K\e(Bl\e$A$A\e(B...")
 +;;            (("x" 3 nil nil "\e$(Gemk#\e(B") . "x")
 +;;            (("\e$AVP\e(B" 2 nil nil "\e$(Gemk#\e(B") . "\e$AVP\e(B")
 +;;            (("\e$AVP\e(B" 1 nil ?x "\e$(Gemk#\e(B") . "x") ;; XEmacs error
 +;;            (("\e$AVPND\e(B" 3 nil ?  "\e$(Gemk#\e(B") . "\e$AVP\e(B ") ;; XEmacs error
 +;;            (("foobarbaz" 4 nil nil  "\e$(Gemk#\e(B") . "\e$(Gemk#\e(B")
 +;;            (("foobarbaz" 5 nil nil  "\e$(Gemk#\e(B") . "f\e$(Gemk#\e(B")
 +;;            (("foobarbaz" 6 nil nil  "\e$(Gemk#\e(B") . "fo\e$(Gemk#\e(B")
 +;;            (("foobarbaz" 8 3 nil "\e$(Gemk#\e(B") . "b\e$(Gemk#\e(B")
 +;;            (("\e$A$3\e(Bh\e$A$s\e(Be\e$A$K\e(Bl\e$A$A\e(Bl\e$A$O\e(Bo" 14 4 ?x "\e$AHU1>\e$(Gk#\e(B") . "xe\e$A$KHU1>\e$(Gk#\e(B")
 +;;            (("\e$A$3\e(Bh\e$A$s\e(Be\e$A$K\e(Bl\e$A$A\e(Bl\e$A$O\e(Bo" 13 4 ?x "\e$AHU1>\e$(Gk#\e(B") . "xex\e$AHU1>\e$(Gk#\e(B")
  ;;            ))
  ;;   (let (ret)
  ;;     (condition-case e
@@@ -297,57 -294,56 +297,57 @@@ Optional 3rd argument NIL-FOR-TOO-LONG 
  ;;;###autoload
  (defun coding-system-post-read-conversion (coding-system)
    "Return the value of CODING-SYSTEM's `post-read-conversion' property."
 -  (coding-system-get coding-system 'post-read-conversion))
 +  (coding-system-get coding-system :post-read-conversion))
  
  ;;;###autoload
  (defun coding-system-pre-write-conversion (coding-system)
    "Return the value of CODING-SYSTEM's `pre-write-conversion' property."
 -  (coding-system-get coding-system 'pre-write-conversion))
 +  (coding-system-get coding-system :pre-write-conversion))
  
  ;;;###autoload
  (defun coding-system-translation-table-for-decode (coding-system)
 -  "Return the value of CODING-SYSTEM's `translation-table-for-decode' property."
 -  (coding-system-get coding-system 'translation-table-for-decode))
 +  "Return the value of CODING-SYSTEM's `decode-translation-table' property."
 +  (coding-system-get coding-system :decode-translation-table))
  
  ;;;###autoload
  (defun coding-system-translation-table-for-encode (coding-system)
 -  "Return the value of CODING-SYSTEM's `translation-table-for-encode' property."
 -  (coding-system-get coding-system 'translation-table-for-encode))
 +  "Return the value of CODING-SYSTEM's `encode-translation-table' property."
 +  (coding-system-get coding-system :encode-translation-table))
 +
 +;;;###autoload
 +(defmacro with-coding-priority (coding-systems &rest body)
 +  "Execute BODY like `progn' with CODING-SYSTEMS at the front of priority list.
 +CODING-SYSTEMS is a list of coding systems.  See
 +`set-coding-priority'.  This affects the implicit sorting of lists of
 +coding sysems returned by operations such as `find-coding-systems-region'."
 +  (let ((current (make-symbol "current")))
 +  `(let ((,current (coding-system-priority-list)))
 +     (apply #'set-coding-system-priority ,coding-systems)
 +     (unwind-protect
 +       (progn ,@body)
 +       (apply #'set-coding-system-priority ,current)))))
 +(put 'with-coding-priority 'lisp-indent-function 1)
 +(put 'with-coding-priority 'edebug-form-spec t)
  
  ;;;###autoload
  (defmacro detect-coding-with-priority (from to priority-list)
    "Detect a coding system of the text between FROM and TO with PRIORITY-LIST.
  PRIORITY-LIST is an alist of coding categories vs the corresponding
  coding systems ordered by priority."
 -  `(unwind-protect
 -       (let* ((prio-list ,priority-list)
 -            (coding-category-list coding-category-list)
 -            ,@(mapcar (function (lambda (x) (list x x)))
 -                      coding-category-list))
 -       (mapc (function (lambda (x) (set (car x) (cdr x))))
 -             prio-list)
 -       (set-coding-priority (mapcar #'car prio-list))
 -       ;; Changing the binding of a coding category requires this call.
 -       (update-coding-systems-internal)
 -       (detect-coding-region ,from ,to))
 -     ;; We must restore the internal database.
 -     (set-coding-priority coding-category-list)
 -     (update-coding-systems-internal)))
 +  `(with-coding-priority (mapcar #'cdr ,priority-list)
 +     (detect-coding-region ,from ,to)))
 +(make-obsolete 'detect-coding-with-priority
 +             "Use with-coding-priority and detect-coding-region" "23.1")
  
  ;;;###autoload
  (defun detect-coding-with-language-environment (from to lang-env)
 -  "Detect a coding system of the text between FROM and TO with LANG-ENV.
 +  "Detect a coding system for the text between FROM and TO with LANG-ENV.
  The detection takes into account the coding system priorities for the
  language environment LANG-ENV."
    (let ((coding-priority (get-language-info lang-env 'coding-priority)))
      (if coding-priority
 -      (detect-coding-with-priority
 -       from to
 -       (mapcar (function (lambda (x)
 -                           (cons (coding-system-get x 'coding-category) x)))
 -               coding-priority))
 -      (detect-coding-region from to))))
 +      (with-coding-priority coding-priority
 +          (detect-coding-region from to)))))
  
  ;;;###autoload
  (defun char-displayable-p (char)
@@@ -368,35 -364,14 +368,35 @@@ basis, this may not be accurate.
         ;; currently selected frame.
         (car (internal-char-font nil char)))
        (t
 -       (let ((coding (terminal-coding-system)))
 +       (let ((coding 'iso-2022-7bit))
           (if coding
 -             (let ((safe-chars (coding-system-get coding 'safe-chars))
 -                   (safe-charsets (coding-system-get coding 'safe-charsets)))
 -               (or (and safe-chars
 -                        (aref safe-chars char))
 -                   (and safe-charsets
 -                        (memq (char-charset char) safe-charsets)))))))))
 +             (let ((cs-list (coding-system-get coding :charset-list)))
 +               (cond
 +                ((listp cs-list)
 +                 (catch 'tag
 +                   (mapc #'(lambda (charset) 
 +                             (if (encode-char char charset)
 +                                 (throw 'tag charset)))
 +                         cs-list)
 +                   nil))
 +                ((eq cs-list 'iso-2022)
 +                 (catch 'tag2
 +                   (mapc #'(lambda (charset)
 +                             (if (and (plist-get (charset-plist charset)
 +                                                 :iso-final-char)
 +                                      (encode-char char charset))
 +                                 (throw 'tag2 charset)))
 +                         charset-list)
 +                   nil))
 +                ((eq cs-list 'emacs-mule)
 +                 (catch 'tag3
 +                   (mapc #'(lambda (charset)
 +                             (if (and (plist-get (charset-plist charset) 
 +                                                 :emacs-mule-id)
 +                                      (encode-char char charset))
 +                                 (throw 'tag3 charset)))
 +                         charset-list)
 +                   nil)))))))))
  \f
  (provide 'mule-util)
  
index cf6a3b21244b3893a2410336c4b55ff792646878,25b53027f95f050950c171e4d51172d75f090824..9689725f3114d4c8c255fffb3bf498123fbd167a
@@@ -1,14 -1,11 +1,14 @@@
 -;;; mule.el --- basic commands for mulitilingual environment
 +;;; mule.el --- basic commands for multilingual environment
  
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: mule, multilingual, character set, coding system
  
  
  ;;; Code:
  
 -(defconst mule-version "5.0 (SAKAKI)" "\
 +(defconst mule-version "6.0 (HANACHIRUSATO)" "\
  Version number and name of this version of MULE (multilingual environment).")
  
 -(defconst mule-version-date "1999.12.7" "\
 +(defconst mule-version-date "2003.9.1" "\
  Distribution date of this version of MULE (multilingual environment).")
  
 +\f
 +;;; CHARSET
 +
 +;; Backward compatibility code for handling emacs-mule charsets.
 +(defvar private-char-area-1-min #xF0000)
 +(defvar private-char-area-1-max #xFFFFE)
 +(defvar private-char-area-2-min #x100000)
 +(defvar private-char-area-2-max #x10FFFE)
 +
 +;; Table of emacs-mule charsets indexed by their emacs-mule ID.
 +(defvar emacs-mule-charset-table (make-vector 256 nil))
 +(aset emacs-mule-charset-table 0 'ascii)
 +
 +;; Convert the argument of old-style calll of define-charset to a
 +;; property list used by the new-style.
 +;; INFO-VECTOR is a vector of the format:
 +;;   [DIMENSION CHARS WIDTH DIRECTION ISO-FINAL-CHAR ISO-GRAPHIC-PLANE
 +;;    SHORT-NAME LONG-NAME DESCRIPTION]
 +
 +(defun convert-define-charset-argument (emacs-mule-id info-vector)
 +  (let* ((dim (aref info-vector 0))
 +       (chars (aref info-vector 1))
 +       (total (if (= dim 1) chars (* chars chars)))
 +       (code-space (if (= dim 1) (if (= chars 96) [32 127] [33 126])
 +                     (if (= chars 96) [32 127 32 127] [33 126 33 126])))
 +       code-offset)
 +    (if (integerp emacs-mule-id)
 +      (or (= emacs-mule-id 0)
 +          (and (>= emacs-mule-id 129) (< emacs-mule-id 256))
 +          (error "Invalid CHARSET-ID: %d" emacs-mule-id))
 +      (let (from-id to-id)
 +      (if (= dim 1) (setq from-id 160 to-id 224)
 +        (setq from-id 224 to-id 255))
 +      (while (and (< from-id to-id)
 +                  (not (aref emacs-mule-charset-table from-id)))
 +        (setq from-id (1+ from-id)))
 +      (if (= from-id to-id)
 +          (error "No more room for the new Emacs-mule charset"))
 +      (setq emacs-mule-id from-id)))
 +    (if (> (- private-char-area-1-max private-char-area-1-min) total)
 +      (setq code-offset private-char-area-1-min
 +            private-char-area-1-min (+ private-char-area-1-min total))
 +      (if (> (- private-char-area-2-max private-char-area-2-min) total)
 +        (setq code-offset private-char-area-2-min
 +              private-char-area-2-min (+ private-char-area-2-min total))
 +      (error "No more space for a new charset.")))
 +    (list :dimension dim
 +        :code-space code-space
 +        :iso-final-char (aref info-vector 4)
 +        :code-offset code-offset
 +        :emacs-mule-id emacs-mule-id)))
 +
 +(defun define-charset (name docstring &rest props)
 +  "Define NAME (symbol) as a charset with DOCSTRING.
 +The remaining arguments must come in pairs ATTRIBUTE VALUE.  ATTRIBUTE
 +may be any symbol.  The following have special meanings, and one of
 +`:code-offset', `:map', `:subset', `:superset' must be specified.
 +
 +`:short-name'
 +
 +VALUE must be a short string to identify the charset.  If omitted,
 +NAME is used.
 +
 +`:long-name'
 +
 +VALUE must be a string longer than `:short-name' to identify the
 +charset.  If omitted, the value of the `:short-name' attribute is used.
 +
 +`:dimension'
 +
 +VALUE must be an integer 0, 1, 2, or 3, specifying the dimension of
 +code-points of the charsets.  If omitted, it is calculated from the
 +value of the `:code-space' attribute.
 +
 +`:code-space'
 +
 +VALUE must be a vector of length at most 8 specifying the byte code
 +range of each dimension in this format:
 +      [ MIN-1 MAX-1 MIN-2 MAX-2 ... ]
 +where MIN-N is the minimum byte value of Nth dimension of code-point,
 +MAX-N is the maximum byte value of that.
 +
 +`:min-code'
 +
 +VALUE must be an integer specifying the mininum code point of the
 +charset.  If omitted, it is calculated from `:code-space'.  VALUE may
 +be a cons (HIGH . LOW), where HIGH is the most significant 16 bits of
 +the code point and LOW is the least significant 16 bits.
 +
 +`:max-code'
 +
 +VALUE must be an integer specifying the maxinum code point of the
 +charset.  If omitted, it is calculated from `:code-space'.  VALUE may
 +be a cons (HIGH . LOW), where HIGH is the most significant 16 bits of
 +the code point and LOW is the least significant 16 bits.
 +
 +`:iso-final-char'
 +
 +VALUE must be a character in the range 32 to 127 (inclusive)
 +specifying the final char of the charset for ISO-2022 encoding.  If
 +omitted, the charset can't be encoded by ISO-2022 based
 +coding-systems.
 +
 +`:iso-revision-number'
 +
 +VALUE must be an integer in the range 0..63, specifying the revision
 +number of the charset for ISO-2022 encoding.
 +
 +`:emacs-mule-id'
 +
 +VALUE must be an integer of 0, 129..255.  If omitted, the charset
 +can't be encoded by coding-systems of type `emacs-mule'.
 +
 +`:ascii-compatible-p'
 +
 +VALUE must be nil or t (default nil).  If VALUE is t, the charset is
 +compatible with ASCII, i.e. the first 128 code points map to ASCII.
 +
 +`:supplementary-p'
 +
 +VALUE must be nil or t.  If the VALUE is t, the charset is
 +supplementary, which means it is used only as a parent of some other
 +charset.
 +
 +`:invalid-code'
 +
 +VALUE must be a nonnegative integer that can be used as an invalid
 +code point of the charset.  If the minimum code is 0 and the maximum
 +code is greater than Emacs' maximum integer value, `:invalid-code'
 +should not be omitted.
 +
 +`:code-offset'
 +
 +VALUE must be an integer added to the index number of a character to
 +get the corresponding character code.
 +
 +`:map'
 +
 +VALUE must be vector or string.
 +
 +If it is a vector, the format is [ CODE-1 CHAR-1 CODE-2 CHAR-2 ... ],
 +where CODE-n is a code-point of the charset, and CHAR-n is the
 +corresponding character code.
 +
 +If it is a string, it is a name of file that contains the above
 +information.   Each line of the file must be this format:
 +      0xXXX 0xYYY
 +where XXX is a hexadecimal representation of CODE-n and YYY is a
 +hexadecimal representation of CHAR-n.  A line starting with `#' is a
 +comment line.
 +
 +`:subset'
 +
 +VALUE must be a list:
 +      ( PARENT MIN-CODE MAX-CODE OFFSET )
 +PARENT is a parent charset.  MIN-CODE and MAX-CODE specify the range
 +of characters inherited from the parent.  OFFSET is an integer value
 +to add to a code point of the parent charset to get the corresponding
 +code point of this charset.
 +
 +`:superset'
 +
 +VALUE must be a list of parent charsets.  The charset inherits
 +characters from them.  Each element of the list may be a cons (PARENT
 +. OFFSET), where PARENT is a parent charset, and OFFSET is an offset
 +value to add to a code point of PARENT to get the corresponding code
 +point of this charset.
 +
 +`:unify-map'
 +
 +VALUE must be vector or string.
 +
 +If it is a vector, the format is [ CODE-1 CHAR-1 CODE-2 CHAR-2 ... ],
 +where CODE-n is a code-point of the charset, and CHAR-n is the
 +corresponding Unicode character code.
 +
 +If it is a string, it is a name of file that contains the above
 +information.  The file format is the same as what described for `:map'
 +attribute."
 +  (when (vectorp (car props))
 +    ;; Old style code:
 +    ;;   (define-charset CHARSET-ID CHARSET-SYMBOL INFO-VECTOR)
 +    ;; Convert the argument to make it fit with the current style.
 +    (let ((vec (car props)))
 +      (setq props (convert-define-charset-argument name vec)
 +          name docstring
 +          docstring (aref vec 8))))
 +  (let ((attrs (mapcar 'list '(:dimension
 +                             :code-space
 +                             :min-code
 +                             :max-code
 +                             :iso-final-char
 +                             :iso-revision-number
 +                             :emacs-mule-id
 +                             :ascii-compatible-p
 +                             :supplementary-p
 +                             :invalid-code
 +                             :code-offset
 +                             :map
 +                             :subset
 +                             :superset
 +                             :unify-map
 +                             :plist))))
 +
 +    ;; If :dimension is omitted, get the dimension from :code-space.
 +    (let ((dimension (plist-get props :dimension)))
 +      (or dimension
 +        (let ((code-space (plist-get props :code-space)))
 +          (setq dimension (if code-space (/ (length code-space) 2) 4))
 +          (setq props (plist-put props :dimension dimension)))))
 +
 +    (let ((code-space (plist-get props :code-space)))
 +      (or code-space
 +        (let ((dimension (plist-get props :dimension)))
 +          (setq code-space (make-vector 8 0))
 +          (dotimes (i dimension)
 +            (aset code-space (1+ (* i 2)) #xFF))
 +          (setq props (plist-put props :code-space code-space)))))
 +
 +    ;; If :emacs-mule-id is specified, update emacs-mule-charset-table.
 +    (let ((emacs-mule-id (plist-get props :emacs-mule-id)))
 +      (if (integerp emacs-mule-id)
 +        (aset emacs-mule-charset-table emacs-mule-id name)))
 +
 +    (dolist (slot attrs)
 +      (setcdr slot (plist-get props (car slot))))
 +
 +    ;; Make sure that the value of :code-space is a vector of 8
 +    ;; elements.
 +    (let* ((slot (assq :code-space attrs))
 +         (val (cdr slot))
 +         (len (length val)))
 +      (if (< len 8)
 +        (setcdr slot
 +                (vconcat val (make-vector (- 8 len) 0)))))
 +
 +    ;; Add :name and :docstring properties to PROPS.
 +    (setq props
 +        (cons :name (cons name (cons :docstring (cons docstring props)))))
 +    (or (plist-get props :short-name)
 +      (plist-put props :short-name (symbol-name name)))
 +    (or (plist-get props :long-name)
 +      (plist-put props :long-name (plist-get props :short-name)))
 +    ;; We can probably get a worthwhile amount in purespace.
 +    (setq props
 +        (mapcar (lambda (elt)
 +                  (if (stringp elt)
 +                      (purecopy elt)
 +                    elt))
 +                props))
 +    (setcdr (assq :plist attrs) props)
 +
 +    (apply 'define-charset-internal name (mapcar 'cdr attrs))))
 +
 +
  (defun load-with-code-conversion (fullname file &optional noerror nomessage)
    "Execute a file of Lisp code named FILE whose absolute name is FULLNAME.
  The file contents are decoded before evaluation if necessary.
@@@ -339,8 -81,8 +339,8 @@@ Return t if file exists.
              ;; Otherwise, eval-buffer might try to interpret random
              ;; binary junk as multibyte characters.
              (if (and enable-multibyte-characters
 -                     (or (eq (coding-system-type last-coding-system-used) 5)
 -                         (eq last-coding-system-used 'no-conversion)))
 +                     (or (eq (coding-system-type last-coding-system-used)
 +                             'raw-text)))
                  (set-buffer-multibyte nil))
              ;; Make `kill-buffer' quiet.
              (set-buffer-modified-p nil))
          (message "Loading %s...done" file)))
        t)))
  
 -;; API (Application Program Interface) for charsets.
 -
 -(defsubst charset-quoted-standard-p (obj)
 -  "Return t if OBJ is a quoted symbol, and is the name of a standard charset."
 -  (and (listp obj) (eq (car obj) 'quote)
 -       (symbolp (car-safe (cdr obj)))
 -       (let ((vector (get (car-safe (cdr obj)) 'charset)))
 -       (and (vectorp vector)
 -            (< (aref vector 0) 160)))))
 -
 -(defsubst charsetp (object)
 -  "Return t if OBJECT is a charset."
 -  (and (symbolp object) (vectorp (get object 'charset))))
 -
 -(defsubst charset-info (charset)
 +(defun charset-info (charset)
    "Return a vector of information of CHARSET.
 +This function is provided for backward compatibility.
 +
  The elements of the vector are:
        CHARSET-ID, BYTES, DIMENSION, CHARS, WIDTH, DIRECTION,
        LEADING-CODE-BASE, LEADING-CODE-EXT,
        ISO-FINAL-CHAR, ISO-GRAPHIC-PLANE,
        REVERSE-CHARSET, SHORT-NAME, LONG-NAME, DESCRIPTION,
 -      PLIST,
 +      PLIST.
  where
 -CHARSET-ID (integer) is the identification number of the charset.
 -BYTES (integer) is the length of multi-byte form of a character in
 -  the charset: one of 1, 2, 3, and 4.
 -DIMENSION (integer) is the number of bytes to represent a character of
 -the charset: 1 or 2.
 -CHARS (integer) is the number of characters in a dimension: 94 or 96.
 -WIDTH (integer) is the number of columns a character in the charset
 -  occupies on the screen: one of 0, 1, and 2.
 -DIRECTION (integer) is the rendering direction of characters in the
 -  charset when rendering.  If 0, render from left to right, else
 -  render from right to left.
 -LEADING-CODE-BASE (integer) is the base leading-code for the
 -  charset.
 -LEADING-CODE-EXT (integer) is the extended leading-code for the
 -  charset.  All charsets of less than 0xA0 has the value 0.
 +CHARSET-ID is always 0.
 +BYTES is always 0.
 +DIMENSION is the number of bytes of a code-point of the charset:
 +  1, 2, 3, or 4.
 +CHARS is the number of characters in a dimension:
 +  94, 96, 128, or 256.
 +WIDTH is always 0.
 +DIRECTION is always 0.
 +LEADING-CODE-BASE is always 0.
 +LEADING-CODE-EXT is always 0.
  ISO-FINAL-CHAR (character) is the final character of the
    corresponding ISO 2022 charset.  If the charset is not assigned
    any final character, the value is -1.
 -ISO-GRAPHIC-PLANE (integer) is the graphic plane to be invoked
 -  while encoding to variants of ISO 2022 coding system, one of the
 -  following: 0/graphic-plane-left(GL), 1/graphic-plane-right(GR).
 -  If the charset is not assigned any final character, the value is -1.
 -REVERSE-CHARSET (integer) is the charset which differs only in
 -  LEFT-TO-RIGHT value from the charset.  If there's no such a
 -  charset, the value is -1.
 +ISO-GRAPHIC-PLANE is always 0.
 +REVERSE-CHARSET is always -1.
  SHORT-NAME (string) is the short name to refer to the charset.
  LONG-NAME (string) is the long name to refer to the charset
  DESCRIPTION (string) is the description string of the charset.
  PLIST (property list) may contain any type of information a user
    want to put and get by functions `put-charset-property' and
    `get-charset-property' respectively."
 -  (get charset 'charset))
 +  (vector 0
 +        0
 +        (charset-dimension charset)
 +        (charset-chars charset)
 +        0
 +        0
 +        0
 +        0
 +        (charset-iso-final-char charset)
 +        0
 +        -1
 +        (get-charset-property charset :short-name)
 +        (get-charset-property charset :short-name)
 +        (charset-description charset)
 +        (charset-plist charset)))
  
  ;; It is better not to use backquote in this file,
  ;; because that makes a bootstrapping problem
  ;; if you need to recompile all the Lisp files using interpreted code.
  
 -(defmacro charset-id (charset)
 -  "Return charset identification number of CHARSET."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 0)
 -    (list 'aref (list 'charset-info charset) 0)))
 +(defun charset-id (charset)
 +  "Always return 0.  This is provided for backward compatibility."
 +  0)
  
  (defmacro charset-bytes (charset)
 -  "Return bytes of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 1)
 -    (list 'aref (list 'charset-info charset) 1)))
 -
 -(defmacro charset-dimension (charset)
 -  "Return dimension of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 2)
 -    (list 'aref (list 'charset-info charset) 2)))
 -
 -(defmacro charset-chars (charset)
 -  "Return character numbers contained in a dimension of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 3)
 -    (list 'aref (list 'charset-info charset) 3)))
 -
 -(defmacro charset-width (charset)
 -  "Return width (how many column occupied on a screen) of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 4)
 -    (list 'aref (list 'charset-info charset) 4)))
 -
 -(defmacro charset-direction (charset)
 -  "Return direction of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 5)
 -    (list 'aref (list 'charset-info charset) 5)))
 -
 -(defmacro charset-iso-final-char (charset)
 -  "Return final char of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 8)
 -    (list 'aref (list 'charset-info charset) 8)))
 -
 -(defmacro charset-iso-graphic-plane (charset)
 -  "Return graphic plane of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 9)
 -    (list 'aref (list 'charset-info charset) 9)))
 -
 -(defmacro charset-reverse-charset (charset)
 -  "Return reverse charset of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 10)
 -    (list 'aref (list 'charset-info charset) 10)))
 +  "Always return 0.  This is provided for backward compatibility."
 +  0)
 +
 +(defun get-charset-property (charset propname)
 +  "Return the value of CHARSET's PROPNAME property.
 +This is the last value stored with
 + (put-charset-property CHARSET PROPNAME VALUE)."
 +  (plist-get (charset-plist charset) propname))
 +
 +(defun put-charset-property (charset propname value)
 +  "Set CHARSETS's PROPNAME property to value VALUE.
 +It can be retrieved with `(get-charset-property CHARSET PROPNAME)'."
 +  (set-charset-plist charset
 +                   (plist-put (charset-plist charset) propname value)))
 +
 +(defun charset-description (charset)
 +  "Return description string of CHARSET."
 +  (plist-get (charset-plist charset) :docstring))
 +
 +(defun charset-dimension (charset)
 +  "Return dimension of CHARSET."
 +  (plist-get (charset-plist charset) :dimension))
 +
 +(defun charset-chars (charset &optional dimension)
 +  "Return number of characters contained in DIMENSION of CHARSET.
 +DIMENSION defaults to the first dimension."
 +  (unless dimension (setq dimension 1))
 +  (let ((code-space (plist-get (charset-plist charset) :code-space)))
 +    (1+ (- (aref code-space (1- (* 2 dimension)))
 +         (aref code-space (- (* 2 dimension) 2))))))
 +
 +(defun charset-iso-final-char (charset)
 +  "Return ISO-2022 final character of CHARSET.
 +Return -1 if charset isn't an ISO 2022 one."
 +  (or (plist-get (charset-plist charset) :iso-final-char)
 +      -1))
  
  (defmacro charset-short-name (charset)
 -  "Return short name of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 11)
 -    (list 'aref (list 'charset-info charset) 11)))
 +  "Return short name of CHARSET."
 +  (plist-get (charset-plist charset) :short-name))
  
  (defmacro charset-long-name (charset)
 -  "Return long name of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 12)
 -    (list 'aref (list 'charset-info charset) 12)))
 -
 -(defmacro charset-description (charset)
 -  "Return description of CHARSET.
 -See the function `charset-info' for more detail."
 -  (if (charset-quoted-standard-p charset)
 -      (aref (charset-info (nth 1 charset)) 13)
 -    (list 'aref (list 'charset-info charset) 13)))
 -
 -(defmacro charset-plist (charset)
 -  "Return list charset property of CHARSET.
 -See the function `charset-info' for more detail."
 -  (list 'aref
 -      (if (charset-quoted-standard-p charset)
 -          (charset-info (nth 1 charset))
 -        (list 'charset-info charset))
 -      14))
 -
 -(defun set-charset-plist (charset plist)
 -  "Set CHARSET's property list to PLIST, and return PLIST."
 -  (aset (charset-info  charset) 14 plist))
 -
 -(defun make-char (charset &optional code1 code2)
 -  "Return a character of CHARSET whose position codes are CODE1 and CODE2.
 -CODE1 and CODE2 are optional, but if you don't supply
 -sufficient position codes, return a generic character which stands for
 -all characters or group of characters in the character set.
 -A generic character can be used to index a char table (e.g. `syntax-table').
 -
 -Such character sets as ascii, eight-bit-control, and eight-bit-graphic
 -don't have corresponding generic characters.  If CHARSET is one of
 -them and you don't supply CODE1, return the character of the smallest
 -code in CHARSET.
 -
 -If CODE1 or CODE2 are invalid (out of range), this function signals an
 -error.  However, the eighth bit of both CODE1 and CODE2 is zeroed
 -before they are used to index CHARSET.  Thus you may use, say, the
 -actual ISO 8859 character code rather than subtracting 128, as you
 -would need to index the corresponding Emacs charset."
 -  (make-char-internal (charset-id charset) code1 code2))
 -
 -(put 'make-char 'byte-compile
 -     (lambda (form)
 -       (let ((charset (nth 1 form)))
 -         (byte-compile-normal-call
 -          (cons 'make-char-internal
 -                (cons (if (charset-quoted-standard-p charset)
 -                          (charset-id (nth 1 charset))
 -                        (list 'charset-id charset))
 -                      (nthcdr 2 form)))))))
 +  "Return long name of CHARSET."
 +  (plist-get (charset-plist charset) :long-name))
  
  (defun charset-list ()
 -  "Return list of charsets ever defined.
 +  "Return list of all charsets ever defined.
  
  This function is provided for backward compatibility.
  Now we have the variable `charset-list'."
    charset-list)
 +(make-obsolete 'charset-list "Use variable `charset-list'" "23.1")
  
 -(defsubst generic-char-p (char)
 -  "Return t if and only if CHAR is a generic character.
 -See also the documentation of `make-char'."
 -  (and (>= char 0400)
 -       (let ((l (split-char char)))
 -       (and (or (= (nth 1 l) 0) (eq (nth 2 l) 0))
 -            (not (eq (car l) 'composition))))))
 -
 -(defun decode-char (ccs code-point &optional restriction)
 -  "Return character specified by coded character set CCS and CODE-POINT in it.
 -Return nil if such a character is not supported.
 -Currently the only supported coded character set is `ucs' (ISO/IEC
 -10646: Universal Multi-Octet Coded Character Set), and the result is
 -translated through the translation-table named
 -`utf-translation-table-for-decode', or through the
 -translation-hash-table named `utf-subst-table-for-decode'
 -\(if `utf-translate-cjk-mode' is non-nil).
 -
 -Optional argument RESTRICTION specifies a way to map the pair of CCS
 -and CODE-POINT to a character.  Currently not supported and just ignored."
 -  (cond
 -   ((eq ccs 'ucs)
 -    (or (and utf-translate-cjk-mode
 -           (utf-lookup-subst-table-for-decode code-point))
 -      (let ((c (cond
 -                ((< code-point 160)
 -                 code-point)
 -                ((< code-point 256)
 -                 (make-char 'latin-iso8859-1 code-point))
 -                ((< code-point #x2500)
 -                 (setq code-point (- code-point #x0100))
 -                 (make-char 'mule-unicode-0100-24ff
 -                            (+ (/ code-point 96) 32) (+ (% code-point 96) 32)))
 -                ((< code-point #x3400)
 -                 (setq code-point (- code-point #x2500))
 -                 (make-char 'mule-unicode-2500-33ff
 -                            (+ (/ code-point 96) 32) (+ (% code-point 96) 32)))
 -                ((and (>= code-point #xe000) (< code-point #x10000))
 -                 (setq code-point (- code-point #xe000))
 -                 (make-char 'mule-unicode-e000-ffff
 -                            (+ (/ code-point 96) 32)
 -                            (+ (% code-point 96) 32))))))
 -        (when c
 -          (or (aref (get 'utf-translation-table-for-decode
 -                         'translation-table) c)
 -              c)))))))
 -
 -(defun encode-char (char ccs &optional restriction)
 -  "Return code-point in coded character set CCS that corresponds to CHAR.
 -Return nil if CHAR is not included in CCS.
 -Currently the only supported coded character set is `ucs' (ISO/IEC
 -10646: Universal Multi-Octet Coded Character Set), and CHAR is first
 -translated through the translation-table named
 -`utf-translation-table-for-encode', or through the
 -translation-hash-table named `utf-subst-table-for-encode' \(if
 -`utf-translate-cjk-mode' is non-nil).
 -
 -CHAR should be in one of these charsets:
 -  ascii, latin-iso8859-1, mule-unicode-0100-24ff, mule-unicode-2500-33ff,
 -  mule-unicode-e000-ffff, eight-bit-control
 -Otherwise, return nil.
 -
 -Optional argument RESTRICTION specifies a way to map CHAR to a
 -code-point in CCS.  Currently not supported and just ignored."
 -  (let* ((split (split-char char))
 -       (charset (car split))
 -       trans)
 -    (cond ((eq ccs 'ucs)
 -         (or (and utf-translate-cjk-mode
 -                  (utf-lookup-subst-table-for-encode char))
 -             (let ((table (get 'utf-translation-table-for-encode
 -                               'translation-table)))
 -               (setq trans (aref table char))
 -               (if trans
 -                   (setq split (split-char trans)
 -                         charset (car split)))
 -               (cond ((eq charset 'ascii)
 -                      (or trans char))
 -                     ((eq charset 'latin-iso8859-1)
 -                      (+ (nth 1 split) 128))
 -                     ((eq charset 'mule-unicode-0100-24ff)
 -                      (+ #x0100 (+ (* (- (nth 1 split) 32) 96)
 -                                   (- (nth 2 split) 32))))
 -                     ((eq charset 'mule-unicode-2500-33ff)
 -                      (+ #x2500 (+ (* (- (nth 1 split) 32) 96)
 -                                   (- (nth 2 split) 32))))
 -                     ((eq charset 'mule-unicode-e000-ffff)
 -                      (+ #xe000 (+ (* (- (nth 1 split) 32) 96)
 -                                   (- (nth 2 split) 32))))
 -                     ((eq charset 'eight-bit-control)
 -                      char))))))))
 +\f
 +;;; CHARACTER
 +(defalias 'char-valid-p 'characterp)
 +(make-obsolete 'char-valid-p 'characterp "23.1")
  
 +(defun generic-char-p (char)
 +  "Always return nil.  This is provided for backward compatibility."
 +  nil)
 +(make-obsolete 'generic-char-p "Generic characters no longer exist" "23.1")
 +
 +(defun make-char-internal (charset-id &optional code1 code2)
 +  (let ((charset (aref emacs-mule-charset-table charset-id)))
 +    (or charset
 +      (error "Invalid Emacs-mule charset ID: %d" charset-id))
 +    (make-char charset code1 code2)))
  \f
  ;; Coding system stuff
  
 -;; Coding system is a symbol that has the property `coding-system'.
 -;;
 -;; The value of the property `coding-system' is a vector of the
 -;; following format:
 -;;    [TYPE MNEMONIC DOC-STRING PLIST FLAGS]
 -;; We call this vector as coding-spec.  See comments in src/coding.c
 -;; for more detail.
 -
 -(defconst coding-spec-type-idx 0)
 -(defconst coding-spec-mnemonic-idx 1)
 -(defconst coding-spec-doc-string-idx 2)
 -(defconst coding-spec-plist-idx 3)
 -(defconst coding-spec-flags-idx 4)
 -
 -;; PLIST is a property list of a coding system.  To share PLIST among
 -;; alias coding systems, a coding system has PLIST in coding-spec
 -;; instead of having it in normal property list of Lisp symbol.
 -;; Here's a list of coding system properties currently being used.
 -;;
 -;; o coding-category
 -;;
 -;; The value is a coding category the coding system belongs to.  The
 -;; function `make-coding-system' sets this value automatically
 -;; unless its argument PROPERTIES specifies this property.
 -;;
 -;; o alias-coding-systems
 -;;
 -;; The value is a list of coding systems of the same alias group.  The
 -;; first element is the coding system made at first, which we call as
 -;; `base coding system'.  The function `make-coding-system' sets this
 -;; value automatically and `define-coding-system-alias' updates it.
 -;;
 -;; See the documentation of make-coding-system for the meanings of the
 -;; following properties.
 -;;
 -;; o post-read-conversion
 -;; o pre-write-conversion
 -;; o translation-table-for-decode
 -;; o translation-table-for-encode
 -;; o safe-chars
 -;; o safe-charsets
 -;; o mime-charset
 -;; o valid-codes (meaningful only for a coding system based on CCL)
 -
 -
 -(defsubst coding-system-spec (coding-system)
 -  "Return coding-spec of CODING-SYSTEM."
 -  (get (check-coding-system coding-system) 'coding-system))
 +;; Coding system is a symbol that has been defined by the function
 +;; `define-coding-system'.
  
 -(defun coding-system-type (coding-system)
 -  "Return the coding type of CODING-SYSTEM.
 -A coding type is an integer value indicating the encoding method
 -of CODING-SYSTEM.  See the function `make-coding-system' for more detail."
 -  (aref (coding-system-spec coding-system) coding-spec-type-idx))
 +(defconst coding-system-iso-2022-flags
 +  '(long-form
 +    ascii-at-eol
 +    ascii-at-cntl
 +    7-bit
 +    locking-shift
 +    single-shift
 +    designation
 +    revision
 +    direction
 +    init-at-bol
 +    designate-at-bol
 +    safe
 +    latin-extra
 +    composition
 +    euc-tw-shift
 +    use-roman
 +    use-oldjis)
 +  "List of symbols that control ISO-2022 encoder/decoder.
  
 -(defun coding-system-mnemonic (coding-system)
 -  "Return the mnemonic character of CODING-SYSTEM.
 -The mnemonic character of a coding system is used in mode line
 -to indicate the coding system.  If the arg is nil, return ?-."
 -  (let ((spec (coding-system-spec coding-system)))
 -    (if spec (aref spec coding-spec-mnemonic-idx) ?-)))
 +The value of the `:flags' attribute in the argument of the function
 +`define-coding-system' must be one of them.
 +
 +If `long-form' is specified, use a long designation sequence on
 +encoding for the charsets `japanese-jisx0208-1978', `chinese-gb2312',
 +and `japanese-jisx0208'.  The long designation sequence doesn't
 +conform to ISO 2022, but is used by such coding systems as
 +`compound-text'.
 +
 +If `ascii-at-eol' is specified, designate ASCII to g0 at end of line
 +on encoding.
 +
 +If `ascii-at-cntl' is specified, designate ASCII to g0 before control
 +codes and SPC on encoding.
 +
 +If `7-bit' is specified, use 7-bit code only on encoding.
 +
 +If `locking-shift' is specified, decode locking-shift code correctly
 +on decoding, and use locking-shift to invoke a graphic element on
 +encoding.
 +
 +If `single-shift' is specified, decode single-shift code correctly on
 +decoding, and use single-shift to invoke a graphic element on encoding.
 +
 +If `designation' is specified, decode designation code correctly on
 +decoding, and use designation to designate a charset to a graphic
 +element on encoding.
 +
 +If `revision' is specified, produce an escape sequence to specify
 +revision number of a charset on encoding.  Such an escape sequence is
 +always correctly decoded on decoding.
 +
 +If `direction' is specified, decode ISO6429's code for specifying
 +direction correctly, and produce the code on encoding.
 +
 +If `init-at-bol' is specified, on encoding, it is assumed that
 +invocation and designation statuses are reset at each beginning of
 +line even if `ascii-at-eol' is not specified; thus no codes for
 +resetting them are produced.
 +
 +If `safe' is specified, on encoding, characters not supported by a
 +coding are replaced with `?'.
 +
 +If `latin-extra' is specified, the code-detection routine assumes that a
 +code specified in `latin-extra-code-table' (which see) is valid.
 +
 +If `composition' is specified, an escape sequence to specify
 +composition sequence is correctly decoded on decoding, and is produced
 +on encoding.
 +
 +If `euc-tw-shift' is specified, the EUC-TW specific shifting code is
 +correctly decoded on decoding, and is produced on encoding.
 +
 +If `use-roman' is specified, JIS0201-1976-Roman is designated instead
 +of ASCII.
 +
 +If `use-oldjis' is specified, JIS0208-1976 is designated instead of
 +JIS0208-1983.")
 +
 +(defun define-coding-system (name docstring &rest props)
 +  "Define NAME (a symbol) as a coding system with DOCSTRING and attributes.
 +The remaining arguments must come in pairs ATTRIBUTE VALUE.  ATTRIBUTE
 +may be any symbol.
 +
 +The following attributes have special meanings.  Those labeled as
 +\"(required)\", should not be omitted.
 +
 +`:mnemonic' (required)
 +
 +VALUE is a character to display on mode line for the coding system.
 +
 +`:coding-type' (required)
 +
 +VALUE must be one of `charset', `utf-8', `utf-16', `iso-2022',
 +`emacs-mule', `shift-jis', `ccl', `raw-text', `undecided'.
 +
 +`:eol-type'
 +
 +VALUE is the EOL (end-of-line) format of the coding system.  It must be
 +one of `unix', `dos', `mac'.  The symbol `unix' means Unix-like EOL
 +\(i.e. single LF), `dos' means DOS-like EOL \(i.e. sequence of CR LF),
 +and `mac' means MAC-like EOL \(i.e. single CR).  If omitted, on
 +decoding by the coding system, Emacs automatically detects the EOL
 +format of the source text.
 +
 +`:charset-list'
 +
 +VALUE must be a list of charsets supported by the coding system.  On
 +encoding by the coding system, if a character belongs to multiple
 +charsets in the list, a charset that comes earlier in the list is
 +selected.  If `:coding-type' is `iso-2022', VALUE may be `iso-2022',
 +which indicates that the coding system supports all ISO-2022 based
 +charsets.  If `:coding-type' is `emacs-mule', VALUE may be
 +`emacs-mule', which indicates that the coding system supports all
 +charsets that have the `:emacs-mule-id' property.
 +
 +`:ascii-compatible-p'
 +
 +If VALUE is non-nil, the coding system decodes all 7-bit bytes into
 +the corresponding ASCII characters, and encodes all ASCII characters
 +back to the corresponding 7-bit bytes.  VALUE defaults to nil.
 +
 +`:decode-translation-table'
 +
 +VALUE must be a translation table to use on decoding.
 +
 +`:encode-translation-table'
 +
 +VALUE must be a translation table to use on encoding.
 +
 +`:post-read-conversion'
 +
 +VALUE must be a function to call after some text is inserted and
 +decoded by the coding system itself and before any functions in
 +`after-insert-functions' are called.  The arguments to this function
 +are the same as those of a function in `after-insert-file-functions',
 +i.e. LENGTH of the text to be decoded with point at the head of it,
 +and the function should leave point unchanged.
 +
 +`:pre-write-conversion'
 +
 +VALUE must be a function to call after all functions in
 +`write-region-annotate-functions' and `buffer-file-format' are called,
 +and before the text is encoded by the coding system itself.  The
 +arguments to this function are the same as those of a function in
 +`write-region-annotate-functions'.
 +
 +`:default-char'
 +
 +VALUE must be a character.  On encoding, a character not supported by
 +the coding system is replaced with VALUE.
 +
 +`:for-unibyte'
 +
 +VALUE non-nil means that visiting a file with the coding system
 +results in a unibyte buffer.
 +
 +`:eol-type'
 +
 +VALUE must be `unix', `dos', `mac'.  The symbol `unix' means Unix-like
 +EOL (LF), `dos' means DOS-like EOL (CRLF), and `mac' means MAC-like
 +EOL (CR).  If omitted, on decoding, the coding system detects EOL
 +format automatically, and on encoding, uses Unix-like EOL.
 +
 +`:mime-charset'
 +
 +VALUE must be a symbol whose name is that of a MIME charset converted
 +to lower case.
 +
 +`:mime-text-unsuitable'
 +
 +VALUE non-nil means the `:mime-charset' property names a charset which
 +is unsuitable for the top-level media type \"text\".
 +
 +`:flags'
 +
 +VALUE must be a list of symbols that control the ISO-2022 converter.
 +Each must be a member of the list `coding-system-iso-2022-flags'
 +\(which see).  This attribute has a meaning only when `:coding-type'
 +is `iso-2022'.
 +
 +`:designation'
 +
 +VALUE must be a vector [G0-USAGE G1-USAGE G2-USAGE G3-USAGE].
 +GN-USAGE specifies the usage of graphic register GN as follows.
 +
 +If it is nil, no charset can be designated to GN.
 +
 +If it is a charset, the charset is initially designated to GN, and
 +never used by the other charsets.
 +
 +If it is a list, the elements must be charsets, nil, 94, or 96.  GN
 +can be used by all the listed charsets.  If the list contains 94, any
 +iso-2022 charset whose code-space ranges are 94 long can be designated
 +to GN.  If the list contains 96, any charsets whose whose ranges are
 +96 long can be designated to GN.  If the first element is a charset,
 +that charset is initially designated to GN.
 +
 +This attribute has a meaning only when `:coding-type' is `iso-2022'.
 +
 +`:bom'
 +
 +This attributes specifies whether the coding system uses a `byte order
 +mark'.  VALUE must nil, t, or cons of coding systems whose
 +`:coding-type' is `utf-16'.
 +
 +If the value is nil, on decoding, don't treat the first two-byte as
 +BOM, and on encoding, don't produce BOM bytes.
 +
 +If the value is t, on decoding, skip the first two-byte as BOM, and on
 +encoding, produce BOM bytes accoding to the value of `:endian'.
 +
 +If the value is cons, on decoding, check the first two-byte.  If theyq
 +are 0xFE 0xFF, use the car part coding system of the value.  If they
 +are 0xFF 0xFE, use the car part coding system of the value.
 +Otherwise, treat them as bytes for a normal character.  On encoding,
 +produce BOM bytes accoding to the value of `:endian'.
 +
 +This attribute has a meaning only when `:coding-type' is `utf-16'.
 +
 +`:endian'
 +
 +VALUE must be `big' or `little' specifying big-endian and
 +little-endian respectively.  The default value is `big'.
 +
 +This attribute has a meaning only when `:coding-type' is `utf-16'.
 +
 +`:ccl-decoder'
 +
 +VALUE is a symbol representing the registered CCL program used for
 +decoding.  This attribute has a meaning only when `:coding-type' is
 +`ccl'.
 +
 +`:ccl-encoder'
 +
 +VALUE is a symbol representing the registered CCL program used for
 +encoding.  This attribute has a meaning only when `:coding-type' is
 +`ccl'."
 +  (let* ((common-attrs (mapcar 'list
 +                             '(:mnemonic
 +                               :coding-type
 +                               :charset-list
 +                               :ascii-compatible-p
 +                               :decode-translation-table
 +                               :encode-translation-table
 +                               :post-read-conversion
 +                               :pre-write-conversion
 +                               :default-char
 +                               :for-unibyte
 +                               :plist
 +                               :eol-type)))
 +       (coding-type (plist-get props :coding-type))
 +       (spec-attrs (mapcar 'list
 +                           (cond ((eq coding-type 'iso-2022)
 +                                  '(:initial
 +                                    :reg-usage
 +                                    :request
 +                                    :flags))
 +                                 ((eq coding-type 'utf-16)
 +                                  '(:bom
 +                                    :endian))
 +                                 ((eq coding-type 'ccl)
 +                                  '(:ccl-decoder
 +                                    :ccl-encoder
 +                                    :valids))))))
 +
 +    (dolist (slot common-attrs)
 +      (setcdr slot (plist-get props (car slot))))
 +
 +    (dolist (slot spec-attrs)
 +      (setcdr slot (plist-get props (car slot))))
 +
 +    (if (eq coding-type 'iso-2022)
 +      (let ((designation (plist-get props :designation))
 +            (flags (plist-get props :flags))
 +            (initial (make-vector 4 nil))
 +            (reg-usage (cons 4 4))
 +            request elt)
 +        (dotimes (i 4)
 +          (setq elt (aref designation i))
 +          (cond ((charsetp elt)
 +                 (aset initial i elt)
 +                 (setq request (cons (cons elt i) request)))
 +                ((consp elt)
 +                 (aset initial i (car elt))
 +                 (if (charsetp (car elt))
 +                     (setq request (cons (cons (car elt) i) request)))
 +                 (dolist (e (cdr elt))
 +                   (cond ((charsetp e)
 +                          (setq request (cons (cons e i) request)))
 +                         ((eq e 94)
 +                          (setcar reg-usage i))
 +                         ((eq e 96)
 +                          (setcdr reg-usage i))
 +                         ((eq e t)
 +                          (setcar reg-usage i)
 +                          (setcdr reg-usage i)))))))
 +        (setcdr (assq :initial spec-attrs) initial)
 +        (setcdr (assq :reg-usage spec-attrs) reg-usage)
 +        (setcdr (assq :request spec-attrs) request)
 +
 +        ;; Change :flags value from a list to a bit-mask.
 +        (let ((bits 0)
 +              (i 0))
 +          (dolist (elt coding-system-iso-2022-flags)
 +            (if (memq elt flags)
 +                (setq bits (logior bits (lsh 1 i))))
 +            (setq i (1+ i)))
 +          (setcdr (assq :flags spec-attrs) bits))))
 +
 +    ;; Add :name and :docstring properties to PROPS.
 +    (setq props
 +        (cons :name (cons name (cons :docstring (cons (purecopy docstring)
 +                                                      props)))))
 +    (setcdr (assq :plist common-attrs) props)
 +    (apply 'define-coding-system-internal 
 +         name (mapcar 'cdr (append common-attrs spec-attrs)))))
  
  (defun coding-system-doc-string (coding-system)
    "Return the documentation string for CODING-SYSTEM."
 -  (aref (coding-system-spec coding-system) coding-spec-doc-string-idx))
 -
 -(defun coding-system-plist (coding-system)
 -  "Return the property list of CODING-SYSTEM."
 -  (aref (coding-system-spec coding-system) coding-spec-plist-idx))
 +  (plist-get (coding-system-plist coding-system) :docstring))
  
 -(defun coding-system-flags (coding-system)
 -  "Return `flags' of CODING-SYSTEM.
 -A `flags' of a coding system is a vector of length 32 indicating detailed
 -information of a coding system.  See the function `make-coding-system'
 -for more detail."
 -  (aref (coding-system-spec coding-system) coding-spec-flags-idx))
 +(defun coding-system-mnemonic (coding-system)
 +  "Return the mnemonic character of CODING-SYSTEM.
 +The mnemonic character of a coding system is used in mode line to
 +indicate the coding system.  If CODING-SYSTEM. is nil, return ?=."
 +  (plist-get (coding-system-plist coding-system) :mnemonic))
  
 -(defun coding-system-get (coding-system prop)
 -  "Extract a value from CODING-SYSTEM's property list for property PROP."
 -  (plist-get (coding-system-plist coding-system) prop))
 +(defun coding-system-type (coding-system)
 +  "Return the coding type of CODING-SYSTEM.
 +A coding type is a symbol indicating the encoding method of CODING-SYSTEM.
 +See the function `define-coding-system' for more detail."
 +  (plist-get (coding-system-plist coding-system) :coding-type))
  
 -(defun coding-system-put (coding-system prop val)
 -  "Change value in CODING-SYSTEM's property list PROP to VAL."
 -  (let ((plist (coding-system-plist coding-system)))
 -    (if plist
 -      (plist-put plist prop val)
 -      (aset (coding-system-spec coding-system) coding-spec-plist-idx
 -          (list prop val)))))
 +(defun coding-system-charset-list (coding-system)
 +  "Return list of charsets supported by CODING-SYSTEM.
 +If CODING-SYSTEM supports all ISO-2022 charsets, return `iso-2022'.
 +If CODING-SYSTEM supports all emacs-mule charsets, return `emacs-mule'."
 +  (plist-get (coding-system-plist coding-system) :charset-list))
  
  (defun coding-system-category (coding-system)
 -  "Return the coding category of CODING-SYSTEM.
 -See also `coding-category-list'."
 -  (coding-system-get coding-system 'coding-category))
 -
 -(defun coding-system-base (coding-system)
 -  "Return the base coding system of CODING-SYSTEM.
 -A base coding system is what made by `make-coding-system'.
 -Any alias nor subsidiary coding systems are not base coding system."
 -  (car (coding-system-get coding-system 'alias-coding-systems)))
 -
 -;; Coding system also has a property `eol-type'.
 -;;
 -;; This property indicates how the coding system handles end-of-line
 -;; format.  The value is integer 0, 1, 2, or a vector of three coding
 -;; systems.  Each integer value 0, 1, and 2 indicates the format of
 -;; end-of-line LF, CRLF, and CR respectively.  A vector value
 -;; indicates that the format of end-of-line should be detected
 -;; automatically.  Nth element of the vector is the subsidiary coding
 -;; system whose `eol-type' property is N.
 -
 -(defun coding-system-eol-type (coding-system)
 -  "Return eol-type of CODING-SYSTEM.
 -An eol-type is integer 0, 1, 2, or a vector of coding systems.
 -
 -Integer values 0, 1, and 2 indicate a format of end-of-line; LF,
 -CRLF, and CR respectively.
 -
 -A vector value indicates that a format of end-of-line should be
 -detected automatically.  Nth element of the vector is the subsidiary
 -coding system whose eol-type is N."
 -  (get coding-system 'eol-type))
 +  "Return a category symbol of CODING-SYSTEM."
 +  (plist-get (coding-system-plist coding-system) :category))
 +
 +(defun coding-system-get (coding-system prop)
 +  "Extract a value from CODING-SYSTEM's property list for property PROP.
 +For compatibility with Emacs 20/21, this accepts old-style symbols
 +like `mime-charset' as well as the current style like `:mime-charset'."
 +  (or (plist-get (coding-system-plist coding-system) prop)
 +      (if (not (keywordp prop))
 +        ;; For backward compatiblity.
 +        (if (eq prop 'ascii-incompatible)
 +            (not (plist-get (coding-system-plist coding-system)
 +                            :ascii-compatible-p))
 +          (plist-get (coding-system-plist coding-system)
 +                     (intern (concat ":" (symbol-name prop))))))))
  
  (defun coding-system-eol-type-mnemonic (coding-system)
    "Return the string indicating end-of-line format of CODING-SYSTEM."
  Two coding systems are identical if two symbols are equal
  or one is an alias of the other."
    (or (eq coding-system-1 coding-system-2)
 -      (and (equal (coding-system-spec coding-system-1)
 -                (coding-system-spec coding-system-2))
 +      (and (equal (coding-system-plist coding-system-1)
 +                (coding-system-plist coding-system-2))
           (let ((eol-type-1 (coding-system-eol-type coding-system-1))
                 (eol-type-2 (coding-system-eol-type coding-system-2)))
             (or (eq eol-type-1 eol-type-2)
  
  (defun coding-system-list (&optional base-only)
    "Return a list of all existing non-subsidiary coding systems.
 -If optional arg BASE-ONLY is non-nil, only base coding systems are listed.
 -The value doesn't include subsidiary coding systems which are what
 +If optional arg BASE-ONLY is non-nil, only base coding systems are
 +listed.  The value doesn't include subsidiary coding systems which are
  made from bases and aliases automatically for various end-of-line
  formats (e.g. iso-latin-1-unix, koi8-r-dos)."
 -  (let* ((codings (copy-sequence coding-system-list))
 -       (tail (cons nil codings)))
 -    ;; Remove subsidiary coding systems (eol variants) and alias
 -    ;; coding systems (if necessary).
 -    (while (cdr tail)
 -      (let* ((coding (car (cdr tail)))
 -           (aliases (coding-system-get coding 'alias-coding-systems)))
 -      (if (or
 -           ;; CODING is an eol variant if not in ALIASES.
 -           (not (memq coding aliases))
 -           ;; CODING is an alias if it is not car of ALIASES.
 -           (and base-only (not (eq coding (car aliases)))))
 -          (setcdr tail (cdr (cdr tail)))
 -        (setq tail (cdr tail)))))
 +  (let ((codings nil))
 +    (dolist (coding coding-system-list)
 +      (if (eq (coding-system-base coding) coding)
 +        (if base-only
 +            (setq codings (cons coding codings))
 +          (dolist (alias (coding-system-aliases coding))
 +            (setq codings (cons alias codings))))))
      codings))
  
 -(defun map-charset-chars (func charset)
 -  "Use FUNC to map over all characters in CHARSET for side effects.
 -FUNC is a function of two args, the start and end (inclusive) of a
 -character code range.  Thus FUNC should iterate over [START, END]."
 -  (let* ((dim (charset-dimension charset))
 -       (chars (charset-chars charset))
 -       (start (if (= chars 94)
 -                  33
 -                32)))
 -    (if (= dim 1)
 -      (funcall func
 -               (make-char charset start)
 -               (make-char charset (+ start chars -1)))
 -      (dotimes (i chars)
 -      (funcall func
 -               (make-char charset (+ i start) start)
 -               (make-char charset (+ i start) (+ start chars -1)))))))
 -
 -(defalias 'register-char-codings 'ignore "")
 -(make-obsolete 'register-char-codings
 -               "it exists just for backward compatibility, and does nothing."
 -             "21.3")
 -
  (defconst char-coding-system-table nil
    "This is an obsolete variable.
  It exists just for backward compatibility, and the value is always nil.")
  
 -(defun make-subsidiary-coding-system (coding-system)
 -  "Make subsidiary coding systems (eol-type variants) of CODING-SYSTEM."
 -  (let ((coding-spec (coding-system-spec coding-system))
 -      (subsidiaries (vector (intern (format "%s-unix" coding-system))
 -                            (intern (format "%s-dos" coding-system))
 -                            (intern (format "%s-mac" coding-system))))
 -      elt)
 -    (dotimes (i 3)
 -      (setq elt (aref subsidiaries i))
 -      (put elt 'coding-system coding-spec)
 -      (put elt 'eol-type i)
 -      (put elt 'coding-system-define-form nil)
 -      (add-to-coding-system-list elt)
 -      (or (assoc (symbol-name elt) coding-system-alist)
 -        (setq coding-system-alist
 -              (cons (list (symbol-name elt)) coding-system-alist))))
 -    subsidiaries))
 -
  (defun transform-make-coding-system-args (name type &optional doc-string props)
    "For internal use only.
  Transform XEmacs style args for `make-coding-system' to Emacs style.
@@@ -1010,8 -721,169 +1010,8 @@@ Value is a list of transformed argument
                                         properties
                                         eol-type)
    "Define a new coding system CODING-SYSTEM (symbol).
 -Remaining arguments are TYPE, MNEMONIC, DOC-STRING, FLAGS (optional),
 -and PROPERTIES (optional) which construct a coding-spec of CODING-SYSTEM
 -in the following format:
 -      [TYPE MNEMONIC DOC-STRING PLIST FLAGS]
 -
 -TYPE is an integer value indicating the type of the coding system as follows:
 -  0: Emacs internal format,
 -  1: Shift-JIS (or MS-Kanji) used mainly on Japanese PCs,
 -  2: ISO-2022 including many variants,
 -  3: Big5 used mainly on Chinese PCs,
 -  4: private, CCL programs provide encoding/decoding algorithm,
 -  5: Raw-text, which means that text contains random 8-bit codes.
 -
 -MNEMONIC is a character to be displayed on mode line for the coding system.
 -
 -DOC-STRING is a documentation string for the coding system.
 -
 -FLAGS specifies more detailed information of the coding system as follows:
 -
 -  If TYPE is 2 (ISO-2022), FLAGS is a list of these elements:
 -      CHARSET0, CHARSET1, CHARSET2, CHARSET3, SHORT-FORM,
 -      ASCII-EOL, ASCII-CNTL, SEVEN, LOCKING-SHIFT, SINGLE-SHIFT,
 -      USE-ROMAN, USE-OLDJIS, NO-ISO6429, INIT-BOL, DESIGNATION-BOL,
 -      SAFE, ACCEPT-LATIN-EXTRA-CODE.
 -    CHARSETn are character sets initially designated to Gn graphic registers.
 -      If CHARSETn is nil, Gn is never used.
 -      If CHARSETn is t, Gn can be used but nothing designated initially.
 -      If CHARSETn is a list of character sets, those character sets are
 -        designated to Gn on output, but nothing designated to Gn initially.
 -        But, character set `ascii' can be designated only to G0.
 -    SHORT-FORM non-nil means use short designation sequence on output.
 -    ASCII-EOL non-nil means designate ASCII to g0 at end of line on output.
 -    ASCII-CNTL non-nil means designate ASCII to g0 before control codes and
 -      SPACE on output.
 -    SEVEN non-nil means use 7-bit code only on output.
 -    LOCKING-SHIFT non-nil means use locking-shift.
 -    SINGLE-SHIFT non-nil means use single-shift.
 -    USE-ROMAN non-nil means designate JIS0201-1976-Roman instead of ASCII.
 -    USE-OLDJIS non-nil means designate JIS0208-1976 instead of JIS0208-1983.
 -    NO-ISO6429 non-nil means not use ISO6429's direction specification.
 -    INIT-BOL non-nil means any designation state is assumed to be reset
 -      to initial at each beginning of line on output.
 -    DESIGNATION-BOL non-nil means designation sequences should be placed
 -      at beginning of line on output.
 -    SAFE non-nil means convert unsafe characters to `?' on output.
 -      Characters not specified in the property `safe-charsets' nor
 -      `safe-chars' are unsafe.
 -    ACCEPT-LATIN-EXTRA-CODE non-nil means code-detection routine accepts
 -      a code specified in `latin-extra-code-table' (which see) as a valid
 -      code of the coding system.
 -
 -  If TYPE is 4 (private), FLAGS should be a cons of CCL programs, for
 -    decoding and encoding.  CCL programs should be specified by their
 -    symbols.
 -
 -PROPERTIES is an alist of properties vs the corresponding values.  The
 -following properties are recognized:
 -
 -  o post-read-conversion
 -
 -  The value is a function to call after some text is inserted and
 -  decoded by the coding system itself and before any functions in
 -  `after-insert-functions' are called.  The argument of this
 -  function is the same as for a function in
 -  `after-insert-file-functions', i.e. LENGTH of the text inserted,
 -  with point at the head of the text to be decoded.
 -
 -  o pre-write-conversion
 -
 -  The value is a function to call after all functions in
 -  `write-region-annotate-functions' and `buffer-file-format' are
 -  called, and before the text is encoded by the coding system itself.
 -  The arguments to this function are the same as those of a function
 -  in `write-region-annotate-functions', i.e. FROM and TO, specifying
 -  a region of text.
 -
 -  o translation-table-for-decode
 -
 -  The value is a translation table to be applied on decoding.  See
 -  the function `make-translation-table' for the format of translation
 -  table.  This is not applicable to type 4 (CCL-based) coding systems.
 -
 -  o translation-table-for-encode
 -
 -  The value is a translation table to be applied on encoding.  This is
 -  not applicable to type 4 (CCL-based) coding systems.
 -
 -  o safe-chars
 -
 -  The value is a char table.  If a character has non-nil value in it,
 -  the character is safely supported by the coding system.  This
 -  overrides the specification of safe-charsets.
 -
 -  o safe-charsets
 -
 -  The value is a list of charsets safely supported by the coding
 -  system.  The value t means that all charsets Emacs handles are
 -  supported.  Even if some charset is not in this list, it doesn't
 -  mean that the charset can't be encoded in the coding system;
 -  it just means that some other receiver of text encoded
 -  in the coding system won't be able to handle that charset.
 -
 -  o mime-charset
 -
 -  The value is a symbol whose name is the `MIME-charset' parameter of
 -  the coding system.
 -
 -  o mime-text-unsuitable
 -
 -  A non-nil value means the `mime-charset' property names a charset
 -  which is unsuitable for the top-level media type \"text\".
 -
 -  o valid-codes (meaningful only for a coding system based on CCL)
 -
 -  The value is a list to indicate valid byte ranges of the encoded
 -  file.  Each element of the list is an integer or a cons of integer.
 -  In the former case, the integer value is a valid byte code.  In the
 -  latter case, the integers specify the range of valid byte codes.
 -
 -  o composition (meaningful only when TYPE is 0 or 2)
 -
 -  If the value is non-nil, the coding system preserves composition
 -  information.
 -
 -  o ascii-incompatible
 -
 -  If the value is non-nil, the coding system is not compatible
 -  with ASCII, which means it encodes or decodes ASCII character
 -  string to the different byte sequence.
 -
 -These properties are set in PLIST, a property list.  This function
 -also sets properties `coding-category' and `alias-coding-systems'
 -automatically.
 -
 -EOL-TYPE specifies the EOL type of the coding-system in one of the
 -following formats:
 -
 -  o symbol (unix, dos, or mac)
 -
 -      The symbol `unix' means Unix-like EOL (LF), `dos' means
 -      DOS-like EOL (CRLF), and `mac' means MAC-like EOL (CR).
 -
 -  o number (0, 1, or 2)
 -
 -      The number 0, 1, and 2 mean UNIX, DOS, and MAC-like EOL
 -      respectively.
 -
 -  o vector of coding-systems of length 3
 -
 -      The EOL type is detected automatically for the coding system.
 -      And, according to the detected EOL type, one of the coding
 -      systems in the vector is selected.  Elements of the vector
 -      corresponds to Unix-like EOL, DOS-like EOL, and Mac-like EOL
 -      in this order.
 -
 -Kludgy features for backward compatibility:
 -
 -1. If TYPE is 4 and car or cdr of FLAGS is a vector, the vector is
 -treated as a compiled CCL code.
 -
 -2. If PROPERTIES is just a list of character sets, the list is set as
 -a value of `safe-charsets' in PLIST."
 -
 +This function is provided for backward compatibility.
 +Use `define-coding-system' instead."
    ;; For compatiblity with XEmacs, we check the type of TYPE.  If it
    ;; is a symbol, perhaps, this function is called with XEmacs-style
    ;; arguments.  Here, try to transform that kind of arguments to
              properties (nth 5 args)
              eol-type (nth 6 args))))
  
 -  ;; Set a value of `coding-system' property.
 -  (let ((coding-spec (make-vector 5 nil))
 -      (no-initial-designation t)
 -      (no-alternative-designation t)
 -      (accept-latin-extra-code nil)
 -      coding-category)
 -    (if (or (not (integerp type)) (< type 0) (> type 5))
 -      (error "TYPE argument must be 0..5"))
 -    (if (or (not (integerp mnemonic)) (<= mnemonic ? ) (> mnemonic 127))
 -      (error "MNEMONIC argument must be an ASCII printable character"))
 -    (aset coding-spec coding-spec-type-idx type)
 -    (aset coding-spec coding-spec-mnemonic-idx mnemonic)
 -    (aset coding-spec coding-spec-doc-string-idx
 -        (purecopy (if (stringp doc-string) doc-string "")))
 -    (cond ((= type 0)
 -         (setq coding-category 'coding-category-emacs-mule))
 -        ((= type 1)
 -         (setq coding-category 'coding-category-sjis))
 -        ((= type 2)                   ; ISO2022
 -         (let ((i 0)
 -               (vec (make-vector 32 nil))
 -               (g1-designation nil)
 -               (fl flags))
 -           (while (< i 4)
 -             (let ((charset (car fl)))
 -               (if (and no-initial-designation
 -                        (> i 0)
 -                        (or (charsetp charset)
 -                            (and (consp charset)
 -                                 (charsetp (car charset)))))
 -                   (setq no-initial-designation nil))
 -               (if (charsetp charset)
 -                   (if (= i 1) (setq g1-designation charset))
 -                 (if (consp charset)
 -                     (let ((tail charset)
 -                           elt)
 -                       (while tail
 -                         (setq elt (car tail))
 -                         (if (eq elt t)
 -                             (setq no-alternative-designation nil)
 -                           (if (and elt (not (charsetp elt)))
 -                               (error "Invalid charset: %s" elt)))
 -                         (setq tail (cdr tail)))
 -                       (setq g1-designation (car charset)))
 -                   (if charset
 -                       (if (eq charset t)
 -                           (setq no-alternative-designation nil)
 -                         (error "Invalid charset: %s" charset)))))
 -               (aset vec i charset))
 -             (setq fl (cdr fl) i (1+ i)))
 -           (while (and (< i 32) fl)
 -             (aset vec i (car fl))
 -             (if (and (= i 16)        ; ACCEPT-LATIN-EXTRA-CODE
 -                      (car fl))
 -                 (setq accept-latin-extra-code t))
 -             (setq fl (cdr fl) i (1+ i)))
 -           (aset coding-spec 4 vec)
 -           (setq coding-category
 -                 (if (aref vec 8)     ; Use locking-shift.
 -                     (or (and (aref vec 7) 'coding-category-iso-7-else)
 -                         'coding-category-iso-8-else)
 -                   (if (aref vec 7)   ; 7-bit only.
 -                       (if (aref vec 9) ; Use single-shift.
 -                           'coding-category-iso-7-else
 -                         (if no-alternative-designation
 -                             'coding-category-iso-7-tight
 -                           'coding-category-iso-7))
 -                     (if (or no-initial-designation
 -                             (not no-alternative-designation))
 -                         'coding-category-iso-8-else
 -                       (if (and (charsetp g1-designation)
 -                                (= (charset-dimension g1-designation) 2))
 -                           'coding-category-iso-8-2
 -                         'coding-category-iso-8-1)))))))
 -        ((= type 3)
 -         (setq coding-category 'coding-category-big5))
 -        ((= type 4)                   ; private
 -         (setq coding-category 'coding-category-ccl)
 -         (if (not (consp flags))
 -             (error "Invalid FLAGS argument for TYPE 4 (CCL)")
 -           (let ((decoder (check-ccl-program
 -                           (car flags)
 -                           (intern (format "%s-decoder" coding-system))))
 -                 (encoder (check-ccl-program
 -                           (cdr flags)
 -                           (intern (format "%s-encoder" coding-system)))))
 -             (if (and decoder encoder)
 -                 (aset coding-spec 4 (cons decoder encoder))
 -               (error "Invalid FLAGS argument for TYPE 4 (CCL)")))))
 -        (t                            ; i.e. (= type 5)
 -         (setq coding-category 'coding-category-raw-text)))
 -
 -    (let ((plist (list 'coding-category coding-category
 -                     'alias-coding-systems (list coding-system))))
 -      (if no-initial-designation
 -        (plist-put plist 'no-initial-designation t))
 -      (if (and properties
 -             (or (eq properties t)
 -                 (not (consp (car properties)))))
 -        ;; In the old version, the arg PROPERTIES is a list to be
 -        ;; set in PLIST as a value of property `safe-charsets'.
 -        (setq properties (list (cons 'safe-charsets properties))))
 -      ;; In the current version PROPERTIES is a property list.
 -      ;; Reflect it into PLIST one by one while handling safe-chars
 -      ;; specially.
 -      (let ((safe-charsets (cdr (assq 'safe-charsets properties)))
 -          (safe-chars (cdr (assq 'safe-chars properties)))
 -          (l properties)
 -          prop val)
 -      ;; If only safe-charsets is specified, make a char-table from
 -      ;; it, and store that char-table as the value of `safe-chars'.
 -      (if (and (not safe-chars) safe-charsets)
 -          (let (charset)
 -            (if (eq safe-charsets t)
 -                (setq safe-chars t)
 -              (setq safe-chars (make-char-table 'safe-chars))
 -              (while safe-charsets
 -                (setq charset (car safe-charsets)
 -                      safe-charsets (cdr safe-charsets))
 -                (cond ((eq charset 'ascii)) ; just ignore
 -                      ((eq charset 'eight-bit-control)
 -                       (let ((i 128))
 -                         (while (< i 160)
 -                           (aset safe-chars i t)
 -                           (setq i (1+ i)))))
 -                      ((eq charset 'eight-bit-graphic)
 -                       (let ((i 160))
 -                         (while (< i 256)
 -                           (aset safe-chars i t)
 -                           (setq i (1+ i)))))
 -                      (t
 -                       (aset safe-chars (make-char charset) t))))
 -              (if accept-latin-extra-code
 -                  (let ((i 128))
 -                    (while (< i 160)
 -                      (if (aref latin-extra-code-table i)
 -                          (aset safe-chars i t))
 -                      (setq i (1+ i))))))
 -            (setq l (cons (cons 'safe-chars safe-chars) l))))
 -      (while l
 -        (setq prop (car (car l)) val (cdr (car l)) l (cdr l))
 -        (if (eq prop 'safe-chars)
 -            (progn
 -              (if (and (symbolp val)
 -                       (get val 'translation-table))
 -                  (setq safe-chars (get val 'translation-table)))
 -              (setq val safe-chars)))
 -        (plist-put plist prop val)))
 -      ;; The property `coding-category' may have been set differently
 -      ;; through PROPERTIES.
 -      (setq coding-category (plist-get plist 'coding-category))
 -      (aset coding-spec coding-spec-plist-idx plist))
 -    (put coding-system 'coding-system coding-spec)
 -    (put coding-system 'coding-system-define-form nil)
 -    (put coding-category 'coding-systems
 -       (cons coding-system (get coding-category 'coding-systems))))
 -
 -  ;; Next, set a value of `eol-type' property.
 -  (if (not eol-type)
 -      ;; If EOL-TYPE is nil, set a vector of subsidiary coding
 -      ;; systems, each corresponds to a coding system for the detected
 -      ;; EOL format.
 -      (setq eol-type (make-subsidiary-coding-system coding-system)))
 -  (setq eol-type
 -      (cond ((or (eq eol-type 'unix) (null eol-type))
 -             0)
 -            ((eq eol-type 'dos)
 -             1)
 -            ((eq eol-type 'mac)
 -             2)
 -            ((or (and (vectorp eol-type)
 -                      (= (length eol-type) 3))
 -                 (and (numberp eol-type)
 -                      (and (>= eol-type 0)
 -                           (<= eol-type 2))))
 -             eol-type)
 +  (setq type
 +      (cond ((eq type 0) 'emacs-mule)
 +            ((eq type 1) 'shift-jis)
 +            ((eq type 2) 'iso2022)
 +            ((eq type 3) 'big5)
 +            ((eq type 4) 'ccl)
 +            ((eq type 5) 'raw-text)
              (t
 -             (error "Invalid EOL-TYPE spec:%S" eol-type))))
 -  (put coding-system 'eol-type eol-type)
 -
 -  (define-coding-system-internal coding-system)
 -
 -  ;; At last, register CODING-SYSTEM in `coding-system-list' and
 -  ;; `coding-system-alist'.
 -  (add-to-coding-system-list coding-system)
 -  (or (assoc (symbol-name coding-system) coding-system-alist)
 -      (setq coding-system-alist (cons (list (symbol-name coding-system))
 -                                    coding-system-alist)))
 -
 -  ;; For a coding system of cateogory iso-8-1 and iso-8-2, create
 -  ;; XXX-with-esc variants.
 -  (let ((coding-category (coding-system-category coding-system)))
 -    (if (or (eq coding-category 'coding-category-iso-8-1)
 -          (eq coding-category 'coding-category-iso-8-2))
 -      (let ((esc (intern (concat (symbol-name coding-system) "-with-esc")))
 -            (doc (format "Same as %s but can handle any charsets by ISO's escape sequences." coding-system))
 -            (safe-charsets (assq 'safe-charsets properties))
 -            (mime-charset (assq 'mime-charset properties)))
 -        (if safe-charsets
 -            (setcdr safe-charsets t)
 -          (setq properties (cons (cons 'safe-charsets t) properties)))
 -        (if mime-charset
 -            (setcdr mime-charset nil))
 -        (make-coding-system esc type mnemonic doc
 -                            (if (listp (car flags))
 -                                (cons (append (car flags) '(t)) (cdr flags))
 -                              (cons (list (car flags) t) (cdr flags)))
 -                            properties))))
 -
 -  coding-system)
 -
 -(put 'safe-chars 'char-table-extra-slots 0)
 -
 -(defun define-coding-system-alias (alias coding-system)
 -  "Define ALIAS as an alias for coding system CODING-SYSTEM."
 -  (put alias 'coding-system (coding-system-spec coding-system))
 -  (put alias 'coding-system-define-form nil)
 -  (add-to-coding-system-list alias)
 -  (or (assoc (symbol-name alias) coding-system-alist)
 -      (setq coding-system-alist (cons (list (symbol-name alias))
 -                                    coding-system-alist)))
 -  (let ((eol-type (coding-system-eol-type coding-system)))
 -    (if (vectorp eol-type)
 -      (progn
 -        (nconc (coding-system-get alias 'alias-coding-systems) (list alias))
 -        (put alias 'eol-type (make-subsidiary-coding-system alias)))
 -      (put alias 'eol-type eol-type))))
 +             (error "Invalid coding system type: %s" type))))
 +
 +  (setq properties
 +      (let ((plist nil) key)
 +        (dolist (elt properties)
 +          (setq key (car elt))
 +          (cond ((eq key 'post-read-conversion)
 +                 (setq key :post-read-conversion))
 +                ((eq key 'pre-write-conversion)
 +                 (setq key :pre-write-conversion))
 +                ((eq key 'translation-table-for-decode)
 +                 (setq key :decode-translation-table))
 +                ((eq key 'translation-table-for-encode)
 +                 (setq key :encode-translation-table))
 +                ((eq key 'safe-charsets)
 +                 (setq key :charset-list))
 +                ((eq key 'mime-charset)
 +                 (setq key :mime-charset))
 +                ((eq key 'valid-codes)
 +                 (setq key :valids)))
 +          (setq plist (plist-put plist key (cdr elt))))
 +        plist))
 +  (setq properties (plist-put properties :mnemonic mnemonic))
 +  (plist-put properties :coding-type type)
 +  (cond ((eq eol-type 0) (setq eol-type 'unix))
 +      ((eq eol-type 1) (setq eol-type 'dos))
 +      ((eq eol-type 2) (setq eol-type 'mac))
 +      ((vectorp eol-type) (setq eol-type nil)))
 +  (plist-put properties :eol-type eol-type)
 +
 +  (cond
 +   ((eq type 'iso2022)
 +    (plist-put properties :flags
 +             (list (and (or (consp (nth 0 flags))
 +                            (consp (nth 1 flags))
 +                            (consp (nth 2 flags))
 +                            (consp (nth 3 flags))) 'designation)
 +                   (or (nth 4 flags) 'long-form)
 +                   (and (nth 5 flags) 'ascii-at-eol)
 +                   (and (nth 6 flags) 'ascii-at-cntl)
 +                   (and (nth 7 flags) '7-bit)
 +                   (and (nth 8 flags) 'locking-shift)
 +                   (and (nth 9 flags) 'single-shift)
 +                   (and (nth 10 flags) 'use-roman)
 +                   (and (nth 11 flags) 'use-oldjis)
 +                   (or (nth 12 flags) 'direction)
 +                   (and (nth 13 flags) 'init-at-bol)
 +                   (and (nth 14 flags) 'designate-at-bol)
 +                   (and (nth 15 flags) 'safe)
 +                   (and (nth 16 flags) 'latin-extra)))
 +    (plist-put properties :designation
 +             (let ((vec (make-vector 4 nil)))
 +               (dotimes (i 4)
 +                 (let ((spec (nth i flags)))
 +                   (if (eq spec t)
 +                       (aset vec i '(94 96))
 +                   (if (consp spec)
 +                       (progn
 +                         (if (memq t spec)
 +                             (setq spec (append (delq t spec) '(94 96))))
 +                         (aset vec i spec))))))
 +               vec)))
 +
 +   ((eq type 'ccl)
 +    (plist-put properties :ccl-decoder (car flags))
 +    (plist-put properties :ccl-encoder (cdr flags))))
 +
 +  (apply 'define-coding-system coding-system doc-string properties))
  
  (defun merge-coding-systems (first second)
    "Fill in any unspecified aspects of coding system FIRST from SECOND.
@@@ -1187,9 -1210,8 +1187,9 @@@ see) to CODING-SYSTEM.
    (interactive "zCoding system for file names (default nil): ")
    (check-coding-system coding-system)
    (if (and coding-system
 -         (coding-system-get coding-system 'ascii-incompatible))
 -      (error "%s is not ASCII-compatible" coding-system))
 +         (not (coding-system-get coding-system :ascii-compatible-p))
 +         (not (coding-system-get coding-system :suitable-for-file-name)))
 +      (error "%s is not suitable for file names" coding-system))
    (setq file-name-coding-system coding-system))
  
  (defvar default-terminal-coding-system nil
@@@ -1247,9 -1269,8 +1247,9 @@@ or by the previous use of this command.
    (if coding-system
        (setq default-keyboard-coding-system coding-system))
    (if (and coding-system
 -         (coding-system-get coding-system 'ascii-incompatible))
 -      (error "%s is not ASCII-compatible" coding-system))
 +         (not (coding-system-get coding-system :ascii-compatible-p))
 +         (not (coding-system-get coding-system :suitable-for-keyboard)))
 +      (error "%s is not suitable for keyboard" coding-system))
    (set-keyboard-coding-system-internal coding-system)
    (setq keyboard-coding-system coding-system)
    (encoded-kbd-mode (if coding-system 1 0)))
@@@ -1307,14 -1328,14 +1307,14 @@@ the text is encoded or decoded by CODIN
  (defvar last-next-selection-coding-system nil)
  
  (defun set-next-selection-coding-system (coding-system)
 -  "Make CODING-SYSTEM used for the next communication with other X clients.
 +  "Use CODING-SYSTEM for next communication with other window system clients.
  This setting is effective for the next communication only."
    (interactive
     (list (read-coding-system
          (if last-next-selection-coding-system
 -            (format "Coding system for the next selection (default %S): "
 +            (format "Coding system for the next selection (default %S): "
                      last-next-selection-coding-system)
 -          "Coding system for the next selection: ")
 +          "Coding system for the next selection: ")
          last-next-selection-coding-system)))
    (if coding-system
        (setq last-next-selection-coding-system coding-system)
  
  (defun set-coding-priority (arg)
    "Set priority of coding categories according to ARG.
 -ARG is a list of coding categories ordered by priority."
 -  (let ((l arg)
 -      (current-list (copy-sequence coding-category-list)))
 -    ;; Check the validity of ARG while deleting coding categories in
 -    ;; ARG from CURRENT-LIST.  We assume that CODING-CATEGORY-LIST
 -    ;; contains all coding categories.
 -    (while l
 -      (if (or (null (get (car l) 'coding-category-index))
 -            (null (memq (car l) current-list)))
 -        (error "Invalid or duplicated element in argument: %s" arg))
 -      (setq current-list (delq (car l) current-list))
 -      (setq l (cdr l)))
 -    ;; Update `coding-category-list' and return it.
 -    (setq coding-category-list (append arg current-list))
 -    (set-coding-priority-internal)))
 +ARG is a list of coding categories ordered by priority.
 +
 +This function is provided for backward compatibility.
 +Now we have more convenient function `set-coding-system-priority'."
 +  (apply 'set-coding-system-priority
 +       (mapcar #'(lambda (x) (symbol-value x)) arg)))
 +(make-obsolete 'set-coding-priority 'set-coding-system-priority "23.1")
  
  ;;; X selections
  
  (defvar ctext-non-standard-encodings-alist
 -  '(("big5-0" big5 2 (chinese-big5-1 chinese-big5-2))
 +  '(("big5-0" big5 2 big5)
      ("ISO8859-14" iso-8859-14 1 latin-iso8859-14)
 -    ("ISO8859-15" iso-8859-15 1 latin-iso8859-15))
 +    ("ISO8859-15" iso-8859-15 1 latin-iso8859-15)
 +    ("gbk-0" gbk 2 chinese-gbk))
    "Alist of non-standard encoding names vs the corresponding usages in CTEXT.
  
  It controls how extended segments of a compound text are handled
@@@ -1357,7 -1385,9 +1357,7 @@@ in the segment.  It can be 0 (meaning t
  character is variable), 1, 2, 3, or 4.
  
  CHARSET is a charater set containing characters that are encoded
 -in the segment.  It can be a list of character sets.  It can also
 -be a char-table, in which case characters that have non-nil value
 -in the char-table are the target.
 +in the segment.  It can be a list of character sets.
  
  On decoding CTEXT, all encoding names listed here are recognized.
  
@@@ -1366,7 -1396,8 +1366,7 @@@ On encoding CTEXT, encoding names in th
  listed for the current language environment under the key
  `ctext-non-standard-encodings' are used.")
  
 -(defvar ctext-non-standard-encodings
 -  '("big5-0")
 +(defvar ctext-non-standard-encodings nil
    "List of non-standard encoding names used in extended segments of CTEXT.
  Each element must be one of the names listed in the variable
  `ctext-non-standard-encodings-alist' (which see).")
  
  (defun ctext-post-read-conversion (len)
    "Decode LEN characters encoded as Compound Text with Extended Segments."
 +  ;; We don't need the following because it is expected that this
 +  ;; function is mainly used for decoding X selection which is not
 +  ;; that big data.
 +  ;;(buffer-disable-undo) ; minimize consing due to insertions and deletions
    (save-match-data
      (save-restriction
 +      (narrow-to-region (point) (+ (point) len))
        (let ((case-fold-search nil)
 -          (in-workbuf (string= (buffer-name) " *code-converting-work*"))
            last-coding-system-used
            pos bytes)
 -      (or in-workbuf
 -          (narrow-to-region (point) (+ (point) len)))
 -      (if in-workbuf
 -          (set-buffer-multibyte t))
 +      (decode-coding-region (point-min) (point-max) 'ctext)
        (while (re-search-forward ctext-non-standard-encodings-regexp
                                  nil 'move)
          (setq pos (match-beginning 0))
          (if (match-beginning 1)
              ;; ESC % / [0-4] M L --ENCODING-NAME-- \002 --BYTES--
 -            (let* ((M (char-after (+ pos 4)))
 -                   (L (char-after (+ pos 5)))
 +            (let* ((M (multibyte-char-to-unibyte (char-after (+ pos 4))))
 +                   (L (multibyte-char-to-unibyte (char-after (+ pos 5))))
                     (encoding (match-string 2))
                     (encoding-info (assoc-string
                                     encoding
        (goto-char (point-min))
        (- (point-max) (point)))))
  
 -;; Return a char table of extended segment usage for each character.
 -;; Each value of the char table is nil, one of the elements of
 -;; `ctext-non-standard-encodings-alist', or the symbol `utf-8'.
 +;; Return an alist of CHARSET vs CTEXT-USAGE-INFO generated from
 +;; `ctext-non-standard-encodings' and a list specified by the key
 +;; `ctext-non-standard-encodings' for the currrent language
 +;; environment.  CTEXT-USAGE-INFO is one of the element of
 +;; `ctext-non-standard-encodings-alist' or nil.  In the former case, a
 +;; character in CHARSET is encoded using extended segment.  In the
 +;; latter case, a character in CHARSET is encoded using normal ISO2022
 +;; designation sequence.  If a character is not in any of CHARSETs, it
 +;; is encoded using UTF-8 encoding extention.
  
  (defun ctext-non-standard-encodings-table ()
 -  (let ((table (make-char-table 'translation-table)))
 -    (aset table (make-char 'mule-unicode-0100-24ff) 'utf-8)
 -    (aset table (make-char 'mule-unicode-2500-33ff) 'utf-8)
 -    (aset table (make-char 'mule-unicode-e000-ffff) 'utf-8)
 -    (dolist (encoding (reverse
 -                     (append
 +  (let (table)
 +    ;; Setup charsets specified by the key
 +    ;; `ctext-non-standard-encodings' for the current language
 +    ;; environment and in `ctext-non-standard-encodings'.
 +    (dolist (encoding (append
                        (get-language-info current-language-environment
                                           'ctext-non-standard-encodings)
 -                      ctext-non-standard-encodings)))
 +                      ctext-non-standard-encodings))
        (let* ((slot (assoc encoding ctext-non-standard-encodings-alist))
             (charset (nth 3 slot)))
 -      (if charset
 -          (cond ((charsetp charset)
 -                 (aset table (make-char charset) slot))
 -                ((listp charset)
 -                 (dolist (elt charset)
 -                   (aset table (make-char elt) slot)))
 -                ((char-table-p charset)
 -                 (map-char-table #'(lambda (k v)
 -                                 (if (and v (> k 128)) (aset table k slot)))
 -                                 charset))))))
 -    table))
 +      (if (charsetp charset)
 +          (push (cons charset slot) table)
 +        (dolist (cs charset)
 +          (push (cons cs slot) table)))))
 +
 +    ;; Next prepend charsets for ISO2022 designation sequence.
 +    (dolist (charset charset-list)
 +      (let ((final (plist-get (charset-plist charset) :iso-final-char)))
 +      (if (and (integerp final)
 +               (>= final #x40) (<= final #x7e)
 +               ;; Exclude ascii and chinese-cns11643-X.
 +               (not (eq charset 'ascii))
 +               (not (string-match "cns11643" (symbol-name charset))))
 +          (push (cons charset nil) table))))
 +
 +    ;; Returned reversed list so that the charsets specified by the
 +    ;; key `ctext-non-standard-encodings' for the current language
 +    ;; have the highest priority.
 +    (nreverse table)))
  
  (defun ctext-pre-write-conversion (from to)
    "Encode characters between FROM and TO as Compound Text w/Extended Segments.
@@@ -1475,40 -1492,39 +1475,40 @@@ If FROM is a string, or if the current 
  by encode-coding-string, generate a new temp buffer, insert the
  text, and convert it in the temporary buffer.  Otherwise, convert in-place."
    (save-match-data
 -    (let ((workbuf (get-buffer-create " *code-conversion-work*")))
 -      ;; Setup a working buffer if necessary.
 -      (cond ((stringp from)
 -           (set-buffer workbuf)
 -           (erase-buffer)
 -           (set-buffer-multibyte (multibyte-string-p from))
 -           (insert from))
 -          ((not (eq (current-buffer) workbuf))
 -           (let ((buf (current-buffer))
 -                 (multibyte enable-multibyte-characters))
 -             (set-buffer workbuf)
 -             (erase-buffer)
 -             (set-buffer-multibyte multibyte)
 -             (insert-buffer-substring buf from to)))))
 +    ;; Setup a working buffer if necessary.
 +    (when (stringp from)
 +      (set-buffer (generate-new-buffer " *temp"))
 +      (set-buffer-multibyte (multibyte-string-p from))
 +      (insert from))
  
      ;; Now we can encode the whole buffer.
      (let ((encoding-table (ctext-non-standard-encodings-table))
          last-coding-system-used
          last-pos last-encoding-info
 -        encoding-info end-pos)
 +        encoding-info end-pos ch)
        (goto-char (setq last-pos (point-min)))
        (setq end-pos (point-marker))
        (while (re-search-forward "[^\000-\177]+" nil t)
        ;; Found a sequence of non-ASCII characters.
        (setq last-pos (match-beginning 0)
 -            last-encoding-info (aref encoding-table (char-after last-pos)))
 +            ch (char-after last-pos)
 +            last-encoding-info (catch 'tag
 +                                 (dolist (elt encoding-table)
 +                                   (if (encode-char ch (car elt))
 +                                       (throw 'tag (cdr elt))))
 +                                 'utf-8))
        (set-marker end-pos (match-end 0))
        (goto-char (1+ last-pos))
        (catch 'tag
          (while t
            (setq encoding-info
                  (if (< (point) end-pos)
 -                    (aref encoding-table (following-char))))
 +                    (catch 'tag
 +                      (setq ch (following-char))
 +                      (dolist (elt encoding-table)
 +                        (if (encode-char ch (car elt))
 +                            (throw 'tag (cdr elt))))
 +                      'utf-8)))
            (unless (eq last-encoding-info encoding-info)
              (cond ((consp last-encoding-info)
                     ;; Encode the previous range using an extended
                       (encode-coding-region last-pos (point) coding-system)
                       (setq len (+ (length encoding-name) 1
                                    (- (point) last-pos)))
 +                     ;; According to the spec of CTEXT, it is not
 +                     ;; necessary to produce this extra designation
 +                     ;; sequence, but some buggy application
 +                     ;; (e.g. crxvt-gb) requires it.
 +                     (insert "\e(B")
                       (save-excursion
                         (goto-char last-pos)
 -                       (insert (string-to-multibyte
 -                                (format "\e%%/%d%c%c%s\ 2"
 -                                        noctets
 -                                        (+ (/ len 128) 128)
 -                                        (+ (% len 128) 128)
 -                                        encoding-name))))))
 +                       (insert (format "\e%%/%d" noctets))
 +                       (insert-byte (+ (/ len 128) 128) 1)
 +                       (insert-byte (+ (% len 128) 128) 1)
 +                       (insert encoding-name)
 +                       (insert 2))))
                    ((eq last-encoding-info 'utf-8)
                     ;; Encode the previous range using UTF-8 encoding
                     ;; extention.
@@@ -1575,8 -1587,7 +1575,8 @@@ and the contents of `file-coding-system
    '(("^BABYL OPTIONS:[ \t]*-\\*-[ \t]*rmail[ \t]*-\\*-" . no-conversion)
      ("\\`\xFE\xFF" . utf-16be-with-signature)
      ("\\`\xFF\xFE" . utf-16le-with-signature)
 -    ("\\`\xEF\xBB\xBF" . utf-8))
 +    ("\\`\xEF\xBB\xBF" . utf-8)
 +    ("\\`;ELC\024\0\0\0" . emacs-mule))       ; Emacs 20-compiled
    "Alist of patterns vs corresponding coding systems.
  Each element looks like (REGEXP . CODING-SYSTEM).
  A file whose first bytes match REGEXP is decoded by CODING-SYSTEM on reading.
@@@ -1832,13 -1843,35 +1832,13 @@@ The optional second arg VISIT non-nil m
        (setq buffer-file-coding-system-explicit coding-system-for-read))
    (if last-coding-system-used
        (let ((coding-system
 -           (find-new-buffer-file-coding-system last-coding-system-used))
 -          (modified-p (buffer-modified-p)))
 +           (find-new-buffer-file-coding-system last-coding-system-used)))
        (when coding-system
          ;; Tell set-buffer-file-coding-system not to mark the file
          ;; as modified; we just read it, and it's supposed to be unmodified.
          ;; Marking it modified would try to lock it, which would
          ;; check the modtime, and we don't want to do that again now.
 -        (set-buffer-file-coding-system coding-system t t)
 -        (if (and enable-multibyte-characters
 -                 (or (eq coding-system 'no-conversion)
 -                     (eq (coding-system-type coding-system) 5))
 -                 ;; If buffer was unmodified and the size is the
 -                 ;; same as INSERTED, we must be visiting it.
 -                 (not modified-p)
 -                 (= (buffer-size) inserted))
 -            ;; For coding systems no-conversion and raw-text...,
 -            ;; edit the buffer as unibyte.
 -            (let ((pos-marker (copy-marker (+ (point) inserted)))
 -                  ;; Prevent locking.
 -                  (buffer-file-name nil))
 -              (if visit
 -                  ;; If we're doing this for find-file,
 -                  ;; don't record undo info; this counts as
 -                  ;; part of producing the buffer's initial contents.
 -                  (let ((buffer-undo-list t))
 -                    (set-buffer-multibyte nil))
 -                (set-buffer-multibyte nil))
 -              (setq inserted (- pos-marker (point)))))
 -        (restore-buffer-modified-p modified-p))))
 +        (set-buffer-file-coding-system coding-system t t))))
    inserted)
  
  ;; The coding-spec and eol-type of coding-system returned is decided
@@@ -1865,8 -1898,8 +1865,8 @@@ Return nil if there's no need to set `b
          ;; But eol-type is not yet set.
          (setq local-eol nil))
        (if (and buffer-file-coding-system
 -             (not (eq (coding-system-type buffer-file-coding-system) t)))
 -        ;; This is not `undecided'.
 +             (not (eq (coding-system-type buffer-file-coding-system)
 +                      'undecided)))
          (setq local-coding (coding-system-base buffer-file-coding-system)))
  
        (if (and (local-variable-p 'buffer-file-coding-system)
            ;; But eol-type is not found.
            ;; If EOL conversions are inhibited, force unix eol-type.
            (setq found-eol (if inhibit-eol-conversion 0)))
 -      (if (eq (coding-system-type coding) t)
 -          (setq found-coding 'undecided)
 -        (setq found-coding (coding-system-base coding)))
 +      (setq found-coding (coding-system-base coding))
  
        (if (and (not found-eol) (eq found-coding 'undecided))
            ;; No valid coding information found.
@@@ -2031,38 -2066,62 +2031,38 @@@ translation in CCL programs
  Each argument is a list of elements of the form (FROM . TO), where FROM
  is a character to be translated to TO.
  
 -FROM can be a generic character (see `make-char').  In this case, TO is
 -a generic character containing the same number of characters, or an
 -ordinary character.  If FROM and TO are both generic characters, all
 -characters belonging to FROM are translated to characters belonging to TO
 -without changing their position code(s).
 -
  The arguments and forms in each argument are processed in the given
  order, and if a previous form already translates TO to some other
  character, say TO-ALT, FROM is also translated to TO-ALT."
    (let ((table (make-char-table 'translation-table))
        revlist)
 -    (while args
 -      (let ((elts (car args)))
 -      (while elts
 -        (let* ((from (car (car elts)))
 -               (from-i 0)             ; degree of freedom of FROM
 -               (from-rev (nreverse (split-char from)))
 -               (to (cdr (car elts)))
 -               (to-i 0)               ; degree of freedom of TO
 -               (to-rev (nreverse (split-char to))))
 -          ;; Check numbers of heading 0s in FROM-REV and TO-REV.
 -          (while (eq (car from-rev) 0)
 -            (setq from-i (1+ from-i) from-rev (cdr from-rev)))
 -          (while (eq (car to-rev) 0)
 -            (setq to-i (1+ to-i) to-rev (cdr to-rev)))
 -          (if (and (/= from-i to-i) (/= to-i 0))
 -              (error "Invalid character pair (%d . %d)" from to))
 -          ;; If we have already translated TO to TO-ALT, FROM should
 -          ;; also be translated to TO-ALT.  But, this is only if TO
 -          ;; is a generic character or TO-ALT is not a generic
 -          ;; character.
 -          (let ((to-alt (aref table to)))
 -            (if (and to-alt
 -                     (or (> to-i 0) (not (generic-char-p to-alt))))
 -                (setq to to-alt)))
 -          (if (> from-i 0)
 -              (set-char-table-default table from to)
 -            (aset table from to))
 -          ;; If we have already translated some chars to FROM, they
 -          ;; should also be translated to TO.
 -          (let ((l (assq from revlist)))
 -            (if l
 -                (let ((ch (car l)))
 -                  (setcar l to)
 -                  (setq l (cdr l))
 -                  (while l
 -                    (aset table ch to)
 -                    (setq l (cdr l)) ))))
 -          ;; Now update REVLIST.
 -          (let ((l (assq to revlist)))
 -            (if l
 -                (setcdr l (cons from (cdr l)))
 -              (setq revlist (cons (list to from) revlist)))))
 -        (setq elts (cdr elts))))
 -      (setq args (cdr args)))
 +    (dolist (elts args)
 +      (dolist (elt elts)
 +      (let ((from (car elt))
 +            (to (cdr elt))
 +            to-alt rev-from rev-to)
 +        ;; If we have already translated TO to TO-ALT, FROM should
 +        ;; also be translated to TO-ALT.
 +        (if (setq to-alt (aref table to))
 +            (setq to to-alt))
 +        (aset table from to)
 +        ;; If we have already translated some chars to FROM, they
 +        ;; should also be translated to TO.
 +        (when (setq rev-from (assq from revlist))
 +          (dolist (elt (cdr rev-from))
 +            (aset table elt to))
 +          (setq revlist (delq rev-from revlist)
 +                rev-from (cdr rev-from)))
 +        ;; Now update REVLIST.
 +        (setq rev-to (assq to revlist))
 +        (if rev-to
 +            (setcdr rev-to (cons from (cdr rev-to)))
 +          (setq rev-to (list to from)
 +                revlist (cons rev-to revlist)))
 +        (if rev-from
 +            (setcdr rev-to (append rev-from (cdr rev-to)))))))
      ;; Return TABLE just created.
 +    (set-char-table-extra-slot table 1 1)
      table))
  
  (defun make-translation-table-from-vector (vec)
@@@ -2080,47 -2139,8 +2080,47 @@@ See also the variable `nonascii-transla
        (if (>= ch 256)
            (aset rev-table ch i))))
      (set-char-table-extra-slot table 0 rev-table)
 +    (set-char-table-extra-slot table 1 1)
 +    (set-char-table-extra-slot rev-table 1 1)
      table))
  
 +(defun make-translation-table-from-alist (alist)
 +  "Make translation table from N<->M mapping in ALIST.
 +ALIST is an alist, each element has the form (FROM . TO).
 +FROM and TO are a character or a vector of characters.
 +If FROM is a character, that character is translated to TO.
 +If FROM is a vector of characters, that sequence is translated to TO.
 +The first extra-slot of the value is a translation table for reverse mapping."
 +  (let ((tables (vector (make-char-table 'translation-table)
 +                      (make-char-table 'translation-table)))
 +      table max-lookup from to idx val)
 +    (dotimes (i 2)
 +      (setq table (aref tables i))
 +      (setq max-lookup 1)
 +      (dolist (elt alist)
 +      (if (= i 0)
 +          (setq from (car elt) to (cdr elt))
 +        (setq from (cdr elt) to (car elt)))
 +      (if (characterp from)
 +          (setq idx from)
 +        (setq idx (aref from 0)
 +              max-lookup (max max-lookup (length from))))
 +      (setq val (aref table idx))
 +      (if val
 +          (progn
 +            (or (consp val)
 +                (setq val (list (cons (vector idx) val))))
 +            (if (characterp from)
 +                (setq from (vector from)))
 +            (setq val (nconc val (list (cons from to)))))
 +        (if (characterp from)
 +            (setq val to)
 +          (setq val (list (cons from to)))))
 +      (aset table idx val))
 +      (set-char-table-extra-slot table 1 max-lookup))
 +    (set-char-table-extra-slot (aref tables 0) 0 (aref tables 1))
 +    (aref tables 0)))
 +
  (defun define-translation-table (symbol &rest args)
    "Define SYMBOL as the name of translation table made by ARGS.
  This sets up information so that the table can be used for
@@@ -2191,7 -2211,7 +2191,7 @@@ It returns the number of characters cha
  (put 'with-category-table 'lisp-indent-function 1)
  
  (defmacro with-category-table (table &rest body)
 -  "Evaluate BODY with category table of current buffer set to TABLE.
 +  "Execute BODY like `progn' with CATEGORY-TABLE the current category table.
  The category table of the current buffer is saved, BODY is evaluated,
  then the saved table is restored, even in case of an abnormal exit.
  Value is what BODY returns."
@@@ -2241,8 -2261,6 +2241,8 @@@ Analogous to `define-translation-table'
  (setq ignore-relative-composition
        (make-char-table 'ignore-relative-composition))
  
 +(make-obsolete 'set-char-table-default
 +             "Generic characters no longer exist" "23.1")
  
  ;;; Built-in auto-coding-functions:
  
@@@ -2274,7 -2292,12 +2274,12 @@@ This function is intended to be added t
                        ;; In case of no header, search only 10 lines.
                        (forward-line 10))
                    (point))))
-   (when (re-search-forward "<meta\\s-+http-equiv=[\"']?content-type[\"']?\\s-+content=[\"']text/\\sw+;\\s-*charset=\\(.+?\\)[\"']" size t)
+   ;; Make sure that the buffer really contains an HTML document, by
+   ;; checking that it starts with a doctype or a <HTML> start tag
+   ;; (allowing for whitespace at bob).  Note: 'DOCTYPE NETSCAPE' is
+   ;; useful for Mozilla bookmark files.
+   (when (and (re-search-forward "\\`[[:space:]\n]*\\(<!doctype[[:space:]\n]+\\(html\\|netscape\\)\\|<html\\)" size t)
+            (re-search-forward "<meta\\s-+http-equiv=[\"']?content-type[\"']?\\s-+content=[\"']text/\\sw+;\\s-*charset=\\(.+?\\)[\"']" size t))
      (let* ((match (match-string 1))
           (sym (intern (downcase match))))
        (if (coding-system-p sym)
index c13cd3660ff1e06ca1375fb0bef201417abbeed7,3244a6a1c0b0d0bf12b5cb3e1f3b55d97d77278a..7f2c1e9a69c64f12aa9cbd2fb85b3bd6bc5a7899
@@@ -1,9 -1,9 +1,9 @@@
  ;;; quail.el --- provides simple input method for multilingual text
  
  ;; Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
- ;;   2006  Free Software Foundation, Inc.
+ ;;   2006, 2007  Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
@@@ -800,9 -800,7 +800,9 @@@ The format of KBD-LAYOUT is the same a
        (if translation
            (progn
              (if (consp translation)
 -                (setq translation (aref (cdr translation) 0)))
 +                (if (> (length (cdr translation)) 0)
 +                    (setq translation (aref (cdr translation) 0))
 +                  (setq translation " ")))
              (setq done-list (cons translation done-list)))
          (setq translation ch))
        (aset layout i translation))
@@@ -1278,16 -1276,28 +1278,16 @@@ The returned value is a Quail map speci
  
  (defun quail-input-string-to-events (str)
    "Convert input string STR to a list of events.
 -Do so while interleaving with the following special events:
 -\(compose-last-chars LEN COMPONENTS)
 -\(quail-advice INPUT-STRING)"
 -  (let* ((events (mapcar
 -                (lambda (c)
 -                  ;; This gives us the chance to unify on input
 -                  ;; (e.g. using ucs-tables.el).
 -                  (or (and translation-table-for-input
 -                           (aref translation-table-for-input c))
 -                      c))
 -                str))
 -       (len (length str))
 -       (idx len)
 -       composition from to)
 -    (while (and (> idx 0)
 -              (setq composition (find-composition idx 0 str t)))
 -      (setq from (car composition) to (nth 1 composition))
 -      (setcdr (nthcdr (1- to) events)
 -            (cons (list 'compose-last-chars (- to from)
 -                        (and (not (nth 3 composition)) (nth 2 composition)))
 -                  (nthcdr to events)))
 -      (setq idx (1- from)))
 +If STR has `advice' text property, append the following special event:
 +\(quail-advice STR)"
 +  (let ((events (mapcar
 +               (lambda (c)
 +                 ;; This gives us the chance to unify on input
 +                 ;; (e.g. using ucs-tables.el).
 +                 (or (and translation-table-for-input
 +                          (aref translation-table-for-input c))
 +                     c))
 +               str)))
      (if (or (get-text-property 0 'advice str)
            (next-single-property-change 0 'advice str))
        (setq events
@@@ -1587,10 -1597,7 +1587,10 @@@ with more keys.
    "Return string to be shown as current translation of key sequence.
  LEN is the length of the sequence.  DEF is a definition part of the
  Quail map for the sequence."
 -  (or (and (consp def) (aref (cdr def) (car (car def))))
 +  (or (and (consp def)
 +         (if (> (length (cdr def)) (car (car def)))
 +             (aref (cdr def) (car (car def)))
 +           ""))
        def
        (and (> len 1)
           (let* ((str (quail-get-current-str
@@@ -2068,8 -2075,6 +2068,8 @@@ minibuffer and the selected frame has n
  
  (defun quail-get-translations ()
    "Return a string containing the current possible translations."
 +  (or (multibyte-string-p quail-current-key)
 +      (setq quail-current-key (string-to-multibyte quail-current-key)))
    (let ((map (quail-lookup-key quail-current-key nil t))
        (str (copy-sequence quail-current-key)))
      (if quail-current-translations
      ;; Show the current key.
      (let ((guidance (quail-guidance)))
        (if (listp guidance)
 -        ;; We must replace thetyped key with the specified PROMPTKEY.
 +        ;; We must replace the typed key with the specified PROMPT-KEY.
          (dotimes (i (length str))
            (let ((prompt-key (cdr (assoc (aref str i) guidance))))
              (if prompt-key
@@@ -2518,7 -2523,7 +2518,7 @@@ physical keyboard layout as specified w
          (when (> num 0)
            (insert "
  KEY SEQUENCE
 ------------
 +------------
  ")
            (if (quail-show-layout)
                (insert "You can also input more characters")
@@@ -2983,8 -2988,8 +2983,8 @@@ of each directory.
  
      ;; At last, write out LEIM list file.
      (with-current-buffer list-buf
 -      (setq buffer-file-coding-system 'iso-2022-7bit)
 -      (save-buffer 0))
 +      (let ((coding-system-for-write 'iso-2022-7bit))
 +      (save-buffer 0)))
      (kill-buffer list-buf)
      (message "Updating %s ... done" leim-list)))
  \f
index e07df7b925f199a9b7edce80982def7af932cc33,9577ccf50ad60f4b94e90a316f037745ee94b81c..4f982d1403954b57920330ca51804ee8f605499e
@@@ -1,14 -1,11 +1,14 @@@
  ;;; titdic-cnv.el --- convert cxterm dictionary (TIT format) to Quail package -*- coding:iso-2022-7bit; -*-
  
  ;; Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006  Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007  Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: Quail, TIT, cxterm
  
@@@ -274,8 -271,7 +274,8 @@@ SPC, 6, 3, 4, or 7 specifing a tone (SP
        (tit-keyprompt nil))
  
      (princ ";; Quail package `")
 -    (princ package) (princ "' -*- coding:iso-2022-7bit; -*-\n")
 +    (princ package)
 +    (princ (format "' -*- coding:%s; -*-\n" coding-system-for-write))
      (princ ";;   Generated by the command `titdic-convert'\n;;\tDate: ")
      (princ (current-time-string))
      (princ "\n;;\tOriginal TIT dictionary file: ")
  Optional argument DIRNAME if specified is the directory name under which
  the generated Quail package is saved."
    (interactive "FTIT dictionary file: ")
 -  (let ((coding-system-for-write 'iso-2022-7bit))
 +  (let ((coding-system-for-write nil))
      (with-temp-file  (tit-make-quail-package-file-name filename dirname)
 -      (set-buffer-file-coding-system 'iso-2022-7bit)
        (let ((standard-output (current-buffer)))
        (with-temp-buffer
          (set-buffer-multibyte nil)
            (setq coding-system (nth 1 slot))
            (message "Decoding with coding system %s..." coding-system)
            (goto-char (point-min))
 -          (decode-coding-region (point-min) (point-max) coding-system))
 +          (decode-coding-region (point-min) (point-max) coding-system)
 +          (setq coding-system-for-write coding-system)
 +          (remove-text-properties (point-min) (point-max) '(charset nil)))
  
 +        (set-buffer-multibyte t)
          ;; Set point the starting position of the body part.
          (goto-char (point-min))
          (if (not (search-forward "\nBEGIN" nil t))
              (error "TIT dictionary can't be decoded correctly"))
  
 -        ;; Process the header part in multibyte mode.
 -        (with-current-buffer standard-output
 -          (set-buffer-multibyte t))
 -        (set-buffer-multibyte t)
 +        ;; Process the header part.
          (forward-line 1)
          (narrow-to-region (point-min) (point))
          (tit-process-header filename)
          (widen)
  
 -        ;; Process the body part.  For speed, we turn off multibyte facility.
 -        (with-current-buffer standard-output
 -          (set-buffer-multibyte nil))
 -        (set-buffer-multibyte nil)
 +        ;; Process the body part
          (tit-process-body))))))
  
  ;;;###autoload
@@@ -1112,7 -1112,7 +1112,7 @@@ the generated Quail package is saved.
    (or (file-readable-p filename)
        (error "%s does not exist" filename))
    (let ((tail quail-misc-package-ext-info)
 -      (default-buffer-file-coding-system 'iso-2022-7bit)
 +      coding-system-for-write
        slot
        name title dicfile coding quailfile converter copyright
        dicbuf)
              converter (nth 5 slot)
              copyright (nth 6 slot))
        (message "Converting %s to %s..." dicfile quailfile)
 +      (setq coding-system-for-write coding)
        (with-temp-file (expand-file-name quailfile dirname)
 -        (set-buffer-file-coding-system 'iso-2022-7bit)
 -        (insert ";; Quail package `" name "' -*- coding:iso-2022-7bit; -*-\n")
 +        (insert (format ";; Quail package `%s' -*- coding:%s; -*-\n"
 +                        name coding))
          (insert ";;   Generated by the command `miscdic-convert'\n")
          (insert ";;   Date: " (current-time-string) "\n")
          (insert ";;   Source dictionary file: " dicfile "\n")
          (insert ";;; Code:\n\n")
          (insert "(require 'quail)\n")
          (insert "(quail-define-package \"" name "\" \""
 -                (if (eq coding 'big5) "Chinese-BIG5" "Chinese-CNS")
 +                (if (eq coding 'big5) "Chinese-BIG5"
 +                  (if (eq coding 'iso-2022-cn-ext) "Chinese-CNS"
 +                    "Chinese-GB"))
                  "\" \"" title "\" t\n")
          (let* ((coding-system-for-read coding)
                 (dicbuf (find-file-noselect filename)))
@@@ -1186,8 -1183,7 +1186,8 @@@ to store generated Quail packages.
            command-line-args-left (cdr command-line-args-left))
        (if (file-directory-p filename)
          (dolist (file (directory-files filename t nil t))
 -          (miscdic-convert file dir))
 +          (or (file-directory-p file)
 +              (miscdic-convert file dir)))
        (miscdic-convert filename dir))))
    (kill-emacs 0))
  
index 023062692590cdc24be59a066e8dc6d46695dc85,eb413b29f7bdcf60e2c98d57208990a26b7b66a2..9b22cf6e3ce47f6b3a554ec1b17c70ce87626e2f
@@@ -1,6 -1,6 +1,6 @@@
  ;;; utf-7.el --- utf-7 coding system
  
- ;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Author: Dave Love <fx@gnu.org>
  ;; Keywords: i18n, mail
  
  ;;; Code:
  
 -;;;###autoload(autoload-coding-system 'utf-7 '(require 'utf-7))
 -(make-coding-system
 - 'utf-7 0 ?U
 - "UTF-7 encoding of Unicode (RFC 2152)"
 - nil
 - `((safe-chars . ,(coding-system-get 'utf-16be 'safe-chars))
 -   (mime-charset . utf-7)
 -   (pre-write-conversion . utf-7-pre-write-conversion)
 -   (post-read-conversion . utf-7-post-read-conversion)))
 -
 -;; (make-coding-system
 -;;  'utf-7-imap 0 ?u
 -;;  "UTF-7 encoding of Unicode, IMAP version (RFC 2060)"
 -;;  nil
 -;;  `((safe-chars . ,(coding-system-get 'utf-16be 'safe-chars))
 -;;    (pre-write-conversion . utf-7-imap-pre-write-conversion)
 -;;    (post-read-conversion . utf-7-imap-post-read-conversion)))
 +;; (define-coding-system 'utf-7-imap
 +;;   "UTF-7 encoding of Unicode, IMAP version (RFC 2060)"
 +;;   :coding-type 'utf-8
 +;;   :mnemonic ?u
 +;;   :charset-list '(unicode)
 +;;   :pre-write-conversion 'utf-7-imap-pre-write-conversion
 +;;   :post-read-conversion 'utf-7-imap-post-read-conversion)
  
  (defun utf-7-decode (len imap)
    "Decode LEN bytes of UTF-7 at point.
@@@ -72,7 -82,6 +72,7 @@@ IMAP non-nil means use the IMAP version
                  (delete-backward-char 1)))))))
        (- (point-max) (point-min)))))
  
 +;;;###autoload
  (defun utf-7-post-read-conversion (len)
    (utf-7-decode len nil))
  
@@@ -121,7 -130,6 +121,7 @@@ ESC and SKIP-CHARS are adjusted for th
            (insert ?-)))))
      nil))
  
 +;;;###autoload
  (defun utf-7-pre-write-conversion (from to)
    (utf-7-encode from to nil))
  
diff --combined lisp/isearch.el
index 66b1bef19ca4a9b5e69e859c6bdcb0d037e0545a,28d309f88c4916c56bb4ce09f64b2c301ac59619..9e4c0a3c6c745d1e31e590047ae3c7b21bc8ba4b
@@@ -1,7 -1,7 +1,7 @@@
  ;;; isearch.el --- incremental search minor mode
  
  ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
- ;;   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
  ;; Maintainer: FSF
@@@ -306,11 -306,15 +306,11 @@@ A value of nil means highlight all matc
  (defvar isearch-mode-map
    (let* ((i 0)
         (map (make-keymap)))
 -    (or (vectorp (nth 1 map))
 -      (char-table-p (nth 1 map))
 +    (or (char-table-p (nth 1 map))
        (error "The initialization of isearch-mode-map must be updated"))
      ;; Make all multibyte characters search for themselves.
 -    (let ((l (generic-character-list))
 -        (table (nth 1 map)))
 -      (while l
 -      (set-char-table-default table (car l) 'isearch-printing-char)
 -      (setq l (cdr l))))
 +    (set-char-table-range (nth 1 map) (cons #x100 (max-char))
 +                        'isearch-printing-char)
      ;; Make function keys, etc, which aren't bound to a scrolling-function
      ;; exit the search.
      (define-key map [t] 'isearch-other-control-char)
@@@ -2231,7 -2235,18 +2231,18 @@@ since they have special meaning in a re
              (setq found t))
          (setq quote-flag nil)))
        (setq i (1+ i)))
-     (not found)))
+     (not (or found
+              ;; Even if there's no uppercase char, we want to detect the use
+              ;; of [:upper:] or [:lower:] char-class, which indicates
+              ;; clearly that the user cares about case distinction.
+              (and regexp-flag (string-match "\\[:\\(upp\\|low\\)er:]" string)
+                   (condition-case err
+                       (progn
+                         (string-match (substring string 0 (match-beginning 0))
+                                       "")
+                         nil)
+                     (invalid-regexp
+                      (equal "Unmatched [ or [^" (cadr err)))))))))
  
  ;; Portability functions to support various Emacs versions.
  
index ce417796bef46d9ab98b0841b38851cca98511ca,49041e611acf96fbb01be49609ee167645a2afe1..407832347d1cb489fa833647c0e10bdd949ee20d
@@@ -1,14 -1,11 +1,14 @@@
  ;;; china-util.el --- utilities for Chinese  -*- coding: iso-2022-7bit -*-
  
- ;; Copyright (C) 1995, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1995, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: mule, multilingual, Chinese
  
@@@ -77,7 -74,7 +77,7 @@@
        (push i chars)
        (setq i (1+ i)))
        (while (< i 127)
 -      (push (+ i 128) chars)
 +      (push (decode-char 'eight-bit (+ i 128)) chars)
        (setq i (1+ i)))
        (apply 'string (nreverse chars)))))
  
@@@ -171,25 -168,255 +171,25 @@@ Return the length of resulting text.
    (interactive)
    (encode-hz-region (point-min) (point-max)))
  
 -;; The following sets up a translation table (big5-to-cns) from Big 5
 -;; to CNS encoding, using some auxiliary functions to make the code
 -;; more readable.
 -
 -;; Many kudos to Himi!  The used code has been adapted from his
 -;; mule-ucs package.
 -
 -(eval-when-compile
 -(defun big5-to-flat-code (num)
 -  "Convert NUM in Big 5 encoding to a `flat code'.
 -0xA140 will be mapped to position 0, 0xA141 to position 1, etc.
 -There are no gaps in the flat code."
 -
 -  (let ((hi (/ num 256))
 -        (lo (% num 256)))
 -    (+ (* 157 (- hi #xa1))
 -       (- lo (if (>= lo #xa1) 98 64)))))
 -
 -(defun flat-code-to-big5 (num)
 -  "Convert NUM from a `flat code' to Big 5 encoding.
 -This is the inverse function of `big5-to-flat-code'."
 -
 -  (let ((hi (/ num 157))
 -        (lo (% num 157)))
 -    (+ (* 256 (+ hi #xa1))
 -       (+ lo (if (< lo 63) 64 98)))))
 -
 -(defun euc-to-flat-code (num)
 -  "Convert NUM in EUC encoding (in GL representation) to a `flat code'.
 -0x2121 will be mapped to position 0, 0x2122 to position 1, etc.
 -There are no gaps in the flat code."
 -
 -  (let ((hi (/ num 256))
 -        (lo (% num 256)))
 -    (+ (* 94 (- hi #x21))
 -       (- lo #x21))))
 -
 -(defun flat-code-to-euc (num)
 -  "Convert NUM from a `flat code' to EUC encoding (in GL representation).
 -The inverse function of `euc-to-flat-code'.  The high and low bytes are
 -returned in a list."
 -
 -  (let ((hi (/ num 94))
 -        (lo (% num 94)))
 -    (list (+ hi #x21) (+ lo #x21))))
 -
 -(defun expand-euc-big5-alist (alist)
 -  "Create a translation table and fills it with data given in ALIST.
 -Elements of ALIST can be either given as
 -
 -  ((euc-charset . startchar) . (big5-range-begin . big5-range-end))
 -
 -or as
 -
 -  (euc-character . big5-charcode)
 -
 -The former maps a range of glyphs in an EUC charset (where STARTCHAR
 -is in GL representation) to a certain range of Big 5 encoded
 -characters, the latter maps a single glyph.  Glyphs which can't be
 -mapped will be represented with the byte 0xFF.
 -
 -The return value is the filled translation table."
 -
 -  (let ((chartable (make-char-table 'translation-table #xFF))
 -        char
 -        big5
 -        i
 -        end
 -        codepoint
 -        charset)
 -    (dolist (elem alist)
 -      (setq char (car elem)
 -            big5 (cdr elem))
 -      (cond ((and (consp char)
 -                  (consp big5))
 -           (setq i (big5-to-flat-code (car big5))
 -                 end (big5-to-flat-code (cdr big5))
 -                 codepoint (euc-to-flat-code (cdr char))
 -                 charset (car char))
 -           (while (>= end i)
 -             (aset chartable
 -                   (decode-big5-char (flat-code-to-big5 i))
 -                   (apply (function make-char)
 -                          charset
 -                          (flat-code-to-euc codepoint)))
 -             (setq i (1+ i)
 -                   codepoint (1+ codepoint))))
 -            ((and (char-valid-p char)
 -                  (numberp big5))
 -           (setq i (decode-big5-char big5))
 -           (aset chartable i char))
 -            (t
 -             (error "Unknown slot type: %S" elem))))
 -    ;; the return value
 -    chartable)))
 -
 -;; All non-CNS encodings are commented out.
 -
 -(define-translation-table 'big5-to-cns
 -  (eval-when-compile
 -  (expand-euc-big5-alist
 -   '(
 -     ;; Symbols
 -     ((chinese-cns11643-1 . #x2121) . (#xA140 . #xA1F5))
 -     (?\e$(G"X\e(B . #xA1F6)
 -     (?\e$(G"W\e(B . #xA1F7)
 -     ((chinese-cns11643-1 . #x2259) . (#xA1F8 . #xA2AE))
 -     ((chinese-cns11643-1 . #x2421) . (#xA2AF . #xA3BF))
 -     ;; Control codes (vendor dependent)
 -     ((chinese-cns11643-1 . #x4221) . (#xA3C0 . #xA3E0))
 -     ;; Level 1 Ideographs
 -     ((chinese-cns11643-1 . #x4421) . (#xA440 . #xACFD))
 -     (?\e$(GWS\e(B . #xACFE)
 -     ((chinese-cns11643-1 . #x5323) . (#xAD40 . #xAFCF))
 -     ((chinese-cns11643-1 . #x5754) . (#xAFD0 . #xBBC7))
 -     ((chinese-cns11643-1 . #x6B51) . (#xBBC8 . #xBE51))
 -     (?\e$(GkP\e(B . #xBE52)
 -     ((chinese-cns11643-1 . #x6F5C) . (#xBE53 . #xC1AA))
 -     ((chinese-cns11643-1 . #x7536) . (#xC1AB . #xC2CA))
 -     (?\e$(Gu5\e(B . #xC2CB)
 -     ((chinese-cns11643-1 . #x7737) . (#xC2CC . #xC360))
 -     ((chinese-cns11643-1 . #x782E) . (#xC361 . #xC3B8))
 -     (?\e$(Gxe\e(B . #xC3B9)
 -     (?\e$(Gxd\e(B . #xC3BA)
 -     ((chinese-cns11643-1 . #x7866) . (#xC3BB . #xC455))
 -     (?\e$(Gx-\e(B . #xC456)
 -     ((chinese-cns11643-1 . #x7962) . (#xC457 . #xC67E))
 -     ;; Symbols
 -     ((chinese-cns11643-1 . #x2621) . (#xC6A1 . #xC6BE))
 -     ;; Radicals
 -     (?\e$(G'#\e(B . #xC6BF)
 -     (?\e$(G'$\e(B . #xC6C0)
 -     (?\e$(G'&\e(B . #xC6C1)
 -     (?\e$(G'(\e(B . #xC6C2)
 -     (?\e$(G'-\e(B . #xC6C3)
 -     (?\e$(G'.\e(B . #xC6C4)
 -     (?\e$(G'/\e(B . #xC6C5)
 -     (?\e$(G'4\e(B . #xC6C6)
 -     (?\e$(G'7\e(B . #xC6C7)
 -     (?\e$(G':\e(B . #xC6C8)
 -     (?\e$(G'<\e(B . #xC6C9)
 -     (?\e$(G'B\e(B . #xC6CA)
 -     (?\e$(G'G\e(B . #xC6CB)
 -     (?\e$(G'N\e(B . #xC6CC)
 -     (?\e$(G'S\e(B . #xC6CD)
 -     (?\e$(G'T\e(B . #xC6CE)
 -     (?\e$(G'U\e(B . #xC6CF)
 -     (?\e$(G'Y\e(B . #xC6D0)
 -     (?\e$(G'Z\e(B . #xC6D1)
 -     (?\e$(G'a\e(B . #xC6D2)
 -     (?\e$(G'f\e(B . #xC6D3)
 -     (?\e$(G()\e(B . #xC6D4)
 -     (?\e$(G(*\e(B . #xC6D5)
 -     (?\e$(G(c\e(B . #xC6D6)
 -     (?\e$(G(l\e(B . #xC6D7)
 -     ;; Diacritical Marks
 -     ; ((japanese-jisx0208 . #x212F) . (#xC6D8 . #xC6D9))
 -     ;; Japanese Kana Supplement
 -     ; ((japanese-jisx0208 . #x2133) . (#xC6DA . #xC6E3))
 -     ;; Japanese Hiragana
 -     ; ((japanese-jisx0208 . #x2421) . (#xC6E7 . #xC77A))
 -     ;; Japanese Katakana
 -     ; ((japanese-jisx0208 . #x2521) . (#xC77B . #xC7F2))
 -     ;; Cyrillic Characters
 -     ; ((japanese-jisx0208 . #x2721) . (#xC7F3 . #xC854))
 -     ; ((japanese-jisx0208 . #x2751) . (#xC855 . #xC875))
 -     ;; Special Chinese Characters
 -     (?\e$(J!#\e(B . #xC879)
 -     (?\e$(J!$\e(B . #xC87B)
 -     (?\e$(J!*\e(B . #xC87D)
 -     (?\e$(J!R\e(B . #xC8A2)
 -
 -     ;; JIS X 0208 NOT SIGN (cf. U+00AC)
 -     ; (?\e$B"L\e(B . #xC8CD)
 -     ;; JIS X 0212 BROKEN BAR (cf. U+00A6)
 -     ; (?\e$(D"C\e(B . #xC8CE)
 -
 -     ;; GB 2312 characters
 -     ; (?\e$A!d\e(B . #xC8CF)
 -     ; (?\e$A!e\e(B . #xC8D0)
 -        ;;;;; C8D1 - Japanese `(\e$B3t\e(B)'
 -     ; (?\e$A!m\e(B . #xC8D2)
 -        ;;;;; C8D2 - Tel.
 -
 -     ;; Level 2 Ideographs
 -     ((chinese-cns11643-2 . #x2121) . (#xC940 . #xC949))
 -     (?\e$(GDB\e(B . #xC94A);; a duplicate of #xA461
 -     ((chinese-cns11643-2 . #x212B) . (#xC94B . #xC96B))
 -     ((chinese-cns11643-2 . #x214D) . (#xC96C . #xC9BD))
 -     (?\e$(H!L\e(B . #xC9BE)
 -     ((chinese-cns11643-2 . #x217D) . (#xC9BF . #xC9EC))
 -     ((chinese-cns11643-2 . #x224E) . (#xC9ED . #xCAF6))
 -     (?\e$(H"M\e(B . #xCAF7)
 -     ((chinese-cns11643-2 . #x2439) . (#xCAF8 . #xD6CB))
 -     (?\e$(H>c\e(B . #xD6CC)
 -     ((chinese-cns11643-2 . #x3770) . (#xD6CD . #xD779))
 -     (?\e$(H?j\e(B . #xD77A)
 -     ((chinese-cns11643-2 . #x387E) . (#xD77B . #xDADE))
 -     (?\e$(H7o\e(B . #xDADF)
 -     ((chinese-cns11643-2 . #x3E64) . (#xDAE0 . #xDBA6))
 -     ((chinese-cns11643-2 . #x3F6B) . (#xDBA7 . #xDDFB))
 -     (?\e$(HAv\e(B . #xDDFC);; a duplicate of #xDCD1
 -     ((chinese-cns11643-2 . #x4424) . (#xDDFD . #xE8A2))
 -     ((chinese-cns11643-2 . #x554C) . (#xE8A3 . #xE975))
 -     ((chinese-cns11643-2 . #x5723) . (#xE976 . #xEB5A))
 -     ((chinese-cns11643-2 . #x5A29) . (#xEB5B . #xEBF0))
 -     (?\e$(HUK\e(B . #xEBF1)
 -     ((chinese-cns11643-2 . #x5B3F) . (#xEBF2 . #xECDD))
 -     (?\e$(HW"\e(B . #xECDE)
 -     ((chinese-cns11643-2 . #x5C6A) . (#xECDF . #xEDA9))
 -     ((chinese-cns11643-2 . #x5D75) . (#xEDAA . #xEEEA))
 -     (?\e$(Hd/\e(B . #xEEEB)
 -     ((chinese-cns11643-2 . #x6039) . (#xEEEC . #xF055))
 -     (?\e$(H]t\e(B . #xF056)
 -     ((chinese-cns11643-2 . #x6243) . (#xF057 . #xF0CA))
 -     (?\e$(HZ(\e(B . #xF0CB)
 -     ((chinese-cns11643-2 . #x6337) . (#xF0CC . #xF162))
 -     ((chinese-cns11643-2 . #x6430) . (#xF163 . #xF16A))
 -     (?\e$(Hga\e(B . #xF16B)
 -     ((chinese-cns11643-2 . #x6438) . (#xF16C . #xF267))
 -     (?\e$(Hi4\e(B . #xF268)
 -     ((chinese-cns11643-2 . #x6573) . (#xF269 . #xF2C2))
 -     ((chinese-cns11643-2 . #x664E) . (#xF2C3 . #xF374))
 -     ((chinese-cns11643-2 . #x6762) . (#xF375 . #xF465))
 -     ((chinese-cns11643-2 . #x6935) . (#xF466 . #xF4B4))
 -     (?\e$(HfM\e(B . #xF4B5)
 -     ((chinese-cns11643-2 . #x6962) . (#xF4B6 . #xF4FC))
 -     ((chinese-cns11643-2 . #x6A4C) . (#xF4FD . #xF662))
 -     (?\e$(HjK\e(B . #xF663)
 -     ((chinese-cns11643-2 . #x6C52) . (#xF664 . #xF976))
 -     ((chinese-cns11643-2 . #x7167) . (#xF977 . #xF9C3))
 -     (?\e$(Hqf\e(B . #xF9C4)
 -     (?\e$(Hr4\e(B . #xF9C5)
 -     (?\e$(Hr@\e(B . #xF9C6)
 -     ((chinese-cns11643-2 . #x7235) . (#xF9C7 . #xF9D1))
 -     ((chinese-cns11643-2 . #x7241) . (#xF9D2 . #xF9D5))
 -
 -     ;; Additional Ideographs
 -     (?\e$(IC7\e(B . #xF9D6)
 -     (?\e$(IOP\e(B . #xF9D7)
 -     (?\e$(IDN\e(B . #xF9D8)
 -     (?\e$(IPJ\e(B . #xF9D9)
 -     (?\e$(I,]\e(B . #xF9DA)
 -     (?\e$(I=~\e(B . #xF9DB)
 -     (?\e$(IK\\e(B . #xF9DC)
 -    )
 -  ))
 -)
 +;;;###autoload
 +(defun post-read-decode-hz (len)
 +  (let ((pos (point))
 +      (buffer-modified-p (buffer-modified-p))
 +      last-coding-system-used)
 +    (prog1
 +      (decode-hz-region pos (+ pos len))
 +      (set-buffer-modified-p buffer-modified-p))))
  
 +;;;###autoload
 +(defun pre-write-encode-hz (from to)
 +  (let ((buf (current-buffer)))
 +    (set-buffer (generate-new-buffer " *temp*"))
 +    (if (stringp from)
 +      (insert from)
 +      (insert-buffer-substring buf from to))
 +    (let (last-coding-system-used)
 +      (encode-hz-region 1 (point-max)))
 +    nil))
  ;;
  (provide 'china-util)
  
diff --combined lisp/language/chinese.el
index aaed3808a65dfb655a949cbbd6c1d7a17bf6f3ad,9d2297cb7a75cef3a7b21aff5d2acf1c3b3a810d..fdb4dae710ae4307b13f5282baa031e08b9841c3
@@@ -1,14 -1,11 +1,14 @@@
  ;;; chinese.el --- support for Chinese -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multilingual, Chinese
  
  ;;; Chinese (general)
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
 -(make-coding-system
 - 'iso-2022-cn 2 ?C
 - "ISO 2022 based 7bit encoding for Chinese GB and CNS (MIME:ISO-2022-CN)."
 - '(ascii
 -   (nil chinese-gb2312 chinese-cns11643-1)
 -   (nil chinese-cns11643-2)
 -   nil
 -   nil ascii-eol ascii-cntl seven locking-shift single-shift nil nil nil
 -   init-bol)
 - '((safe-charsets ascii chinese-gb2312 chinese-cns11643-1 chinese-cns11643-2)
 -   (mime-charset . iso-2022-cn)))
 +
 +(define-coding-system 'iso-2022-cn
 +  "ISO 2022 based 7bit encoding for Chinese GB and CNS (MIME:ISO-2022-CN)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?C
 +  :charset-list '(ascii chinese-gb2312 chinese-cns11643-1 chinese-cns11643-2)
 +  :designation [ascii
 +              (nil chinese-gb2312 chinese-cns11643-1)
 +              (nil chinese-cns11643-2)
 +              nil]
 +  :flags '(ascii-at-eol ascii-at-cntl 7-bit
 +                      designation locking-shift single-shift init-at-bol)
 +  :mime-charset 'iso-2022-cn
 +  :suitable-for-keyboard t)
  
  (define-coding-system-alias 'chinese-iso-7bit 'iso-2022-cn)
  
 -(make-coding-system
 - 'iso-2022-cn-ext 2 ?C
 - "ISO 2022 based 7bit encoding for Chinese GB and CNS (MIME:ISO-2022-CN-EXT)."
 - '(ascii
 -   (nil chinese-gb2312 chinese-cns11643-1)
 -   (nil chinese-cns11643-2)
 -   (nil chinese-cns11643-3 chinese-cns11643-4 chinese-cns11643-5
 -      chinese-cns11643-6 chinese-cns11643-7)
 -   nil ascii-eol ascii-cntl seven locking-shift single-shift nil nil nil
 -   init-bol)
 - '((safe-charsets ascii chinese-gb2312 chinese-cns11643-1 chinese-cns11643-2
 -                chinese-cns11643-3 chinese-cns11643-4 chinese-cns11643-5
 -                chinese-cns11643-6 chinese-cns11643-7)
 -   (mime-charset . iso-2022-cn-ext)))
 +(define-coding-system 'iso-2022-cn-ext
 +  "ISO 2022 based 7bit encoding for Chinese GB and CNS (MIME:ISO-2022-CN-EXT)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?C
 +  :charset-list '(ascii
 +                chinese-gb2312 chinese-cns11643-1
 +                chinese-cns11643-2 chinese-cns11643-3 chinese-cns11643-4
 +                chinese-cns11643-5 chinese-cns11643-6 chinese-cns11643-7)
 +  :designation '[ascii
 +               (nil chinese-gb2312 chinese-cns11643-1)
 +               (nil chinese-cns11643-2)
 +               (nil chinese-cns11643-3 chinese-cns11643-4 chinese-cns11643-5
 +                    chinese-cns11643-6 chinese-cns11643-7)]
 +  :flags '(ascii-at-eol ascii-at-cntl 7-bit
 +                      designation locking-shift single-shift init-at-bol)
 +  :mime-charset 'iso-2022-cn-ext
 +  :suitable-for-keyboard t)
  
  \f
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;; Chinese GB2312 (simplified)
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
 -(make-coding-system
 - 'chinese-iso-8bit 2 ?c
 - "ISO 2022 based EUC encoding for Chinese GB2312 (MIME:GB2312)."
 - '(ascii chinese-gb2312 nil nil
 -   nil ascii-eol ascii-cntl nil nil nil nil)
 - '((safe-charsets ascii chinese-gb2312)
 -   (mime-charset . gb2312)))
 +(define-coding-system 'chinese-iso-8bit
 +  "ISO 2022 based EUC encoding for Chinese GB2312 (MIME:GB2312)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?c
 +  :charset-list '(ascii chinese-gb2312)
 +  :designation [ascii chinese-gb2312 nil nil]
 +  :mime-charset 'gb2312)
  
  (define-coding-system-alias 'cn-gb-2312 'chinese-iso-8bit)
  (define-coding-system-alias 'euc-china 'chinese-iso-8bit)
  (define-coding-system-alias 'gb2312 'chinese-iso-8bit)
  (define-coding-system-alias 'cp936 'chinese-iso-8bit)
  
 -(make-coding-system
 - 'chinese-hz 0 ?z
 - "Hz/ZW 7-bit encoding for Chinese GB2312 (MIME:HZ-GB-2312)."
 - nil
 - '((safe-charsets ascii chinese-gb2312)
 -   (mime-charset . hz-gb-2312)
 -   (post-read-conversion . post-read-decode-hz)
 -   (pre-write-conversion . pre-write-encode-hz)))
 +(define-coding-system 'chinese-hz
 +  "Hz/ZW 7-bit encoding for Chinese GB2312 (MIME:HZ-GB-2312)."
 +  :coding-type 'utf-8
 +  :mnemonic ?z
 +  :charset-list '(ascii chinese-gb2312)
 +  :mime-charset 'hz-gb-2312
 +  :post-read-conversion 'post-read-decode-hz
 +  :pre-write-conversion 'pre-write-encode-hz)
  
  (define-coding-system-alias 'hz-gb-2312 'chinese-hz)
  (define-coding-system-alias 'hz 'chinese-hz)
  
 -(defun post-read-decode-hz (len)
 -  (let ((pos (point))
 -      (buffer-modified-p (buffer-modified-p))
 -      last-coding-system-used)
 -    (prog1
 -      (decode-hz-region pos (+ pos len))
 -      (set-buffer-modified-p buffer-modified-p))))
 -
 -(defun pre-write-encode-hz (from to)
 -  (let ((buf (current-buffer)))
 -    (set-buffer (generate-new-buffer " *temp*"))
 -    (if (stringp from)
 -      (insert from)
 -      (insert-buffer-substring buf from to))
 -    (let (last-coding-system-used)
 -      (encode-hz-region 1 (point-max)))
 -    nil))
 -
  (set-language-info-alist
   "Chinese-GB" '((charset chinese-gb2312 chinese-sisheng)
                (coding-system chinese-iso-8bit iso-2022-cn chinese-hz)
  ;; Chinese BIG5 (traditional)
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
 -(make-coding-system
 - 'chinese-big5 3 ?B
 - "BIG5 8-bit encoding for Chinese (MIME:Big5)."
 - nil
 - '((safe-charsets ascii chinese-big5-1 chinese-big5-2)
 -   (mime-charset . big5)
 -   (charset-origin-alist (chinese-big5-1  "BIG5" encode-big5-char)
 -                       (chinese-big5-2  "BIG5" encode-big5-char))))
 +(define-coding-system 'chinese-big5
 +  "BIG5 8-bit encoding for Chinese (MIME:Big5)"
 +  :coding-type 'charset
 +  :mnemonic ?B 
 +  :charset-list '(ascii big5)
 +  :mime-charset 'big5)
  
  (define-coding-system-alias 'big5 'chinese-big5)
  (define-coding-system-alias 'cn-big5 'chinese-big5)
  (define-coding-system-alias 'cp950 'chinese-big5)
  
 -;; Big5 font requires special encoding.
 -(define-ccl-program ccl-encode-big5-font
 -  `(0
 -    ;; In:  R0:chinese-big5-1 or chinese-big5-2
 -    ;;      R1:position code 1
 -    ;;      R2:position code 2
 -    ;; Out: R1:font code point 1
 -    ;;      R2:font code point 2
 -    ((r2 = ((((r1 - ?\x21) * 94) + r2) - ?\x21))
 -     (if (r0 == ,(charset-id 'chinese-big5-2)) (r2 += 6280))
 -     (r1 = ((r2 / 157) + ?\xA1))
 -     (r2 %= 157)
 -     (if (r2 < ?\x3F) (r2 += ?\x40) (r2 += ?\x62))))
 -  "CCL program to encode a Big5 code to code point of Big5 font.")
 -
 -(setq font-ccl-encoder-alist
 -      (cons (cons "big5" ccl-encode-big5-font) font-ccl-encoder-alist))
 -
  (set-language-info-alist
   "Chinese-BIG5" '((charset chinese-big5-1 chinese-big5-2)
                  (coding-system chinese-big5 chinese-iso-7bit)
                  (coding-priority chinese-big5 iso-2022-cn chinese-iso-8bit)
                  (input-method . "chinese-py-punct-b5")
 +                (ctext-non-standard-encodings "big5-0")
                  (features china-util)
 -                (sample-text . "Cantonese (\e$(0GnM$\e(B,\e$(0N]0*Hd\e(B) \e$(0*/=(\e(B, \e$(0+$)p\e(B")
 +                (sample-text . "Cantonese (\e$(Gemk#\e(B,\e$(Gl]N)fc\e(B) \e$ATg3?\e(B, \e$ADc:C\e(B")
                  (documentation . "Support for Chinese Big5 character set.")
                  (tutorial . "TUTORIAL.zh"))
   '("Chinese"))
  
 +(define-coding-system 'chinese-big5-hkscs
 +  "BIG5-HKSCS 8-bit encoding for Chinese, Hong Kong supplement (MIME:Big5-HKSCS)"
 +  :coding-type 'charset
 +  :mnemonic ?B 
 +  :charset-list '(ascii big5-hkscs)
 +  :mime-charset 'big5-hkscs)
 +(define-coding-system-alias 'big5-hkscs 'chinese-big5-hkscs)
 +(define-coding-system-alias 'cn-big5-hkscs 'chinese-big5-hkscs)
 +
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;; Chinese CNS11643 (traditional)
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
 -(defvar big5-to-cns (make-translation-table)
 -  "Translation table for encoding to `euc-tw'.")
 -;; Could have been done by china-util loaded before.
 -(unless (get 'big5-to-cns 'translation-table)
 -  (define-translation-table 'big5-to-cns big5-to-cns))
 -
 -(define-ccl-program ccl-decode-euc-tw
 -  ;; CNS plane 1 needs either two or four bytes in EUC-TW encoding;
 -  ;; CNS planes 2 to 7 always need four bytes.  In internal encoding of
 -  ;; Emacs, CNS planes 1 and 2 need three bytes, and planes 3 to 7 need
 -  ;; four bytes.  Thus a buffer magnification value of 2 (for both
 -  ;; encoding and decoding) is sufficient.
 -  `(2
 -    ;; we don't have enough registers to hold all charset-ids
 -    ((r4 = ,(charset-id 'chinese-cns11643-1))
 -     (r5 = ,(charset-id 'chinese-cns11643-2))
 -     (r6 = ,(charset-id 'chinese-cns11643-3))
 -     (loop
 -      (read-if (r0 < #x80)
 -        ;; ASCII
 -        (write-repeat r0)
 -      ;; not ASCII
 -      (if (r0 == #x8E)
 -          ;; single shift
 -          (read-if (r1 < #xA1)
 -              ;; invalid byte
 -              ((write r0)
 -               (write-repeat r1))
 -            (if (r1 > #xA7)
 -                ;; invalid plane
 -                ((write r0)
 -                 (write-repeat r1))
 -              ;; OK, we have a plane
 -              (read-if (r2 < #xA1)
 -                  ;; invalid first byte
 -                  ((write r0 r1)
 -                   (write-repeat r2))
 -                (read-if (r3 < #xA1)
 -                    ;; invalid second byte
 -                    ((write r0 r1 r2)
 -                     (write-repeat r3))
 -                  ;; CNS 1-7, finally
 -                  ((branch (r1 - #xA1)
 -                    (r1 = r4)
 -                    (r1 = r5)
 -                    (r1 = r6)
 -                    (r1 = ,(charset-id 'chinese-cns11643-4))
 -                    (r1 = ,(charset-id 'chinese-cns11643-5))
 -                    (r1 = ,(charset-id 'chinese-cns11643-6))
 -                    (r1 = ,(charset-id 'chinese-cns11643-7)))
 -                   (r2 = ((((r2 - #x80) << 7) + r3) - #x80))
 -                   (write-multibyte-character r1 r2)
 -                   (repeat))))))
 -        ;; standard EUC
 -        (if (r0 < #xA1)
 -            ;; invalid first byte
 -            (write-repeat r0)
 -          (read-if (r1 < #xA1)
 -              ;; invalid second byte
 -              ((write r0)
 -               (write-repeat r1))
 -            ;; CNS 1, finally
 -            ((r1 = ((((r0 - #x80) << 7) + r1) - #x80))
 -             (write-multibyte-character r4 r1)
 -             (repeat)))))))))
 -  "CCL program to decode EUC-TW encoding."
 -)
 -
 -(define-ccl-program ccl-encode-euc-tw
 -  `(2
 -    ;; we don't have enough registers to hold all charset-ids
 -    ((r2 = ,(charset-id 'ascii))
 -     (r3 = ,(charset-id 'chinese-big5-1))
 -     (r4 = ,(charset-id 'chinese-big5-2))
 -     (r5 = ,(charset-id 'chinese-cns11643-1))
 -     (r6 = ,(charset-id 'chinese-cns11643-2))
 -     (loop
 -      (read-multibyte-character r0 r1)
 -      (if (r0 == r2)
 -        (write-repeat r1)
 -      (;; Big 5 encoded characters are first translated to CNS
 -       (if (r0 == r3)
 -           (translate-character big5-to-cns r0 r1)
 -         (if (r0 == r4)
 -             (translate-character big5-to-cns r0 r1)))
 -       (if (r0 == r5)
 -           (r0 = #xA1)
 -         (if (r0 == r6)
 -             (r0 = #xA2)
 -           (if (r0 == ,(charset-id 'chinese-cns11643-3))
 -               (r0 = #xA3)
 -             (if (r0 == ,(charset-id 'chinese-cns11643-4))
 -                 (r0 = #xA4)
 -               (if (r0 == ,(charset-id 'chinese-cns11643-5))
 -                   (r0 = #xA5)
 -                 (if (r0 == ,(charset-id 'chinese-cns11643-6))
 -                     (r0 = #xA6)
 -                   (if (r0 == ,(charset-id 'chinese-cns11643-7))
 -                       (r0 = #xA7)
 -                     ;; not CNS.  We use a dummy character which
 -                     ;; can't occur in EUC-TW encoding to indicate
 -                     ;; this.
 -                     (write-repeat #xFF))))))))))
 -      (if (r0 != #xA1)
 -        ;; single shift and CNS plane
 -        ((write #x8E)
 -         (write r0)))
 -      (write ((r1 >> 7) + #x80))
 -      (write ((r1 % #x80) + #x80))
 -      (repeat))))
 -  "CCL program to encode EUC-TW encoding."
 -)
 -
 -(defun euc-tw-pre-write-conversion (beg end)
 -  "Semi-dummy pre-write function effectively to autoload china-util."
 -  ;; Ensure translation table is loaded.
 -  (require 'china-util)
 -  ;; Don't do this again.
 -  (coding-system-put 'euc-tw 'pre-write-conversion nil)
 -  nil)
 -
 -(make-coding-system
 -  'euc-tw 4 ?Z
 -  "ISO 2022 based EUC encoding for Chinese CNS11643.
 -Big5 encoding is accepted for input also (which is then converted to CNS)."
 -  '(ccl-decode-euc-tw . ccl-encode-euc-tw)
 -  '((safe-charsets ascii
 -                 chinese-big5-1
 -                 chinese-big5-2
 -                 chinese-cns11643-1
 -                 chinese-cns11643-2
 -                 chinese-cns11643-3
 -                 chinese-cns11643-4
 -                 chinese-cns11643-5
 -                 chinese-cns11643-6
 -                 chinese-cns11643-7)
 -    (valid-codes (0 . 255))
 -    (pre-write-conversion . euc-tw-pre-write-conversion)))
 +(define-coding-system 'euc-tw
 +  "ISO 2022 based EUC encoding for Chinese CNS11643."
 +  :coding-type 'iso-2022
 +  :mnemonic ?Z
 +  :charset-list '(ascii
 +                chinese-cns11643-1
 +                chinese-cns11643-2
 +                chinese-cns11643-3
 +                chinese-cns11643-4
 +                chinese-cns11643-5
 +                chinese-cns11643-6
 +                chinese-cns11643-7)
 +  :designation [ascii chinese-cns11643-1 (chinese-cns11643-1
 +                                        chinese-cns11643-2
 +                                        chinese-cns11643-3
 +                                        chinese-cns11643-4
 +                                        chinese-cns11643-5
 +                                        chinese-cns11643-6
 +                                        chinese-cns11643-7) nil]
 +  :mime-charset 'euc-tw)
  
  (define-coding-system-alias 'euc-taiwan 'euc-tw)
  
                                  chinese-iso-8bit)
                 (features china-util)
                 (input-method . "chinese-cns-quick")
 +               ;; Fixme: presumably it won't accept big5 now.
                 (documentation . "\
  Support for Chinese CNS character sets.  Note that the EUC-TW coding system
  accepts Big5 for input also (which is then converted to CNS)."))
@@@ -213,60 -349,6 +213,60 @@@ the EUC-TW coding system accepts Big5 f
  converted to CNS)."))
   '("Chinese"))
  
 +
 +;;; Chinese GBK
 +
 +(define-coding-system 'chinese-gbk
 +  "GBK encoding for Chinese (MIME:GBK)."
 +  :coding-type 'charset
 +  :mnemonic ?c
 +  :charset-list '(ascii chinese-gbk)
 +  :mime-charset 'gbk)
 +(define-coding-system-alias 'gbk 'chinese-gbk)
 +(define-coding-system-alias 'cp936 'chinese-gbk)
 +(define-coding-system-alias 'windows-936 'chinese-gbk)
 +
 +(set-language-info-alist
 + "Chinese-GBK" '((charset chinese-gbk)
 +               (coding-system chinese-gbk)
 +               (coding-priority gbk iso-2022-cn chinese-big5
 +                                chinese-iso-8bit) ; fixme?
 +               (ctext-non-standard-encodings "gbk-0")          
 +               (input-method . "chinese-py-punct") ; fixme?
 +               (sample-text . "Chinese (\e$BCfJ8\e(B,\e$BIaDL\e$A;0\e(B,\e$A::So\e(B) \e$(D95\e$B9%\e(B")
 +               (features china-util)
 +               (documentation . "Support for Chinese GBK character set.")
 +               (tutorial . "TUTORIAL.cn"))
 + '("Chinese"))
 +
 +;;; Chinese GB18030
 +
 +(define-coding-system 'chinese-gb18030
 +  "GB18030 encoding for Chinese (MIME:GB18030)."
 +  :coding-type 'charset
 +  :mnemonic ?c
 +  :charset-list '(ascii gb18030-2-byte
 +                      gb18030-4-byte-bmp gb18030-4-byte-smp
 +                      gb18030-4-byte-ext-1 gb18030-4-byte-ext-2)
 +  :mime-charset 'gb18030)
 +
 +(define-coding-system-alias 'gb18030 'chinese-gb18030)
 +
 +(set-language-info-alist
 + "Chinese-GB18030" '((charset gb18030)
 +                   (coding-system chinese-gb18030)
 +                   (coding-priority gb18030 gbk iso-2022-cn chinese-big5
 +                                    chinese-iso-8bit) ; fixme?
 +                   (input-method . "chinese-py-punct") ; fixme?
 +                   (sample-text . "Chinese (\e$BCfJ8\e(B,\e$BIaDL\e$A;0\e(B,\e$A::So\e(B) \e$(D0_\e$B9%\e(B")
 +                   (features china-util)
 +                   (documentation
 +                    . "Support for Chinese GB18030 character set.")
 +                   (tutorial . "TUTORIAL.cn"))
 + '("Chinese"))
 +
 +;; Fixme: add HKSCS
 +
  (provide 'chinese)
  
  ;;; arch-tag: b82fcf7a-84f6-4e0b-b38c-1742dac0e09f
index 1203301708efc63e9821c5d0b8061dbc409dacde,3395ce4d1ac5f3373a1fa1bac75fdb3b9185f44e..532c58824c1b1beb36e293cb2acc192c861cb0db
@@@ -1,7 -1,7 +1,7 @@@
  ;;; cyril-util.el --- utilities for Cyrillic scripts
  
  ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005,
- ;;   2006  Free Software Foundation, Inc.
+ ;;   2006, 2007  Free Software Foundation, Inc.
  
  ;; Keywords: mule, multilingual, Cyrillic
  
  ;;;###autoload
  (defun cyrillic-encode-koi8-r-char (char)
    "Return KOI8-R external character code of CHAR if appropriate."
 -  (aref (char-table-extra-slot
 -       (get 'cyrillic-koi8-r-nonascii-translation-table 'translation-table)
 -       0)
 -      char))
 +  (encode-char char 'koi8-r))
  
  ;;;###autoload
  (defun cyrillic-encode-alternativnyj-char (char)
    "Return ALTERNATIVNYJ external character code of CHAR if appropriate."
 -  (aref (char-table-extra-slot
 -       (get 'cyrillic-alternativnyj-nonascii-translation-table
 -            'translation-table)
 -       0)
 -      char))
 +  (encode-char char 'alternativnyj))
  
  \f
  ;; Display
@@@ -170,13 -177,117 +170,13 @@@ If the argument is nil, we return the d
      (aset standard-display-table ?\e,L*\e(B  [?N ?j])
      (aset standard-display-table ?\e,L/\e(B  [?D ?j])
  
 -    ;; Unicode version:
 -    (aset standard-display-table ?\e$,1(P\e(B  [?a])
 -    (aset standard-display-table ?\e$,1(Q\e(B  [?b])
 -    (aset standard-display-table ?\e$,1(R\e(B  [?v])
 -    (aset standard-display-table ?\e$,1(S\e(B  [?g])
 -    (aset standard-display-table ?\e$,1(T\e(B  [?d])
 -    (aset standard-display-table ?\e$,1(U\e(B  [?e])
 -    (aset standard-display-table ?\e$,1(q\e(B  [?y ?o])
 -    (aset standard-display-table ?\e$,1(V\e(B  [?z ?h])
 -    (aset standard-display-table ?\e$,1(W\e(B  [?z])
 -    (aset standard-display-table ?\e$,1(X\e(B  [?i])
 -    (aset standard-display-table ?\e$,1(Y\e(B  [?j])
 -    (aset standard-display-table ?\e$,1(Z\e(B  [?k])
 -    (aset standard-display-table ?\e$,1([\e(B  [?l])
 -    (aset standard-display-table ?\e$,1(\\e(B  [?m])
 -    (aset standard-display-table ?\e$,1(]\e(B  [?n])
 -    (aset standard-display-table ?\e$,1(^\e(B  [?o])
 -    (aset standard-display-table ?\e$,1(_\e(B  [?p])
 -    (aset standard-display-table ?\e$,1(`\e(B  [?r])
 -    (aset standard-display-table ?\e$,1(a\e(B  [?s])
 -    (aset standard-display-table ?\e$,1(b\e(B  [?t])
 -    (aset standard-display-table ?\e$,1(c\e(B  [?u])
 -    (aset standard-display-table ?\e$,1(d\e(B  [?f])
 -    (aset standard-display-table ?\e$,1(e\e(B  [?k ?h])
 -    (aset standard-display-table ?\e$,1(f\e(B  [?t ?s])
 -    (aset standard-display-table ?\e$,1(g\e(B  [?c ?h])
 -    (aset standard-display-table ?\e$,1(h\e(B  [?s ?h])
 -    (aset standard-display-table ?\e$,1(i\e(B  [?s ?c ?h])
 -    (aset standard-display-table ?\e$,1(j\e(B  [?~])
 -    (aset standard-display-table ?\e$,1(k\e(B  [?y])
 -    (aset standard-display-table ?\e$,1(l\e(B  [?'])
 -    (aset standard-display-table ?\e$,1(m\e(B  [?e ?'])
 -    (aset standard-display-table ?\e$,1(n\e(B  [?y ?u])
 -    (aset standard-display-table ?\e$,1(o\e(B  [?y ?a])
 -
 -    (aset standard-display-table ?\e$,1(0\e(B  [?A])
 -    (aset standard-display-table ?\e$,1(1\e(B  [?B])
 -    (aset standard-display-table ?\e$,1(2\e(B  [?V])
 -    (aset standard-display-table ?\e$,1(3\e(B  [?G])
 -    (aset standard-display-table ?\e$,1(4\e(B  [?D])
 -    (aset standard-display-table ?\e$,1(5\e(B  [?E])
 -    (aset standard-display-table ?\e$,1(!\e(B  [?Y ?o])
 -    (aset standard-display-table ?\e$,1(6\e(B  [?Z ?h])
 -    (aset standard-display-table ?\e$,1(7\e(B  [?Z])
 -    (aset standard-display-table ?\e$,1(8\e(B  [?I])
 -    (aset standard-display-table ?\e$,1(9\e(B  [?J])
 -    (aset standard-display-table ?\e$,1(:\e(B  [?K])
 -    (aset standard-display-table ?\e$,1(;\e(B  [?L])
 -    (aset standard-display-table ?\e$,1(<\e(B  [?M])
 -    (aset standard-display-table ?\e$,1(=\e(B  [?N])
 -    (aset standard-display-table ?\e$,1(>\e(B  [?O])
 -    (aset standard-display-table ?\e$,1(?\e(B  [?P])
 -    (aset standard-display-table ?\e$,1(@\e(B  [?R])
 -    (aset standard-display-table ?\e$,1(A\e(B  [?S])
 -    (aset standard-display-table ?\e$,1(B\e(B  [?T])
 -    (aset standard-display-table ?\e$,1(C\e(B  [?U])
 -    (aset standard-display-table ?\e$,1(D\e(B  [?F])
 -    (aset standard-display-table ?\e$,1(E\e(B  [?K ?h])
 -    (aset standard-display-table ?\e$,1(F\e(B  [?T ?s])
 -    (aset standard-display-table ?\e$,1(G\e(B  [?C ?h])
 -    (aset standard-display-table ?\e$,1(H\e(B  [?S ?h])
 -    (aset standard-display-table ?\e$,1(I\e(B  [?S ?c ?h])
 -    (aset standard-display-table ?\e$,1(J\e(B  [?~])
 -    (aset standard-display-table ?\e$,1(K\e(B  [?Y])
 -    (aset standard-display-table ?\e$,1(L\e(B  [?'])
 -    (aset standard-display-table ?\e$,1(M\e(B  [?E ?'])
 -    (aset standard-display-table ?\e$,1(N\e(B  [?Y ?u])
 -    (aset standard-display-table ?\e$,1(O\e(B  [?Y ?a])
 -
 -    (aset standard-display-table ?\e$,1(t\e(B  [?i ?e])
 -    (aset standard-display-table ?\e$,1(w\e(B  [?i])
 -    (aset standard-display-table ?\e$,1(~\e(B  [?u])
 -    (aset standard-display-table ?\e$,1(r\e(B  [?d ?j])
 -    (aset standard-display-table ?\e$,1({\e(B  [?c ?h ?j])
 -    (aset standard-display-table ?\e$,1(s\e(B  [?g ?j])
 -    (aset standard-display-table ?\e$,1(u\e(B  [?s])
 -    (aset standard-display-table ?\e$,1(|\e(B  [?k])
 -    (aset standard-display-table ?\e$,1(v\e(B  [?i])
 -    (aset standard-display-table ?\e$,1(x\e(B  [?j])
 -    (aset standard-display-table ?\e$,1(y\e(B  [?l ?j])
 -    (aset standard-display-table ?\e$,1(z\e(B  [?n ?j])
 -    (aset standard-display-table ?\e$,1(\7f\e(B  [?d ?z])
 -
 -    (aset standard-display-table ?\e$,1($\e(B  [?Y ?e])
 -    (aset standard-display-table ?\e$,1('\e(B  [?Y ?i])
 -    (aset standard-display-table ?\e$,1(.\e(B  [?U])
 -    (aset standard-display-table ?\e$,1("\e(B  [?D ?j])
 -    (aset standard-display-table ?\e$,1(+\e(B  [?C ?h ?j])
 -    (aset standard-display-table ?\e$,1(#\e(B  [?G ?j])
 -    (aset standard-display-table ?\e$,1(%\e(B  [?S])
 -    (aset standard-display-table ?\e$,1(,\e(B  [?K])
 -    (aset standard-display-table ?\e$,1(&\e(B  [?I])
 -    (aset standard-display-table ?\e$,1((\e(B  [?J])
 -    (aset standard-display-table ?\e$,1()\e(B  [?L ?j])
 -    (aset standard-display-table ?\e$,1(*\e(B  [?N ?j])
 -    (aset standard-display-table ?\e$,1(/\e(B  [?D ?j])
 -
      (when (equal cyrillic-language "Bulgarian")
        (aset standard-display-table ?\e,Li\e(B [?s ?h ?t])
        (aset standard-display-table ?\e,LI\e(B [?S ?h ?t])
        (aset standard-display-table ?\e,Ln\e(B [?i ?u])
        (aset standard-display-table ?\e,LN\e(B [?I ?u])
        (aset standard-display-table ?\e,Lo\e(B [?i ?a])
 -      (aset standard-display-table ?\e,LO\e(B [?I ?a])
 -      ;; Unicode version:
 -      (aset standard-display-table ?\e$,1(i\e(B [?s ?h ?t])
 -      (aset standard-display-table ?\e$,1(I\e(B [?S ?h ?t])
 -      (aset standard-display-table ?\e$,1(n\e(B [?i ?u])
 -      (aset standard-display-table ?\e$,1(N\e(B [?I ?u])
 -      (aset standard-display-table ?\e$,1(o\e(B [?i ?a])
 -      (aset standard-display-table ?\e$,1(O\e(B [?I ?a]))
 +      (aset standard-display-table ?\e,LO\e(B [?I ?a]))
  
      (when (equal cyrillic-language "Ukrainian")       ; based on the official
                                        ; transliteration table
        (aset standard-display-table ?\e,LY\e(B [?i])
        (aset standard-display-table ?\e,L9\e(B [?Y])
        (aset standard-display-table ?\e,Ln\e(B [?i ?u])
 -      (aset standard-display-table ?\e,Lo\e(B [?i ?a])
 -      ;; Unicode version:
 -      (aset standard-display-table ?\e$,1(X\e(B [?y])
 -      (aset standard-display-table ?\e$,1(8\e(B [?Y])
 -      (aset standard-display-table ?\e$,1(Y\e(B [?i])
 -      (aset standard-display-table ?\e$,1(9\e(B [?Y])
 -      (aset standard-display-table ?\e$,1(n\e(B [?i ?u])
 -      (aset standard-display-table ?\e$,1(o\e(B [?i ?a]))))
 +      (aset standard-display-table ?\e,Lo\e(B [?i ?a]))))
  
  ;;
  (provide 'cyril-util)
index 110f07e14eabd92ab71cdc76b298a72e50f9c9d6,656f6b600963c75630340299148e32973e3fd4f5..5ecfe5cf4ed90d9a5f3521ac002fede4bb7668f3
@@@ -1,14 -1,11 +1,14 @@@
  ;;; cyrillic.el --- support for Cyrillic -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Author: Kenichi Handa <handa@etl.go.jp>
  ;; Keywords: multilingual, Cyrillic, i18n
  
  ;; ISO-8859-5 stuff
  
 -(make-coding-system
 - 'cyrillic-iso-8bit 2 ?5
 - "ISO 2022 based 8-bit encoding for Cyrillic script (MIME:ISO-8859-5)."
 - '(ascii cyrillic-iso8859-5  nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii cyrillic-iso8859-5)
 -   (mime-charset . iso-8859-5)))
 +(define-coding-system 'cyrillic-iso-8bit
 +  "ISO 2022 based 8-bit encoding for Cyrillic script (MIME:ISO-8859-5)."
 +  :coding-type 'charset
 +  :mnemonic ?5
 +  :charset-list '(iso-8859-5)
 +  :mime-charset 'iso-8859-5)
  
  (define-coding-system-alias 'iso-8859-5 'cyrillic-iso-8bit)
  
  (set-language-info-alist
 - "Cyrillic-ISO" '((charset cyrillic-iso8859-5)
 + "Cyrillic-ISO" '((charset iso-8859-5)
                  (coding-system cyrillic-iso-8bit)
                  (coding-priority cyrillic-iso-8bit)
                  (input-method . "cyrillic-yawerty") ; fixme
 -                (nonascii-translation . cyrillic-iso8859-5)
 +                (nonascii-translation . iso-8859-5)
                  (unibyte-display . cyrillic-iso-8bit)
                  (features cyril-util)
                  (sample-text . "Russian (\e,L@caaZXY\e(B)       \e,L7T`PRabRcYbU\e(B!")
  
  ;; KOI-8R stuff
  
 -;; The mule-unicode portion of this is from
 -;; http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT,
 -;; which references RFC 1489.
 -(defvar cyrillic-koi8-r-decode-table
 -  [
 -   0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
 -   16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 -   32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 -   48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
 -   64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
 -   80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 -   96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
 -   112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 -   ;; 8859-5 plus Unicode
 -   ?\e$,2  \e(B ?\e$,2 "\e(B ?\e$,2 ,\e(B ?\e$,2 0\e(B ?\e$,2 4\e(B ?\e$,2 8\e(B ?\e$,2 <\e(B ?\e$,2 D\e(B ?\e$,2 L\e(B ?\e$,2 T\e(B ?\e$,2 \\e(B ?\e$,2!@\e(B ?\e$,2!D\e(B ?\e$,2!H\e(B ?\e$,2!L\e(B ?\e$,2!P\e(B
 -   ?\e$,2!Q\e(B ?\e$,2!R\e(B ?\e$,2!S\e(B ?\e$,1{ \e(B ?\e$,2!`\e(B ?\e$,1s"\e(B ?\e$,1x:\e(B ?\e$,1xh\e(B ?\e$,1y$\e(B ?\e$,1y%\e(B ?\e,L \e(B ?\e$,1{!\e(B ?\e,A0\e(B ?\e,A2\e(B ?\e,A7\e(B ?\e,Aw\e(B
 -   ?\e$,2 p\e(B ?\e$,2 q\e(B ?\e$,2 r\e(B ?\e,Lq\e(B ?\e$,2 s\e(B ?\e$,2 t\e(B ?\e$,2 u\e(B ?\e$,2 v\e(B ?\e$,2 w\e(B ?\e$,2 x\e(B ?\e$,2 y\e(B ?\e$,2 z\e(B ?\e$,2 {\e(B ?\e$,2 |\e(B ?\e$,2 }\e(B ?\e$,2 ~\e(B
 -   ?\e$,2 \7f\e(B ?\e$,2! \e(B ?\e$,2!!\e(B ?\e,L!\e(B ?\e$,2!"\e(B ?\e$,2!#\e(B ?\e$,2!$\e(B ?\e$,2!%\e(B ?\e$,2!&\e(B ?\e$,2!'\e(B ?\e$,2!(\e(B ?\e$,2!)\e(B ?\e$,2!*\e(B ?\e$,2!+\e(B ?\e$,2!,\e(B ?\e,A)\e(B
 -   ?\e,Ln\e(B  ?\e,LP\e(B  ?\e,LQ\e(B  ?\e,Lf\e(B  ?\e,LT\e(B  ?\e,LU\e(B  ?\e,Ld\e(B  ?\e,LS\e(B  ?\e,Le\e(B  ?\e,LX\e(B  ?\e,LY\e(B  ?\e,LZ\e(B  ?\e,L[\e(B  ?\e,L\\e(B  ?\e,L]\e(B  ?\e,L^\e(B
 -   ?\e,L_\e(B  ?\e,Lo\e(B  ?\e,L`\e(B  ?\e,La\e(B  ?\e,Lb\e(B  ?\e,Lc\e(B  ?\e,LV\e(B  ?\e,LR\e(B  ?\e,Ll\e(B  ?\e,Lk\e(B  ?\e,LW\e(B  ?\e,Lh\e(B  ?\e,Lm\e(B  ?\e,Li\e(B  ?\e,Lg\e(B  ?\e,Lj\e(B
 -   ?\e,LN\e(B  ?\e,L0\e(B  ?\e,L1\e(B  ?\e,LF\e(B  ?\e,L4\e(B  ?\e,L5\e(B  ?\e,LD\e(B  ?\e,L3\e(B  ?\e,LE\e(B  ?\e,L8\e(B  ?\e,L9\e(B  ?\e,L:\e(B  ?\e,L;\e(B  ?\e,L<\e(B  ?\e,L=\e(B  ?\e,L>\e(B
 -   ?\e,L?\e(B  ?\e,LO\e(B  ?\e,L@\e(B  ?\e,LA\e(B  ?\e,LB\e(B  ?\e,LC\e(B  ?\e,L6\e(B  ?\e,L2\e(B  ?\e,LL\e(B  ?\e,LK\e(B  ?\e,L7\e(B  ?\e,LH\e(B  ?\e,LM\e(B  ?\e,LI\e(B  ?\e,LG\e(B  ?\e,LJ\e(B
 -   ;; All Unicode:
 -;;    ?\e$,2  \e(B ?\e$,2 "\e(B ?\e$,2 ,\e(B ?\e$,2 0\e(B ?\e$,2 4\e(B ?\e$,2 8\e(B ?\e$,2 <\e(B ?\e$,2 D\e(B ?\e$,2 L\e(B ?\e$,2 T\e(B ?\e$,2 \\e(B ?\e$,2!@\e(B ?\e$,2!D\e(B ?\e$,2!H\e(B ?\e$,2!L\e(B ?\e$,2!P\e(B
 -;;    ?\e$,2!Q\e(B ?\e$,2!R\e(B ?\e$,2!S\e(B ?\e$,1{ \e(B ?\e$,2!`\e(B ?\e$,1s"\e(B ?\e$,1x:\e(B ?\e$,1xh\e(B ?\e$,1y$\e(B ?\e$,1y%\e(B ?\e,A \e(B ?\e$,1{!\e(B ?\e,A0\e(B ?\e,A2\e(B ?\e,A7\e(B ?\e,Aw\e(B
 -;;    ?\e$,2 p\e(B ?\e$,2 q\e(B ?\e$,2 r\e(B ?\e$,1(q\e(B ?\e$,2 s\e(B ?\e$,2 t\e(B ?\e$,2 u\e(B ?\e$,2 v\e(B ?\e$,2 w\e(B ?\e$,2 x\e(B ?\e$,2 y\e(B ?\e$,2 z\e(B ?\e$,2 {\e(B ?\e$,2 |\e(B ?\e$,2 }\e(B ?\e$,2 ~\e(B
 -;;    ?\e$,2 \7f\e(B ?\e$,2! \e(B ?\e$,2!!\e(B ?\e$,1(!\e(B ?\e$,2!"\e(B ?\e$,2!#\e(B ?\e$,2!$\e(B ?\e$,2!%\e(B ?\e$,2!&\e(B ?\e$,2!'\e(B ?\e$,2!(\e(B ?\e$,2!)\e(B ?\e$,2!*\e(B ?\e$,2!+\e(B ?\e$,2!,\e(B ?\e,A)\e(B
 -;;    ?\e$,1(n\e(B ?\e$,1(P\e(B ?\e$,1(Q\e(B ?\e$,1(f\e(B ?\e$,1(T\e(B ?\e$,1(U\e(B ?\e$,1(d\e(B ?\e$,1(S\e(B ?\e$,1(e\e(B ?\e$,1(X\e(B ?\e$,1(Y\e(B ?\e$,1(Z\e(B ?\e$,1([\e(B ?\e$,1(\\e(B ?\e$,1(]\e(B ?\e$,1(^\e(B
 -;;    ?\e$,1(_\e(B ?\e$,1(o\e(B ?\e$,1(`\e(B ?\e$,1(a\e(B ?\e$,1(b\e(B ?\e$,1(c\e(B ?\e$,1(V\e(B ?\e$,1(R\e(B ?\e$,1(l\e(B ?\e$,1(k\e(B ?\e$,1(W\e(B ?\e$,1(h\e(B ?\e$,1(m\e(B ?\e$,1(i\e(B ?\e$,1(g\e(B ?\e$,1(j\e(B
 -;;    ?\e$,1(N\e(B ?\e$,1(0\e(B ?\e$,1(1\e(B ?\e$,1(F\e(B ?\e$,1(4\e(B ?\e$,1(5\e(B ?\e$,1(D\e(B ?\e$,1(3\e(B ?\e$,1(E\e(B ?\e$,1(8\e(B ?\e$,1(9\e(B ?\e$,1(:\e(B ?\e$,1(;\e(B ?\e$,1(<\e(B ?\e$,1(=\e(B ?\e$,1(>\e(B
 -;;    ?\e$,1(?\e(B ?\e$,1(O\e(B ?\e$,1(@\e(B ?\e$,1(A\e(B ?\e$,1(B\e(B ?\e$,1(C\e(B ?\e$,1(6\e(B ?\e$,1(2\e(B ?\e$,1(L\e(B ?\e$,1(K\e(B ?\e$,1(7\e(B ?\e$,1(H\e(B ?\e$,1(M\e(B ?\e$,1(I\e(B ?\e$,1(G\e(B ?\e$,1(J\e(B
 -   ]
 -  "Cyrillic KOI8-R decoding table.")
 -
 -(let ((table (make-translation-table-from-vector
 -            cyrillic-koi8-r-decode-table)))
 -  (define-translation-table 'cyrillic-koi8-r-nonascii-translation-table table)
 -  (define-translation-table 'cyrillic-koi8-r-encode-table
 -    (char-table-extra-slot table 0)))
 -
 -;; No point in keeping it around.  (It can't be let-bound, since it's
 -;; needed for macro expansion.)
 -(makunbound 'cyrillic-koi8-r-decode-table)
 -
 -(define-ccl-program ccl-decode-koi8
 -  `(4
 -    ((loop
 -      (r0 = 0)
 -      (read r1)
 -      (if (r1 < 128)
 -        (write-repeat r1)
 -      ((translate-character cyrillic-koi8-r-nonascii-translation-table r0 r1)
 -       (translate-character ucs-translation-table-for-decode r0 r1)
 -       (write-multibyte-character r0 r1)
 -       (repeat))))))
 -  "CCL program to decode KOI8-R.")
 -
 -(define-ccl-program ccl-encode-koi8
 -  `(1
 -    ((loop
 -      (read-multibyte-character r0 r1)
 -      (translate-character cyrillic-koi8-r-encode-table r0 r1)
 -      (if (r0 != ,(charset-id 'ascii))
 -        (if (r0 != ,(charset-id 'eight-bit-graphic))
 -            (if (r0 != ,(charset-id 'eight-bit-control))
 -                (r1 = ??))))
 -      (write-repeat r1))))
 -  "CCL program to encode KOI8-R.")
 -
 -(defun cyrillic-unify-encoding (table)
 -  "Set up equivalent characters in the encoding TABLE.
 -This works whether or not the table is Unicode-based or
 -8859-5-based.  (Only appropriate for Cyrillic.)"
 -  (let ((table (get table 'translation-table)))
 -    (dotimes (i 96)
 -      (let* ((c (make-char 'cyrillic-iso8859-5 (+ i 32)))
 -           (u                         ; equivalent Unicode char
 -            (cond ((eq c ?\e,L \e(B) ?\e,A \e(B)
 -                  ((eq c ?\e,L-\e(B) ?\e,A-\e(B)
 -                  ((eq c ?\e,L}\e(B) ?\e,A'\e(B)
 -                  (t (decode-char 'ucs (+ #x400 i)))))
 -           (ec (aref table c))        ; encoding of 8859-5
 -           (uc (aref table u)))       ; encoding of Unicode
 -      (unless (memq c '(?\e,L \e(B ?\e,L-\e(B ?\e,L}\e(B))  ; 8859-5 exceptions
 -        (unless uc
 -          (aset table u ec))
 -        (unless ec
 -          (aset table c uc)))))))
 -
 -(cyrillic-unify-encoding 'cyrillic-koi8-r-encode-table)
 -
 -(make-coding-system
 - 'cyrillic-koi8 4
 - ;; We used to use ?K.  It is true that ?K is more strictly correct,
 - ;; but it is also used for Korean.
 - ;; So people who use koi8 for languages other than Russian
 - ;; will have to forgive us.
 - ?R "KOI8-R 8-bit encoding for Cyrillic (MIME: KOI8-R)."
 - '(ccl-decode-koi8 . ccl-encode-koi8)
 - `((safe-chars . cyrillic-koi8-r-encode-table)
 -   (mime-charset . koi8-r)
 -   (valid-codes (0 . 255))
 -   (dependency unify-8859-on-encoding-mode unify-8859-on-decoding-mode)))
 +(define-coding-system 'cyrillic-koi8
 +  "KOI8 8-bit encoding for Cyrillic (MIME: KOI8-R)."
 +  :coding-type 'charset
 +  ;; We used to use ?K.  It is true that ?K is more strictly correct,
 +  ;; but it is also used for Korean.  So people who use koi8 for
 +  ;; languages other than Russian will have to forgive us.
 +  :mnemonic ?R
 +  :charset-list '(koi8)
 +  :mime-charset 'koi8-r)
  
  (define-coding-system-alias 'koi8-r 'cyrillic-koi8)
  (define-coding-system-alias 'koi8 'cyrillic-koi8)
  (define-coding-system-alias 'cp878 'cyrillic-koi8)
  
 -(let ((elt `("koi8-r" koi8-r 1
 -           ,(get 'cyrillic-koi8-r-encode-table 'translation-table)))
 -      (slot (assoc "koi8-r" ctext-non-standard-encodings-alist)))
 -  (if slot
 -      (setcdr slot (cdr elt))
 -    (push elt ctext-non-standard-encodings-alist)))
 -
 -;; Allow displaying some of KOI & al with an 8859-5-encoded font.  We
 -;; won't bother about the exceptions when encoding the font, since
 -;; NBSP will fall through below and work anyhow, and we'll have
 -;; avoided setting the fontset for the other two to 8859-5 -- they're
 -;; not in KOI and Alternativnyj anyhow.
 -(define-ccl-program ccl-encode-8859-5-font
 -  `(0
 -    ((if (r0 == ,(charset-id 'cyrillic-iso8859-5))
 -       (r1 += 128)
 -       (if (r0 == ,(charset-id 'mule-unicode-0100-24ff))
 -         (r1 = (r2 + 128))))))
 -  "Encode ISO 8859-5 and Cyrillic Unicode chars to 8859-5 font.")
 -
 -(add-to-list 'font-ccl-encoder-alist '("iso8859-5" . ccl-encode-8859-5-font))
 -
 -;; The table is set up later to encode both Unicode and 8859-5.
 -(define-ccl-program ccl-encode-koi8-font
 -  `(0
 -    (if (r2 >= 0)
 -      ((r1 <<= 7)
 -       (r1 += r2)))
 -    (translate-character cyrillic-koi8-r-encode-table r0 r1))
 -  "CCL program to encode Cyrillic chars to KOI font.")
 -
 -(add-to-list 'font-ccl-encoder-alist '("koi8" . ccl-encode-koi8-font))
 -
  (set-language-info-alist
 - "Cyrillic-KOI8" `((charset cyrillic-iso8859-5)
 -                 (nonascii-translation
 -                  . ,(get 'cyrillic-koi8-r-nonascii-translation-table
 -                          'translation-table))
 + "Cyrillic-KOI8" `((charset koi8)
                   (coding-system cyrillic-koi8)
                   (coding-priority cyrillic-koi8 cyrillic-iso-8bit)
                   (ctext-non-standard-encodings "koi8-r")
 +                 (nonascii-translation . koi8)
                   (input-method . "russian-typewriter")
                   (features cyril-util)
                   (unibyte-display . cyrillic-koi8)
@@@ -126,18 -253,95 +126,18 @@@ Support for Russian using koi8-r and th
             (tutorial . "TUTORIAL.ru"))
   '("Cyrillic"))
  
 -
 -(defvar cyrillic-koi8-u-decode-table
 -  [
 -   0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
 -   16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 -   32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 -   48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
 -   64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
 -   80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 -   96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
 -   112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 -   ;; All Unicode:
 -;;    ?\e$,2  \e(B ?\e$,2 "\e(B ?\e$,2 ,\e(B ?\e$,2 0\e(B ?\e$,2 4\e(B ?\e$,2 8\e(B ?\e$,2 <\e(B ?\e$,2 D\e(B ?\e$,2 L\e(B ?\e$,2 T\e(B ?\e$,2 \\e(B ?\e$,2!@\e(B ?\e$,2!D\e(B ?\e$,2!H\e(B ?\e$,2!L\e(B ?\e$,2!P\e(B
 -;;    ?\e$,2!Q\e(B ?\e$,2!R\e(B ?\e$,2!S\e(B ?\e$,1{ \e(B ?\e$,2!`\e(B ?\e$,1x9\e(B ?\e$,1x:\e(B ?\e$,1xh\e(B ?\e$,1y$\e(B ?\e$,1y%\e(B ?\e,L \e(B ?\e$,1{!\e(B ?\e,A0\e(B ?\e,A2\e(B ?\e,A7\e(B ?\e,Aw\e(B
 -;;    ?\e$,2 p\e(B ?\e$,2 q\e(B ?\e$,2 r\e(B ?\e$,1(q\e(B ?\e$,1(t\e(B ?\e$,2 t\e(B ?\e$,1(v\e(B ?\e$,1(w\e(B ?\e$,2 w\e(B ?\e$,2 x\e(B ?\e$,2 y\e(B ?\e$,2 z\e(B ?\e$,2 {\e(B ?\e$,1)Q\e(B ?\e$,2 }\e(B ?\e$,2 ~\e(B
 -;;    ?\e$,2 \7f\e(B ?\e$,2! \e(B ?\e$,2!!\e(B ?\e$,1(!\e(B ?\e$,1($\e(B ?\e$,2!#\e(B ?\e$,1(&\e(B ?\e$,1('\e(B ?\e$,2!&\e(B ?\e$,2!'\e(B ?\e$,2!(\e(B ?\e$,2!)\e(B ?\e$,2!*\e(B ?\e$,1)P\e(B ?\e$,2!,\e(B ?\e,A)\e(B
 -;;    ?\e$,1(n\e(B ?\e$,1(P\e(B ?\e$,1(Q\e(B ?\e$,1(f\e(B ?\e$,1(T\e(B ?\e$,1(U\e(B ?\e$,1(d\e(B ?\e$,1(S\e(B ?\e$,1(e\e(B ?\e$,1(X\e(B ?\e$,1(Y\e(B ?\e$,1(Z\e(B ?\e$,1([\e(B ?\e$,1(\\e(B ?\e$,1(]\e(B ?\e$,1(^\e(B
 -;;    ?\e$,1(_\e(B ?\e$,1(o\e(B ?\e$,1(`\e(B ?\e$,1(a\e(B ?\e$,1(b\e(B ?\e$,1(c\e(B ?\e$,1(V\e(B ?\e$,1(R\e(B ?\e$,1(l\e(B ?\e$,1(k\e(B ?\e$,1(W\e(B ?\e$,1(h\e(B ?\e$,1(m\e(B ?\e$,1(i\e(B ?\e$,1(g\e(B ?\e$,1(j\e(B
 -;;    ?\e$,1(N\e(B ?\e$,1(0\e(B ?\e$,1(1\e(B ?\e$,1(F\e(B ?\e$,1(4\e(B ?\e$,1(5\e(B ?\e$,1(D\e(B ?\e$,1(3\e(B ?\e$,1(E\e(B ?\e$,1(8\e(B ?\e$,1(9\e(B ?\e$,1(:\e(B ?\e$,1(;\e(B ?\e$,1(<\e(B ?\e$,1(=\e(B ?\e$,1(>\e(B
 -;;    ?\e$,1(?\e(B ?\e$,1(O\e(B ?\e$,1(@\e(B ?\e$,1(A\e(B ?\e$,1(B\e(B ?\e$,1(C\e(B ?\e$,1(6\e(B ?\e$,1(2\e(B ?\e$,1(L\e(B ?\e$,1(K\e(B ?\e$,1(7\e(B ?\e$,1(H\e(B ?\e$,1(M\e(B ?\e$,1(I\e(B ?\e$,1(G\e(B ?\e$,1(J\e(B
 -;; 8859-5 plus Unicode:
 -   ?\e$,2  \e(B ?\e$,2 "\e(B ?\e$,2 ,\e(B ?\e$,2 0\e(B ?\e$,2 4\e(B ?\e$,2 8\e(B ?\e$,2 <\e(B ?\e$,2 D\e(B ?\e$,2 L\e(B ?\e$,2 T\e(B ?\e$,2 \\e(B ?\e$,2!@\e(B ?\e$,2!D\e(B ?\e$,2!H\e(B ?\e$,2!L\e(B ?\e$,2!P\e(B
 -   ?\e$,2!Q\e(B ?\e$,2!R\e(B ?\e$,2!S\e(B ?\e$,1{ \e(B ?\e$,2!`\e(B ?\e$,1x9\e(B ?\e$,1x:\e(B ?\e$,1xh\e(B ?\e$,1y$\e(B ?\e$,1y%\e(B ?\e,L \e(B ?\e$,1{!\e(B ?\e,A0\e(B ?\e,A2\e(B ?\e,A7\e(B ?\e,Aw\e(B
 -   ?\e$,2 p\e(B ?\e$,2 q\e(B ?\e$,2 r\e(B ?\e,Lq\e(B ?\e,Lt\e(B ?\e$,2 t\e(B ?\e,Lv\e(B ?\e,Lw\e(B ?\e$,2 w\e(B ?\e$,2 x\e(B ?\e$,2 y\e(B ?\e$,2 z\e(B ?\e$,2 {\e(B ?\e$,1)Q\e(B ?\e$,2 }\e(B ?\e$,2 ~\e(B
 -   ?\e$,2 \7f\e(B ?\e$,2! \e(B ?\e$,2!!\e(B ?\e,L!\e(B ?\e,L$\e(B ?\e$,2!#\e(B ?\e,L&\e(B ?\e,L'\e(B ?\e$,2!&\e(B ?\e$,2!'\e(B ?\e$,2!(\e(B ?\e$,2!)\e(B ?\e$,2!*\e(B ?\e$,1)P\e(B ?\e$,2!,\e(B ?\e,A)\e(B
 -   ?\e,Ln\e(B ?\e,LP\e(B ?\e,LQ\e(B ?\e,Lf\e(B ?\e,LT\e(B ?\e,LU\e(B ?\e,Ld\e(B ?\e,LS\e(B ?\e,Le\e(B ?\e,LX\e(B ?\e,LY\e(B ?\e,LZ\e(B ?\e,L[\e(B ?\e,L\\e(B ?\e,L]\e(B ?\e,L^\e(B
 -   ?\e,L_\e(B ?\e,Lo\e(B ?\e,L`\e(B ?\e,La\e(B ?\e,Lb\e(B ?\e,Lc\e(B ?\e,LV\e(B ?\e,LR\e(B ?\e,Ll\e(B ?\e,Lk\e(B ?\e,LW\e(B ?\e,Lh\e(B ?\e,Lm\e(B ?\e,Li\e(B ?\e,Lg\e(B ?\e,Lj\e(B
 -   ?\e,LN\e(B ?\e,L0\e(B ?\e,L1\e(B ?\e,LF\e(B ?\e,L4\e(B ?\e,L5\e(B ?\e,LD\e(B ?\e,L3\e(B ?\e,LE\e(B ?\e,L8\e(B ?\e,L9\e(B ?\e,L:\e(B ?\e,L;\e(B ?\e,L<\e(B ?\e,L=\e(B ?\e,L>\e(B
 -   ?\e,L?\e(B ?\e,LO\e(B ?\e,L@\e(B ?\e,LA\e(B ?\e,LB\e(B ?\e,LC\e(B ?\e,L6\e(B ?\e,L2\e(B ?\e,LL\e(B ?\e,LK\e(B ?\e,L7\e(B ?\e,LH\e(B ?\e,LM\e(B ?\e,LI\e(B ?\e,LG\e(B ?\e,LJ\e(B
 -   ]
 -  "Cyrillic KOI8-U decoding table.")
 -
 -(let ((table (make-translation-table-from-vector
 -            cyrillic-koi8-u-decode-table)))
 -  (define-translation-table 'cyrillic-koi8-u-nonascii-translation-table table)
 -  (define-translation-table 'cyrillic-koi8-u-encode-table
 -    (char-table-extra-slot table 0)))
 -
 -(makunbound 'cyrillic-koi8-u-decode-table)
 -
 -(define-ccl-program ccl-decode-koi8-u
 -  `(4
 -    ((loop
 -      (r0 = 0)
 -      (read r1)
 -      (if (r1 < 128)
 -        (write-repeat r1)
 -      ((translate-character cyrillic-koi8-u-nonascii-translation-table r0 r1)
 -       (translate-character ucs-translation-table-for-decode r0 r1)
 -       (write-multibyte-character r0 r1)
 -       (repeat))))))
 -  "CCL program to decode KOI8-U.")
 -
 -(define-ccl-program ccl-encode-koi8-u
 -  `(1
 -    ((loop
 -      (read-multibyte-character r0 r1)
 -      (translate-character cyrillic-koi8-u-encode-table r0 r1)
 -      (if (r0 != ,(charset-id 'ascii))
 -        (if (r0 != ,(charset-id 'eight-bit-graphic))
 -            (if (r0 != ,(charset-id 'eight-bit-control))
 -                (r1 = ??))))
 -      (write-repeat r1))))
 -  "CCL program to encode KOI8-U.")
 -
 -(cyrillic-unify-encoding 'cyrillic-koi8-u-encode-table)
 -
 -(make-coding-system
 - 'koi8-u 4
 - ?U "KOI8-U 8-bit encoding for Cyrillic (MIME: KOI8-U)"
 - '(ccl-decode-koi8-u . ccl-encode-koi8-u)
 - `((safe-chars . cyrillic-koi8-u-encode-table)
 -   (mime-charset . koi8-u)
 -   (valid-codes (0 . 255))
 -   (dependency unify-8859-on-encoding-mode unify-8859-on-decoding-mode)))
 -
 -(define-ccl-program ccl-encode-koi8-u-font
 -  `(0
 -    (translate-character cyrillic-koi8-u-encode-table r0 r1))
 -  "CCL program to encode Cyrillic chars to KOI-U font.")
 -
 -(add-to-list 'font-ccl-encoder-alist '("koi8-u" . ccl-encode-koi8-u-font))
 +(define-coding-system 'koi8-u
 +  "KOI8-U 8-bit encoding for Cyrillic (MIME: KOI8-U)"
 +  :coding-type 'charset
 +  :mnemonic ?U 
 +  :charset-list '(koi8-u)
 +  :mime-charset 'koi8-u)
  
  (set-language-info-alist
 - "Ukrainian" `((coding-system koi8-u)
 + "Ukrainian" `((charset koi8-u)
 +             (coding-system koi8-u)
               (coding-priority koi8-u)
 -             (nonascii-translation
 -              . ,(get 'cyrillic-koi8-u-nonascii-translation-table
 -                      'translation-table))
 +             (nonascii-translation . koi8-u)
               (input-method . "ukrainian-computer")
               (documentation
                . "Support for Ukrainian with KOI8-U character set."))
  
  ;;; ALTERNATIVNYJ stuff
  
 -;; Fixme: It's unclear what's the correct table.  I've found
 -;; statements both that it's the same as cp866 and somewhat different,
 -;; but nothing that looks really definitive.
 -(defvar cyrillic-alternativnyj-decode-table
 -  [
 -   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
 -   16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
 -   32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47
 -   48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63
 -   64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79
 -   80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95
 -   96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111
 -   112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 -;;    ?\e$,1(0\e(B  ?\e$,1(1\e(B  ?\e$,1(2\e(B  ?\e$,1(3\e(B  ?\e$,1(4\e(B  ?\e$,1(5\e(B  ?\e$,1(6\e(B  ?\e$,1(7\e(B  ?\e$,1(8\e(B  ?\e$,1(9\e(B  ?\e$,1(:\e(B  ?\e$,1(;\e(B  ?\e$,1(<\e(B  ?\e$,1(=\e(B  ?\e$,1(>\e(B  ?\e$,1(?\e(B
 -;;    ?\e$,1(@\e(B  ?\e$,1(A\e(B  ?\e$,1(B\e(B  ?\e$,1(C\e(B  ?\e$,1(D\e(B  ?\e$,1(E\e(B  ?\e$,1(F\e(B  ?\e$,1(G\e(B  ?\e$,1(H\e(B  ?\e$,1(I\e(B  ?\e$,1(J\e(B  ?\e$,1(K\e(B  ?\e$,1(L\e(B  ?\e$,1(M\e(B  ?\e$,1(N\e(B  ?\e$,1(O\e(B
 -;;    ?\e$,1(P\e(B  ?\e$,1(Q\e(B  ?\e$,1(R\e(B  ?\e$,1(S\e(B  ?\e$,1(T\e(B  ?\e$,1(U\e(B  ?\e$,1(V\e(B  ?\e$,1(W\e(B  ?\e$,1(X\e(B  ?\e$,1(Y\e(B  ?\e$,1(Z\e(B  ?\e$,1([\e(B  ?\e$,1(\\e(B  ?\e$,1(]\e(B  ?\e$,1(^\e(B  ?\e$,1(_\e(B
 -;;    ?\e$,2!Q\e(B  ?\e$,2!R\e(B  ?\e$,2!S\e(B  ?\e$,2 "\e(B  ?\e$,2 D\e(B  ?\e$,2!!\e(B  ?\e$,2!"\e(B  ?\e$,2 v\e(B  ?\e$,2 u\e(B  ?\e$,2!#\e(B  ?\e$,2 q\e(B  ?\e$,2 w\e(B  ?\e$,2 }\e(B  ?\e$,2 |\e(B  ?\e$,2 {\e(B  ?\e$,2 0\e(B
 -;;    ?\e$,2 4\e(B  ?\e$,2 T\e(B  ?\e$,2 L\e(B  ?\e$,2 <\e(B  ?\e$,2  \e(B  ?\e$,2 \\e(B  ?\e$,2 ~\e(B  ?\e$,2 \7f\e(B  ?\e$,2 z\e(B  ?\e$,2 t\e(B  ?\e$,2!)\e(B  ?\e$,2!&\e(B  ?\e$,2! \e(B  ?\e$,2 p\e(B  ?\e$,2!,\e(B  ?\e$,2!'\e(B
 -;;    ?\e$,2!(\e(B  ?\e$,2!$\e(B  ?\e$,2!%\e(B  ?\e$,2 y\e(B  ?\e$,2 x\e(B  ?\e$,2 r\e(B  ?\e$,2 s\e(B  ?\e$,2!+\e(B  ?\e$,2!*\e(B  ?\e$,2 8\e(B  ?\e$,2 ,\e(B  ?\e$,2!H\e(B  ?\e$,2!D\e(B  ?\e$,2!L\e(B  ?\e$,2!P\e(B  ?\e$,2!@\e(B
 -;;    ?\e$,1(`\e(B  ?\e$,1(a\e(B  ?\e$,1(b\e(B  ?\e$,1(c\e(B  ?\e$,1(d\e(B  ?\e$,1(e\e(B  ?\e$,1(f\e(B  ?\e$,1(g\e(B  ?\e$,1(h\e(B  ?\e$,1(i\e(B  ?\e$,1(j\e(B  ?\e$,1(k\e(B  ?\e$,1(l\e(B  ?\e$,1(m\e(B  ?\e$,1(n\e(B  ?\e$,1(o\e(B
 -;;    ?\e$,1(!\e(B  ?\e$,1(q\e(B  ?\e$,1ry\e(B  ?\e$,1rx\e(B  ?\e$,1%A\e(B  ?\e$,1%@\e(B  ?\e$,1s:\e(B  ?\e$,1s9\e(B  ?\e$,1vq\e(B  ?\e$,1vs\e(B  ?\e,A1\e(B  ?\e,Aw\e(B  ?\e$,1uV\e(B  ?\e,A$\e(B  ?\e$,2!`\e(B  ?\e,A \e(B ;
 -;; 8859+Unicode
 -   ?\e,L0\e(B  ?\e,L1\e(B  ?\e,L2\e(B  ?\e,L3\e(B  ?\e,L4\e(B  ?\e,L5\e(B  ?\e,L6\e(B  ?\e,L7\e(B  ?\e,L8\e(B  ?\e,L9\e(B  ?\e,L:\e(B  ?\e,L;\e(B  ?\e,L<\e(B  ?\e,L=\e(B  ?\e,L>\e(B  ?\e,L?\e(B
 -   ?\e,L@\e(B  ?\e,LA\e(B  ?\e,LB\e(B  ?\e,LC\e(B  ?\e,LD\e(B  ?\e,LE\e(B  ?\e,LF\e(B  ?\e,LG\e(B  ?\e,LH\e(B  ?\e,LI\e(B  ?\e,LJ\e(B  ?\e,LK\e(B  ?\e,LL\e(B  ?\e,LM\e(B  ?\e,LN\e(B  ?\e,LO\e(B
 -   ?\e,LP\e(B  ?\e,LQ\e(B  ?\e,LR\e(B  ?\e,LS\e(B  ?\e,LT\e(B  ?\e,LU\e(B  ?\e,LV\e(B  ?\e,LW\e(B  ?\e,LX\e(B  ?\e,LY\e(B  ?\e,LZ\e(B  ?\e,L[\e(B  ?\e,L\\e(B  ?\e,L]\e(B  ?\e,L^\e(B  ?\e,L_\e(B
 -   ?\e$,2!Q\e(B  ?\e$,2!R\e(B  ?\e$,2!S\e(B  ?\e$,2 "\e(B  ?\e$,2 D\e(B  ?\e$,2!!\e(B  ?\e$,2!"\e(B  ?\e$,2 v\e(B  ?\e$,2 u\e(B  ?\e$,2!#\e(B  ?\e$,2 q\e(B  ?\e$,2 w\e(B  ?\e$,2 }\e(B  ?\e$,2 |\e(B  ?\e$,2 {\e(B  ?\e$,2 0\e(B
 -   ?\e$,2 4\e(B  ?\e$,2 T\e(B  ?\e$,2 L\e(B  ?\e$,2 <\e(B  ?\e$,2  \e(B  ?\e$,2 \\e(B  ?\e$,2 ~\e(B  ?\e$,2 \7f\e(B  ?\e$,2 z\e(B  ?\e$,2 t\e(B  ?\e$,2!)\e(B  ?\e$,2!&\e(B  ?\e$,2! \e(B  ?\e$,2 p\e(B  ?\e$,2!,\e(B  ?\e$,2!'\e(B
 -   ?\e$,2!(\e(B  ?\e$,2!$\e(B  ?\e$,2!%\e(B  ?\e$,2 y\e(B  ?\e$,2 x\e(B  ?\e$,2 r\e(B  ?\e$,2 s\e(B  ?\e$,2!+\e(B  ?\e$,2!*\e(B  ?\e$,2 8\e(B  ?\e$,2 ,\e(B  ?\e$,2!H\e(B  ?\e$,2!D\e(B  ?\e$,2!L\e(B  ?\e$,2!P\e(B  ?\e$,2!@\e(B
 -   ?\e,L`\e(B  ?\e,La\e(B  ?\e,Lb\e(B  ?\e,Lc\e(B  ?\e,Ld\e(B  ?\e,Le\e(B  ?\e,Lf\e(B  ?\e,Lg\e(B  ?\e,Lh\e(B  ?\e,Li\e(B  ?\e,Lj\e(B  ?\e,Lk\e(B  ?\e,Ll\e(B  ?\e,Lm\e(B  ?\e,Ln\e(B  ?\e,Lo\e(B
 -   ;; Taken from http://www.cyrillic.com/ref/cyrillic/koi-8alt.html
 -   ;; with guesses for the Unicodes of the glyphs in the absence of a
 -   ;; table.
 -   ?\e,L!\e(B  ?\e,Lq\e(B  ?\e$,1ry\e(B  ?\e$,1rx\e(B  ?\e$,1%A\e(B  ?\e$,1%@\e(B  ?\e$,1s:\e(B  ?\e$,1s9\e(B  ?\e$,1vq\e(B  ?\e$,1vs\e(B  ?\e,A1\e(B  ?\e,Aw\e(B  ?\e,Lp\e(B  ?\e,A$\e(B  ?\e$,2!`\e(B  ?\e,L \e(B]
 -  "Cyrillic ALTERNATIVNYJ decoding table.")
 -
 -(let ((table (make-translation-table-from-vector
 -            cyrillic-alternativnyj-decode-table)))
 -  (define-translation-table 'cyrillic-alternativnyj-nonascii-translation-table
 -    table)
 -  (define-translation-table 'cyrillic-alternativnyj-encode-table
 -    (char-table-extra-slot table 0)))
 -
 -(makunbound 'cyrillic-alternativnyj-decode-table)
 -
 -(define-ccl-program ccl-decode-alternativnyj
 -  `(4
 -    ((loop
 -      (r0 = 0)
 -      (read r1)
 -      (if (r1 < 128)
 -        (write-repeat r1)
 -      ((translate-character cyrillic-alternativnyj-nonascii-translation-table
 -                            r0 r1)
 -       (translate-character ucs-translation-table-for-decode r0 r1)
 -       (write-multibyte-character r0 r1)
 -       (repeat))))))
 -  "CCL program to decode Alternativnyj.")
 -
 -(define-ccl-program ccl-encode-alternativnyj
 -  `(1
 -    ((loop
 -      (read-multibyte-character r0 r1)
 -      (translate-character cyrillic-alternativnyj-encode-table r0 r1)
 -      (if (r0 != ,(charset-id 'ascii))
 -        (if (r0 != ,(charset-id 'eight-bit-graphic))
 -            (if (r0 != ,(charset-id 'eight-bit-control))
 -                (r1 = ??))))
 -      (write-repeat r1))))
 -  "CCL program to encode Alternativnyj.")
 -
 -(cyrillic-unify-encoding 'cyrillic-alternativnyj-encode-table)
 -
 -(make-coding-system
 - 'cyrillic-alternativnyj 4 ?A
 - "ALTERNATIVNYJ 8-bit encoding for Cyrillic."
 - '(ccl-decode-alternativnyj . ccl-encode-alternativnyj)
 - `((safe-chars . cyrillic-alternativnyj-encode-table)
 -   (valid-codes (0 . 255))
 -   (dependency unify-8859-on-encoding-mode unify-8859-on-decoding-mode)))
 +(define-coding-system 'cyrillic-alternativnyj
 +  "ALTERNATIVNYJ 8-bit encoding for Cyrillic."
 +  :coding-type 'charset
 +  :mnemonic ?A
 +  :charset-list '(alternativnyj))
  
  (define-coding-system-alias 'alternativnyj 'cyrillic-alternativnyj)
  
 -(define-ccl-program ccl-encode-alternativnyj-font
 -  `(0
 -    (translate-character cyrillic-alternativnyj-encode-table r0 r1))
 -  "CCL program to encode Cyrillic chars to Alternativnyj font.")
 -
 -(add-to-list 'font-ccl-encoder-alist
 -           '("alternativnyj" . ccl-encode-alternativnyj-font))
 -
  (set-language-info-alist
 - "Cyrillic-ALT" `((charset cyrillic-iso8859-5)
 -                (nonascii-translation
 -                 . ,(get 'cyrillic-alternativnyj-nonascii-translation-table
 -                         'translation-table))
 + "Cyrillic-ALT" `((charset alternativnyj)
                  (coding-system cyrillic-alternativnyj)
                  (coding-priority cyrillic-alternativnyj)
 +                (nonascii-translation . alternativnyj)
                  (input-method . "russian-typewriter")
                  (features cyril-util)
                  (unibyte-display . cyrillic-alternativnyj)
                  (documentation . "Support for Cyrillic ALTERNATIVNYJ."))
   '("Cyrillic"))
  
 +(define-coding-system 'cp866
 +  "CP866 encoding for Cyrillic."
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(ibm866)
 +  :mime-charset 'cp866)
 +
 +(define-coding-system 'koi8-u
 +  "KOI8-U 8-bit encoding for Cyrillic (MIME: KOI8-U)"
 +  :coding-type 'charset
 +  :mnemonic ?U
 +  :charset-list '(koi8-u)
 +  :mime-charset 'koi8-u)
 +
 +(define-coding-system 'koi8-t
 +  "KOI8-T 8-bit encoding for Cyrillic"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(koi8-t)
 +  :mime-charset 'koi8-t)
 +
 +(define-coding-system 'windows-1251
 +  "windows-1251 8-bit encoding for Cyrillic (MIME: WINDOWS-1251)"
 +  :coding-type 'charset
 +  :mnemonic ?b
 +  :charset-list '(windows-1251)
 +  :mime-charset 'windows-1251)
 +(define-coding-system-alias 'cp1251 'windows-1251)
 +
 +(define-coding-system 'cp1125
 +  "cp1125 8-bit encoding for Cyrillic"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(cp1125))
 +(define-coding-system-alias 'ruscii 'cp1125)
 +;; Original name for cp1125, says Serhii Hlodin <hlodin@lutsk.bank.gov.ua>
 +(define-coding-system-alias 'cp866u 'cp1125)
 +
 +(define-coding-system 'cp855
 +  "DOS codepage 855 (Russian)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp855)
 +  :mime-charset 'cp855)
 +(define-coding-system-alias 'ibm855 'cp855)
 +
 +(define-coding-system 'mik
 +  "Bulgarian DOS codepage"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(mik))
 +
 +(define-coding-system 'pt154
 +  "Parattype Asian Cyrillic codepage"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(pt154))
 +
 +;; (set-language-info-alist
 +;;  "Windows-1251" `((coding-system windows-1251)
 +;;              (coding-priority windows-1251)
 +;;              (input-method . "russian-typewriter") ; fixme?
 +;;              (features code-pages)
 +;;              (documentation . "Support for windows-1251 character set."))
 +;;  '("Cyrillic"))
 +
  (set-language-info-alist
 - "Tajik" `((coding-system cyrillic-koi8-t)
 -         (coding-priority cyrillic-koi8-t)
 -         (nonascii-translation
 -          . ,(get 'decode-koi8-t 'translation-table))
 + "Tajik" `((coding-system koi8-t)
 +         (coding-priority koi8-t)
 +         (nonascii-translation . cyrillic-koi8-t)
 +         (charset koi8-t)
           (input-method . "russian-typewriter") ; fixme?
           (features code-pages)
           (documentation . "Support for Tajik using KOI8-T."))
   '("Cyrillic"))
  
 -(eval-and-compile
 -  (setq
 -   non-iso-charset-alist
 -   (cp-make-coding-system
 -    windows-1251
 -    [?\\e$,1("\e(B ?\\e$,1(#\e(B ?\\e$,1rz\e(B ?\\e$,1(s\e(B ?\\e$,1r~\e(B ?\\e$,1s&\e(B ?\\e$,1s \e(B ?\\e$,1s!\e(B ?\\e$,1tL\e(B ?\\e$,1s0\e(B ?\\e$,1()\e(B ?\\e$,1s9\e(B ?\\e$,1(*\e(B ?\\e$,1(,\e(B ?\\e$,1(+\e(B ?\\e$,1(/\e(B ?\\e$,1(r\e(B
 -       ?\\e$,1rx\e(B ?\\e$,1ry\e(B ?\\e$,1r|\e(B ?\\e$,1r}\e(B ?\\e$,1s"\e(B ?\\e$,1rs\e(B ?\\e$,1rt\e(B nil ?\\e$,1ub\e(B ?\\e$,1(y\e(B ?\\e$,1s:\e(B ?\\e$,1(z\e(B ?\\e$,1(|\e(B ?\\e$,1({\e(B ?\\e$,1(\7f\e(B ?\\e,A \e(B ?\\e$,1(.\e(B
 -       ?\\e$,1(~\e(B ?\\e$,1((\e(B ?\\e,A$\e(B ?\\e$,1)P\e(B ?\\e,A&\e(B ?\\e,A'\e(B ?\\e$,1(!\e(B ?\\e,A)\e(B ?\\e$,1($\e(B ?\\e,A+\e(B ?\\e,A,\e(B ?\\e,A-\e(B ?\\e,A.\e(B ?\\e$,1('\e(B ?\\e,A0\e(B ?\\e,A1\e(B ?\\e$,1(&\e(B
 -       ?\\e$,1(v\e(B ?\\e$,1)Q\e(B ?\\e,A5\e(B ?\\e,A6\e(B ?\\e,A7\e(B ?\\e$,1(q\e(B ?\\e$,1uV\e(B ?\\e$,1(t\e(B ?\\e,A;\e(B ?\\e$,1(x\e(B ?\\e$,1(%\e(B ?\\e$,1(u\e(B ?\\e$,1(w\e(B ?\\e$,1(0\e(B ?\\e$,1(1\e(B ?\\e$,1(2\e(B ?\\e$,1(3\e(B
 -       ?\\e$,1(4\e(B ?\\e$,1(5\e(B ?\\e$,1(6\e(B ?\\e$,1(7\e(B ?\\e$,1(8\e(B ?\\e$,1(9\e(B ?\\e$,1(:\e(B ?\\e$,1(;\e(B ?\\e$,1(<\e(B ?\\e$,1(=\e(B ?\\e$,1(>\e(B ?\\e$,1(?\e(B ?\\e$,1(@\e(B ?\\e$,1(A\e(B ?\\e$,1(B\e(B ?\\e$,1(C\e(B ?\\e$,1(D\e(B
 -       ?\\e$,1(E\e(B ?\\e$,1(F\e(B ?\\e$,1(G\e(B ?\\e$,1(H\e(B ?\\e$,1(I\e(B ?\\e$,1(J\e(B ?\\e$,1(K\e(B ?\\e$,1(L\e(B ?\\e$,1(M\e(B ?\\e$,1(N\e(B ?\\e$,1(O\e(B ?\\e$,1(P\e(B ?\\e$,1(Q\e(B ?\\e$,1(R\e(B ?\\e$,1(S\e(B ?\\e$,1(T\e(B ?\\e$,1(U\e(B
 -       ?\\e$,1(V\e(B ?\\e$,1(W\e(B ?\\e$,1(X\e(B ?\\e$,1(Y\e(B ?\\e$,1(Z\e(B ?\\e$,1([\e(B ?\\e$,1(\\e(B ?\\e$,1(]\e(B ?\\e$,1(^\e(B ?\\e$,1(_\e(B ?\\e$,1(`\e(B ?\\e$,1(a\e(B ?\\e$,1(b\e(B ?\\e$,1(c\e(B ?\\e$,1(d\e(B ?\\e$,1(e\e(B ?\\e$,1(f\e(B
 -       ?\\e$,1(g\e(B ?\\e$,1(h\e(B ?\\e$,1(i\e(B ?\\e$,1(j\e(B ?\\e$,1(k\e(B ?\\e$,1(l\e(B ?\\e$,1(m\e(B ?\\e$,1(n\e(B ?\\e$,1(o\e(B] nil ?b)))
 -
 -;; Register cyrillic-iso8859-5 characters in the encode table of
 -;; windows-1251.
 -(let ((table (get 'encode-windows-1251 'translation-table))
 -      ;; Nth element is a cyrillic-iso8859-5 character encoded to a
 -      ;; code (128 + N), or nil.
 -      (vec [?\\e,L"\e(B ?\\e,L#\e(B nil ?\\e,Ls\e(B nil nil nil nil nil nil ?\\e,L)\e(B nil ?\\e,L*\e(B ?\\e,L,\e(B ?\\e,L+\e(B ?\\e,L/\e(B
 -          ?\\e,Lr\e(B nil nil nil nil nil nil nil nil nil ?\\e,Ly\e(B nil ?\\e,Lz\e(B ?\\e,L|\e(B ?\\e,L{\e(B ?\\e,L\7f\e(B
 -          nil ?\\e,L.\e(B ?\\e,L~\e(B ?\\e,L(\e(B nil nil nil nil ?\\e,L!\e(B nil ?\\e,L$\e(B nil nil nil nil ?\\e,L'\e(B
 -          nil nil ?\\e,L&\e(B ?\\e,Lv\e(B nil nil nil nil ?\\e,Lq\e(B ?\\e,Lp\e(B ?\\e,Lt\e(B nil ?\\e,Lx\e(B ?\\e,L%\e(B ?\\e,Lu\e(B ?\\e,Lw\e(B
 -          ?\\e,L0\e(B ?\\e,L1\e(B ?\\e,L2\e(B ?\\e,L3\e(B ?\\e,L4\e(B ?\\e,L5\e(B ?\\e,L6\e(B ?\\e,L7\e(B ?\\e,L8\e(B ?\\e,L9\e(B ?\\e,L:\e(B ?\\e,L;\e(B ?\\e,L<\e(B ?\\e,L=\e(B ?\\e,L>\e(B ?\\e,L?\e(B
 -          ?\\e,L@\e(B ?\\e,LA\e(B ?\\e,LB\e(B ?\\e,LC\e(B ?\\e,LD\e(B ?\\e,LE\e(B ?\\e,LF\e(B ?\\e,LG\e(B ?\\e,LH\e(B ?\\e,LI\e(B ?\\e,LJ\e(B ?\\e,LK\e(B ?\\e,LL\e(B ?\\e,LM\e(B ?\\e,LN\e(B ?\\e,LO\e(B
 -          ?\\e,LP\e(B ?\\e,LQ\e(B ?\\e,LR\e(B ?\\e,LS\e(B ?\\e,LT\e(B ?\\e,LU\e(B ?\\e,LV\e(B ?\\e,LW\e(B ?\\e,LX\e(B ?\\e,LY\e(B ?\\e,LZ\e(B ?\\e,L[\e(B ?\\e,L\\e(B ?\\e,L]\e(B ?\\e,L^\e(B ?\\e,L_\e(B
 -          ?\\e,L`\e(B ?\\e,La\e(B ?\\e,Lb\e(B ?\\e,Lc\e(B ?\\e,Ld\e(B ?\\e,Le\e(B ?\\e,Lf\e(B ?\\e,Lg\e(B ?\\e,Lh\e(B ?\\e,Li\e(B ?\\e,Lj\e(B ?\\e,Lk\e(B ?\\e,Ll\e(B ?\\e,Lm\e(B ?\\e,Ln\e(B ?\\e,Lo\e(B]))
 -  (dotimes (i (length vec))
 -    (if (aref vec i)
 -      (aset table (aref vec i) (+ 128 i)))))
 -
 -(define-coding-system-alias 'cp1251 'windows-1251)
 -
  (let ((elt `("microsoft-cp1251" windows-1251 1
             ,(get 'encode-windows-1251 'translation-table)))
        (slot (assoc "microsoft-cp1251" ctext-non-standard-encodings-alist)))
        (setcdr slot (cdr elt))
      (push elt ctext-non-standard-encodings-alist)))
  
 -(define-ccl-program ccl-encode-windows-1251-font
 -  `(0
 -    ((if (r0 == ,(charset-id 'mule-unicode-0100-24ff))
 -       ((r1 <<= 7)
 -        (r1 += r2)))
 -     (translate-character encode-windows-1251 r0 r1))))
 -
 -(add-to-list 'font-ccl-encoder-alist
 -           '("microsoft-cp1251" . ccl-encode-windows-1251-font))
 -
  (set-language-info-alist
   "Bulgarian" `((coding-system windows-1251)
               (coding-priority windows-1251)
 +             (nonascii-translation . windows-1251)
 +             (charset windows-1251)
               (ctext-non-standard-encodings "microsoft-cp1251")
 -             (overriding-fontspec
 -              (,(get 'encode-windows-1251 'translation-table)
 -               . (nil . "microsoft-cp1251"))
 -              (,(get 'cyrillic-koi8-r-encode-table 'translation-table)
 -               . (nil . "koi8-r")))
 -             (nonascii-translation
 -              . ,(get 'decode-windows-1251 'translation-table))
               (input-method . "bulgarian-bds")
               (documentation
 -              . "Support for Bulgarian with windows-1251 character set.")
 -             (tutorial . "TUTORIAL.bg"))
 +              . "Support for Bulgrian with windows-1251 character set."))
   '("Cyrillic"))
  
  (set-language-info-alist
   "Belarusian" `((coding-system windows-1251)
                (coding-priority windows-1251)
 +              (nonascii-translation . windows-1251)
 +              (charset windows-1251)
                (ctext-non-standard-encodings "microsoft-cp1251")
 -              (overriding-fontspec
 -               (,(get 'encode-windows-1251 'translation-table)
 -                . (nil . "microsoft-cp1251"))
 -               (,(get 'cyrillic-koi8-r-encode-table 'translation-table)
 -                . (nil . "koi8-r")))
 -              (nonascii-translation
 -               . ,(get 'decode-windows-1251 'translation-table))
                (input-method . "belarusian")
                (documentation
                 . "Support for Belarusian with windows-1251 character set.
  \(The name Belarusian replaced Byelorussian in the early 1990s.)"))
   '("Cyrillic"))
  
 +(set-language-info-alist
 + "Ukrainian" `((coding-system koi8-u)
 +             (coding-priority koi8-u)
 +             (input-method . "ukrainian-computer")
 +             (documentation
 +              . "Support for Ukrainian with koi8-u character set."))
 + '("Cyrillic"))
 +
  (provide 'cyrillic)
  
  ;;; arch-tag: bda71ae0-ba41-4cb6-a6e0-1dff542313d3
diff --combined lisp/language/czech.el
index 5db734565abcae75d0bf5ee956823b5822420859,43dff0d57ba678b2aad09a290971455131dca988..41dbc9657dcc21a51ead8a77ad7610b4333fce2f
@@@ -1,6 -1,6 +1,6 @@@
  ;;; czech.el --- support for Czech -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation.
  
  ;; Author: Milan Zamazal <pdm@zamazal.org>
@@@ -35,7 -35,8 +35,7 @@@
           (coding-system . (iso-8859-2))
           (coding-priority . (iso-8859-2))
           (input-method . "czech")
 -         (nonascii-translation . latin-iso8859-2)
 -         (unibyte-syntax . "latin-2")
 +         (nonascii-translation . iso-8859-2)
           (unibyte-display . iso-8859-2)
           (tutorial . "TUTORIAL.cs")
           (sample-text . "P\e,Bx\e(Bejeme v\e,Ba\e(Bm hezk\e,B}\e(B den!")
index 92453078306a46997fdcb5a55a796edbe27a5264,b25e90cebe9cebd7287c3d5e933bc9ff79ea1b3f..b236a95e3b466645dcb205cd105719b547d22006
@@@ -1,8 -1,8 +1,8 @@@
 -;;; devan-util.el --- Support for composing Devanagari characters
 +;;; devan-util.el --- Support for composing Devanagari characters -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
@@@ -35,6 -35,8 +35,6 @@@
  
  ;;; Code:
  
 -;;;###autoload
 -
  ;; Devanagari Composable Pattern
  ;;    C .. Consonants
  ;;    V .. Vowel
  (defconst devanagari-consonant
    "[\e$,15U\e(B-\e$,15y68\e(B-\e$,16?\e(B]")
  
 +    ;;("\e$,16B\e(B" . nil)
 +    ;;("\e$,16A\e(B" . nil)
 +    ;;("\e$,16C\e(B" . nil)
 +
 +
  (defconst devanagari-composable-pattern
    (concat
     "\\([\e$,15E\e(B-\e$,15T6@6A\e(B][\e$,15A5B\e(B]?\\)\\|[\e$,15C6D\e(B]"
     "\\)")
    "Regexp matching a composable sequence of Devanagari characters.")
  
 +(dolist (range '((#x0903 . #x0903)
 +               (#x0905 . #x0939)
 +               (#x0958 . #x0961)))
 +  (set-char-table-range indian-composable-pattern range
 +                      devanagari-composable-pattern))
 +
  ;;;###autoload
  (defun devanagari-compose-region (from to)
    (interactive "r")
@@@ -81,8 -72,8 +81,8 @@@
        (narrow-to-region from to)
        (goto-char (point-min))
        (while (re-search-forward devanagari-composable-pattern nil t)
 -        (devanagari-compose-syllable-region (match-beginning 0)
 -                                            (match-end 0))))))
 +      (devanagari-compose-syllable-region (match-beginning 0)
 +                                          (match-end 0))))))
  (defun devanagari-compose-string (string)
    (with-temp-buffer
      (insert (decompose-string string))
        (set-buffer-modified-p buffer-modified-p)
        (- (point-max) (point-min))))))
  
 -(defun devanagari-range (from to)
 -  "Make the list of the integers of range FROM to TO."
 -  (let (result)
 -    (while (<= from to) (setq result (cons to result) to (1- to))) result))
 -
  (defun devanagari-regexp-of-hashtbl-keys (hashtbl)
    "Return a regular expression that matches all keys in hashtable HASHTBL."
    (let ((max-specpdl-size 1000))
        dummy)
        (function (lambda (x y) (> (length x) (length y))))))))
  
 -(defun devanagari-composition-function (from to pattern &optional string)
 -  "Compose Devanagari characters in REGION, or STRING if specified.
 -Assume that the REGION or STRING must fully match the composable
 -PATTERN regexp."
 -  (if string (devanagari-compose-syllable-string string)
 -    (devanagari-compose-syllable-region from to))
 -  (- to from))
 -
 -;; Register a function to compose Devanagari characters.
 -(mapc
 - (function (lambda (ucs)
 -   (aset composition-function-table (decode-char 'ucs ucs)
 -       (list (cons devanagari-composable-pattern
 -                     'devanagari-composition-function)))))
 - (nconc '(#x0903) (devanagari-range #x0905 #x0939) (devanagari-range #x0958 #x0961)))
 +;;;###autoload
 +(defun devanagari-composition-function (pos &optional string)
 +  "Compose Devanagari characters after the position POS.
 +If STRING is not nil, it is a string, and POS is an index to the string.
 +In this case, compose characters after POS of the string."
 +  (if string
 +      ;; Not yet implemented.
 +      nil
 +    (goto-char pos)
 +    (if (looking-at devanagari-composable-pattern)
 +      (prog1 (match-end 0)
 +        (devanagari-compose-syllable-region pos (match-end 0))))))
  
  ;; Notes on conversion steps.
  
@@@ -497,10 -496,11 +497,10 @@@ preferred rule from the sanskrit fonts.
  (defvar dev-glyph-glyph-2-regexp
    (devanagari-regexp-of-hashtbl-keys dev-glyph-glyph-2-hash))
  
 -
  (defun dev-charseq (from &optional to)
    (if (null to) (setq to from))
 -  (mapcar (function (lambda (x) (indian-glyph-char x 'devanagari)))
 -          (devanagari-range from to)))
 +  (number-sequence (decode-char 'devanagari-cdac from)
 +                 (decode-char 'devanagari-cdac to)))
  
  (defvar dev-glyph-cvn
    (append
index 515b8f4bbaff5c34f41c72c6e7ee5f5bdb60221c,c337ecb2a4f45b46e37efd74c25557fe25e8f767..46ed04145043b130202b7bc48818b015534877c8
@@@ -1,6 -1,6 +1,6 @@@
  ;;; devanagari.el --- Support for Devanagari -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 1996, 1997, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1996, 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  
  ;; Maintainer:  KAWABATA, Taichi <kawabata@m17n.org>
@@@ -34,8 -34,8 +34,8 @@@
   "Devanagari" '((charset indian-is13194 mule-unicode-0100-24ff
                           indian-2-column indian-glyph ;; comment out later
                           )
 -              (coding-system in-is13194)
 -              (coding-priority in-is13194)
 +              (coding-system in-is13194-devanagari)
 +              (coding-priority in-is13194-devanagari)
                (input-method . "dev-aiba")
                (features devan-util)
                (documentation . "\
@@@ -43,13 -43,6 +43,13 @@@ Such languages using Devanagari script 
  are supported in this language environment."))
   '("Indian"))
  
 +;; For automatic composition.
 +(dolist (range '((#x0903 . #x0903)
 +               (#x0905 . #x0939)
 +               (#x0958 . #x0961)))
 +  (set-char-table-range composition-function-table range
 +                      'devanagari-composition-function))
 +
  (provide 'devanagari)
  
  ;;; arch-tag: fd13667d-868b-41e8-81ef-79dd28bbfed2
diff --combined lisp/language/english.el
index 00eba11174236401faa6e134fc37e114ec2eb50b,d12ed650186f19e65bb7ca9a64ffdd3cc235c822..852c0c65bbbb3092e72223e045a084310644a757
@@@ -1,13 -1,10 +1,13 @@@
  ;;; english.el --- support for English -*- no-byte-compile: t -*-
  
- ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multibyte character, character set, syntax, category
  
  Nothing special is needed to handle English.")
             ))
  
 +;; Mostly because we can now...
 +(define-coding-system 'ebcdic-us
 +  "US version of EBCDIC"
 +  :coding-type 'charset
 +  :charset-list '(ebcdic-us)
 +  :mnemonic ?*)
 +
 +(define-coding-system 'ebcdic-uk
 +  "UK version of EBCDIC"
 +  :coding-type 'charset
 +  :charset-list '(ebcdic-uk)
 +  :mnemonic ?*)
 +
 +(define-coding-system 'ibm1047
 +  "A version of EBCDIC used in OS/390 Unix"  ; says Groff
 +  :coding-type 'charset
 +  :charset-list '(ibm1047)
 +  :mnemonic ?*)
 +(define-coding-system-alias 'cp1047 'ibm1047)
 +
  ;; Make "ASCII" an alias of "English" language environment.
  (set-language-info-alist
   "ASCII" (cdr (assoc "English" language-info-alist)))
index 93de5e74c4df5703da4806bc7c0610099e777e45,857df138670a376004d5acbb36b84e2377c800e3..6354a41b93c0e5331d5f190dfc8db7c1855c6803
@@@ -1,13 -1,10 +1,13 @@@
 -;;; ethio-util.el --- utilities for Ethiopic -*- coding: iso-2022-7bit; -*-
 +;;; ethio-util.el --- utilities for Ethiopic  -*- coding: utf-8-emacs; -*-
  
- ;; Copyright (C) 1997, 1998, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2005, 2006
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number: H15PRO110
  
  ;; Keywords: mule, multilingual, Ethiopic
  
@@@ -34,8 -31,6 +34,8 @@@
  
  ;;; Code:
  
 +(require 'robin)
 +
  (defvar rmail-current-message)
  (defvar rmail-message-vector)
  
  (defun setup-ethiopic-environment-internal ()
    (let ((key-bindings '((" " . ethio-insert-space)
                        ([?\S- ] . ethio-insert-ethio-space)
 -                      ([?\C-'] . ethio-gemination)
 -
 -                      ;; these old bindings conflict
 -                      ;; with Emacs' binding policy
 -
 -                      ;; ([f2] . ethio-toggle-space)
 -                      ;; ([S-f2] . ethio-replace-space) ; as requested
 -                      ;; ([f3] . ethio-toggle-punctuation)
 -                      ;; ([f4] . ethio-sera-to-fidel-buffer)
 -                      ;; ([S-f4] . ethio-sera-to-fidel-region)
 -                      ;; ([C-f4] . ethio-sera-to-fidel-mail-or-marker)
 -                      ;; ([f5] . ethio-fidel-to-sera-buffer)
 -                      ;; ([S-f5] . ethio-fidel-to-sera-region)
 -                      ;; ([C-f5] . ethio-fidel-to-sera-mail-or-marker)
 -                      ;; ([f6] . ethio-modify-vowel)
 -                      ;; ([f7] . ethio-replace-space)
 -                      ;; ([f8] . ethio-input-special-character)
 -
 -                      ;; this is the rewritten bindings
 -
 +                      ;; ([?\C-'] . ethio-gemination)
                        ([f3] . ethio-fidel-to-sera-buffer)
                        ([S-f3] . ethio-fidel-to-sera-region)
 -                      ([C-f3] . ethio-fidel-to-sera-mail-or-marker)
 +                      ([C-f3] . ethio-fidel-to-sera-marker)
                        ([f4] . ethio-sera-to-fidel-buffer)
                        ([S-f4] . ethio-sera-to-fidel-region)
 -                      ([C-f4] . ethio-sera-to-fidel-mail-or-marker)
 +                      ([C-f4] . ethio-sera-to-fidel-marker)
                        ([S-f5] . ethio-toggle-punctuation)
                        ([S-f6] . ethio-modify-vowel)
                        ([S-f7] . ethio-replace-space)
 -                      ([S-f8] . ethio-input-special-character)
 +                      ;; ([S-f8] . ethio-input-special-character) ; deprecated
                        ([C-f9] . ethio-toggle-space)
                        ([S-f9] . ethio-replace-space) ; as requested
                        ))
@@@ -69,6 -83,7 +69,6 @@@
        (global-set-key kb (cdr (car key-bindings)))
        (setq key-bindings (cdr key-bindings))))
  
 -  (add-hook 'quail-activate-hook 'ethio-select-a-translation)
    (add-hook 'find-file-hook 'ethio-find-file)
    (add-hook 'write-file-functions 'ethio-write-file)
    (add-hook 'after-save-hook 'ethio-find-file))
@@@ -81,6 -96,7 +81,6 @@@
      (setq exit-ethiopic-environment-data
          (cdr exit-ethiopic-environment-data)))
  
 -  (remove-hook 'quail-activate-hook 'ethio-select-a-translation)
    (remove-hook 'find-file-hook 'ethio-find-file)
    (remove-hook 'write-file-functions 'ethio-write-file)
    (remove-hook 'after-save-hook 'ethio-find-file))
  ;;
  ;; If the filename ends in ".tex", editing is done in fidel
  ;; but file I/O is done in EthioTeX format.
 -;;
 -;; To automatically convert Ethiopic text to SERA format when sending mail,
 -;;   (add-hook 'mail-send-hook 'ethio-fidel-to-sera-mail)
 -;;
 -;; To automatically convert SERA format to Ethiopic when receiving mail,
 -;;   (add-hook 'rmail-show-message-hook 'ethio-sera-to-fidel-mail)
 -;;
 -;; To automatically convert Ethiopic text to SERA format when posting news,
 -;;   (add-hook 'news-inews-hook 'ethio-fidel-to-sera-mail)
  
  ;;
  ;; users' preference
@@@ -124,7 -149,7 +124,7 @@@ mark.  All SERA <--> FIDEL converters r
  
  (defvar ethio-quote-vowel-always nil
    "*Non-nil means always put an apostrophe before an isolated vowel (except at word initial) in FIDEL --> SERA conversion.
 -If nil, put an apostrophe only between a sixth-form consonant and an
 +If nil, put an apostrophe only between a 6th-form consonant and an
  isolated vowel.")
  
  (defvar ethio-W-sixth-always nil
@@@ -138,98 -163,313 +138,98 @@@ For example, ({10}{9}{100}{80}{7}) is c
      `109100807            if `ethio-numeric-reduction' is 1,
      `10900807     if `ethio-numeric-reduction' is 2.")
  
 -(defvar ethio-implicit-period-conversion t
 -  "*Non-nil means replacing the Ethiopic dot at the end of an Ethiopic sentence
 -with an Ethiopic full stop.")
 -
  (defvar ethio-java-save-lowercase nil
    "*Non-nil means save Ethiopic characters in lowercase hex numbers to Java files.
  If nil, use uppercases.")
  
 +(defun ethio-prefer-amharic-p ()
 +  (or (eq ethio-primary-language 'amharic)
 +      (and (not (eq ethio-primary-language 'tigrigna))
 +         (eq ethio-secondary-language 'amharic))))
 +
 +(defun ethio-prefer-amharic (arg)
 +  (if arg
 +      (progn
 +      (robin-modify-package "ethiopic-sera" "'a" ?አ)
 +      (robin-modify-package "ethiopic-sera" "a" "አ")
 +      (robin-modify-package "ethiopic-sera" "'A" ?ኣ)
 +      (robin-modify-package "ethiopic-sera" "A" "ኣ"))
 +    (robin-modify-package "ethiopic-sera" "'A" ?አ)
 +    (robin-modify-package "ethiopic-sera" "A" "አ")
 +    (robin-modify-package "ethiopic-sera" "'a" ?ኣ)
 +    (robin-modify-package "ethiopic-sera" "a" "ኣ")))
 +
 +(defun ethio-use-colon-for-colon (arg)
 +  (if arg
 +      (progn
 +      (robin-modify-package "ethiopic-sera" ":" ?á¥)
 +      (robin-modify-package "ethiopic-sera" "`:" ?á¡))
 +    (robin-modify-package "ethiopic-sera" " : " ?á¡)
 +    (robin-modify-package "ethiopic-sera" ":" "á¡")
 +    (robin-modify-package "ethiopic-sera" "-:" ?á¥)))
 +
 +(defun ethio-use-three-dot-question (arg)
 +  (if arg
 +      (progn
 +      (robin-modify-package "ethiopic-sera" "?" ?á§)
 +      (robin-modify-package "ethiopic-sera" "`?" ??))
 +    (robin-modify-package "ethiopic-sera" "?" ??)
 +    (robin-modify-package "ethiopic-sera" "`?" ?á§)))
 +
 +(defun ethio-adjust-robin ()
 +  (ethio-prefer-amharic (ethio-prefer-amharic-p))
 +  (ethio-use-colon-for-colon ethio-use-colon-for-colon)
 +  (ethio-use-three-dot-question ethio-use-three-dot-question))
 +
 +(add-hook 'robin-activate-hook 'ethio-adjust-robin)
 +
  ;;
  ;; SERA to FIDEL
  ;;
  
 -(defconst ethio-sera-to-fidel-table
 -  [
 -   nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil
 -;;; SP
 -   (" "
 -    (?: (if ethio-use-colon-for-colon " \e$(3$l\e(B" "\e$(3$h\e(B")
 -      (32 (if ethio-use-colon-for-colon " \e$(3$l\e(B " "\e$(3$h\e(B"))
 -      (?- " \e$(3$m\e(B")
 -      (?: " \e$(3$i\e(B")
 -      (?| (if ethio-use-colon-for-colon " \e$(3$l\e(B|" " \e$(3$h\e(B|")
 -          (?: " \e$(3$o\e(B"))))
 -
 -;;; !   "   #   $   %   &    '
 -   nil nil nil nil nil nil ("" (?' "\e$(3%s\e(B"))
 -;;; (   )   *   +    ,      -               .
 -   nil nil nil nil ("\e$(3$j\e(B") ("-" (?: "\e$(3$l\e(B")) ("\e$(3%u\e(B")
 -;;;  /   0   1   2   3   4   5   6   7   8   9
 -    nil nil nil nil nil nil nil nil nil nil nil
 -;;; :
 -   ((if ethio-use-colon-for-colon "\e$(3$l\e(B" "\e$(3$h\e(B")
 -    (32 (if ethio-use-colon-for-colon "\e$(3$l\e(B " "\e$(3$h\e(B"))
 -    (?- "\e$(3$m\e(B")
 -    (?: "\e$(3$i\e(B")
 -    (?| (if ethio-use-colon-for-colon "\e$(3$l\e(B|" "\e$(3$h\e(B|")
 -      (?: "\e$(3$o\e(B")))
 -;;;  ;      <              =    >
 -   ("\e$(3$k\e(B") ("<" (?< "\e$(3%v\e(B")) nil (">" (?> "\e$(3%w\e(B"))
 -;;; ?
 -   ((if ethio-use-three-dot-question "\e$(3$n\e(B" "\e$(3%x\e(B"))
 -;;; @
 -    nil
 -;;; A
 -   ("\e$(3"f\e(B" (?2 "\e$(3#8\e(B"))
 -;;; B
 -   ("\e$(3"(\e(B" (?e "\e$(3"#\e(B") (?u "\e$(3"$\e(B") (?i "\e$(3"%\e(B") (?a "\e$(3"&\e(B") (?E "\e$(3"'\e(B") (?o "\e$(3")\e(B")
 -         (?W "\e$(3%b\e(B" (?e "\e$(3%2\e(B") (?u "\e$(3%b\e(B") (?i "\e$(3%B\e(B") (?a "\e$(3"*\e(B") (?E "\e$(3%R\e(B")))
 -;;; C
 -   ("\e$(3$4\e(B" (?e "\e$(3$/\e(B") (?u "\e$(3$0\e(B") (?i "\e$(3$1\e(B") (?a "\e$(3$2\e(B") (?E "\e$(3$3\e(B") (?o "\e$(3$5\e(B")
 -         (?W "\e$(3$6\e(B" (?a "\e$(3$6\e(B")
 -                  (?e "\e$(3$4%n\e(B") (?u "\e$(3$4%r\e(B") (?i "\e$(3$4%o\e(B") (?E "\e$(3$4%q\e(B")))
 -;;; D
 -   ("\e$(3#b\e(B" (?e "\e$(3#]\e(B") (?u "\e$(3#^\e(B") (?i "\e$(3#_\e(B") (?a "\e$(3#`\e(B") (?E "\e$(3#a\e(B") (?o "\e$(3#c\e(B")
 -         (?W "\e$(3#d\e(B" (?a "\e$(3#d\e(B")
 -                  (?e "\e$(3#b%n\e(B") (?u "\e$(3#b%r\e(B") (?i "\e$(3#b%o\e(B") (?E "\e$(3#b%q\e(B")))
 -;;; E
 -   ("\e$(3"g\e(B" (?2 "\e$(3#9\e(B"))
 -;;; F
 -   ("\e$(3$T\e(B" (?e "\e$(3$O\e(B") (?u "\e$(3$P\e(B") (?i "\e$(3$Q\e(B") (?a "\e$(3$R\e(B") (?E "\e$(3$S\e(B") (?o "\e$(3$U\e(B")
 -         (?W "\e$(3%d\e(B" (?e "\e$(3%4\e(B") (?u "\e$(3%d\e(B") (?i "\e$(3%D\e(B") (?a "\e$(3$V\e(B") (?E "\e$(3%T\e(B"))
 -       (?Y "\e$(3$a\e(B" (?a "\e$(3$a\e(B")))
 -;;; G
 -   ("\e$(3$$\e(B" (?e "\e$(3#}\e(B") (?u "\e$(3#~\e(B") (?i "\e$(3$!\e(B") (?a "\e$(3$"\e(B") (?E "\e$(3$#\e(B") (?o "\e$(3$%\e(B")
 -         (?W "\e$(3%c\e(B" (?e "\e$(3%3\e(B") (?u "\e$(3%c\e(B") (?i "\e$(3%C\e(B") (?a "\e$(3$&\e(B") (?E "\e$(3%S\e(B")))
 -;;; H
 -   ("\e$(3!6\e(B" (?e "\e$(3!1\e(B") (?u "\e$(3!2\e(B") (?i "\e$(3!3\e(B") (?a "\e$(3!4\e(B") (?E "\e$(3!5\e(B") (?o "\e$(3!7\e(B")
 -         (?W "\e$(3!8\e(B" (?a "\e$(3!8\e(B")
 -                  (?e "\e$(3!6%n\e(B") (?u "\e$(3!6%r\e(B") (?i "\e$(3!6%o\e(B") (?E "\e$(3!6%q\e(B")))
 -;;; I
 -   ("\e$(3"h\e(B" (?2 "\e$(3#:\e(B"))
 -;;; J
 -   ("\e$(3#j\e(B" (?e "\e$(3#e\e(B") (?u "\e$(3#f\e(B") (?i "\e$(3#g\e(B") (?a "\e$(3#h\e(B") (?E "\e$(3#i\e(B") (?o "\e$(3#k\e(B")
 -         (?W "\e$(3#l\e(B" (?a "\e$(3#l\e(B")
 -                (?e "\e$(3#j%n\e(B") (?u "\e$(3#j%r\e(B") (?i "\e$(3#j%o\e(B") (?E "\e$(3#j%q\e(B")))
 -;;; K
 -   ("\e$(3#"\e(B" (?e "\e$(3"{\e(B") (?u "\e$(3"|\e(B") (?i "\e$(3"}\e(B") (?a "\e$(3"~\e(B") (?E "\e$(3#!\e(B") (?o "\e$(3##\e(B")
 -         (?W "\e$(3#*\e(B" (?e "\e$(3#%\e(B") (?u "\e$(3#*\e(B") (?i "\e$(3#'\e(B") (?a "\e$(3#(\e(B") (?E "\e$(3#)\e(B")))
 -;;; L
 -   ("\e$(3!.\e(B" (?e "\e$(3!)\e(B") (?u "\e$(3!*\e(B") (?i "\e$(3!+\e(B") (?a "\e$(3!,\e(B") (?E "\e$(3!-\e(B") (?o "\e$(3!/\e(B")
 -         (?W "\e$(3!0\e(B" (?a "\e$(3!0\e(B")
 -                  (?e "\e$(3!.%n\e(B") (?u "\e$(3!.%r\e(B") (?i "\e$(3!.%o\e(B") (?E "\e$(3!.%q\e(B")))
 -;;; M
 -   ("\e$(3!>\e(B" (?e "\e$(3!9\e(B") (?u "\e$(3!:\e(B") (?i "\e$(3!;\e(B") (?a "\e$(3!<\e(B") (?E "\e$(3!=\e(B") (?o "\e$(3!?\e(B")
 -         (?W "\e$(3%a\e(B" (?e "\e$(3%1\e(B") (?u "\e$(3%a\e(B") (?i "\e$(3%A\e(B") (?a "\e$(3!@\e(B") (?E "\e$(3%Q\e(B"))
 -       (?Y "\e$(3$_\e(B" (?a "\e$(3$_\e(B")))
 -;;; N
 -   ("\e$(3"`\e(B" (?e "\e$(3"[\e(B") (?u "\e$(3"\\e(B") (?i "\e$(3"]\e(B") (?a "\e$(3"^\e(B") (?E "\e$(3"_\e(B") (?o "\e$(3"a\e(B")
 -         (?W "\e$(3"b\e(B" (?a "\e$(3"b\e(B")
 -                  (?e "\e$(3"`%n\e(B") (?u "\e$(3"`%r\e(B") (?i "\e$(3"`%o\e(B") (?E "\e$(3"`%q\e(B")))
 -;;; O
 -   ("\e$(3"i\e(B" (?2 "\e$(3#;\e(B"))
 -;;; P
 -   ("\e$(3$<\e(B" (?e "\e$(3$7\e(B") (?u "\e$(3$8\e(B") (?i "\e$(3$9\e(B") (?a "\e$(3$:\e(B") (?E "\e$(3$;\e(B") (?o "\e$(3$=\e(B")
 -         (?W "\e$(3$>\e(B" (?a "\e$(3$>\e(B")
 -                  (?e "\e$(3$<%n\e(B") (?u "\e$(3$<%r\e(B") (?i "\e$(3$<%o\e(B") (?E "\e$(3$<%q\e(B")))
 -;;; Q
 -   ("\e$(3!v\e(B" (?e "\e$(3!q\e(B") (?u "\e$(3!r\e(B") (?i "\e$(3!s\e(B") (?a "\e$(3!t\e(B") (?E "\e$(3!u\e(B") (?o "\e$(3!w\e(B")
 -         (?W "\e$(3!~\e(B" (?e "\e$(3!y\e(B") (?u "\e$(3!~\e(B") (?i "\e$(3!{\e(B") (?a "\e$(3!|\e(B") (?E "\e$(3!}\e(B")))
 -;;; R
 -   ("\e$(3!N\e(B" (?e "\e$(3!I\e(B") (?u "\e$(3!J\e(B") (?i "\e$(3!K\e(B") (?a "\e$(3!L\e(B") (?E "\e$(3!M\e(B") (?o "\e$(3!O\e(B")
 -         (?W "\e$(3!P\e(B" (?a "\e$(3!P\e(B")
 -                (?e "\e$(3!N%n\e(B") (?u "\e$(3!N%r\e(B") (?i "\e$(3!N%o\e(B") (?E "\e$(3!N%q\e(B"))
 -         (?Y "\e$(3$`\e(B" (?a "\e$(3$`\e(B")))
 -;;; S
 -   ("\e$(3$D\e(B" (?e "\e$(3$?\e(B") (?u "\e$(3$@\e(B") (?i "\e$(3$A\e(B") (?a "\e$(3$B\e(B") (?E "\e$(3$C\e(B") (?o "\e$(3$E\e(B")
 -         (?W "\e$(3$F\e(B" (?a "\e$(3$F\e(B")
 -                  (?e "\e$(3$D%n\e(B") (?u "\e$(3$D%r\e(B") (?i "\e$(3$D%o\e(B") (?E "\e$(3$D%q\e(B"))
 -       (?2 "\e$(3$L\e(B"
 -           (?e "\e$(3$G\e(B") (?u "\e$(3$H\e(B") (?i "\e$(3$I\e(B") (?a "\e$(3$J\e(B") (?E "\e$(3$K\e(B") (?o "\e$(3$M\e(B")
 -           (?W "\e$(3$F\e(B" (?a "\e$(3$F\e(B")
 -               (?e "\e$(3$L%n\e(B") (?u "\e$(3$L%r\e(B") (?i "\e$(3$L%o\e(B") (?E "\e$(3$L%q\e(B"))))
 -;;; T
 -   ("\e$(3$,\e(B" (?e "\e$(3$'\e(B") (?u "\e$(3$(\e(B") (?i "\e$(3$)\e(B") (?a "\e$(3$*\e(B") (?E "\e$(3$+\e(B") (?o "\e$(3$-\e(B")
 -         (?W "\e$(3$.\e(B" (?a "\e$(3$.\e(B")
 -                (?e "\e$(3$,%n\e(B") (?u "\e$(3$,%r\e(B") (?i "\e$(3$,%o\e(B") (?E "\e$(3$,%q\e(B")))
 -;;; U
 -   ("\e$(3"d\e(B" (?2 "\e$(3#6\e(B"))
 -;;; V
 -   ("\e$(3"0\e(B" (?e "\e$(3"+\e(B") (?u "\e$(3",\e(B") (?i "\e$(3"-\e(B") (?a "\e$(3".\e(B") (?E "\e$(3"/\e(B") (?o "\e$(3"1\e(B")
 -         (?W "\e$(3"2\e(B" (?a "\e$(3"2\e(B")
 -                (?e "\e$(3"0%n\e(B") (?u "\e$(3"0%r\e(B") (?i "\e$(3"0%o\e(B") (?E "\e$(3"0%q\e(B")))
 -;;; W
 -   ("\e$(3%r\e(B" (?e "\e$(3%n\e(B") (?u "\e$(3%r\e(B") (?i "\e$(3%o\e(B") (?a "\e$(3%p\e(B") (?E "\e$(3%q\e(B"))
 -;;; X
 -   ("\e$(3%N\e(B" (?e "\e$(3%I\e(B") (?u "\e$(3%J\e(B") (?i "\e$(3%K\e(B") (?a "\e$(3%L\e(B") (?E "\e$(3%M\e(B") (?o "\e$(3%O\e(B"))
 -;;; Y
 -   ("\e$(3#R\e(B" (?e "\e$(3#M\e(B") (?u "\e$(3#N\e(B") (?i "\e$(3#O\e(B") (?a "\e$(3#P\e(B") (?E "\e$(3#Q\e(B") (?o "\e$(3#S\e(B")
 -         (?W "\e$(3#T\e(B" (?a "\e$(3#T\e(B")
 -                (?e "\e$(3#R%n\e(B") (?u "\e$(3#R%r\e(B") (?i "\e$(3#R%o\e(B") (?E "\e$(3#R%q\e(B")))
 -;;; Z
 -   ("\e$(3#J\e(B" (?e "\e$(3#E\e(B") (?u "\e$(3#F\e(B") (?i "\e$(3#G\e(B") (?a "\e$(3#H\e(B") (?E "\e$(3#I\e(B") (?o "\e$(3#K\e(B")
 -         (?W "\e$(3#L\e(B" (?a "\e$(3#L\e(B")
 -                (?e "\e$(3#J%n\e(B") (?u "\e$(3#J%r\e(B") (?i "\e$(3#J%o\e(B") (?E "\e$(3#J%q\e(B")))
 -;;; [   \   ]   ^   _
 -   nil nil nil nil nil
 -;;; `
 -   (""
 -    (?: "\e$(3$h\e(B")
 -    (?? (if ethio-use-three-dot-question "\e$(3%x\e(B" "\e$(3$n\e(B"))
 -    (?! "\e$(3%t\e(B")
 -    (?e "\e$(3#5\e(B") (?u "\e$(3#6\e(B") (?U "\e$(3#6\e(B") (?i "\e$(3#7\e(B") (?a "\e$(3#8\e(B") (?A "\e$(3#8\e(B")
 -        (?E "\e$(3#9\e(B") (?I "\e$(3#:\e(B") (?o "\e$(3#;\e(B") (?O "\e$(3#;\e(B")
 -    (?g "\e$(3%^\e(B"
 -        (?e "\e$(3%Y\e(B") (?u "\e$(3%Z\e(B") (?i "\e$(3%[\e(B") (?a "\e$(3%\\e(B") (?E "\e$(3%]\e(B") (?o "\e$(3%_\e(B"))
 -    (?h "\e$(3"H\e(B"
 -        (?e "\e$(3"C\e(B") (?u "\e$(3"D\e(B") (?i "\e$(3"E\e(B") (?a "\e$(3"F\e(B") (?E "\e$(3"G\e(B") (?o "\e$(3"I\e(B")
 -                (?W "\e$(3"P\e(B" (?e "\e$(3"K\e(B") (?u "\e$(3"P\e(B") (?i "\e$(3"M\e(B") (?a "\e$(3"N\e(B") (?E "\e$(3"O\e(B")))
 -    (?k "\e$(3%>\e(B"
 -        (?e "\e$(3%9\e(B") (?u "\e$(3%:\e(B") (?i "\e$(3%;\e(B") (?a "\e$(3%<\e(B") (?E "\e$(3%=\e(B") (?o "\e$(3%?\e(B"))
 -    (?s "\e$(3!F\e(B"
 -        (?e "\e$(3!A\e(B") (?u "\e$(3!B\e(B") (?i "\e$(3!C\e(B") (?a "\e$(3!D\e(B") (?E "\e$(3!E\e(B") (?o "\e$(3!G\e(B")
 -      (?W "\e$(3!H\e(B" (?a "\e$(3!H\e(B")
 -                 (?e "\e$(3!F%n\e(B") (?u "\e$(3!F%r\e(B") (?i "\e$(3!F%o\e(B") (?E "\e$(3!F%q\e(B")))
 -    (?S "\e$(3$L\e(B"
 -      (?e "\e$(3$G\e(B") (?u "\e$(3$H\e(B") (?i "\e$(3$I\e(B") (?a "\e$(3$J\e(B") (?E "\e$(3$K\e(B") (?o "\e$(3$M\e(B")
 -      (?W "\e$(3$F\e(B" (?a "\e$(3$F\e(B")
 -               (?e "\e$(3$L%n\e(B") (?u "\e$(3$L%r\e(B") (?i "\e$(3$L%o\e(B") (?E "\e$(3$L%q\e(B")))
 -    (?q "\e$(3%.\e(B" (?e "\e$(3%)\e(B") (?u "\e$(3%*\e(B") (?i "\e$(3%+\e(B") (?a "\e$(3%,\e(B") (?E "\e$(3%-\e(B") (?o "\e$(3%/\e(B")))
 -;;; a
 -   ("\e$(3"f\e(B" (?2 "\e$(3#8\e(B"))
 -;;; b
 -   ("\e$(3"(\e(B" (?e "\e$(3"#\e(B") (?u "\e$(3"$\e(B") (?i "\e$(3"%\e(B") (?a "\e$(3"&\e(B") (?E "\e$(3"'\e(B") (?o "\e$(3")\e(B")
 -         (?W "\e$(3%b\e(B" (?e "\e$(3%2\e(B") (?u "\e$(3%b\e(B") (?i "\e$(3%B\e(B") (?a "\e$(3"*\e(B") (?E "\e$(3%R\e(B")))
 -;;; c
 -   ("\e$(3"@\e(B" (?e "\e$(3";\e(B") (?u "\e$(3"<\e(B") (?i "\e$(3"=\e(B") (?a "\e$(3">\e(B") (?E "\e$(3"?\e(B") (?o "\e$(3"A\e(B")
 -         (?W "\e$(3"B\e(B" (?a "\e$(3"B\e(B")
 -                (?e "\e$(3"@%n\e(B") (?u "\e$(3"@%r\e(B") (?i "\e$(3"@%o\e(B") (?E "\e$(3"@%q\e(B")))
 -;;; d
 -   ("\e$(3#Z\e(B" (?e "\e$(3#U\e(B") (?u "\e$(3#V\e(B") (?i "\e$(3#W\e(B") (?a "\e$(3#X\e(B") (?E "\e$(3#Y\e(B") (?o "\e$(3#[\e(B")
 -         (?W "\e$(3#\\e(B" (?a "\e$(3#\\e(B")
 -                (?e "\e$(3#Z%o\e(B") (?u "\e$(3#Z%r\e(B") (?i "\e$(3#Z%p\e(B") (?E "\e$(3#Z%q\e(B")))
 -;;; e
 -   ("\e$(3"c\e(B" (?2 "\e$(3#5\e(B") (?a "\e$(3"j\e(B"))
 -;;; f
 -   ("\e$(3$T\e(B" (?e "\e$(3$O\e(B") (?u "\e$(3$P\e(B") (?i "\e$(3$Q\e(B") (?a "\e$(3$R\e(B") (?E "\e$(3$S\e(B") (?o "\e$(3$U\e(B")
 -         (?W "\e$(3%d\e(B" (?e "\e$(3%4\e(B") (?u "\e$(3%d\e(B") (?i "\e$(3%D\e(B") (?a "\e$(3$V\e(B") (?E "\e$(3%T\e(B"))
 -       (?Y "\e$(3$a\e(B" (?a "\e$(3$a\e(B")))
 -;;; g
 -   ("\e$(3#r\e(B" (?e "\e$(3#m\e(B") (?u "\e$(3#n\e(B") (?i "\e$(3#o\e(B") (?a "\e$(3#p\e(B") (?E "\e$(3#q\e(B") (?o "\e$(3#s\e(B")
 -         (?W "\e$(3#z\e(B" (?e "\e$(3#u\e(B") (?u "\e$(3#z\e(B") (?i "\e$(3#w\e(B") (?a "\e$(3#x\e(B") (?E "\e$(3#y\e(B"))
 -         (?2 "\e$(3%^\e(B" (?e "\e$(3%Y\e(B") (?u "\e$(3%Z\e(B") (?i "\e$(3%[\e(B") (?a "\e$(3%\\e(B") (?E "\e$(3%]\e(B") (?o "\e$(3%_\e(B")))
 -;;; h
 -   ("\e$(3!&\e(B" (?e "\e$(3!!\e(B") (?u "\e$(3!"\e(B") (?i "\e$(3!#\e(B") (?a "\e$(3!$\e(B") (?E "\e$(3!%\e(B") (?o "\e$(3!'\e(B")
 -         (?W "\e$(3"P\e(B" (?e "\e$(3"K\e(B") (?u "\e$(3"P\e(B") (?i "\e$(3"M\e(B") (?a "\e$(3"N\e(B") (?E "\e$(3"O\e(B"))
 -       (?2 "\e$(3"H\e(B" (?e "\e$(3"C\e(B") (?u "\e$(3"D\e(B") (?i "\e$(3"E\e(B") (?a "\e$(3"F\e(B") (?E "\e$(3"G\e(B") (?o "\e$(3"I\e(B")
 -                (?W "\e$(3"P\e(B" (?e "\e$(3"K\e(B") (?u "\e$(3"P\e(B") (?i "\e$(3"M\e(B") (?a "\e$(3"N\e(B") (?E "\e$(3"O\e(B"))))
 -;;; i
 -   ("\e$(3"e\e(B" (?2 "\e$(3#7\e(B"))
 -;;; j
 -   ("\e$(3#j\e(B" (?e "\e$(3#e\e(B") (?u "\e$(3#f\e(B") (?i "\e$(3#g\e(B") (?a "\e$(3#h\e(B") (?E "\e$(3#i\e(B") (?o "\e$(3#k\e(B")
 -         (?W "\e$(3#l\e(B" (?a "\e$(3#l\e(B")
 -                (?e "\e$(3#j%n\e(B") (?u "\e$(3#j%r\e(B") (?i "\e$(3#j%o\e(B") (?E "\e$(3#j%q\e(B")))
 -;;; k
 -   ("\e$(3"p\e(B" (?e "\e$(3"k\e(B") (?u "\e$(3"l\e(B") (?i "\e$(3"m\e(B") (?a "\e$(3"n\e(B") (?E "\e$(3"o\e(B") (?o "\e$(3"q\e(B")
 -         (?W "\e$(3"x\e(B" (?e "\e$(3"s\e(B") (?u "\e$(3"x\e(B") (?i "\e$(3"u\e(B") (?a "\e$(3"v\e(B") (?E "\e$(3"w\e(B"))
 -       (?2 "\e$(3%>\e(B" (?e "\e$(3%9\e(B") (?u "\e$(3%:\e(B") (?i "\e$(3%;\e(B") (?a "\e$(3%<\e(B") (?E "\e$(3%=\e(B") (?o "\e$(3%?\e(B")))
 -;;; l
 -   ("\e$(3!.\e(B" (?e "\e$(3!)\e(B") (?u "\e$(3!*\e(B") (?i "\e$(3!+\e(B") (?a "\e$(3!,\e(B") (?E "\e$(3!-\e(B") (?o "\e$(3!/\e(B")
 -         (?W "\e$(3!0\e(B" (?a "\e$(3!0\e(B")
 -                  (?e "\e$(3!.%n\e(B") (?u "\e$(3!.%r\e(B") (?i "\e$(3!.%o\e(B") (?E "\e$(3!.%q\e(B")))
 -;;; m
 -   ("\e$(3!>\e(B" (?e "\e$(3!9\e(B") (?u "\e$(3!:\e(B") (?i "\e$(3!;\e(B") (?a "\e$(3!<\e(B") (?E "\e$(3!=\e(B") (?o "\e$(3!?\e(B")
 -         (?W "\e$(3%a\e(B" (?e "\e$(3%1\e(B") (?u "\e$(3%a\e(B") (?i "\e$(3%A\e(B") (?a "\e$(3!@\e(B") (?E "\e$(3%Q\e(B"))
 -       (?Y "\e$(3$_\e(B" (?a "\e$(3$_\e(B")))
 -;;; n
 -   ("\e$(3"X\e(B" (?e "\e$(3"S\e(B") (?u "\e$(3"T\e(B") (?i "\e$(3"U\e(B") (?a "\e$(3"V\e(B") (?E "\e$(3"W\e(B") (?o "\e$(3"Y\e(B")
 -         (?W "\e$(3"Z\e(B" (?a "\e$(3"Z\e(B")
 -                (?e "\e$(3"X%n\e(B") (?u "\e$(3"X%r\e(B") (?i "\e$(3"X%o\e(B") (?E "\e$(3"X%q\e(B")))
 -;;; o
 -   ("\e$(3"i\e(B" (?2 "\e$(3#;\e(B"))
 -;;; p
 -   ("\e$(3$\\e(B" (?e "\e$(3$W\e(B") (?u "\e$(3$X\e(B") (?i "\e$(3$Y\e(B") (?a "\e$(3$Z\e(B") (?E "\e$(3$[\e(B") (?o "\e$(3$]\e(B")
 -         (?W "\e$(3%e\e(B" (?e "\e$(3%5\e(B") (?u "\e$(3%e\e(B") (?i "\e$(3%E\e(B") (?a "\e$(3$^\e(B") (?E "\e$(3%U\e(B")))
 -;;; q
 -   ("\e$(3!f\e(B" (?e "\e$(3!a\e(B") (?u "\e$(3!b\e(B") (?i "\e$(3!c\e(B") (?a "\e$(3!d\e(B") (?E "\e$(3!e\e(B") (?o "\e$(3!g\e(B")
 -         (?W "\e$(3!n\e(B" (?e "\e$(3!i\e(B") (?u "\e$(3!n\e(B") (?i "\e$(3!k\e(B") (?a "\e$(3!l\e(B") (?E "\e$(3!m\e(B"))
 -         (?2 "\e$(3%.\e(B" (?e "\e$(3%)\e(B") (?u "\e$(3%*\e(B") (?i "\e$(3%+\e(B") (?a "\e$(3%,\e(B") (?E "\e$(3%-\e(B") (?o "\e$(3%/\e(B")))
 -;;; r
 -   ("\e$(3!N\e(B" (?e "\e$(3!I\e(B") (?u "\e$(3!J\e(B") (?i "\e$(3!K\e(B") (?a "\e$(3!L\e(B") (?E "\e$(3!M\e(B") (?o "\e$(3!O\e(B")
 -         (?W "\e$(3!P\e(B" (?a "\e$(3!P\e(B")
 -                (?e "\e$(3!N%n\e(B") (?u "\e$(3!N%r\e(B") (?i "\e$(3!N%o\e(B") (?E "\e$(3!N%q\e(B"))
 -         (?Y "\e$(3$`\e(B" (?a "\e$(3$`\e(B")))
 -;;; s
 -   ("\e$(3!V\e(B" (?e "\e$(3!Q\e(B") (?u "\e$(3!R\e(B") (?i "\e$(3!S\e(B") (?a "\e$(3!T\e(B") (?E "\e$(3!U\e(B") (?o "\e$(3!W\e(B")
 -         (?W "\e$(3!X\e(B" (?a "\e$(3!X\e(B")
 -                (?e "\e$(3!V%n\e(B") (?u "\e$(3!V%r\e(B") (?i "\e$(3!V%o\e(B") (?E "\e$(3!V%q\e(B"))
 -       (?2 "\e$(3!F\e(B" (?e "\e$(3!A\e(B") (?u "\e$(3!B\e(B") (?i "\e$(3!C\e(B") (?a "\e$(3!D\e(B") (?E "\e$(3!E\e(B") (?o "\e$(3!G\e(B")
 -                (?W "\e$(3!H\e(B" (?a "\e$(3!H\e(B")
 -                         (?e "\e$(3!F%n\e(B") (?u "\e$(3!F%r\e(B") (?i "\e$(3!F%o\e(B") (?E "\e$(3!F%q\e(B"))))
 -;;; t
 -   ("\e$(3"8\e(B" (?e "\e$(3"3\e(B") (?u "\e$(3"4\e(B") (?i "\e$(3"5\e(B") (?a "\e$(3"6\e(B") (?E "\e$(3"7\e(B") (?o "\e$(3"9\e(B")
 -         (?W "\e$(3":\e(B" (?a "\e$(3":\e(B")
 -                (?e "\e$(3"8%n\e(B") (?u "\e$(3"8%r\e(B") (?i "\e$(3"8%o\e(B") (?E "\e$(3"8%q\e(B")))
 -;;; u
 -   ("\e$(3"d\e(B" (?2 "\e$(3#6\e(B"))
 -;;; v
 -   ("\e$(3"0\e(B" (?e "\e$(3"+\e(B") (?u "\e$(3",\e(B") (?i "\e$(3"-\e(B") (?a "\e$(3".\e(B") (?E "\e$(3"/\e(B") (?o "\e$(3"1\e(B")
 -         (?W "\e$(3"2\e(B" (?a "\e$(3"2\e(B")
 -                (?e "\e$(3"0%n\e(B") (?u "\e$(3"0%r\e(B") (?i "\e$(3"0%o\e(B") (?E "\e$(3"0%q\e(B")))
 -;;; w
 -   ("\e$(3#2\e(B" (?e "\e$(3#-\e(B") (?u "\e$(3#.\e(B") (?i "\e$(3#/\e(B") (?a "\e$(3#0\e(B") (?E "\e$(3#1\e(B") (?o "\e$(3#3\e(B")
 -         (?W "\e$(3%p\e(B" (?e "\e$(3%n\e(B") (?u "\e$(3%r\e(B") (?i "\e$(3%o\e(B") (?a "\e$(3%p\e(B") (?E "\e$(3%q\e(B")))
 -;;; x
 -   ("\e$(3!^\e(B" (?e "\e$(3!Y\e(B") (?u "\e$(3!Z\e(B") (?i "\e$(3![\e(B") (?a "\e$(3!\\e(B") (?E "\e$(3!]\e(B") (?o "\e$(3!_\e(B")
 -         (?W "\e$(3!`\e(B" (?a "\e$(3!`\e(B")
 -                (?e "\e$(3!^%n\e(B") (?u "\e$(3!^%r\e(B") (?i "\e$(3!^%o\e(B") (?E "\e$(3!^%q\e(B")))
 -;;; y
 -   ("\e$(3#R\e(B" (?e "\e$(3#M\e(B") (?u "\e$(3#N\e(B") (?i "\e$(3#O\e(B") (?a "\e$(3#P\e(B") (?E "\e$(3#Q\e(B") (?o "\e$(3#S\e(B")
 -         (?W "\e$(3#T\e(B" (?a "\e$(3#T\e(B")
 -                (?e "\e$(3#R%n\e(B") (?u "\e$(3#R%r\e(B") (?i "\e$(3#R%o\e(B") (?E "\e$(3#R%q\e(B")))
 -;;; z
 -   ("\e$(3#B\e(B" (?e "\e$(3#=\e(B") (?u "\e$(3#>\e(B") (?i "\e$(3#?\e(B") (?a "\e$(3#@\e(B") (?E "\e$(3#A\e(B") (?o "\e$(3#C\e(B")
 -         (?W "\e$(3#D\e(B" (?a "\e$(3#D\e(B")
 -                (?e "\e$(3#B%n\e(B") (?u "\e$(3#B%r\e(B") (?i "\e$(3#B%o\e(B") (?E "\e$(3#B%q\e(B")))
 -;;; {   |   }   ~  DEL
 -   nil nil nil nil nil
 -   ])
 -
 -;; To avoid byte-compiler warnings.  It should never be set globally.
 -(defvar ethio-sera-being-called-by-w3)
 -;; This variable will be bound by some third-party package.
 -(defvar sera-being-called-by-w3)
 -
  ;;;###autoload
 -(defun ethio-sera-to-fidel-region (beg end &optional secondary force)
 -  "Convert the characters in region from SERA to FIDEL.
 -The variable `ethio-primary-language' specifies the primary language
 -and `ethio-secondary-language' specifies the secondary.
 +(defun ethio-sera-to-fidel-buffer (&optional secondary force)
 +  "Convert the current buffer from SERA to FIDEL.
 +
 +The variable `ethio-primary-language' specifies the primary
 +language and `ethio-secondary-language' specifies the secondary.
  
 -If the 3rd parameter SECONDARY is given and non-nil, assume the region
 -begins with the secondary language; otherwise with the primary
 -language.
 +If the 1st optional argument SECONDARY is non-nil, assume the
 +buffer begins with the secondary language; otherwise with the
 +primary language.
  
 -If the 4th parameter FORCE is given and non-nil, perform conversion
 +If the 2nd optional argument FORCE is non-nil, perform conversion
  even if the buffer is read-only.
  
  See also the descriptions of the variables
 -`ethio-use-colon-for-colon' and
 -`ethio-use-three-dot-question'."
 +`ethio-use-colon-for-colon' and `ethio-use-three-dot-question'."
  
 -  (interactive "r\nP")
 -  (save-restriction
 -    (narrow-to-region beg end)
 -    (ethio-sera-to-fidel-buffer secondary force)))
 +  (interactive "P")
 +  (ethio-sera-to-fidel-region (point-min) (point-max) secondary force))
 +
 +;; To avoid byte-compiler warnings.  It should never be set globally.
 +(defvar ethio-sera-being-called-by-w3)
 +;; This variable will be bound by some third-party package.
 +(defvar sera-being-called-by-w3)
  
  ;;;###autoload
 -(defun ethio-sera-to-fidel-buffer (&optional secondary force)
 -  "Convert the current buffer from SERA to FIDEL.
 +(defun ethio-sera-to-fidel-region (begin end &optional secondary force)
 +  "Convert the characters in region from SERA to FIDEL.
  
  The variable `ethio-primary-language' specifies the primary
  language and `ethio-secondary-language' specifies the secondary.
  
 -If the 1st optional parameter SECONDARY is non-nil, assume the buffer
 -begins with the secondary language; otherwise with the primary
 -language.
 +If the 3rd argument SECONDARY is given and non-nil, assume the
 +region begins with the secondary language; otherwise with the
 +primary language.
  
 -If the 2nd optional parametr FORCE is non-nil, perform conversion even if the
 -buffer is read-only.
 +If the 4th argument FORCE is given and non-nil, perform
 +conversion even if the buffer is read-only.
  
  See also the descriptions of the variables
 -`ethio-use-colon-for-colon' and
 -`ethio-use-three-dot-question'."
 -
 -  (interactive "P")
 +`ethio-use-colon-for-colon' and `ethio-use-three-dot-question'."
  
 +  (interactive "r\nP")
    (if (and buffer-read-only
           (not force)
           (not (y-or-n-p "Buffer is read-only.  Force to convert? ")))
  
    (let ((ethio-primary-language ethio-primary-language)
        (ethio-secondary-language ethio-secondary-language)
 -      (ethio-use-colon-for-colon ethio-use-colon-for-colon)
 -      (ethio-use-three-dot-question ethio-use-three-dot-question)
 -      ;; The above four variables may be changed temporary
 -      ;; by tilde escapes during conversion.  So we bind them to other
 -      ;; variables but of the same names.
 +      ;; The above two variables may be changed temporarily by tilde
 +      ;; escapes during conversion.  We bind them to the variables
 +      ;; of the same names so that the original values are restored
 +      ;; when this function exits.
        (buffer-read-only nil)
 -      (case-fold-search nil)
 -      current-language
 -      next-language)
 +      (lang (if secondary ethio-secondary-language ethio-primary-language))
 +      ret)
  
 -    (setq current-language
 -        (if secondary
 -            ethio-secondary-language
 -          ethio-primary-language))
 +    (ethio-use-colon-for-colon ethio-use-colon-for-colon)
 +    (ethio-use-three-dot-question ethio-use-three-dot-question)
  
 -    (goto-char (point-min))
 -
 -    (while (not (eobp))
 -      (setq next-language
 -          (cond
 -           ((eq current-language 'english)
 -            (ethio-sera-to-fidel-english))
 -           ((eq current-language 'amharic)
 -            (ethio-sera-to-fidel-ethio 'amharic))
 -           ((eq current-language 'tigrigna)
 -            (ethio-sera-to-fidel-ethio 'tigrigna))
 -           (t                         ; we don't know what to do
 -            (ethio-sera-to-fidel-english))))
 -
 -      (setq current-language
 -          (cond
 -
 -           ;; when language tag is explicitly specified
 -           ((not (eq next-language 'toggle))
 -            next-language)
 -
 -           ;; found a toggle in a primary language section
 -           ((eq current-language ethio-primary-language)
 -            ethio-secondary-language)
 -
 -           ;; found a toggle in a secondary, third, fourth, ...
 -           ;; language section
 -           (t
 -            ethio-primary-language))))
 -
 -    ;; If ethio-implicit-period-conversion is non-nil, the
 -    ;; Ethiopic dot "\e$(3%u\e(B" at the end of an Ethiopic sentence is
 -    ;; replaced with the Ethiopic full stop "\e$(3$i\e(B".
 -    (if ethio-implicit-period-conversion
 -      (progn
 -        (goto-char (point-min))
 -        (while (re-search-forward "\\([\e$(3!!\e(B-\e$(3$a%)\e(B-\e$(3%e%n\e(B-\e$(3%r%s\e(B]\\)\e$(3%u\e(B\\([ \t]\\)"
 -                                  nil t)
 -          (replace-match "\\1\e$(3$i\e(B\\2"))
 -        (goto-char (point-min))
 -        (while (re-search-forward "\\([\e$(3!!\e(B-\e$(3$a%)\e(B-\e$(3%e%n\e(B-\e$(3%r%s\e(B]\\)\e$(3%u\e(B$" nil t)
 -          (replace-match "\\1\e$(3$i\e(B"))))
 -
 -    ;; gemination
 -    (goto-char (point-min))
 -    (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
 -      (compose-region
 -       (save-excursion (backward-char 2) (point))
 -       (point)))
 -    ))
 -
 -(defun ethio-sera-to-fidel-english nil
 -  "Handle English section in SERA to FIDEL conversion.
 -Conversion stops when a language switch is found.  Then delete that
 -switch and return the name of the new language as a symbol."
 -  (let ((new-language nil))
 -
 -    (while (and (not (eobp)) (null new-language))
 -      (cond
 -
 -       ;; if no more "\", nothing to do.
 -       ((not (search-forward "\\" nil 0)))
 -
 -       ;; hereafter point is put after a "\".
 -       ;; first delete that "\", then check the following chars
 -
 -       ;; "\\" :  leave the second "\"
 -       ((progn
 -        (delete-backward-char 1)
 -        (= (following-char) ?\\ ))
 -      (forward-char 1))
 -
 -       ;; "\ " :  delete the following " "
 -       ((= (following-char) 32)
 -      (delete-char 1)
 -      (setq new-language 'toggle))
 -
 -       ;; a language flag
 -       ((setq new-language (ethio-process-language-flag)))
 -
 -       ;; just a "\" :  not special sequence.
 -       (t
 -      (setq new-language 'toggle))))
 +    (save-restriction
 +      (narrow-to-region begin end)
 +      (goto-char (point-min))
 +      (while (not (eobp))
 +      (setq ret
 +            (cond
 +             ((eq lang 'amharic)
 +              (ethio-prefer-amharic t)
 +              (ethio-sera-to-fidel-region-ethio 'amharic))
 +             ((eq lang 'tigrigna)
 +              (ethio-prefer-amharic nil)
 +              (ethio-sera-to-fidel-region-ethio 'tigrigna))
 +             (t
 +              (ethio-sera-to-fidel-region-noethio))))
 +      (setq lang
 +            (if (eq ret 'toggle)
 +                (if (eq lang ethio-primary-language)
 +                    ethio-secondary-language
 +                  ethio-primary-language)
 +              ret)))))
 +
 +  ;; Restore user's preference.
 +  (ethio-adjust-robin))
 +
 +(defun ethio-sera-to-fidel-region-noethio ()
 +  "Return next language as symbol: amharic, tigrigna, toggle or nil."
 +  (let (lflag)
 +    (cond
  
 -    new-language))
 +     ;; No more "\", i.e. nothing to do.
 +     ((not (search-forward "\\" nil 0))
 +      nil)
  
 -(defun ethio-sera-to-fidel-ethio (lang)
 -  "Handle Ethiopic section in SERA to FIDEL conversion.
 -Conversion stops when a language switch is found.  Then delete that
 -switch and return the name of the new language as a symbol.
 +     ;; Hereafter point is put after a "\".
 +     ;; First delete that "\", then check the following chars.
  
 -The parameter LANG (symbol, either `amharic' or `tigrigna') affects
 -the conversion of \"a\"."
 +     ;; A language flag.
 +     ((progn (delete-char -1) (setq lflag (ethio-process-language-flag)))
 +      lflag)
  
 -  (let ((new-language nil)
 -      (verbatim nil)
 -      start table table2 ch)
 +     ;; "\\" : leave the second "\" and continue in the same language.
 +     ((= (following-char) ?\\)
 +      (forward-char 1)
 +      nil)
  
 -    (setcar (aref ethio-sera-to-fidel-table ?a)
 -          (if (eq lang 'tigrigna) "\e$(3"f\e(B" "\e$(3"c\e(B"))
 +     ;; "\ " : delete the following " " and toggle the language.
 +     ((= (following-char) 32)
 +      (delete-char 1)
 +      'toggle)
  
 -    (while (and (not (eobp)) (null new-language))
 -      (setq ch (following-char))
 -      (cond
 +     ;; A  "\" but not a special sequence: simply toggle the language.
 +     (t
 +      'toggle))))
  
 -       ;; skip from "<" to ">" (or from "&" to ";") if in w3-mode
 -       ((and (or (= ch ?<) (= ch ?&))
 -           (or (and (boundp 'ethio-sera-being-called-by-w3)
 -                    ethio-sera-being-called-by-w3)
 -               (and (boundp 'sera-being-called-by-w3)
 -                    sera-being-called-by-w3)))
 -      (search-forward (if (= ch ?<) ">" ";")
 -                      nil 0))
 -
 -       ;; leave non-ASCII characters as they are
 -       ((>= ch 128)
 +(defun ethio-sera-to-fidel-region-ethio (lang)
 +  "Return next language as symbol: amharic, tigrigna, toggle or nil."
 +  (save-restriction
 +    (narrow-to-region
 +     (point)
 +     (if (re-search-forward "\\(`[1-9][0-9]*\\)\\|[\\<&]" nil t)
 +       (match-beginning 0)
 +       (point-max)))
 +    (robin-convert-region (point-min) (point-max) "ethiopic-sera")
 +    (goto-char (point-max)))
 +
 +  (let (lflag)
 +    (cond
 +     ((= (following-char) ?`)
 +      (delete-char 1)
 +      (ethio-process-digits)
 +      lang)
 +
 +     ((looking-at "[<&]")
 +      (if (or (and (boundp 'ethio-sera-being-called-by-w3)
 +                 ethio-sera-being-called-by-w3)
 +            (and (boundp 'sera-being-called-by-w3)
 +                 sera-being-called-by-w3))
 +        (search-forward (if (= (following-char) ?<) ">" ";") nil 0)
        (forward-char 1))
 +      lang)
  
 -       ;; ethiopic digits
 -       ((looking-at "`[1-9][0-9]*")
 -      (delete-char 1)
 -      (ethio-convert-digit))
 +     ((eobp)
 +      nil)
  
 -       ;; if not seeing a "\", do sera to fidel conversion
 -       ((/= ch ?\\ )
 -      (setq start (point))
 -      (forward-char 1)
 -      (setq table (aref ethio-sera-to-fidel-table ch))
 -      (while (setq table2 (cdr (assoc (following-char) table)))
 -        (setq table table2)
 -        (forward-char 1))
 -      (if (setq ch (car table))
 -          (progn
 -            (delete-region start (point))
 -            (if (stringp ch)
 -                (insert ch)
 -              (insert (eval ch))))))
 +     ;; Now we must be looking at a "\".
 +     ;; First delete that "\", then check the following chars.
  
 -       ;; if control reaches here, we must be looking at a "\"
 +     ((progn (delete-char 1) (= (following-char) 32))
 +      (delete-char 1)
 +      'toggle)
  
 -       ;; verbatim mode
 -       (verbatim
 -      (if (looking-at "\\\\~! ?")
 +     ((looking-at "[,.;:'`?\\]+")
 +      (goto-char (match-end 0))
 +      lang)
  
 -          ;; "\~!" or "\~! ".  switch to non-verbatim mode
 -          (progn
 -            (replace-match "")
 -            (setq verbatim nil))
 +     ((/= (following-char) ?~)
 +      'toggle)
  
 -        ;; "\" but not "\~!" nor "\~! ".  skip the current "\".
 -        (forward-char 1)))
 +     ;; Now we must be looking at a "~".
  
 -       ;; hereafter, non-verbatim mode and looking at a "\"
 -       ;; first delete that "\", then check the following chars.
 +     ((setq lflag (ethio-process-language-flag))
 +      lflag)
  
 -       ;; "\ " : delete the following " "
 -       ((progn
 -        (delete-char 1)
 -        (setq ch (following-char))
 -        (= ch 32))
 -      (delete-char 1)
 -      (setq new-language 'toggle))
 +     ;; Delete the following "~" and check the following chars.
  
 -       ;; "\~!" or "\~! " : switch to verbatim mode
 -       ((looking-at "~! ?")
 -      (replace-match "")
 -      (setq verbatim t))
 +     ((progn (delete-char 1) (looking-at "! ?"))
 +      (replace-match "")
 +      (if (re-search-forward "\\\\~! ?" nil 0)
 +        (replace-match ""))
 +      lang)
  
 -       ;; a language flag
 -       ((setq new-language (ethio-process-language-flag)))
 +     ((looking-at "-: ?")
 +      (replace-match "")
 +      (ethio-use-colon-for-colon t)
 +      lang)
  
 -       ;; "\~" but not "\~!" nor a language flag
 -       ((= ch ?~)
 -      (delete-char 1)
 -      (ethio-tilde-escape))
 +     ((looking-at "`: ?")
 +      (replace-match "")
 +      (ethio-use-colon-for-colon nil)
 +      lang)
  
 -       ;; ASCII punctuation escape.  skip
 -       ((looking-at "\\(,\\|\\.\\|;\\|:\\|'\\|`\\|\?\\|\\\\\\)+")
 -      (goto-char (match-end 0)))
 +     ((looking-at "`| ?")
 +      (replace-match "")
 +      (ethio-use-three-dot-question t)
 +      lang)
  
 -       ;; "\", but not special sequence
 -       (t
 -      (setq new-language 'toggle))))
 +     ((looking-at "\\? ?")
 +      (replace-match "")
 +      (ethio-use-three-dot-question nil)
 +      lang)
  
 -    new-language))
 +     ;; Unknown tilde escape.  Recover the deleted chars.
 +     (t
 +      (insert "\\~")
 +      lang))))
  
  (defun ethio-process-language-flag nil
    "Process a language flag of the form \"~lang\" or \"~lang1~lang2\".
  
  If looking at \"~lang1~lang2\", set `ethio-primary-language' and
 -`ethio-une-secondary-language' based on \"lang1\" and \"lang2\".
 +`ethio-secondary-language' based on \"lang1\" and \"lang2\".
  Then delete the language flag \"~lang1~lang2\" from the buffer.
  Return value is the new primary language.
  
 -If looking at \"~lang\", delete that language flag \"~lang\" from the
 -buffer and return that language.  In this case
 -`ethio-primary-language' and `ethio-uni-secondary-language'
 -are left unchanged.
 +If looking at \"~lang\", delete that language flag \"~lang\" from
 +the buffer and return that language.  In this case
 +`ethio-primary-language' and `ethio-secondary-language' are left
 +unchanged.
  
  If an unsupported language flag is found, just return nil without
  changing anything."
       ;; ~lang1~lang2
       ((and (looking-at
            "~\\([a-z][a-z][a-z]?\\)~\\([a-z][a-z][a-z]?\\)[ \t\n\\]")
 -         (setq lang1
 -               (ethio-flag-to-language
 -                (buffer-substring (match-beginning 1) (match-end 1))))
 -         (setq lang2
 -               (ethio-flag-to-language
 -                (buffer-substring (match-beginning 2) (match-end 2)))))
 +         (setq lang1 (ethio-flag-to-language (match-string 1)))
 +         (setq lang2 (ethio-flag-to-language (match-string 2))))
        (setq ethio-primary-language lang1
            ethio-secondary-language lang2)
        (delete-region (point) (match-end 2))
  
       ;; ~lang
       ((and (looking-at "~\\([a-z][a-z][a-z]?\\)[ \t\n\\]")
 -         (setq lang1
 -               (ethio-flag-to-language
 -                (buffer-substring (match-beginning 1) (match-end 1)))))
 +         (setq lang1 (ethio-flag-to-language (match-string 1))))
        (delete-region (point) (match-end 1))
        (if (= (following-char) 32)
          (delete-char 1))
       (t
        nil))))
  
 -(defun ethio-tilde-escape nil
 -  "Handle a SERA tilde escape in Ethiopic section and delete it.
 -Delete the escape even it is not recognized."
 -
 -  (let ((p (point)) command)
 -    (skip-chars-forward "^ \t\n\\\\")
 -    (setq command (buffer-substring p (point)))
 -    (delete-region p (point))
 -    (if (= (following-char) 32)
 -      (delete-char 1))
 -
 -    (cond
 -
 -     ;; \~-:
 -     ((string= command "-:")
 -      (setq ethio-use-colon-for-colon t))
 -
 -     ;; \~`:
 -     ((string= command "`:")
 -      (setq ethio-use-colon-for-colon nil))
 -
 -     ;; \~?
 -     ((string= command "?")
 -      (setq ethio-use-three-dot-question nil))
 -
 -     ;; \~`|
 -     ((string= command "`|")
 -      (setq ethio-use-three-dot-question t))
 -
 -     ;; \~e
 -     ((string= command "e")
 -      (insert "\e$(3%j\e(B"))
 -
 -     ;; \~E
 -     ((string= command "E")
 -      (insert "\e$(3%k\e(B"))
 -
 -     ;; \~a
 -     ((string= command "a")
 -      (insert "\e$(3%l\e(B"))
 -
 -     ;; \~A
 -     ((string= command "A")
 -      (insert "\e$(3%m\e(B"))
 -
 -     ;; \~X
 -     ((string= command "X")
 -      (insert "\e$(3%i\e(B"))
 -
 -     ;; unsupported tilde escape
 -     (t
 -      nil))))
 -
  (defun ethio-flag-to-language (flag)
    (cond
     ((or (string= flag "en") (string= flag "eng")) 'english)
     ((or (string= flag "am") (string= flag "amh")) 'amharic)
     (t nil)))
  
 -(defun ethio-convert-digit nil
 +(defun ethio-process-digits nil
    "Convert Arabic digits to Ethiopic digits."
    (let (ch z)
      (while (and (>= (setq ch (following-char)) ?1)
  
         ;; first digit is 10, 20, ..., or 90
         ((= (mod z 2) 1)
 -      (insert (aref [?\e$(3$y\e(B ?\e$(3$z\e(B ?\e$(3${\e(B ?\e$(3$|\e(B ?\e$(3$}\e(B ?\e$(3$~\e(B ?\e$(3%!\e(B ?\e$(3%"\e(B ?\e$(3%#\e(B] (- ch ?1)))
 +      (insert (aref [?á² ?á³ ?á´ ?áµ ?ᶠ?á· ?Ḡ?á¹ ?áº] (- ch ?1)))
        (setq z (1- z)))
  
         ;; first digit is 2, 3, ..., or 9
         ((/= ch ?1)
 -      (insert (aref [?\e$(3$q\e(B ?\e$(3$r\e(B ?\e$(3$s\e(B ?\e$(3$t\e(B ?\e$(3$u\e(B ?\e$(3$v\e(B ?\e$(3$w\e(B ?\e$(3$x\e(B] (- ch ?2))))
 +      (insert (aref [?᪠?á« ?ᬠ?á­ ?á® ?ᯠ?á° ?á±] (- ch ?2))))
  
         ;; single 1
         ((= z 0)
 -      (insert "\e$(3$p\e(B")))
 +      (insert "á©")))
  
        ;; 100
        (if (= (mod z 4) 2)
 -        (insert "\e$(3%$\e(B"))
 +        (insert "á»"))
  
        ;; 10000
 -      (insert-char ?\e$(3%%\e(B (/ z 4)))))
 -
 -;;;###autoload
 -(defun ethio-sera-to-fidel-mail-or-marker (&optional arg)
 -  "Execute `ethio-sera-to-fidel-mail' or `ethio-sera-to-fidel-marker' depending on the current major mode.
 -If in rmail-mode or in mail-mode, execute the former; otherwise latter."
 -
 -  (interactive "P")
 -  (if (or (eq major-mode 'rmail-mode)
 -        (eq major-mode 'mail-mode))
 -      (ethio-sera-to-fidel-mail (prefix-numeric-value arg))
 -    (ethio-sera-to-fidel-marker arg)))
 -
 -;;;###autoload
 -(defun ethio-sera-to-fidel-mail (&optional arg)
 -  "Convert SERA to FIDEL to read/write mail and news.
 -
 -If the buffer contains the markers \"<sera>\" and \"</sera>\",
 -convert the segments between them into FIDEL.
 -
 -If invoked interactively and there is no marker, convert the subject field
 -and the body into FIDEL using `ethio-sera-to-fidel-region'."
 -
 -  (interactive "p")
 -  (let ((buffer-read-only nil)
 -      border)
 -    (save-excursion
 -
 -      ;; follow RFC822 rules instead of looking for a fixed separator
 -      (rfc822-goto-eoh)
 -      (forward-line 1)
 -      (setq border (point))
 -
 -      ;; note that the point is placed at the border
 -      (if (or (re-search-forward "^<sera>$" nil t)
 -            (progn
 -              (goto-char (point-min))
 -              (re-search-forward "^Subject: <sera>" border t)))
 -
 -        ;; there are markers
 -        (progn
 -          ;; we start with the body so that the border will not change
 -          ;; use "^<sera>\n" instead of "^<sera>$" not to leave a blank line
 -          (goto-char border)
 -          (while (re-search-forward "^<sera>\n" nil t)
 -            (replace-match "")
 -            (ethio-sera-to-fidel-region
 -             (point)
 -             (progn
 -               (if (re-search-forward "^</sera>\n" nil 0)
 -                   (replace-match ""))
 -               (point))))
 -          ;; now process the subject
 -          (goto-char (point-min))
 -          (if (re-search-forward "^Subject: <sera>" border t)
 -              (ethio-sera-to-fidel-region
 -               (progn (delete-backward-char 6) (point))
 -               (progn
 -                 (if (re-search-forward "</sera>$" (line-end-position) 0)
 -                     (replace-match ""))
 -                 (point)))))
 -
 -      ;; in case there are no marks but invoked interactively
 -      (if arg
 -          (progn
 -            (ethio-sera-to-fidel-region border (point-max))
 -            (goto-char (point-min))
 -            (if (re-search-forward "^Subject: " border t)
 -                (ethio-sera-to-fidel-region (point) (line-end-position))))))
 -
 -      ;; adjust the rmail marker
 -      (if (eq major-mode 'rmail-mode)
 -        (set-marker
 -         (aref rmail-message-vector (1+ rmail-current-message))
 -         (point-max))))))
 +      (insert-char ?á¼ (/ z 4)))))
  
  ;;;###autoload
  (defun ethio-sera-to-fidel-marker (&optional force)
@@@ -481,10 -908,10 +481,10 @@@ The markers \"<sera>\" and \"</sera>\" 
        (error ""))
    (save-excursion
      (goto-char (point-min))
 -    (while (re-search-forward "<sera>" nil t)
 +    (while (search-forward "<sera>" nil t)
        (ethio-sera-to-fidel-region
         (point)
 -       (if (re-search-forward "</sera>" nil t)
 +       (if (search-forward "</sera>" nil t)
           (match-beginning 0)
         (point-max))
         nil
  ;; FIDEL to SERA
  ;;
  
 -(defconst ethio-fidel-to-sera-map
 - [ "he"  "hu"  "hi"  "ha"  "hE"  "h"  "ho"    ""       ;;   0 - 7
 -   "le"  "lu"  "li"  "la"  "lE"  "l"  "lo"  "lWa"      ;;   8
 -   "He"  "Hu"  "Hi"  "Ha"  "HE"  "H"  "Ho"  "HWa"      ;;  16
 -   "me"  "mu"  "mi"  "ma"  "mE"  "m"  "mo"  "mWa"      ;;  24
 -  "`se" "`su" "`si" "`sa" "`sE" "`s" "`so" "`sWa"      ;;  32
 -   "re"  "ru"  "ri"  "ra"  "rE"  "r"  "ro"  "rWa"      ;;  40
 -   "se"  "su"  "si"  "sa"  "sE"  "s"  "so"  "sWa"      ;;  48
 -   "xe"  "xu"  "xi"  "xa"  "xE"  "x"  "xo"  "xWa"      ;;  56
 -   "qe"  "qu"  "qi"  "qa"  "qE"  "q"  "qo"    ""       ;;  64
 -  "qWe"   ""  "qWi" "qWa" "qWE"  "qW'" ""     ""       ;;  72
 -   "Qe"  "Qu"  "Qi"  "Qa"  "QE"  "Q"  "Qo"    ""       ;;  80
 -  "QWe"   ""  "QWi" "QWa" "QWE"  "QW'" ""     ""       ;;  88
 -   "be"  "bu"  "bi"  "ba"  "bE"  "b"  "bo"  "bWa"      ;;  96
 -   "ve"  "vu"  "vi"  "va"  "vE"  "v"  "vo"  "vWa"      ;; 104
 -   "te"  "tu"  "ti"  "ta"  "tE"  "t"  "to"  "tWa"      ;; 112
 -   "ce"  "cu"  "ci"  "ca"  "cE"  "c"  "co"  "cWa"      ;; 120
 -  "`he" "`hu" "`hi" "`ha" "`hE" "`h" "`ho"    ""       ;; 128
 -  "hWe"   ""  "hWi" "hWa"  "hWE" "hW'" ""     ""       ;; 136
 -   "ne"  "nu"  "ni"  "na"  "nE"  "n"  "no"  "nWa"      ;; 144
 -   "Ne"  "Nu"  "Ni"  "Na"  "NE"  "N"  "No"  "NWa"      ;; 152
 -    "e"   "u"   "i"   "A"   "E"  "I"   "o"   "ea"      ;; 160
 -   "ke"  "ku"  "ki"  "ka"  "kE"  "k"  "ko"    ""       ;; 168
 -  "kWe"   ""  "kWi" "kWa" "kWE"  "kW'" ""     ""       ;; 176
 -   "Ke"  "Ku"  "Ki"  "Ka"  "KE"  "K"  "Ko"    ""       ;; 184
 -  "KWe"   ""  "KWi" "KWa" "KWE"  "KW'" ""     ""       ;; 192
 -   "we"  "wu"  "wi"  "wa"  "wE"  "w"  "wo"    ""       ;; 200
 -   "`e"  "`u"  "`i"  "`a"  "`E" "`I"  "`o"    ""       ;; 208
 -   "ze"  "zu"  "zi"  "za"  "zE"  "z"  "zo"  "zWa"      ;; 216
 -   "Ze"  "Zu"  "Zi"  "Za"  "ZE"  "Z"  "Zo"  "ZWa"      ;; 224
 -   "ye"  "yu"  "yi"  "ya"  "yE"  "y"  "yo"  "yWa"      ;; 232
 -   "de"  "du"  "di"  "da"  "dE"  "d"  "do"  "dWa"      ;; 240
 -   "De"  "Du"  "Di"  "Da"  "DE"  "D"  "Do"  "DWa"      ;; 248
 -   "je"  "ju"  "ji"  "ja"  "jE"  "j"  "jo"  "jWa"      ;; 256
 -   "ge"  "gu"  "gi"  "ga"  "gE"  "g"  "go"    ""       ;; 264
 -  "gWe"   ""  "gWi" "gWa" "gWE" "gW'"  ""     ""       ;; 272
 -   "Ge"  "Gu"  "Gi"  "Ga"  "GE"  "G"  "Go"  "GWa"      ;; 280
 -   "Te"  "Tu"  "Ti"  "Ta"  "TE"  "T"  "To"  "TWa"      ;; 288
 -   "Ce"  "Cu"  "Ci"  "Ca"  "CE"  "C"  "Co"  "CWa"      ;; 296
 -   "Pe"  "Pu"  "Pi"  "Pa"  "PE"  "P"  "Po"  "PWa"      ;; 304
 -   "Se"  "Su"  "Si"  "Sa"  "SE"  "S"  "So"  "SWa"      ;; 312
 -  "`Se" "`Su" "`Si" "`Sa" "`SE" "`S" "`So"    ""       ;; 320
 -   "fe"  "fu"  "fi"  "fa"  "fE"  "f"  "fo"  "fWa"      ;; 328
 -   "pe"  "pu"  "pi"  "pa"  "pE"  "p"  "po"  "pWa"      ;; 336
 -  "mYa" "rYa" "fYa"   ""    ""   ""    ""     ""       ;; 344
 -   " "  " : "  "::"  ","   ";"  "-:"  ":-"   "`?"      ;; 352
 -  ":|:"  "1"   "2"   "3"   "4"   "5"   "6"   "7"       ;; 360
 -   "8"   "9"   "10"  "20"  "30"  "40" "50"   "60"      ;; 368
 -   "70"  "80"  "90" "100" "10000" ""   ""     ""       ;; 376
 -  "`qe" "`qu" "`qi" "`qa" "`qE" "`q" "`qo"    ""       ;; 384
 -  "mWe" "bWe" "GWe" "fWe" "pWe"  ""    ""     ""       ;; 392
 -  "`ke" "`ku" "`ki" "`ka" "`kE" "`k" "`ko"    ""       ;; 400
 -  "mWi" "bWi" "GWi" "fWi" "pWi"  ""    ""     ""       ;; 408
 -   "Xe"  "Xu"  "Xi"  "Xa"  "XE"  "X"  "Xo"    ""       ;; 416
 -  "mWE" "bWE" "GWE" "fWE" "pWE"  ""    ""     ""       ;; 424
 -  "`ge" "`gu" "`gi" "`ga" "`gE" "`g" "`go"    ""       ;; 432
 -  "mW'" "bW'" "GW'" "fW'" "pW'"  ""    ""     ""       ;; 440
 -  "\\~X " "\\~e " "\\~E " "\\~a " "\\~A " "wWe" "wWi" "wWa" ;; 448
 -  "wWE" "wW'"  "''"  "`!"  "."  "<<"  ">>"   "?" ])    ;; 456
 -
 -(defun ethio-prefer-amharic-p nil
 -  (or (eq ethio-primary-language 'amharic)
 -      (and (not (eq ethio-primary-language 'tigrigna))
 -         (eq ethio-secondary-language 'amharic))))
 -
  (defun ethio-language-to-flag (lang)
    (cond
     ((eq lang 'english) "eng")
     (t "")))
  
  ;;;###autoload
 -(defun ethio-fidel-to-sera-region (begin end &optional secondary force)
 -  "Replace all the FIDEL characters in the region to the SERA format.
 +(defun ethio-fidel-to-sera-buffer (&optional secondary force)
 +  "Replace all the FIDEL characters in the current buffer to the SERA format.
  The variable `ethio-primary-language' specifies the primary
  language and `ethio-secondary-language' specifies the secondary.
  
 -If the 3dr parameter SECONDARY is given and non-nil, try to convert
 -the region so that it begins in the secondary language; otherwise with
 -the primary language.
 +If the 1st optional argument SECONDARY is non-nil, try to convert the
 +region so that it begins with the secondary language; otherwise with the
 +primary language.
  
 -If the 4th parameter FORCE is given and non-nil, convert even if the
 +If the 2nd optional argument FORCE is non-nil, convert even if the
  buffer is read-only.
  
  See also the descriptions of the variables
  `ethio-use-colon-for-colon', `ethio-use-three-dot-question',
  `ethio-quote-vowel-always' and `ethio-numeric-reduction'."
  
 -  (interactive "r\nP")
 -  (save-restriction
 -    (narrow-to-region begin end)
 -    (ethio-fidel-to-sera-buffer secondary force)))
 +  (interactive "P")
 +  (ethio-fidel-to-sera-region (point-min) (point-max) secondary force))
  
  ;;;###autoload
 -(defun ethio-fidel-to-sera-buffer (&optional secondary force)
 -  "Replace all the FIDEL characters in the current buffer to the SERA format.
 +(defun ethio-fidel-to-sera-region (begin end &optional secondary force)
 +  "Replace all the FIDEL characters in the region to the SERA format.
 +
  The variable `ethio-primary-language' specifies the primary
  language and `ethio-secondary-language' specifies the secondary.
  
 -If the 1st optional parameter SECONDARY is non-nil, try to convert the
 -region so that it begins in the secondary language; otherwise with the
 -primary language.
 +If the 3rd argument SECONDARY is given and non-nil, convert
 +the region so that it begins with the secondary language; otherwise with
 +the primary language.
  
 -If the 2nd optional parameter FORCE is non-nil, convert even if the
 +If the 4th argument FORCE is given and non-nil, convert even if the
  buffer is read-only.
  
  See also the descriptions of the variables
  `ethio-use-colon-for-colon', `ethio-use-three-dot-question',
  `ethio-quote-vowel-always' and `ethio-numeric-reduction'."
  
 -  (interactive "P")
 +  (interactive "r\nP")
    (if (and buffer-read-only
           (not force)
           (not (y-or-n-p "Buffer is read-only.  Force to convert? ")))
        (error ""))
  
 -  (let ((buffer-read-only nil)
 -      (case-fold-search nil)
 -      (lonec nil) ;; t means previous char was a lone consonant
 -      (fidel nil) ;; t means previous char was a FIDEL
 -      (digit nil) ;; t means previous char was an Ethiopic digit
 -      (flag (if (ethio-prefer-amharic-p) "\\~amh " "\\~tir "))
 -      mode ch)
 -
 -    ;; user's preference in transcription
 -    (if ethio-use-colon-for-colon
 -      (progn
 -        (aset ethio-fidel-to-sera-map 353 "`:")
 -        (aset ethio-fidel-to-sera-map 357 ":"))
 -      (aset ethio-fidel-to-sera-map 353 " : ")
 -      (aset ethio-fidel-to-sera-map 357 "-:"))
 -
 -    (if ethio-use-three-dot-question
 -      (progn
 -        (aset ethio-fidel-to-sera-map 359 "?")
 -        (aset ethio-fidel-to-sera-map 463 "`?"))
 -      (aset ethio-fidel-to-sera-map 359 "`?")
 -      (aset ethio-fidel-to-sera-map 463 "?"))
 -
 -    (mapcar
 -     '(lambda (x)
 -      (aset (aref ethio-fidel-to-sera-map x)
 -            2
 -            (if ethio-W-sixth-always ?' ?u)))
 -     '(77 93 141 181 197 277 440 441 442 443 444 457))
 -
 -    (if (ethio-prefer-amharic-p)
 -      (aset ethio-fidel-to-sera-map 160 "a")
 -      (aset ethio-fidel-to-sera-map 160 "e"))
 -    ;; end of user's preference
 -
 -    ;; first, decompose geminated characters
 -    (decompose-region (point-min) (point-max))
 -
 -    ;; main conversion routine
 -    (goto-char (point-min))
 -    (while (not (eobp))
 -      (setq ch (following-char))
 -
 -      (cond                           ; ethiopic, english, neutral
 -
 -       ;; ethiopic character.  must go to ethiopic mode, if not in it.
 -       ((eq (char-charset ch) 'ethiopic)
 -      (setq ch (ethio-char-to-ethiocode ch))
 -      (delete-char 1)
 -      (if (not (eq mode 'ethiopic))
 -          (progn
 -            (insert flag)
 -            (setq mode 'ethiopic)))
 -
 -      (cond                           ; fidel, punc, digit
 -
 -       ;; fidels
 -       ((or (<= ch 346)               ;  he - fYa
 -            (and (>= ch 384) (<= ch 444)) ; `qe - pw
 -            (and (>= ch 453) (<= ch 457))) ; wWe - wW
 -        (if (and (memq ch '(160 161 162 163 164 166 167)) ; (e - ea)
 -                 (or lonec
 -                     (and ethio-quote-vowel-always
 -                          fidel)))
 -            (insert "'"))
 -        (insert (aref ethio-fidel-to-sera-map ch))
 -        (setq lonec (ethio-lone-consonant-p ch)
 -              fidel t
 -              digit nil))
 -
 -       ;; punctuations or icons
 -       ((or (and (>= ch 353) (<= ch 360)) ;  : - :|:
 -            (>= ch 458)               ;  '' -  ?
 -            (and (>= ch 448) (<= ch 452))) ;  \~X \~e \~E \~a \~A
 -        (insert (aref ethio-fidel-to-sera-map ch))
 -        (setq lonec nil
 -              fidel nil
 -              digit nil))
 -
 -       ;; now CH must be an ethiopic digit
 -
 -       ;; reduction = 0 or not preceded by Ethiopic number(s)
 -       ((or (= ethio-numeric-reduction 0)
 -            (not digit))
 -        (insert "`" (aref ethio-fidel-to-sera-map ch))
 -        (setq lonec nil
 -              fidel nil
 -              digit t))
 -
 -       ;; reduction = 2 and following 10s, 100s, 10000s
 -       ((and (= ethio-numeric-reduction 2)
 -             (memq ch '(370 379 380)))
 -        (insert (substring (aref ethio-fidel-to-sera-map ch) 1))
 -        (setq lonec nil
 -              fidel nil
 -              digit t))
 -
 -       ;; ordinary following digits
 -       (t
 -        (insert (aref ethio-fidel-to-sera-map ch))
 -        (setq lonec nil
 -              fidel nil
 -              digit t))))
 -
 -       ;; english character.  must go to english mode, if not in it.
 -       ((or (and (>= ch ?a) (<= ch ?z))
 -          (and (>= ch ?A) (<= ch ?Z)))
 -      (if (not (eq mode 'english))
 -          (insert "\\~eng "))
 -      (forward-char 1)
 -      (setq mode 'english
 -            lonec nil
 -            fidel nil
 -            digit nil))
 +  (save-restriction
 +    (narrow-to-region begin end)
  
 -       ;; ch can appear both in ethiopic section and in english section.
 -       (t
 +    (let ((buffer-read-only nil)
 +        (mode (if secondary
 +                  ethio-secondary-language
 +                ethio-primary-language))
 +        (flag (if (ethio-prefer-amharic-p) "\\~amh " "\\~tir "))
 +        p ch)
  
 -      ;; we must decide the mode, if not decided yet
 -      (if (null mode)
 +      (goto-char (point-min))
 +      (ethio-adjust-robin)
 +      (unless (eq mode 'english)
 +      (setq mode 'ethiopic))
 +      (if (and (eq mode 'english) (looking-at "\\ce"))
 +        (setq mode 'ethiopic))
 +      (if (and (eq mode 'ethiopic) (looking-at "\\Ce"))
 +        (setq mode 'english))
 +      (insert (if (eq mode 'english) "\\~eng " flag))
 +
 +      (while (not (eobp))
 +
 +      (if (eq mode 'english)
            (progn
 -            (setq mode
 -                  (if secondary
 -                      ethio-secondary-language
 -                    ethio-primary-language))
 -            (if (eq mode 'english)
 -                (insert "\\~eng ")
 +            (if (re-search-forward "\\(\\ce\\|\\\\\\)" nil 0)
 +                (forward-char -1))
 +            (cond
 +             ((eq (following-char) ?\\)
 +              (insert "\\")
 +              (forward-char 1))
 +             ((looking-at "\\ce")
                (insert flag)
 -              (setq mode 'ethiopic)))) ; tigrigna & amharic --> ethiopic
 -
 -      (cond                           ; \ , eng-mode , punc , w3 , other
 +              (setq mode 'ethiopic))))
  
 -       ;; backslash is always quoted
 -       ((= ch ?\\ )
 -        (insert "\\")
 -        (forward-char 1))
 +        ;; If we reach here, mode is ethiopic.
 +        (setq p (point))
 +        (if (re-search-forward "[a-z,.;:'`?\\<&]" nil 0)
 +            (forward-char -1))
 +        (save-restriction
 +          (narrow-to-region p (point))
 +          (robin-invert-region (point-min) (point-max) "ethiopic-sera")
  
 -       ;; nothing to do if in english mode
 -       ((eq mode 'english)
 -        (forward-char 1))
 -
 -       ;; now we must be in ethiopic mode and seeing a non-"\"
 -
 -       ;; ascii punctuations in ethiopic mode
 -       ((looking-at "[,.;:'`?]+")
 -        (insert "\\")
 -        (goto-char (1+ (match-end 0)))) ; because we inserted one byte (\)
 -
 -       ;; skip from "<" to ">" (or from "&" to ";") if called from w3
 -       ((and (or (= ch ?<) (= ch ?&))
 -             (or (and (boundp 'ethio-sera-being-called-by-w3)
 -                      ethio-sera-being-called-by-w3)
 -                 (and (boundp 'sera-being-called-by-w3)
 -                      sera-being-called-by-w3)))
 -        (search-forward (if (= ch ?<) ">" ";")
 -                        nil 0))
 -
 -       ;; neutral character.  no need to quote.  just skip it.
 -       (t
 -        (forward-char 1)))
 -
 -      (setq lonec nil
 -            fidel nil
 -            digit nil)))
 -    ;; end of main conversion routine
 -    )))
 -
 -(defun ethio-lone-consonant-p (ethiocode)
 -  "If ETHIOCODE is an Ethiopic lone consonant, return t."
 -  (or (and (< ethiocode 344) (= (% ethiocode 8) 5))
 -
 -      ;;                     `q  `k   X  `g  mW  bW  GW  fW  pW  wW
 -      (memq ethiocode '(389 405 421 437 440 441 442 443 444 457))))
 -
 -;;;###autoload
 -(defun ethio-fidel-to-sera-mail-or-marker (&optional arg)
 -  "Execute `ethio-fidel-to-sera-mail' or `ethio-fidel-to-sera-marker' depending on the current major mode.
 -If in rmail-mode or in mail-mode, execute the former; otherwise latter."
 -
 -  (interactive "P")
 -  (if (or (eq major-mode 'rmail-mode)
 -        (eq major-mode 'mail-mode))
 -      (ethio-fidel-to-sera-mail)
 -    (ethio-fidel-to-sera-marker arg)))
 -
 -;;;###autoload
 -(defun ethio-fidel-to-sera-mail nil
 -  "Convert FIDEL to SERA to read/write mail and news.
 -
 -If the body contains at least one Ethiopic character,
 - 1) insert the string \"<sera>\" at the beginning of the body,
 - 2) insert \"</sera>\" at the end of the body, and
 - 3) convert the body into SERA.
 -
 -The very same procedure applies to the subject field, too."
 -
 -  (interactive)
 -  (let ((buffer-read-only nil)
 -      border)
 -    (save-excursion
 -
 -      ;; follow RFC822 rules instead of looking for a fixed separator
 -      (rfc822-goto-eoh)
 -      (forward-line 1)
 -      (setq border (point))
 -
 -      ;; process body first not to change the border
 -      ;; note that the point is already at the border
 -      (if (re-search-forward "\\ce" nil t)
 -        (progn
 -          (ethio-fidel-to-sera-region border (point-max))
 -          (goto-char border)
 -          (insert "<sera>")
 -          (goto-char (point-max))
 -          (insert "</sera>")))
 +          ;; ethio-quote-vowel-alwyas
 +          (goto-char (point-min))
 +          (while (re-search-forward "'[eauio]" nil t)
 +            (save-excursion
 +              (forward-char -2)
 +              (setq ch (preceding-char))
 +              (if (or (and (>= ch ?a) (<= ch ?z))
 +                      (and (>= ch ?A) (<= ch ?Z)))
 +                  (if (and (not ethio-quote-vowel-always)
 +                           (memq ch '(?e ?a ?u ?i ?o ?E ?A ?I)))
 +                      (delete-char 1))
 +                (delete-char 1))))
 +
 +          ;; ethio-W-sixth-always
 +          (unless ethio-W-sixth-always
 +            (goto-char (point-min))
 +            (while (search-forward "W'" nil t)
 +              (delete-char -1)
 +              (insert "u")))
  
 -      ;; process subject
 -      (goto-char (point-min))
 -      (if (re-search-forward "^Subject: " border t)
 -        (let ((beg (point))
 -              (end (line-end-position)))
 -          (if (re-search-forward "\\ce" end t)
 -              (progn
 -                (ethio-fidel-to-sera-region beg end)
 -                (goto-char beg)
 -                (insert "<sera>")
 -                (end-of-line)
 -                (insert "</sera>")))))
 -
 -      ;; adjust the rmail marker
 -      (if (eq major-mode 'rmail-mode)
 -        (set-marker
 -         (aref rmail-message-vector (1+ rmail-current-message))
 -         (point-max))))))
 +          ;; ethio-numeric-reduction
 +          (when (> ethio-numeric-reduction 0)
 +            (goto-char (point-min))
 +            (while (re-search-forward "\\([0-9]\\)`\\([0-9]\\)" nil t)
 +              (replace-match "\\1\\2")
 +              (forward-char -1)))
 +          (when (= ethio-numeric-reduction 2)
 +            (goto-char (point-min))
 +            (while (re-search-forward "\\([0-9]\\)1\\(0+\\)" nil t)
 +              (replace-match "\\1\\2")))
 +
 +          (goto-char (point-max)))
 +
 +        (cond
 +         ((looking-at "[a-z]")
 +          (insert"\\~eng ")
 +          (setq mode 'english))
 +         ((looking-at "[,.;:'`\\]+")
 +          (insert "\\")
 +          (goto-char (1+ (match-end 0))))
 +         ((= (following-char) ??)
 +          (if ethio-use-three-dot-question
 +              (insert "\\"))
 +          (forward-char 1))
 +         ((looking-at "[<&]")
 +          (if (or (and (boundp 'ethio-sera-being-called-by-w3)
 +                       ethio-sera-being-called-by-w3)
 +                  (and (boundp 'sera-being-called-by-w3)
 +                       sera-being-called-by-w3))
 +              (search-forward (if (= (following-char) ?<) ">" "&") nil 0)
 +            (forward-char 1)))))))))
  
  ;;;###autoload
  (defun ethio-fidel-to-sera-marker (&optional force)
@@@ -651,10 -1285,10 +651,10 @@@ The markers \"<sera>\" and \"</sera>\" 
        (error ""))
    (save-excursion
      (goto-char (point-min))
 -    (while (re-search-forward "<sera>" nil t)
 +    (while (search-forward "<sera>" nil t)
        (ethio-fidel-to-sera-region
         (point)
 -       (if (re-search-forward "</sera>" nil t)
 +       (if (search-forward "</sera>" nil t)
           (match-beginning 0)
         (point-max))
         nil
  (defun ethio-modify-vowel nil
    "Modify the vowel of the FIDEL that is under the cursor."
    (interactive)
 -  (let ((ch (following-char))
 -      (composite nil)                 ; geminated or not
 -      newch base vowel modulo)
 -
 -    (cond
 -     ;; in case of gemination
 -     ((eq (char-charset ch) 'composition)
 -      (setq ch (string-to-char (char-to-string ch))
 -          composite t))
 -     ;; neither gemination nor fidel
 -     ((not (eq (char-charset ch) 'ethiopic))
 -      (error "Not a valid character")))
 -
 -    ;; set frequently referred character features
 -    (setq ch     (ethio-char-to-ethiocode ch)
 -        base   (* (/ ch 8) 8)
 -        modulo (% ch 8))
 -
 -    (if (or (and (>= ch 344) (<= ch 380)) ;; mYa - `10000
 -          (and (>= ch 448) (<= ch 452)) ;; \~X - \~A
 -          (>= ch 458))                  ;; private punctuations
 -      (error "Not a valid character"))
 -
 -    (setq
 -     newch
 -     (cond
 -
 -      ;; first standalone vowels
 -      ((= base 160)
 -       (if (ethio-prefer-amharic-p)
 -         (message "Modify vowel to: [auiAEIoW\"] ")
 -       (message "Modify vowel to: [euiAEIoW\"] "))
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 160)
 -      ((= vowel ?u) 161)
 -      ((= vowel ?i) 162)
 -      ((= vowel ?A) 163)
 -      ((= vowel ?E) 164)
 -      ((= vowel ?I) 165)
 -      ((= vowel ?o) 166)
 -      ((= vowel ?W) 167)
 -      ((= vowel ?a) (if (ethio-prefer-amharic-p) 160 163))
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -
 -      ;; second standalone vowels
 -      ((= base 208)
 -       (message "Modify vowel to: [euiaEIo\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 208)
 -      ((= vowel ?u) 209)
 -      ((= vowel ?i) 210)
 -      ((= vowel ?a) 211)
 -      ((= vowel ?E) 212)
 -      ((= vowel ?I) 213)
 -      ((= vowel ?o) 214)
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -
 -      ;; 12-form consonants, *W* form
 -      ((memq base '(72 88 136 176 192 272)) ; qW QW hW kW KW gW
 -       (message "Modify vowel to: [euiaE'\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) base)
 -      ((= vowel ?u) (+ base 5))
 -      ((= vowel ?i) (+ base 2))
 -      ((= vowel ?a) (+ base 3))
 -      ((= vowel ?E) (+ base 4))
 -      ((= vowel ?') (+ base 5))
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -
 -      ;; extended 12-form consonants, mWa bWa GWa fWa pWa
 -      ((= ch 31)                      ; mWa
 -       (message "Modify vowel to: [euiaE'\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 392)
 -      ((= vowel ?u) 440)
 -      ((= vowel ?i) 408)
 -      ((= vowel ?a) ch)
 -      ((= vowel ?E) 424)
 -      ((= vowel ?') 440)
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -      ((= ch 103)                     ; bWa
 -       (message "Modify vowel to: [euiaE'\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 393)
 -      ((= vowel ?u) 441)
 -      ((= vowel ?i) 409)
 -      ((= vowel ?a) ch)
 -      ((= vowel ?E) 425)
 -      ((= vowel ?') 441)
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -      ((= ch 287)                     ; GWa
 -       (message "Modify vowel to: [euiaE'\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 394)
 -      ((= vowel ?u) 442)
 -      ((= vowel ?i) 410)
 -      ((= vowel ?a) ch)
 -      ((= vowel ?E) 426)
 -      ((= vowel ?') 442)
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -      ((= ch 335)                     ; fWa
 -       (message "Modify vowel to: [euiaE'\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 395)
 -      ((= vowel ?u) 443)
 -      ((= vowel ?i) 411)
 -      ((= vowel ?a) ch)
 -      ((= vowel ?E) 427)
 -      ((= vowel ?') 443)
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -      ((= ch 343)                     ; pWa
 -       (message "Modify vowel to: [euiaE'\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 396)
 -      ((= vowel ?u) 444)
 -      ((= vowel ?i) 412)
 -      ((= vowel ?a) ch)
 -      ((= vowel ?E) 428)
 -      ((= vowel ?') 444)
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -
 -      ;; extended 12-form consonatns, mW* bW* GW* fW* pW*
 -      ((memq base '(392 408 424 440)) ; *We *Wi *WE *W
 -       (message "Modify vowel to: [eiEau'\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) (+ 392 modulo))
 -      ((= vowel ?i) (+ 408 modulo))
 -      ((= vowel ?E) (+ 424 modulo))
 -      ((= vowel ?a) (cond
 -                     ((= modulo 0)  31) ; mWa
 -                     ((= modulo 1) 103) ; bWa
 -                     ((= modulo 2) 287) ; GWa
 -                     ((= modulo 3) 335) ; fWa
 -                     ((= modulo 4) 343) ; pWa
 -                     (t nil)))        ; never reach here
 -      ((= vowel ?') (+ 440 modulo))
 -      ((= vowel ?u) (+ 440 modulo))
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -
 -      ((and (>= ch 453) (<= ch 457))  ; wWe wWi wWa wWE wW
 -       (message "Modify vowel to: [eiaE'u\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) 453)
 -      ((= vowel ?i) 454)
 -      ((= vowel ?a) 455)
 -      ((= vowel ?E) 456)
 -      ((= vowel ?') 457)
 -      ((= vowel ?u) 457)
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -
 -      ;; 7-form consonants, or
 -      ;; first 7 of 8-form consonants
 -      ((<= modulo 6)
 -       (message "Modify vowel to: [euiaE'o\"] ")
 -       (setq vowel (read-char))
 -       (cond
 -      ((= vowel ?e) base)
 -      ((= vowel ?u) (+ base 1))
 -      ((= vowel ?i) (+ base 2))
 -      ((= vowel ?a) (+ base 3))
 -      ((= vowel ?E) (+ base 4))
 -      ((= vowel ?') (+ base 5))
 -      ((= vowel ?o) (+ base 6))
 -      ((= vowel ?\") (setq composite t) ch)
 -      (t nil)))
 -
 -      ;; otherwise
 -      (t
 -       nil)))
 -
 -    (cond
 -
 -     ;; could not get new character
 -     ((null newch)
 -      (error "Invalid vowel"))
 -
 -     ;; vowel changed on a composite Fidel
 -     (composite
 +  (ethio-adjust-robin)
 +  (let ((consonant (ethio-get-consonant (following-char)))
 +      vowel)
 +    (if (null consonant)
 +      (error "")                      ; not an Ethiopic char
 +      (setq vowel (read-char "Modify vowel to: "))
        (delete-char 1)
 -      (insert
 -       (compose-string
 -      (concat (char-to-string (ethio-ethiocode-to-char newch))        "\e$(3%s\e(B"))))
 -
 -     ;; simple vowel modification
 -     (t
 -      (delete-char 1)
 -      (insert (ethio-ethiocode-to-char newch))))))
 -
 -(defun ethio-ethiocode-to-char (ethiocode)
 -  (make-char
 -   'ethiopic
 -   (+ (/ ethiocode 94) 33)
 -   (+ (mod ethiocode 94) 33)))
 -
 -(defun ethio-char-to-ethiocode (ch)
 -  (and (eq (char-charset ch) 'ethiopic)
 -       (let ((char-components (split-char ch)))
 -       (+ (* (- (nth 1 char-components) 33) 94)
 -          (- (nth 2 char-components) 33)))))
 +      (if (and (string= consonant "'") (= vowel ?W))
 +        (insert ?ኧ)
 +      (save-restriction
 +        (narrow-to-region (point) (point))
 +        (insert consonant vowel)
 +        (robin-convert-region (point-min) (point-max) "ethiopic-sera"))))))
 +
 +(defun ethio-get-consonant (ch)
 +  "Return the consonant part of CH's SERA spelling in ethiopic-sera."
 +  (let ((sera (get-char-code-property ch 'ethiopic-sera)))
 +    (cond
 +     ((null sera) nil)
 +     ((= ch ?ኧ) "'")                        ; Only this has two vowel letters.
 +     (t (with-temp-buffer
 +        (insert sera)
 +        (if (memq (preceding-char) '(?e ?u ?i ?a ?o ?E ?I ?A ?'))
 +            (delete-char -1))
 +        (buffer-substring (point-min) (point-max)))))))
  
  ;;
  ;; space replacement
    "Replace ASCII spaces with Ethiopic word separators in the region.
  
  In the specified region, replace word separators surrounded by two
 -Ethiopic characters, depending on the first parameter CH, which should
 +Ethiopic characters, depending on the first argument CH, which should
  be 1, 2, or 3.
  
  If CH = 1, word separator will be replaced with an ASCII space.
  If CH = 2, with two ASCII spaces.
  If CH = 3, with the Ethiopic colon-like word separator.
  
 -The second and third parameters BEGIN and END specify the region."
 +The 2nd and 3rd arguments BEGIN and END specify the region."
  
    (interactive "*cReplace spaces to: 1 (sg col), 2 (dbl col), 3 (Ethiopic)\nr")
    (if (not (memq ch '(?1 ?2 ?3)))
         ((= ch ?1)
        ;; an Ethiopic word separator --> an ASCII space
        (goto-char (point-min))
 -      (while (search-forward "\e$(3$h\e(B" nil t)
 -        (replace-match " " nil t))
 +      (while (search-forward "á¡" nil t)
 +        (replace-match " "))
  
        ;; two ASCII spaces between Ethiopic characters --> an ASCII space
        (goto-char (point-min))
        (while (re-search-forward "\\(\\ce\\)  \\(\\ce\\)" nil t)
          (replace-match "\\1 \\2")
 -        (goto-char (match-beginning 2))))
 +        (forward-char -1)))
  
         ((= ch ?2)
        ;; An Ethiopic word separator --> two ASCII spaces
        (goto-char (point-min))
 -      (while (search-forward "\e$(3$h\e(B" nil t)
 +      (while (search-forward "á¡" nil t)
          (replace-match "  "))
  
        ;; An ASCII space between Ethiopic characters --> two ASCII spaces
        (goto-char (point-min))
        (while (re-search-forward "\\(\\ce\\) \\(\\ce\\)" nil t)
          (replace-match "\\1  \\2")
 -        (goto-char (match-beginning 2))))
 +        (forward-char -1)))
  
         (t
        ;; One or two ASCII spaces between Ethiopic characters
        ;;   --> An Ethiopic word separator
        (goto-char (point-min))
        (while (re-search-forward "\\(\\ce\\)  ?\\(\\ce\\)" nil t)
 -        (replace-match "\\1\e$(3$h\e(B\\2")
 -        (goto-char (match-beginning 2)))
 +        (replace-match "\\1á¡\\2")
 +        (forward-char -1))
  
        ;; Three or more ASCII spaces between Ethiopic characters
        ;;   --> An Ethiopic word separator + (N - 2) ASCII spaces
        (goto-char (point-min))
 -      (while (re-search-forward "\\(\\ce\\)  \\( *\\ce\\)" nil t)
 -        (replace-match "\\1\e$(3$h\e(B\\2")
 -        (goto-char (match-beginning 2))))))))
 +      (while (re-search-forward "\\(\\ce\\)  \\( +\\ce\\)" nil t)
 +        (replace-match "\\1á¡\\2")
 +        (forward-char -1)))))))
  
  ;;
  ;; special icons
  ;;
  
 +;; This function is deprecated.
  ;;;###autoload
  (defun ethio-input-special-character (arg)
 -  "Allow the user to input special characters."
 -  (interactive "*cInput number: 1.\e$(3%j\e(B  2.\e$(3%k\e(B  3.\e$(3%l\e(B  4.\e$(3%m\e(B  5.\e$(3%i\e(B")
 +  "This function is deprecated."
 +  (interactive "*cInput number: 1.ö ‡  2.ö ‡‚  3.ö ‡ƒ  4.ö ‡„  5.ö ‡€")
    (cond
     ((= arg ?1)
 -    (insert "\e$(3%j\e(B"))
 +    (insert "ö ‡"))
     ((= arg ?2)
 -    (insert "\e$(3%k\e(B"))
 +    (insert "ö ‡‚"))
     ((= arg ?3)
 -    (insert "\e$(3%l\e(B"))
 +    (insert "ö ‡ƒ"))
     ((= arg ?4)
 -    (insert "\e$(3%m\e(B"))
 +    (insert "ö ‡„"))
     ((= arg ?5)
 -    (insert "\e$(3%i\e(B"))
 +    (insert "ö ‡€"))
     (t
      (error ""))))
  
  ;; TeX support
  ;;
  
 -(defconst ethio-fidel-to-tex-map
 - [ "heG"  "huG"  "hiG"  "haG"  "hEG"   "hG"  "hoG"      ""     ;;   0 - 7
 -   "leG"  "luG"  "liG"  "laG"  "lEG"   "lG"  "loG"  "lWaG"     ;;   8
 -   "HeG"  "HuG"  "HiG"  "HaG"  "HEG"   "HG"  "HoG"  "HWaG"     ;;  16
 -   "meG"  "muG"  "miG"  "maG"  "mEG"   "mG"  "moG"  "mWaG"     ;;  24
 -  "sseG" "ssuG" "ssiG" "ssaG" "ssEG"  "ssG" "ssoG" "ssWaG"     ;;  32
 -   "reG"  "ruG"  "riG"  "raG"  "rEG"   "rG"  "roG"  "rWaG"     ;;  40
 -   "seG"  "suG"  "siG"  "saG"  "sEG"   "sG"  "soG"  "sWaG"     ;;  48
 -   "xeG"  "xuG"  "xiG"  "xaG"  "xEG"   "xG"  "xoG"  "xWaG"     ;;  56
 -   "qeG"  "quG"  "qiG"  "qaG"  "qEG"   "qG"  "qoG"      ""     ;;  64
 -  "qWeG"     "" "qWiG" "qWaG" "qWEG"  "qWG"     ""      ""     ;;  72
 -   "QeG"  "QuG"  "QiG"  "QaG"  "QEG"   "QG"  "QoG"      ""     ;;  80
 -  "QWeG"     "" "QWiG" "QWaG" "QWEG"  "QWG"     ""      ""     ;;  88
 -   "beG"  "buG"  "biG"  "baG"  "bEG"   "bG"  "boG"  "bWaG"     ;;  96
 -   "veG"  "vuG"  "viG"  "vaG"  "vEG"   "vG"  "voG"  "vWaG"     ;; 104
 -   "teG"  "tuG"  "tiG"  "taG"  "tEG"   "tG"  "toG"  "tWaG"     ;; 112
 -   "ceG"  "cuG"  "ciG"  "caG"  "cEG"   "cG"  "coG"  "cWaG"     ;; 120
 -  "hheG" "hhuG" "hhiG" "hhaG" "hhEG"  "hhG" "hhoG"      ""     ;; 128
 -  "hWeG"     "" "hWiG" "hWaG" "hWEG"  "hWG"     ""      ""     ;; 136
 -   "neG"  "nuG"  "niG"  "naG"  "nEG"   "nG"  "noG"  "nWaG"     ;; 144
 -   "NeG"  "NuG"  "NiG"  "NaG"  "NEG"   "NG"  "NoG"  "NWaG"     ;; 152
 -    "eG"   "uG"   "iG"   "AG"   "EG"   "IG"   "oG"   "eaG"     ;; 160
 -   "keG"  "kuG"  "kiG"  "kaG"  "kEG"   "kG"  "koG"      ""     ;; 168
 -  "kWeG"     "" "kWiG" "kWaG" "kWEG"  "kWG"     ""      ""     ;; 176
 -   "KeG"  "KuG"  "KiG"  "KaG"  "KEG"   "KG"  "KoG"      ""     ;; 184
 -  "KWeG"     "" "KWiG" "KWaG" "KWEG"  "KWG"     ""      ""     ;; 192
 -   "weG"  "wuG"  "wiG"  "waG"  "wEG"   "wG"  "woG"      ""     ;; 200
 -   "eeG"  "uuG"  "iiG"  "aaG"  "EEG"  "IIG"  "ooG"      ""     ;; 208
 -   "zeG"  "zuG"  "ziG"  "zaG"  "zEG"   "zG"  "zoG"  "zWaG"     ;; 216
 -   "ZeG"  "ZuG"  "ZiG"  "ZaG"  "ZEG"   "ZG"  "ZoG"  "ZWaG"     ;; 224
 -   "yeG"  "yuG"  "yiG"  "yaG"  "yEG"   "yG"  "yoG"  "yWaG"     ;; 232
 -   "deG"  "duG"  "diG"  "daG"  "dEG"   "dG" "doG"   "dWaG"     ;; 240
 -   "DeG"  "DuG"  "DiG"  "DaG"  "DEG"   "DG"  "DoG"  "DWaG"     ;; 248
 -   "jeG"  "juG"  "jiG"  "jaG"  "jEG"   "jG"  "joG"  "jWaG"     ;; 256
 -   "geG"  "guG"  "giG"  "gaG"  "gEG"   "gG"  "goG"     ""      ;; 264
 -  "gWeG"     "" "gWiG" "gWaG" "gWEG"  "gWG"     ""     ""      ;; 272
 -   "GeG"  "GuG"  "GiG"  "GaG"  "GEG"   "GG"  "GoG"  "GWaG"     ;; 280
 -   "TeG"  "TuG"  "TiG"  "TaG"  "TEG"   "TG"  "ToG"  "TWaG"     ;; 288
 -   "CeG"  "CuG"  "CiG"  "CaG"  "CEG"   "CG"  "CoG"  "CWaG"     ;; 296
 -   "PeG"  "PuG"  "PiG"  "PaG"  "PEG"   "PG"  "PoG"  "PWaG"     ;; 304
 -   "SeG"  "SuG"  "SiG"  "SaG"  "SEG"   "SG"  "SoG"  "SWaG"     ;; 312
 -  "SSeG" "SSuG" "SSiG" "SSaG" "SSEG"  "SSG" "SSoG"      ""     ;; 320
 -   "feG"  "fuG"  "fiG"  "faG"  "fEG"   "fG"  "foG"  "fWaG"     ;; 328
 -   "peG"  "puG"  "piG"  "paG"  "pEG"   "pG"  "poG"  "pWaG"     ;; 336
 -  "mYaG" "rYaG" "fYaG"     ""     ""     ""     ""      ""     ;; 344
 -      "" "spaceG" "periodG" "commaG"                           ;; 352
 -  "semicolonG" "colonG" "precolonG" "oldqmarkG"                ;; 356
 -  "pbreakG" "andG" "huletG" "sostG" "aratG" "amstG" "sadstG" "sabatG"  ;; 360
 -  "smntG" "zeteNG" "asrG" "heyaG" "selasaG" "arbaG" "hemsaG" "slsaG"   ;; 368
 -  "sebaG" "semanyaG" "zeTanaG" "metoG" "asrxiG" "" "" ""               ;; 376
 -  "qqeG" "qquG" "qqiG" "qqaG" "qqEG" "qqG" "qqoG"    ""      ;; 384
 -  "mWeG" "bWeG" "GWeG" "fWeG" "pWeG"    ""     ""    ""      ;; 392
 -  "kkeG" "kkuG" "kkiG" "kkaG" "kkEG" "kkG" "kkoG"    ""      ;; 400
 -  "mWiG" "bWiG" "GWiG" "fWiG" "pWiG"    ""     ""    ""      ;; 408
 -   "XeG"  "XuG" "GXiG"  "XaG"  "XEG"  "XG"  "XoG"    ""      ;; 416
 -  "mWEG" "bWEG" "GWEG" "fWEG" "pWEG"    ""     ""    ""      ;; 424
 -  "ggeG" "gguG" "ggiG" "ggaG" "ggEG" "ggG" "ggoG"    ""      ;; 432
 -   "mWG" "bWG"   "GWG"  "fWG"  "pWG"    ""     ""    ""      ;; 440
 -  "ornamentG" "flandG" "iflandG" "africaG"                     ;; 448
 -  "iafricaG" "wWeG" "wWiG" "wWaG"                            ;; 452
 -  "wWEG"  "wWG" "" "slaqG" "dotG" "lquoteG" "rquoteG" "qmarkG" ])  ;; 456
 -
 -;;
 -;; To make tex-to-fidel mapping.
 -;; The following code makes
 -;;     (get 'ethio-tex-command-he 'ethio-fidel-char)  ==>  ?\e$(3!!\e(B
 -;; etc.
 -;;
 -
 -(let ((i 0) str)
 -  (while (< i (length ethio-fidel-to-tex-map))
 -    (setq str (aref ethio-fidel-to-tex-map i))
 -    (if (not (string= str ""))
 -      (put
 -       (intern (concat "ethio-tex-command-" (aref ethio-fidel-to-tex-map i)))
 -       'ethio-fidel-char
 -       (ethio-ethiocode-to-char i)))
 -    (setq i (1+ i))))
 -
  ;;;###autoload
  (defun ethio-fidel-to-tex-buffer nil
 -  "Convert each fidel characters in the current buffer into a fidel-tex command.
 -Each command is always surrounded by braces."
 +  "Convert each fidel characters in the current buffer into a fidel-tex command."
    (interactive)
 -  (let ((buffer-read-only nil))
 +  (let ((buffer-read-only nil)
 +      comp ch)
  
 -    ;; Isolated gemination marks need special treatement
 +    ;; Special treatment for geminated characters.
 +    ;; Geminated characters la", etc. change into \geminateG{\laG}, etc.
      (goto-char (point-min))
 -    (while (search-forward "\e$(3%s\e(B" nil t)
 -      (replace-match "\\geminateG{}" t t))
 -
 -    ;; First, decompose geminations
 -    ;; Here we assume that each composed character consists of
 -    ;; one Ethiopic character and the Ethiopic gemination mark.
 -    (decompose-region (point-min) (point-max))
 +    (while (re-search-forward "áŸ\\|ö ‡Š" nil t)
 +      (setq comp (find-composition (match-beginning 0)))
 +      (if (null comp)
 +        (replace-match "\\\\geminateG{}" t)
 +      (decompose-region (car comp) (cadr comp))
 +      (delete-char -1)
 +      (forward-char -1)
 +      (insert "\\geminateG{")
 +      (forward-char 1)
 +      (insert "}")))
  
 -    ;; Special treatment for geminated characters
 -    ;; The geminated character (la'') will be "\geminateG{\la}".
 +    ;; Special Ethiopic punctuations.
      (goto-char (point-min))
 -    (while (search-forward "\e$(3%s\e(B" nil t)
 -      (delete-backward-char 1)
 -      (backward-char 1)
 -      (insert "\\geminateG")
 -      (forward-char 1))
 +    (while (re-search-forward "\\ce[»\\.\\?]\\|«\\ce" nil t)
 +      (cond
 +       ((= (setq ch (preceding-char)) ?\»)
 +      (delete-char -1)
 +      (insert "\\rquoteG"))
 +       ((= ch ?.)
 +      (delete-char -1)
 +      (insert "\\dotG"))
 +       ((= ch ??)
 +      (delete-char -1)
 +      (insert "\\qmarkG"))
 +       (t
 +      (forward-char -1)
 +      (delete-char -1)
 +      (insert "\\lquoteG")
 +      (forward-char 1))))
  
      ;; Ethiopic characters to TeX macros
 -    (goto-char (point-min))
 -    (while (re-search-forward "\\ce" nil t)
 -      (insert
 -       "{\\"
 -       (aref ethio-fidel-to-tex-map
 -           (prog1 (ethio-char-to-ethiocode (preceding-char))
 -             (backward-delete-char 1)))
 -       "}"))
 +    (robin-invert-region (point-min) (point-max) "ethiopic-tex")
 +
      (goto-char (point-min))
      (set-buffer-modified-p nil)))
  
    (let ((buffer-read-only nil)
        (p) (ch))
  
 -    ;; Special treatment for gemination
 -    ;; "\geminateG{\la}" or "\geminateG{{\la}}" will be "\la\e$(3%s\e(B"
 -    ;; "\geminateG{}" remains unchanged.
 -    (goto-char (point-min))
 -    (while (re-search-forward "\\\\geminateG{\\(\\\\[a-zA-Z]+\\)}" nil t)
 -      (replace-match "\\1\e$(3%s\e(B"))
 -
      ;; TeX macros to Ethiopic characters
 -    (goto-char (point-min))
 -    (while (search-forward "\\" nil t)
 -      (setq p (point))
 -      (skip-chars-forward "a-zA-Z")
 -      (setq ch
 -          (get (intern (concat "ethio-tex-command-"
 -                               (buffer-substring p (point))))
 -               'ethio-fidel-char))
 -      (if ch
 -        (progn
 -          (delete-region (1- p) (point)) ; don't forget the preceding "\"
 -          (if (and (= (preceding-char) ?{)
 -                   (= (following-char) ?}))
 -              (progn
 -                (backward-delete-char 1)
 -                (delete-char 1)))
 -          (insert ch))))
 +    (robin-convert-region (point-min) (point-max) "ethiopic-tex")
  
      ;; compose geminated characters
      (goto-char (point-min))
 -    (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
 -      (compose-region
 -       (save-excursion (backward-char 2) (point))
 -       (point)))
 +    (while (re-search-forward "\\\\geminateG{\\(\\ce?\\)}" nil t)
 +      (replace-match "\\1áŸ"))
  
 -    ;; Now it's time to convert isolated gemination marks.
 +    ;; remove redundant braces, if any
      (goto-char (point-min))
 -    (while (search-forward "\\geminateG{}" nil t)
 -      (replace-match "\e$(3%s\e(B"))
 +    (while (re-search-forward "{\\(\\ce\\)}" nil t)
 +      (replace-match "\\1"))
  
      (goto-char (point-min))
      (set-buffer-modified-p nil)))
@@@ -870,24 -1793,47 +870,24 @@@ If `ethio-java-save-lowercase' is non-n
  Otherwise, [0-9A-F]."
    (let ((ucode))
  
 -    ;; first, decompose geminations
 -    (decompose-region (point-min) (point-max))
 -
      (goto-char (point-min))
 -    (while (re-search-forward "\\ce" nil t)
 -      (setq ucode (+ ?\x1200 (ethio-char-to-ethiocode (preceding-char))))
 -      (if (> ucode ?\x13bc)
 -        (setq ucode (+ ucode 59952)))
 +    (while (re-search-forward "[ሀ-á¼]" nil t)
 +      (setq ucode (preceding-char))
        (delete-backward-char 1)
 -      (if ethio-java-save-lowercase
 -        (insert (format "\\u%4x" ucode))
 -      (insert (upcase (format "\\u%4x" ucode)))))))
 +      (insert
 +       (format (if ethio-java-save-lowercase "\\u%4x" "\\u%4X")
 +             ucode)))))
  
  ;;;###autoload
  (defun ethio-java-to-fidel-buffer nil
    "Convert the Java escape sequences into corresponding Ethiopic characters."
 -  (let ((ucode))
 -    (goto-char (point-min))
 -    (while (re-search-forward "\\\\u\\([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\\)" nil t)
 -      (setq ucode
 -          (read
 -           (concat
 -            "?\\x"
 -            (buffer-substring (match-beginning 1) (match-end 1)))))
 -      (cond
 -       ((and (>= ucode ?\x1200) (<= ucode ?\x13bc))
 -      (replace-match "")
 -      (insert (ethio-ethiocode-to-char (- ucode ?\x1200))))
 -       ((and (>= ucode ?\xfdf1) (<= ucode ?\xfdff))
 -      (replace-match "")
 -      (insert (ethio-ethiocode-to-char (- ucode 64560))))
 -       (t
 -      nil)))
 -
 -    ;; gemination
 +  (let ((case-fold-search t)
 +      (ucode))
      (goto-char (point-min))
 -    (while (re-search-forward "\\ce\e$(3%s\e(B" nil 0)
 -      (compose-region
 -       (save-excursion (backward-char 2) (point))
 -       (point)))
 -    ))
 +    (while (re-search-forward "\\\\u\\([0-9a-f][0-9a-f][0-9a-f][0-9a-f]\\)" nil t)
 +      (setq ucode (read (concat "#x" (match-string 1))))
 +      (when (and (>= ucode #x1200) (<= ucode #x137f))
 +      (replace-match (char-to-string ucode))))))
  
  ;;
  ;; file I/O hooks
  
  ;;;###autoload
  (defun ethio-find-file nil
 -  "Transcribe file content into Ethiopic depending on filename suffix."
 +  "Transliterate file content into Ethiopic dependig on filename suffix."
    (cond
  
     ((string-match "\\.sera$" (buffer-file-name))
        (save-excursion
        (ethio-sera-to-fidel-marker 'force)
        (goto-char (point-min))
 -      (while (re-search-forward "&[lr]aquote;" nil t)
 +      (while (re-search-forward "&[lr]aquo;" nil t)
          (if (= (char-after (1+ (match-beginning 0))) ?l)
 -            (replace-match "\e$(3%v\e(B")
 -          (replace-match "\e$(3%w\e(B")))
 +            (replace-match "«")
 +          (replace-match "»")))
        (set-buffer-modified-p nil))))
  
     ((string-match "\\.tex$" (buffer-file-name))
  
  ;;;###autoload
  (defun ethio-write-file nil
 -  "Transcribe Ethiopic characters in ASCII depending on the file extension."
 +  "Transliterate Ethiopic characters in ASCII depending on the file extension."
    (cond
  
     ((string-match "\\.sera$" (buffer-file-name))
  
     ((string-match "\\.html$" (buffer-file-name))
      (save-excursion
 -      (let ((ethio-sera-being-called-by-w3 t)
 -          (lq (aref ethio-fidel-to-sera-map 461))
 -          (rq (aref ethio-fidel-to-sera-map 462)))
 -      (aset ethio-fidel-to-sera-map 461 "&laquote;")
 -      (aset ethio-fidel-to-sera-map 462 "&raquote;")
 +      (let ((ethio-sera-being-called-by-w3 t))
        (ethio-fidel-to-sera-marker 'force)
        (goto-char (point-min))
 +      (while (re-search-forward "[«»]" nil t)
 +        (replace-match (if (= (preceding-char) ?«) "&laquo;" "&raquo;")))
 +      (goto-char (point-min))
        (if (search-forward "<sera>" nil t)
            (ethio-record-user-preference))
 -      (aset ethio-fidel-to-sera-map 461 lq)
 -      (aset ethio-fidel-to-sera-map 462 rq)
        (set-buffer-modified-p nil))))
  
     ((string-match "\\.tex$" (buffer-file-name))
      nil)))
  
  (defun ethio-record-user-preference nil
 -  (if (looking-at "\\\\~\\(tir?\\|amh?\\) ")
 -      (goto-char (match-end 0))
 -    (insert (if (ethio-prefer-amharic-p) "\\~amh " "\\~tir ")))
    (insert (if ethio-use-colon-for-colon "\\~-: " "\\~`: ")
 -        (if ethio-use-three-dot-question "\\~`| " "\\~`? ")))
 +        (if ethio-use-three-dot-question "\\~`| " "\\~? ")))
  
  ;;
  ;; Ethiopic word separator vs. ASCII space
    "Toggle ASCII space and Ethiopic separator for keyboard input."
    (interactive)
    (setq ethio-prefer-ascii-space
 -      (not ethio-prefer-ascii-space))
 -  (if (equal current-input-method "ethiopic")
 -      (setq current-input-method-title (quail-title)))
 -  (force-mode-line-update))
 +      (not ethio-prefer-ascii-space)))
  
  (defun ethio-insert-space (arg)
    "Insert ASCII spaces or Ethiopic word separators depending on context.
@@@ -1002,1080 -1957,68 +1002,1080 @@@ many Ethiopic word separators.
     ((save-excursion
        (skip-chars-backward " ")
        (memq (preceding-char)
 -          '(?\e$(3$h\e(B ?\e$(3$i\e(B ?\e$(3$j\e(B ?\e$(3$k\e(B ?\e$(3$l\e(B ?\e$(3$m\e(B ?\e$(3$n\e(B ?\e$(3$o\e(B ?\e$(3%t\e(B ?\e$(3%u\e(B ?\e$(3%v\e(B ?\e$(3%w\e(B ?\e$(3%x\e(B)))
 +          '(?á¡ ?ᢠ?ᣠ?ᤠ?ᥠ?ᦠ?᧠?ᨠ?ö ‡‹ ?ö ‡Œ ?ö ‡ ?ö ‡Ž ?ö ‡)))
      (insert-char 32 arg))
     (t
 -    (insert-char ?\e$(3$h\e(B arg))))
 +    (insert-char ?á¡ arg))))
  
 +;;;###autoload
  (defun ethio-insert-ethio-space (arg)
    "Insert the Ethiopic word delimiter (the colon-like character).
  With ARG, insert that many delimiters."
    (interactive "*p")
 -  (insert-char ?\e$(3$h\e(B arg))
 -
 -;;
 -;; Ethiopic punctuation vs. ASCII punctuation
 -;;
 -
 -(defvar ethio-prefer-ascii-punctuation nil)
 -(make-variable-buffer-local 'ethio-prefer-ascii-punctuation)
 -
 -(defun ethio-toggle-punctuation nil
 -  "Toggle Ethiopic punctuations and ASCII punctuations for keyboard input."
 -  (interactive)
 -  (setq ethio-prefer-ascii-punctuation
 -      (not ethio-prefer-ascii-punctuation))
 -  (let* ((keys '("." ".." "..." "," ",," ";" ";;" ":" "::" ":::" "*" "**"))
 -       (puncs
 -        (if ethio-prefer-ascii-punctuation
 -            '(?. [".."] ["..."] ?, [",,"] ?\; [";;"] ?: ["::"] [":::"] ?* ["**"])
 -          '(?\e$(3$i\e(B ?\e$(3%u\e(B ?. ?\e$(3$j\e(B ?, ?\e$(3$k\e(B ?\; ?\e$(3$h\e(B ?\e$(3$i\e(B ?: ?* ?\e$(3$o\e(B))))
 -    (while keys
 -      (quail-defrule (car keys) (car puncs) "ethiopic")
 -      (setq keys (cdr keys)
 -          puncs (cdr puncs)))
 -    (if (equal current-input-method "ethiopic")
 -      (setq current-input-method-title (quail-title)))
 -    (force-mode-line-update)))
 +  (insert-char ?á¡ arg))
  
  ;;
  ;; Gemination
  ;;
  
 +;;;###autoload
 +(defun ethio-composition-function (pos &optional string)
 +  (setq pos (1- pos))
 +  (let ((pattern "\\ce\\(áŸ\\|ö ‡Š\\)"))
 +    (if string
 +      (if (and (>= pos 0)
 +               (eq (string-match pattern string pos) pos))
 +          (prog1 (match-end 0)
 +            (compose-string string pos (match-end 0))))
 +      (if (>= pos (point-min))
 +        (progn
 +          (goto-char pos)
 +          (if (looking-at pattern)
 +              (prog1 (match-end 0)
 +                (compose-region pos (match-end 0)))))))))
 +
 +;; This function is not used any more.
  (defun ethio-gemination nil
    "Compose the character before the point with the Ethiopic gemination mark.
  If the character is already composed, decompose it and remove the gemination
  mark."
    (interactive "*")
 -  (cond
 -   ((eq (char-charset (preceding-char)) 'ethiopic)
 -    (insert "\e$(3%s\e(B")
 -    (compose-region
 -     (save-excursion (backward-char 2) (point))
 -     (point))
 -    (forward-char 1))
 -   ((eq (char-charset (preceding-char)) 'leading-code-composition)
 -    (decompose-region
 -     (save-excursion (backward-char 1) (point))
 -     (point))
 -    (delete-backward-char 1))
 -   (t
 -    (error ""))))
 +  (let ((ch (preceding-char)))
 +    (cond
 +     ((and (= ch ?ö ‡Š) (find-composition (1- (point))))
 +      (decompose-region (- (point) 2) (point)))
 +     ((and (>= ch #x1200) (<= ch #x137f))
 +      (insert "ö ‡Š")
 +      (compose-region (- (point) 2) (point)))
 +     (t
 +      (error "")))))
 +
 +;;;
 +;;; Robin packages
 +;;;
 +
 +(robin-define-package "ethiopic-sera"
 + "SERA transliteration system for Ethiopic."
 +
 + ("he" ?ሀ)
 + ("hu" ?áˆ)
 + ("hi" ?ሂ)
 + ("ha" ?ሃ)
 + ("hE" ?ሄ) ("hee" "ሄ")
 + ("h" ?ህ)
 + ("ho" ?ሆ)
 +
 + ("le" ?ለ) ("Le" "ለ")
 + ("lu" ?ሉ) ("Lu" "ሉ")
 + ("li" ?ሊ) ("Li" "ሊ")
 + ("la" ?ላ) ("La" "ላ")
 + ("lE" ?ሌ) ("LE" "ሌ") ("lee" "ሌ") ("Lee" "ሌ")
 + ("l" ?áˆ) ("L" "áˆ")
 + ("lo" ?ሎ) ("Lo" "ሎ")
 + ("lWa" ?áˆ) ("LWa" "áˆ") ("lW" "áˆ") ("LW" "áˆ")
 +
 + ("He" ?áˆ)
 + ("Hu" ?ሑ)
 + ("Hi" ?ሒ)
 + ("Ha" ?ሓ)
 + ("HE" ?ሔ) ("Hee" "ሔ")
 + ("H" ?ሕ)
 + ("Ho" ?ሖ)
 + ("HWa" ?ሗ) ("HW" "ሗ")
 +
 + ("me" ?መ) ("Me" "መ")
 + ("mu" ?ሙ) ("Mu" "ሙ")
 + ("mi" ?ሚ) ("Mi" "ሚ")
 + ("ma" ?ማ) ("Ma" "ማ")
 + ("mE" ?ሜ) ("ME" "ሜ") ("mee" "ሜ") ("Mee" "ሜ")
 + ("m" ?áˆ) ("M" "áˆ")
 + ("mo" ?ሞ) ("Mo" "ሞ")
 + ("mWa" ?ሟ) ("MWa" "ሟ") ("mW" "ሟ") ("MW" "ሟ")
 +
 + ("`se" ?ሠ) ("sse" "ሠ") ("s2e" "ሠ")
 + ("`su" ?ሡ) ("ssu" "ሡ") ("s2u" "ሡ")
 + ("`si" ?ሢ) ("ssi" "ሢ") ("s2i" "ሢ")
 + ("`sa" ?ሣ) ("ssa" "ሣ") ("s2a" "ሣ")
 + ("`sE" ?ሤ) ("ssE" "ሤ") ("s2E" "ሤ")
 +   ("`see" "ሤ") ("ssee" "ሤ") ("s2ee" "ሤ")
 + ("`s" ?ሥ) ("ss" "ሥ") ("s2" "ሥ")
 + ("`so" ?ሦ) ("sso" "ሦ") ("s2o" "ሦ")
 + ("`sWa" ?ሧ) ("ssWa" "ሧ") ("s2Wa" "ሧ")
 +   ("`sW" "ሧ") ("ssW" "ሧ") ("s2W" "ሧ")
 +
 + ("re" ?ረ) ("Re" "ረ")
 + ("ru" ?ሩ) ("Ru" "ሩ")
 + ("ri" ?ሪ) ("Ri" "ሪ")
 + ("ra" ?ራ) ("Ra" "ራ")
 + ("rE" ?ሬ) ("RE" "ሬ") ("ree" "ሬ") ("Ree" "ሬ")
 + ("r" ?ር) ("R" "ር")
 + ("ro" ?ሮ) ("Ro" "ሮ")
 + ("rWa" ?ሯ) ("RWa" "ሯ") ("rW" "ሯ") ("RW" "ሯ")
 +
 + ("se" ?ሰ)
 + ("su" ?ሱ)
 + ("si" ?ሲ)
 + ("sa" ?ሳ)
 + ("sE" ?ሴ) ("see" "ሴ")
 + ("s" ?ስ)
 + ("so" ?ሶ)
 + ("sWa" ?ሷ) ("sW" "ሷ")
 +
 + ("xe" ?ሸ)
 + ("xu" ?ሹ)
 + ("xi" ?ሺ)
 + ("xa" ?ሻ)
 + ("xE" ?ሼ) ("xee" "ሼ")
 + ("x" ?ሽ)
 + ("xo" ?ሾ)
 + ("xWa" ?ሿ) ("xW" "ሿ")
 +
 + ("qe" ?ቀ)
 + ("qu" ?á‰)
 + ("qi" ?ቂ)
 + ("qa" ?ቃ)
 + ("qE" ?ቄ) ("qee" "ቄ")
 + ("q" ?ቅ)
 + ("qo" ?ቆ)
 + ("qWe" ?ቈ)
 + ("qWi" ?ቊ)
 + ("qWa" ?ቋ) ("qW" "ቋ")
 + ("qWE" ?ቌ) ("qWee" "ቌ")
 + ("qW'" ?á‰) ("qWu" "á‰")
 +
 + ("Qe" ?á‰)
 + ("Qu" ?ቑ)
 + ("Qi" ?ቒ)
 + ("Qa" ?ቓ)
 + ("QE" ?ቔ) ("Qee" "ቔ")
 + ("Q" ?ቕ)
 + ("Qo" ?ቖ)
 + ("QWe" ?ቘ)
 + ("QWi" ?ቚ)
 + ("QWa" ?ቛ) ("QW" "ቛ")
 + ("QWE" ?ቜ) ("QWee" "ቜ")
 + ("QW'" ?á‰) ("QWu" "á‰")
 +
 + ("be" ?በ) ("Be" "በ")
 + ("bu" ?ቡ) ("Bu" "ቡ")
 + ("bi" ?ቢ) ("Bi" "ቢ")
 + ("ba" ?ባ) ("Ba" "ባ")
 + ("bE" ?ቤ) ("BE" "ቤ") ("bee" "ቤ") ("Bee" "ቤ")
 + ("b" ?ብ) ("B" "ብ")
 + ("bo" ?ቦ) ("Bo" "ቦ")
 + ("bWa" ?ቧ) ("BWa" "ቧ") ("bW" "ቧ") ("BW" "ቧ")
 +
 + ("ve" ?ቨ) ("Ve" "ቨ")
 + ("vu" ?ቩ) ("Vu" "ቩ")
 + ("vi" ?ቪ) ("Vi" "ቪ")
 + ("va" ?ቫ) ("Va" "ቫ")
 + ("vE" ?ቬ) ("VE" "ቬ") ("vee" "ቬ") ("Vee" "ቬ")
 + ("v" ?ቭ) ("V" "ቭ")
 + ("vo" ?ቮ) ("Vo" "ቮ")
 + ("vWa" ?ቯ) ("VWa" "ቯ") ("vW" "ቯ") ("VW" "ቯ")
 +
 + ("te" ?ተ)
 + ("tu" ?ቱ)
 + ("ti" ?ቲ)
 + ("ta" ?ታ)
 + ("tE" ?ቴ) ("tee" "ቴ")
 + ("t" ?ት)
 + ("to" ?ቶ)
 + ("tWa" ?ቷ) ("tW" "ቷ")
 +
 + ("ce" ?ቸ)
 + ("cu" ?ቹ)
 + ("ci" ?ቺ)
 + ("ca" ?ቻ)
 + ("cE" ?ቼ) ("cee" "ቼ")
 + ("c" ?ች)
 + ("co" ?ቾ)
 + ("cWa" ?ቿ) ("cW" "ቿ")
 +
 + ("`he" ?ኀ) ("hhe" "ኀ") ("h2e" "ኀ")
 + ("`hu" ?áŠ) ("hhu" "áŠ") ("h2u" "áŠ")
 + ("`hi" ?ኂ) ("hhi" "ኂ") ("h2i" "ኂ")
 + ("`ha" ?ኃ) ("hha" "ኃ") ("h2a" "ኃ")
 + ("`hE" ?ኄ) ("hhE" "ኄ") ("h2E" "ኄ")
 +   ("`hee" "ኄ") ("hhee" "ኄ") ("h2ee" "ኄ")
 + ("`h" ?ኅ) ("hh" "ኅ") ("h2" "ኅ")
 + ("`ho" ?ኆ) ("hho" "ኆ") ("h2o" "ኆ")
 + ("`hWe" ?ኈ) ("hhWe" "ኈ") ("h2We" "ኈ") ("hWe" "ኈ")
 + ("`hWi" ?ኊ) ("hhWi" "ኊ") ("h2Wi" "ኊ") ("hWi" "ኊ")
 + ("`hWa" ?ኋ) ("hhWa" "ኋ") ("h2Wa" "ኋ") ("hWa" "ኋ")
 +   ("`hW" "ኋ") ("hhW" "ኋ") ("h2W" "ኋ")
 + ("`hWE" ?ኌ) ("hhWE" "ኌ") ("h2WE" "ኌ") ("hWE" "ኌ")
 +   ("`hWee" "ኌ") ("hhWee" "ኌ") ("h2Wee" "ኌ") ("hWee" "ኌ")
 + ("`hW'" ?áŠ) ("hhW'" "áŠ") ("h2W'" "áŠ") ("hW'" "áŠ")
 +   ("`hWu" "áŠ") ("hhWu" "áŠ") ("h2Wu" "áŠ") ("hWu" "áŠ")
 +
 + ("ne" ?áŠ)
 + ("nu" ?ኑ)
 + ("ni" ?ኒ)
 + ("na" ?ና)
 + ("nE" ?ኔ) ("nee" "ኔ")
 + ("n" ?ን)
 + ("no" ?ኖ)
 + ("nWa" ?ኗ) ("nW" "ኗ")
 +
 + ("Ne" ?ኘ)
 + ("Nu" ?ኙ)
 + ("Ni" ?ኚ)
 + ("Na" ?ኛ)
 + ("NE" ?ኜ) ("Nee" "ኜ")
 + ("N" ?áŠ)
 + ("No" ?ኞ)
 + ("NWa" ?ኟ) ("NW" "ኟ")
 +
 + ("'A" ?አ) ("A" "አ")
 + ("'u" ?ኡ) ("u" "ኡ") ("'U" "ኡ") ("U" "ኡ")
 + ("'i" ?ኢ) ("i" "ኢ")
 + ("'a" ?ኣ) ("a" "ኣ")
 + ("'E" ?ኤ) ("E" "ኤ")
 + ("'I" ?እ) ("I" "እ") ("'e" "እ") ("e" "እ")
 + ("'o" ?ኦ) ("o" "ኦ") ("'O" "ኦ") ("O" "ኦ")
 + ("'ea" ?ኧ) ("ea" "ኧ")
 +
 + ("ke" ?ከ)
 + ("ku" ?ኩ)
 + ("ki" ?ኪ)
 + ("ka" ?ካ)
 + ("kE" ?ኬ) ("kee" "ኬ")
 + ("k" ?ክ)
 + ("ko" ?ኮ)
 + ("kWe" ?ኰ)
 + ("kWi" ?ኲ)
 + ("kWa" ?ኳ) ("kW" "ኳ")
 + ("kWE" ?ኴ) ("kWee" "ኴ")
 + ("kW'" ?ኵ) ("kWu" "ኵ")
 +
 + ("Ke" ?ኸ)
 + ("Ku" ?ኹ)
 + ("Ki" ?ኺ)
 + ("Ka" ?ኻ)
 + ("KE" ?ኼ) ("Kee" "ኼ")
 + ("K" ?ኽ)
 + ("Ko" ?ኾ)
 + ("KWe" ?á‹€)
 + ("KWi" ?á‹‚)
 + ("KWa" ?ዃ) ("KW" "ዃ")
 + ("KWE" ?á‹„) ("KWee" "á‹„")
 + ("KW'" ?á‹…) ("KWu" "á‹…")
 +
 + ("we" ?ወ)
 + ("wu" ?ዉ)
 + ("wi" ?á‹Š)
 + ("wa" ?á‹‹)
 + ("wE" ?á‹Œ) ("wee" "á‹Œ")
 + ("w" ?á‹)
 + ("wo" ?á‹Ž)
 +
 + ("`e" ?á‹) ("ae" "á‹") ("aaa" "á‹") ("e2" "á‹")
 + ("`u" ?á‹‘) ("uu" "á‹‘") ("u2" "á‹‘") ("`U" "á‹‘") ("UU" "á‹‘") ("U2" "á‹‘")
 + ("`i" ?á‹’) ("ii" "á‹’") ("i2" "á‹’")
 + ("`a" ?á‹“) ("aa" "á‹“") ("a2" "á‹“") ("`A" "á‹“") ("AA" "á‹“") ("A2" "á‹“")
 + ("`E" ?á‹”) ("EE" "á‹”") ("E2" "á‹”")
 + ("`I" ?á‹•) ("II" "á‹•") ("I2" "á‹•") ("ee" "á‹•")
 + ("`o" ?á‹–) ("oo" "á‹–") ("o2" "á‹–") ("`O" "á‹–") ("OO" "á‹–") ("O2" "á‹–")
 +
 + ("ze" ?ዘ)
 + ("zu" ?á‹™)
 + ("zi" ?á‹š)
 + ("za" ?á‹›)
 + ("zE" ?á‹œ) ("zee" "á‹œ")
 + ("z" ?á‹)
 + ("zo" ?á‹ž)
 + ("zWa" ?á‹Ÿ) ("zW" "á‹Ÿ")
 +
 + ("Ze" ?á‹ )
 + ("Zu" ?á‹¡)
 + ("Zi" ?á‹¢)
 + ("Za" ?á‹£)
 + ("ZE" ?ዤ) ("Zee" "ዤ")
 + ("Z" ?á‹¥)
 + ("Zo" ?ዦ)
 + ("ZWa" ?ዧ) ("ZW" "ዧ")
 +
 + ("ye" ?የ) ("Ye" "የ")
 + ("yu" ?á‹©) ("Yu" "á‹©")
 + ("yi" ?ዪ) ("Yi" "ዪ")
 + ("ya" ?á‹«) ("Ya" "á‹«")
 + ("yE" ?ዬ) ("YE" "ዬ") ("yee" "ዬ") ("Yee" "ዬ")
 + ("y" ?á‹­) ("Y" "á‹­")
 + ("yo" ?á‹®) ("Yo" "á‹®")
 +
 + ("de" ?á‹°)
 + ("du" ?ዱ)
 + ("di" ?ዲ)
 + ("da" ?ዳ)
 + ("dE" ?á‹´) ("dee" "á‹´")
 + ("d" ?ድ)
 + ("do" ?ዶ)
 + ("dWa" ?á‹·) ("dW" "á‹·")
 +
 + ("De" ?ዸ)
 + ("Du" ?ዹ)
 + ("Di" ?ዺ)
 + ("Da" ?á‹»)
 + ("DE" ?ዼ) ("Dee" "ዼ")
 + ("D" ?ዽ)
 + ("Do" ?ዾ)
 + ("DWa" ?á‹¿) ("DW" "á‹¿")
 +
 + ("je" ?ጀ) ("Je" "ጀ")
 + ("ju" ?áŒ) ("Ju" "áŒ")
 + ("ji" ?ጂ) ("Ji" "ጂ")
 + ("ja" ?ጃ) ("Ja" "ጃ")
 + ("jE" ?ጄ) ("JE" "ጄ") ("jee" "ጄ") ("Jee" "ጄ")
 + ("j" ?ጅ) ("J" "ጅ")
 + ("jo" ?ጆ) ("Jo" "ጆ")
 + ("jWa" ?ጇ) ("jW" "ጇ") ("JWa" "ጇ") ("JW" "ጇ")
 +
 + ("ge" ?ገ)
 + ("gu" ?ጉ)
 + ("gi" ?ጊ)
 + ("ga" ?ጋ)
 + ("gE" ?ጌ) ("gee" "ጌ")
 + ("g" ?áŒ)
 + ("go" ?ጎ)
 + ("gWe" ?áŒ)
 + ("gWi" ?ጒ)
 + ("gWa" ?ጓ) ("gW" "ጓ")
 + ("gWE" ?ጔ) ("gWee" "ጔ")
 + ("gW'" ?ጕ) ("gWu" "ጕ")
 +
 + ("Ge" ?ጘ)
 + ("Gu" ?ጙ)
 + ("Gi" ?ጚ)
 + ("Ga" ?ጛ)
 + ("GE" ?ጜ) ("Gee" "ጜ")
 + ("G" ?áŒ)
 + ("Go" ?ጞ)
 +
 + ("Te" ?ጠ)
 + ("Tu" ?ጡ)
 + ("Ti" ?ጢ)
 + ("Ta" ?ጣ)
 + ("TE" ?ጤ) ("Tee" "ጤ")
 + ("T" ?ጥ)
 + ("To" ?ጦ)
 + ("TWa" ?ጧ) ("TW" "ጧ")
 +
 + ("Ce" ?ጨ)
 + ("Cu" ?ጩ)
 + ("Ci" ?ጪ)
 + ("Ca" ?ጫ)
 + ("CE" ?ጬ) ("Cee" "ጬ")
 + ("C" ?ጭ)
 + ("Co" ?ጮ)
 + ("CWa" ?ጯ) ("CW" "ጯ")
 +
 + ("Pe" ?ጰ)
 + ("Pu" ?ጱ)
 + ("Pi" ?ጲ)
 + ("Pa" ?ጳ)
 + ("PE" ?ጴ) ("Pee" "ጴ")
 + ("P" ?ጵ)
 + ("Po" ?ጶ)
 + ("PWa" ?ጷ) ("PW" "ጷ")
 +
 + ("Se" ?ጸ)
 + ("Su" ?ጹ)
 + ("Si" ?ጺ)
 + ("Sa" ?ጻ)
 + ("SE" ?ጼ) ("See" "ጼ")
 + ("S" ?ጽ)
 + ("So" ?ጾ)
 + ("SWa" ?ጿ) ("`SWa" "ጿ") ("SSWa" "ጿ") ("S2Wa" "ጿ")
 +   ("SW" "ጿ") ("`SW" "ጿ") ("SSW" "ጿ") ("S2W" "ጿ")
 +
 + ("`Se" ?á€) ("SSe" "á€") ("S2e" "á€")
 + ("`Su" ?á) ("SSu" "á") ("S2u" "á")
 + ("`Si" ?á‚) ("SSi" "á‚") ("S2i" "á‚")
 + ("`Sa" ?áƒ) ("SSa" "áƒ") ("S2a" "áƒ")
 + ("`SE" ?á„) ("SSE" "á„") ("S2E" "á„")
 +   ("`See" "á„") ("SSee" "á„") ("S2ee" "á„")
 + ("`S" ?á…) ("SS" "á…") ("S2" "á…")
 + ("`So" ?á†) ("SSo" "á†") ("S2o" "á†")
 +
 + ("fe" ?áˆ) ("Fe" "áˆ")
 + ("fu" ?á‰) ("Fu" "á‰")
 + ("fi" ?áŠ) ("Fi" "áŠ")
 + ("fa" ?á‹) ("Fa" "á‹")
 + ("fE" ?áŒ) ("FE" "áŒ") ("fee" "áŒ") ("Fee" "áŒ")
 + ("f" ?á) ("F" "á")
 + ("fo" ?áŽ) ("Fo" "áŽ")
 + ("fWa" ?á) ("FWa" "á") ("fW" "á") ("FW" "á")
 +
 + ("pe" ?á)
 + ("pu" ?á‘)
 + ("pi" ?á’)
 + ("pa" ?á“)
 + ("pE" ?á”) ("pee" "á”")
 + ("p" ?á•)
 + ("po" ?á–)
 + ("pWa" ?á—) ("pW" "á—")
 +
 + ("rYa" ?á˜) ("RYa" "á˜") ("rY" "á˜") ("RY" "á˜")
 + ("mYa" ?á™) ("MYa" "á™") ("mY" "á™") ("MY" "á™")
 + ("fYa" ?áš) ("FYa" "áš") ("fY" "áš") ("FY" "áš")
 +
 + (" : " ?á¡) (":" "á¡") ("`:" "á¡")
 + ("::" ?á¢) ("." "á¢")
 + ("," ?á£)
 + (";" ?á¤)
 + ("-:" ?á¥)
 + (":-" ?á¦)
 + ("`?" ?á§) ("??" "á§")
 + (":|:" ?á¨) ("**" "á¨")
 +
 + ;; Explicit syllable delimiter
 + ("'" "")
 +
 + ;; Quick ASCII input
 + ("''" "'")
 + (":::" ":")
 + (".." ".")
 + (",," ",")
 + (";;" ";")
 +
 + ("`1" ?á©)
 + ("`2" ?áª)
 + ("`3" ?á«)
 + ("`4" ?á¬)
 + ("`5" ?á­)
 + ("`6" ?á®)
 + ("`7" ?á¯)
 + ("`8" ?á°)
 + ("`9" ?á±)
 + ("`10" ?á²)
 + ("`20" ?á³)
 + ("`30" ?á´)
 + ("`40" ?áµ)
 + ("`50" ?á¶)
 + ("`60" ?á·)
 + ("`70" ?á¸)
 + ("`80" ?á¹)
 + ("`90" ?áº)
 + ("`100" ?á»)
 + ("`10000" ?á¼)
 +
 + ("`200" "áªá»")
 + ("`300" "á«á»")
 + ("`400" "á¬á»")
 + ("`500" "á­á»")
 + ("`600" "á®á»")
 + ("`700" "á¯á»")
 + ("`800" "á°á»")
 + ("`900" "á±á»")
 + ("`1000" "á²á»")
 + ("`2000" "á³á»")
 + ("`3000" "á´á»")
 + ("`4000" "áµá»")
 + ("`5000" "á¶á»")
 + ("`6000" "á·á»")
 + ("`7000" "á¸á»")
 + ("`8000" "á¹á»")
 + ("`9000" "áºá»")
 + ("`20000" "áªá¼")
 + ("`30000" "á«á¼")
 + ("`40000" "á¬á¼")
 + ("`50000" "á­á¼")
 + ("`60000" "á®á¼")
 + ("`70000" "á¯á¼")
 + ("`80000" "á°á¼")
 + ("`90000" "á±á¼")
 + ("`100000" "á²á¼")
 + ("`200000" "á³á¼")
 + ("`300000" "á´á¼")
 + ("`400000" "áµá¼")
 + ("`500000" "á¶á¼")
 + ("`600000" "á·á¼")
 + ("`700000" "á¸á¼")
 + ("`800000" "á¹á¼")
 + ("`900000" "áºá¼")
 + ("`1000000" "á»á¼")
 + )
 +
 +(register-input-method
 + "ethiopic-sera" "Ethiopic"
 + 'robin-use-package "et" "An input method for Ethiopic.")
 +
 +(robin-define-package "ethiopic-tex"
 + "TeX transliteration system for Ethiopic."
 +
 + ("\\heG" ?ሀ)                               ; U+1200 ..
 + ("\\huG" ?áˆ)
 + ("\\hiG" ?ሂ)
 + ("\\haG" ?ሃ)
 + ("\\hEG" ?ሄ)
 + ("\\hG" ?ህ)
 + ("\\hoG" ?ሆ)
 + ;; reserved
 + ("\\leG" ?ለ)
 + ("\\luG" ?ሉ)
 + ("\\liG" ?ሊ)
 + ("\\laG" ?ላ)
 + ("\\lEG" ?ሌ)
 + ("\\lG" ?áˆ)
 + ("\\loG" ?ሎ)
 + ("\\lWaG" ?áˆ)
 +
 + ("\\HeG" ?áˆ)                               ; U+1210 ..
 + ("\\HuG" ?ሑ)
 + ("\\HiG" ?ሒ)
 + ("\\HaG" ?ሓ)
 + ("\\HEG" ?ሔ)
 + ("\\HG" ?ሕ)
 + ("\\HoG" ?ሖ)
 + ("\\HWaG" ?ሗ)
 + ("\\meG" ?መ)
 + ("\\muG" ?ሙ)
 + ("\\miG" ?ሚ)
 + ("\\maG" ?ማ)
 + ("\\mEG" ?ሜ)
 + ("\\mG" ?áˆ)
 + ("\\moG" ?ሞ)
 + ("\\mWaG" ?ሟ)
 +
 + ("\\sseG" ?ሠ)                              ; U+1220 ..
 + ("\\ssuG" ?ሡ)
 + ("\\ssiG" ?ሢ)
 + ("\\ssaG" ?ሣ)
 + ("\\ssEG" ?ሤ)
 + ("\\ssG" ?ሥ)
 + ("\\ssoG" ?ሦ)
 + ("\\ssWaG" ?ሧ)
 + ("\\reG" ?ረ)
 + ("\\ruG" ?ሩ)
 + ("\\riG" ?ሪ)
 + ("\\raG" ?ራ)
 + ("\\rEG" ?ሬ)
 + ("\\rG" ?ር)
 + ("\\roG" ?ሮ)
 + ("\\rWaG" ?ሯ)
 +
 + ("\\seG" ?ሰ)                               ; U+1230 ..
 + ("\\suG" ?ሱ)
 + ("\\siG" ?ሲ)
 + ("\\saG" ?ሳ)
 + ("\\sEG" ?ሴ)
 + ("\\sG" ?ስ)
 + ("\\soG" ?ሶ)
 + ("\\sWaG" ?ሷ)
 + ("\\xeG" ?ሸ)
 + ("\\xuG" ?ሹ)
 + ("\\xiG" ?ሺ)
 + ("\\xaG" ?ሻ)
 + ("\\xEG" ?ሼ)
 + ("\\xG" ?ሽ)
 + ("\\xoG" ?ሾ)
 + ("\\xWaG" ?ሿ)
 +
 + ("\\qeG" ?ቀ)                               ; U+1240 ..
 + ("\\quG" ?á‰)
 + ("\\qiG" ?ቂ)
 + ("\\qaG" ?ቃ)
 + ("\\qEG" ?ቄ)
 + ("\\qG" ?ቅ)
 + ("\\qoG" ?ቆ)
 + ;; reserved
 + ("\\qWeG" ?ቈ)
 + ;; reserved
 + ("\\qWiG" ?ቊ)
 + ("\\qWaG" ?ቋ)
 + ("\\qWEG" ?ቌ)
 + ("\\qWG" ?á‰)
 + ;; reserved
 + ;; reserved
 +
 + ("\\QeG" ?á‰)                               ; U+1250 ..
 + ("\\QuG" ?ቑ)
 + ("\\QiG" ?ቒ)
 + ("\\QaG" ?ቓ)
 + ("\\QEG" ?ቔ)
 + ("\\QG" ?ቕ)
 + ("\\QoG" ?ቖ)
 + ;; reserved
 + ("\\QWeG" ?ቘ)
 + ;; reserved
 + ("\\QWiG" ?ቚ)
 + ("\\QWaG" ?ቛ)
 + ("\\QWEG" ?ቜ)
 + ("\\QWG" ?á‰)
 + ;; reserved
 + ;; reserved
 +
 + ("\\beG" ?በ)                               ; U+1260 ..
 + ("\\buG" ?ቡ)
 + ("\\biG" ?ቢ)
 + ("\\baG" ?ባ)
 + ("\\bEG" ?ቤ)
 + ("\\bG" ?ብ)
 + ("\\boG" ?ቦ)
 + ("\\bWaG" ?ቧ)
 + ("\\veG" ?ቨ)
 + ("\\vuG" ?ቩ)
 + ("\\viG" ?ቪ)
 + ("\\vaG" ?ቫ)
 + ("\\vEG" ?ቬ)
 + ("\\vG" ?ቭ)
 + ("\\voG" ?ቮ)
 + ("\\vWaG" ?ቯ)
 +
 + ("\\teG" ?ተ)                               ; U+1270 ..
 + ("\\tuG" ?ቱ)
 + ("\\tiG" ?ቲ)
 + ("\\taG" ?ታ)
 + ("\\tEG" ?ቴ)
 + ("\\tG" ?ት)
 + ("\\toG" ?ቶ)
 + ("\\tWaG" ?ቷ)
 + ("\\ceG" ?ቸ)
 + ("\\cuG" ?ቹ)
 + ("\\ciG" ?ቺ)
 + ("\\caG" ?ቻ)
 + ("\\cEG" ?ቼ)
 + ("\\cG" ?ች)
 + ("\\coG" ?ቾ)
 + ("\\cWaG" ?ቿ)
 +
 + ("\\hheG" ?ኀ)                              ; U+1280 ..
 + ("\\hhuG" ?áŠ)
 + ("\\hhiG" ?ኂ)
 + ("\\hhaG" ?ኃ)
 + ("\\hhEG" ?ኄ)
 + ("\\hhG" ?ኅ)
 + ("\\hhoG" ?ኆ)
 + ;; reserved
 + ("\\hWeG" ?ኈ)
 + ;; reserved
 + ("\\hWiG" ?ኊ)
 + ("\\hWaG" ?ኋ)
 + ("\\hWEG" ?ኌ)
 + ("\\hWG" ?áŠ)
 + ;; reserved
 + ;; reserved
 +
 + ("\\neG" ?áŠ)                               ; U+1290 ..
 + ("\\nuG" ?ኑ)
 + ("\\niG" ?ኒ)
 + ("\\naG" ?ና)
 + ("\\nEG" ?ኔ)
 + ("\\nG" ?ን)
 + ("\\noG" ?ኖ)
 + ("\\nWaG" ?ኗ)
 + ("\\NeG" ?ኘ)
 + ("\\NuG" ?ኙ)
 + ("\\NiG" ?ኚ)
 + ("\\NaG" ?ኛ)
 + ("\\NEG" ?ኜ)
 + ("\\NG" ?áŠ)
 + ("\\NoG" ?ኞ)
 + ("\\NWaG" ?ኟ)
 +
 + ("\\eG" ?አ)                                ; U+12A0 ..
 + ("\\uG" ?ኡ)
 + ("\\iG" ?ኢ)
 + ("\\AG" ?ኣ)
 + ("\\EG" ?ኤ)
 + ("\\IG" ?እ)
 + ("\\oG" ?ኦ)
 + ("\\eaG" ?ኧ)
 + ("\\keG" ?ከ)
 + ("\\kuG" ?ኩ)
 + ("\\kiG" ?ኪ)
 + ("\\kaG" ?ካ)
 + ("\\kEG" ?ኬ)
 + ("\\kG" ?ክ)
 + ("\\koG" ?ኮ)
 + ;; reserved
 +
 + ("\\kWeG" ?ኰ)                              ; U+12B0 ..
 + ;; reserved
 + ("\\kWiG" ?ኲ)
 + ("\\kWaG" ?ኳ)
 + ("\\kWEG" ?ኴ)
 + ("\\kWG" ?ኵ)
 + ;; reserved
 + ;; reserved
 + ("\\KeG" ?ኸ)
 + ("\\KuG" ?ኹ)
 + ("\\KiG" ?ኺ)
 + ("\\KaG" ?ኻ)
 + ("\\KEG" ?ኼ)
 + ("\\KG" ?ኽ)
 + ("\\KoG" ?ኾ)
 + ;; reserved
 +
 + ("\\KWeG" ?á‹€)                              ; U+12C0 ..
 + ;; reserved
 + ("\\KWiG" ?á‹‚)
 + ("\\KWaG" ?ዃ)
 + ("\\KWEG" ?á‹„)
 + ("\\KWG" ?á‹…)
 + ;; reserved
 + ;; reserved
 + ("\\weG" ?ወ)
 + ("\\wuG" ?ዉ)
 + ("\\wiG" ?á‹Š)
 + ("\\waG" ?á‹‹)
 + ("\\wEG" ?á‹Œ)
 + ("\\wG" ?á‹)
 + ("\\woG" ?á‹Ž)
 + ;; reserved
 +
 + ("\\eeG" ?á‹)                               ; U+12D0 ..
 + ("\\uuG" ?á‹‘)
 + ("\\iiG" ?á‹’)
 + ("\\aaG" ?á‹“)
 + ("\\EEG" ?á‹”)
 + ("\\IIG" ?á‹•)
 + ("\\ooG" ?á‹–)
 + ;; reserved
 + ("\\zeG" ?ዘ)
 + ("\\zuG" ?á‹™)
 + ("\\ziG" ?á‹š)
 + ("\\zaG" ?á‹›)
 + ("\\zEG" ?á‹œ)
 + ("\\zG" ?á‹)
 + ("\\zoG" ?á‹ž)
 + ("\\zWaG" ?á‹Ÿ)
 +
 + ("\\ZeG" ?á‹ )                               ; U+12E0 ..
 + ("\\ZuG" ?á‹¡)
 + ("\\ZiG" ?á‹¢)
 + ("\\ZaG" ?á‹£)
 + ("\\ZEG" ?ዤ)
 + ("\\ZG" ?á‹¥)
 + ("\\ZoG" ?ዦ)
 + ("\\ZWaG" ?ዧ)
 + ("\\yeG" ?የ)
 + ("\\yuG" ?á‹©)
 + ("\\yiG" ?ዪ)
 + ("\\yaG" ?á‹«)
 + ("\\yEG" ?ዬ)
 + ("\\yG" ?á‹­)
 + ("\\yoG" ?á‹®)
 + ;; reserved
 +
 + ("\\deG" ?á‹°)                               ; U+12F0 ..
 + ("\\duG" ?ዱ)
 + ("\\diG" ?ዲ)
 + ("\\daG" ?ዳ)
 + ("\\dEG" ?á‹´)
 + ("\\dG" ?ድ)
 + ("\\doG" ?ዶ)
 + ("\\dWaG" ?á‹·)
 + ("\\DeG" ?ዸ)
 + ("\\DuG" ?ዹ)
 + ("\\DiG" ?ዺ)
 + ("\\DaG" ?á‹»)
 + ("\\DEG" ?ዼ)
 + ("\\DG" ?ዽ)
 + ("\\DoG" ?ዾ)
 + ("\\DWaG" ?á‹¿)
 +
 + ("\\jeG" ?ጀ)                               ; U+1300 ..
 + ("\\juG" ?áŒ)
 + ("\\jiG" ?ጂ)
 + ("\\jaG" ?ጃ)
 + ("\\jEG" ?ጄ)
 + ("\\jG" ?ጅ)
 + ("\\joG" ?ጆ)
 + ("\\jWaG" ?ጇ)
 + ("\\geG" ?ገ)
 + ("\\guG" ?ጉ)
 + ("\\giG" ?ጊ)
 + ("\\gaG" ?ጋ)
 + ("\\gEG" ?ጌ)
 + ("\\gG" ?áŒ)
 + ("\\goG" ?ጎ)
 + ;; reserved
 +
 + ("\\gWeG" ?áŒ)                              ; U+1310 ..
 + ;; reserved
 + ("\\gWiG" ?ጒ)
 + ("\\gWaG" ?ጓ)
 + ("\\gWEG" ?ጔ)
 + ("\\gWG" ?ጕ)
 + ;; reserved
 + ;; reserved
 + ("\\GeG" ?ጘ)
 + ("\\GuG" ?ጙ)
 + ("\\GiG" ?ጚ)
 + ("\\GaG" ?ጛ)
 + ("\\GEG" ?ጜ)
 + ("\\GG" ?áŒ)
 + ("\\GoG" ?ጞ)
 + ;; reserved
 +
 + ("\\TeG" ?ጠ)                               ; U+1320 ..
 + ("\\TuG" ?ጡ)
 + ("\\TiG" ?ጢ)
 + ("\\TaG" ?ጣ)
 + ("\\TEG" ?ጤ)
 + ("\\TG" ?ጥ)
 + ("\\ToG" ?ጦ)
 + ("\\TWaG" ?ጧ)
 + ("\\CeG" ?ጨ)
 + ("\\CuG" ?ጩ)
 + ("\\CiG" ?ጪ)
 + ("\\CaG" ?ጫ)
 + ("\\CEG" ?ጬ)
 + ("\\CG" ?ጭ)
 + ("\\CoG" ?ጮ)
 + ("\\CWaG" ?ጯ)
 +
 + ("\\PeG" ?ጰ)                               ; U+1330 ..
 + ("\\PuG" ?ጱ)
 + ("\\PiG" ?ጲ)
 + ("\\PaG" ?ጳ)
 + ("\\PEG" ?ጴ)
 + ("\\PG" ?ጵ)
 + ("\\PoG" ?ጶ)
 + ("\\PWaG" ?ጷ)
 + ("\\SeG" ?ጸ)
 + ("\\SuG" ?ጹ)
 + ("\\SiG" ?ጺ)
 + ("\\SaG" ?ጻ)
 + ("\\SEG" ?ጼ)
 + ("\\SG" ?ጽ)
 + ("\\SoG" ?ጾ)
 + ("\\SWaG" ?ጿ)
 +
 + ("\\SSeG" ?á€)                              ; U+1340 ..
 + ("\\SSuG" ?á)
 + ("\\SSiG" ?á‚)
 + ("\\SSaG" ?áƒ)
 + ("\\SSEG" ?á„)
 + ("\\SSG" ?á…)
 + ("\\SSoG" ?á†)
 + ;; reserved
 + ("\\feG" ?áˆ)
 + ("\\fuG" ?á‰)
 + ("\\fiG" ?áŠ)
 + ("\\faG" ?á‹)
 + ("\\fEG" ?áŒ)
 + ("\\fG" ?á)
 + ("\\foG" ?áŽ)
 + ("\\fWaG" ?á)
 +
 + ("\\peG" ?á)                               ; U+1350 ..
 + ("\\puG" ?á‘)
 + ("\\piG" ?á’)
 + ("\\paG" ?á“)
 + ("\\pEG" ?á”)
 + ("\\pG" ?á•)
 + ("\\poG" ?á–)
 + ("\\pWaG" ?á—)
 + ("\\mYaG" ?á˜)
 + ("\\rYaG" ?á™)
 + ("\\fYaG" ?áš)
 + ;; reserved
 + ;; reserved
 + ;; reserved
 + ;; reserved
 + ;; reserved
 +
 + ;; reserved                          ; U+1360 ..
 + ("\\spaceG" ?á¡)
 + ("\\periodG" ?á¢)
 + ("\\commaG" ?á£)
 + ("\\semicolonG" ?á¤)
 + ("\\colonG" ?á¥)
 + ("\\precolonG" ?á¦)
 + ("\\oldqmarkG" ?á§)
 + ("\\pbreakG" ?á¨)
 + ("\\andG" ?á©)
 + ("\\huletG" ?áª)
 + ("\\sostG" ?á«)
 + ("\\aratG" ?á¬)
 + ("\\amstG" ?á­)
 + ("\\sadstG" ?á®)
 + ("\\sabatG" ?á¯)
 +
 + ("\\smntG" ?á°)                     ; U+1370 ..
 + ("\\zeteNG" ?á±)
 + ("\\asrG" ?á²)
 + ("\\heyaG" ?á³)
 + ("\\selasaG" ?á´)
 + ("\\arbaG" ?áµ)
 + ("\\hemsaG" ?á¶)
 + ("\\slsaG" ?á·)
 + ("\\sebaG" ?á¸)
 + ("\\semanyaG" ?á¹)
 + ("\\zeTanaG" ?áº)
 + ("\\metoG" ?á»)
 + ("\\asrxiG" ?á¼)
 + ;; reserved
 + ;; reserved
 + ;; reserved
 +
 + ;;
 + ;; private extension
 + ;;
 +
 + ("\\yWaG" ?ö ƒ¯)                             ; U+1A00EF (was U+12EF)
 +
 + ("\\GWaG" ?ö „Ÿ)                             ; U+1A011F (was U+131F)
 +
 + ("\\qqeG" ?ö †€)                             ; U+1A0180 .. (was U+1380 ..)
 + ("\\qquG" ?ö †)
 + ("\\qqiG" ?ö †‚)
 + ("\\qqaG" ?ö †ƒ)
 + ("\\qqEG" ?ö †„)
 + ("\\qqG" ?ö †…)
 + ("\\qqoG" ?ö ††)
 + ;; unused
 + ("\\MWeG" ?ö †ˆ)
 + ("\\bWeG" ?ö †‰)
 + ("\\GWeG" ?ö †Š)
 + ("\\fWeG" ?ö †‹)
 + ("\\pWeG" ?ö †Œ)
 + ;; unused
 + ;; unused
 + ;; unused
 +
 + ("\\kkeG" ?ö †)                             ; U+1A0190 .. (was U+1390 ..)
 + ("\\kkuG" ?ö †‘)
 + ("\\kkiG" ?ö †’)
 + ("\\kkaG" ?ö †“)
 + ("\\kkEG" ?ö †”)
 + ("\\kkG" ?ö †•)
 + ("\\kkoG" ?ö †–)
 + ;; unused
 + ("\\mWiG" ?ö †˜)
 + ("\\bWiG" ?ö †™)
 + ("\\GWiG" ?ö †š)
 + ("\\fWiG" ?ö †›)
 + ("\\pWiG" ?ö †œ)
 + ;; unused
 + ;; unused
 + ;; unused
 +
 + ("\\XeG" ?ö † )                              ; U+1A01A0 .. (was U+13A0 ..)
 + ("\\XuG" ?ö †¡)
 + ("\\XiG" ?ö †¢)
 + ("\\XaG" ?ö †£)
 + ("\\XEG" ?ö †¤)
 + ("\\XG" ?ö †¥)
 + ("\\XoG" ?ö †¦)
 + ;; unused
 + ("\\mWEG" ?ö †¨)
 + ("\\bWEG" ?ö †©)
 + ("\\GWEG" ?ö †ª)
 + ("\\fWEG" ?ö †«)
 + ("\\pWEG" ?ö †¬)
 + ;; unused
 + ;; unused
 + ;; unused
 +
 + ("\\ggeG" ?ö †°)                             ; U+1A01B0 .. (was U+13B0 ..)
 + ("\\gguG" ?ö †±)
 + ("\\ggiG" ?ö †²)
 + ("\\ggaG" ?ö †³)
 + ("\\ggEG" ?ö †´)
 + ("\\ggG" ?ö †µ)
 + ("\\ggoG" ?ö †¶)
 + ;; unused
 + ("\\mWG" ?ö †¸)
 + ("\\bWG" ?ö †¹)
 + ("\\GWG" ?ö †º)
 + ("\\fWG" ?ö †»)
 + ("\\pWG" ?ö †¼)
 + ;; unused
 + ;; unused
 + ;; unused
 +
 + ("\\ornamentG" ?ö ‡€)                        ; U+1A01C0 .. (was U+FDF0 ..)
 + ("\\flandG" ?ö ‡)
 + ("\\iflandG" ?ö ‡‚)
 + ("\\africaG" ?ö ‡ƒ)
 + ("\\iafricaG" ?ö ‡„)
 + ("\\wWeG" ?ö ‡…)
 + ("\\wWiG" ?ö ‡†)
 + ("\\wWaG" ?ö ‡‡)
 + ("\\wWEG" ?ö ‡ˆ)
 + ("\\wWG" ?ö ‡‰)
 + ;; Gemination (ö ‡Š) is handled in a special way.
 + ("\\slaqG" ?ö ‡‹)
 +
 + ;; Assign reverse conversion to Fidel chars.
 + ;; Then override forward conversion with ASCII chars.
 + ;; ASCII chars should not have reverse conversions.
 + ("\\dotG" ?ö ‡Œ) ("\\dotG" ".")
 + ("\\lquoteG" ?ö ‡) ("\\lquoteG" "«")
 + ("\\rquoteG" ?ö ‡Ž) ("\\rquoteG" "»")
 + ("\\qmarkG" ?ö ‡) ("\\qmarkG" "?")
 +
 + ;;
 + ;; New characters in Unicode 4.1.
 + ;;
 + ;; In forward conversion, these characters override the old private
 + ;; extensions above.  The old private extensions still keep their
 + ;; reverse conversion.
 + ;;
 +
 + ("\\ornamentG" ?á )
 + ("\\yWaG" ?ዯ)
 + ("\\GWaG" ?ጟ)
 + ("\\MWeG" ?ᎀ)
 + ("\\mWiG" ?áŽ)
 + ("\\mWEG" ?ᎂ)
 + ("\\mWG" ?ᎃ)
 + ("\\bWeG" ?ᎄ)
 + ("\\bWiG" ?ᎅ)
 + ("\\bWEG" ?ᎆ)
 + ("\\bWG" ?ᎇ)
 + ("\\fWeG" ?ᎈ)
 + ("\\fWiG" ?ᎉ)
 + ("\\fWEG" ?ᎊ)
 + ("\\fWG" ?ᎋ)
 + ("\\pWeG" ?ᎌ)
 + ("\\pWiG" ?áŽ)
 + ("\\pWEG" ?ᎎ)
 + ("\\pWG" ?áŽ)
 + ("\\GWeG" ?ⶓ)
 + ("\\GWiG" ?ⶔ)
 + ("\\GWEG" ?ⶕ)
 + ("\\GWG" ?ⶖ)
 + ("\\qqeG" ?â·€)
 + ("\\qquG" ?â·)
 + ("\\qqiG" ?â·‚)
 + ("\\qqaG" ?â·ƒ)
 + ("\\qqEG" ?â·„)
 + ("\\qqG" ?â·…)
 + ("\\qqoG" ?â·†)
 + ("\\kkeG" ?â·ˆ)
 + ("\\kkuG" ?â·‰)
 + ("\\kkiG" ?â·Š)
 + ("\\kkaG" ?â·‹)
 + ("\\kkEG" ?â·Œ)
 + ("\\kkG" ?â·)
 + ("\\kkoG" ?â·Ž)
 + ("\\XeG" ?â·)
 + ("\\XuG" ?â·‘)
 + ("\\XiG" ?â·’)
 + ("\\XaG" ?â·“)
 + ("\\XEG" ?â·”)
 + ("\\XG" ?â·•)
 + ("\\XoG" ?â·–)
 + ("\\ggeG" ?â·˜)
 + ("\\gguG" ?â·™)
 + ("\\ggiG" ?â·š)
 + ("\\ggaG" ?â·›)
 + ("\\ggEG" ?â·œ)
 + ("\\ggG" ?â·)
 + ("\\ggoG" ?â·ž)
 + )
 +
 +;; The ethiopic-tex package is not used for keyboard input, therefore
 +;; not registered with the register-input-method function.
  
 -;;
  (provide 'ethio-util)
  
 +;;; ethio-util.el ends here
 +
  ;;; arch-tag: c8feb3d6-39bf-4b0a-b6ef-26f03fbc8140
  ;;; ethio-util.el ends here
index 3772dceae1e965721c6c290a827940547668015b,1ae1f461f2db3d07667ae1654974e39fbb04f522..5417adb275f373685b4a2def3b2165cf544ab330
@@@ -1,9 -1,9 +1,9 @@@
 -;;; ethiopic.el --- support for Ethiopic -*- coding: iso-2022-7bit; -*-
 +;;; ethiopic.el --- support for Ethiopic      -*- coding: utf-8-emacs; -*-
  
- ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
       (r1 *= 94)
       (r2 += r1)
       (if (r2 < 256)
 -       (r1 = ?\x12)
 +       (r1 = #x12)
         (if (r2 < 448)
 -         ((r1 = ?\x13) (r2 -= 256))
 -       ((r1 = ?\xfd) (r2 -= 208))
 +         ((r1 = #x13) (r2 -= 256))
 +       ((r1 = #xfd) (r2 -= 208))
         ))))
    "CCL program to encode an Ethiopic code to code point of Ethiopic font.")
  
   "Ethiopic" '((setup-function . setup-ethiopic-environment-internal)
              (exit-function . exit-ethiopic-environment)
              (charset ethiopic)
 -            (coding-system iso-2022-7bit)
 -            (coding-priority iso-2022-7bit)
 +            (coding-system utf-8-emacs)
 +            (coding-priority utf-8-emacs)
              (input-method . "ethiopic")
              (features ethio-util)
 -            (sample-text . "\e$(3$Q#U!.\e(B")
 +            (sample-text . "áŠá‹°áˆ")
              (documentation .
 -"This language envrironment provides these function key bindings
 -    \(old bindings are shown in parentheses):
 -    [f3]   ethio-fidel-to-sera-buffer         (f5)
 -    [S-f3] ethio-fidel-to-sera-region         (f5)
 -    [C-f3] ethio-fidel-to-sera-mail-or-marker (f5)
 -
 -    [f4]   ethio-sera-to-fidel-buffer         (unchanged)
 -    [S-f4] ethio-sera-to-fidel-region         (unchanged)
 -    [C-f4] ethio-sera-to-fidel-mail-or-marker (unchanged)
 -
 -    [S-f5] ethio-toggle-punctuation           (f3)
 -    [S-f6] ethio-modify-vowel                 (f6)
 -    [S-f7] ethio-replace-space                (f7)
 -    [S-f8] ethio-input-special-character      (f8)
 -    [S-f9] ethio-replace-space                (unchanged)
 -    [C-f9] ethio-toggle-space                 (f2)"
 +"This language envrironment provides these function key bindings:
 +    [f3]   ethio-fidel-to-sera-buffer
 +    [S-f3] ethio-fidel-to-sera-region
 +    [C-f3] ethio-fidel-to-sera-marker
 +
 +    [f4]   ethio-sera-to-fidel-buffer
 +    [S-f4] ethio-sera-to-fidel-region
 +    [C-f4] ethio-sera-to-fidel-marker
 +
 +    [S-f5] ethio-toggle-punctuation
 +    [S-f6] ethio-modify-vowel
 +    [S-f7] ethio-replace-space
 +
 +    [S-f9] ethio-replace-space
 +    [C-f9] ethio-toggle-space"
  )))
  
 +;; For automatic composition
 +(aset composition-function-table ?ö ‡Š 'ethio-composition-function)
 +(aset composition-function-table ?០'ethio-composition-function)
 +
  (provide 'ethiopic)
  
  ;;; arch-tag: e81329d9-1286-43ba-92fd-54ce5c7b213c
index ecdca8b20f40e87af94dcf7cfdb64c883b5ff6fd,ccbbf8318c9af230aa421ee23c9f914ddc44fbab..b7532eb1a47420b597e31d6c80a590d4aac5dc65
@@@ -1,14 -1,11 +1,14 @@@
  ;;; european.el --- support for European languages -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multilingual, European
  
  ;; Latin-1 (ISO-8859-1)
  
  (set-language-info-alist
 - "Latin-1" '((charset ascii latin-iso8859-1)
 -           (coding-system iso-latin-1)
 -           (coding-priority iso-latin-1 windows-1252)
 -           (nonascii-translation . latin-iso8859-1)
 -           (unibyte-syntax . "latin-1")
 + "Latin-1" '((charset iso-8859-1)
 +           (coding-system iso-latin-1 iso-latin-9 windows-1252)
 +           (coding-priority iso-latin-1)
 +           (nonascii-translation . iso-8859-1)
             (unibyte-display . iso-latin-1)
             (input-method . "latin-1-prefix")
             (sample-text
 -            . "Hello, Hej, Tere, Hei, Bonjour, Gr\e,A|_\e(B Gott, Ciao, \e,A!\e(BHola!")
 +            . "Hello, Hej, Tere, Hei, Bonjour, Gr\e$(D+d)N\e(B Gott, Ciao, \e$(D"B\e(BHola!")
             (documentation . "\
  This language environment is a generic one for the Latin-1 (ISO-8859-1)
  character set which supports the following European languages:
@@@ -67,24 -65,42 +67,24 @@@ Latin-1 also covers several written lan
  Indonesian/Malay, Tagalog (Philippines), Swahili and Afrikaans."))
   '("European"))
  
 -(eval-and-compile
 -  (setq
 -   non-iso-charset-alist
 -   (cp-make-coding-system
 -    windows-1252
 -    [?\\e$,1tL\e(B nil ?\\e$,1rz\e(B ?\\e$,1!R\e(B ?\\e$,1r~\e(B ?\\e$,1s&\e(B ?\\e$,1s \e(B ?\\e$,1s!\e(B ?\\e$,1$f\e(B ?\\e$,1s0\e(B ?\\e$,1! \e(B ?\\e$,1s9\e(B ?\\e$,1 r\e(B nil ?\\e$,1!=\e(B nil nil
 -       ?\\e$,1rx\e(B ?\\e$,1ry\e(B ?\\e$,1r|\e(B ?\\e$,1r}\e(B ?\\e$,1s"\e(B ?\\e$,1rs\e(B ?\\e$,1rt\e(B ?\\e$,1$|\e(B ?\\e$,1ub\e(B ?\\e$,1!!\e(B ?\\e$,1s:\e(B ?\\e$,1 s\e(B nil ?\\e$,1!>\e(B ?\\e$,1!8\e(B ?\\e,A \e(B ?\\e,A!\e(B
 -       ?\\e,A"\e(B ?\\e,A#\e(B ?\\e,A$\e(B ?\\e,A%\e(B ?\\e,A&\e(B ?\\e,A'\e(B ?\\e,A(\e(B ?\\e,A)\e(B ?\\e,A*\e(B ?\\e,A+\e(B ?\\e,A,\e(B ?\\e,A-\e(B ?\\e,A.\e(B ?\\e,A/\e(B ?\\e,A0\e(B ?\\e,A1\e(B ?\\e,A2\e(B
 -       ?\\e,A3\e(B ?\\e,A4\e(B ?\\e,A5\e(B ?\\e,A6\e(B ?\\e,A7\e(B ?\\e,A8\e(B ?\\e,A9\e(B ?\\e,A:\e(B ?\\e,A;\e(B ?\\e,A<\e(B ?\\e,A=\e(B ?\\e,A>\e(B ?\\e,A?\e(B ?\\e,A@\e(B ?\\e,AA\e(B ?\\e,AB\e(B ?\\e,AC\e(B
 -       ?\\e,AD\e(B ?\\e,AE\e(B ?\\e,AF\e(B ?\\e,AG\e(B ?\\e,AH\e(B ?\\e,AI\e(B ?\\e,AJ\e(B ?\\e,AK\e(B ?\\e,AL\e(B ?\\e,AM\e(B ?\\e,AN\e(B ?\\e,AO\e(B ?\\e,AP\e(B ?\\e,AQ\e(B ?\\e,AR\e(B ?\\e,AS\e(B ?\\e,AT\e(B
 -       ?\\e,AU\e(B ?\\e,AV\e(B ?\\e,AW\e(B ?\\e,AX\e(B ?\\e,AY\e(B ?\\e,AZ\e(B ?\\e,A[\e(B ?\\e,A\\e(B ?\\e,A]\e(B ?\\e,A^\e(B ?\\e,A_\e(B ?\\e,A`\e(B ?\\e,Aa\e(B ?\\e,Ab\e(B ?\\e,Ac\e(B ?\\e,Ad\e(B ?\\e,Ae\e(B
 -       ?\\e,Af\e(B ?\\e,Ag\e(B ?\\e,Ah\e(B ?\\e,Ai\e(B ?\\e,Aj\e(B ?\\e,Ak\e(B ?\\e,Al\e(B ?\\e,Am\e(B ?\\e,An\e(B ?\\e,Ao\e(B ?\\e,Ap\e(B ?\\e,Aq\e(B ?\\e,Ar\e(B ?\\e,As\e(B ?\\e,At\e(B ?\\e,Au\e(B ?\\e,Av\e(B
 -       ?\\e,Aw\e(B ?\\e,Ax\e(B ?\\e,Ay\e(B ?\\e,Az\e(B ?\\e,A{\e(B ?\\e,A|\e(B ?\\e,A}\e(B ?\\e,A~\e(B ?\\e,A\7f\e(B])))
 -
 -(define-coding-system-alias 'cp1252 'windows-1252)
 -
  \f
  ;; Latin-2 (ISO-8859-2)
  
 -(make-coding-system
 - 'iso-latin-2 2 ?2
 - "ISO 2022 based 8-bit encoding for Latin-2 (MIME:ISO-8859-2)."
 - '(ascii latin-iso8859-2 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii latin-iso8859-2)
 -   (mime-charset . iso-8859-2)))
 +(define-coding-system 'iso-latin-2
 +   "ISO 2022 based 8-bit encoding for Latin-2 (MIME:ISO-8859-2)."
 +  :coding-type 'charset
 +  :mnemonic ?2
 +  :charset-list '(iso-8859-2)
 +  :mime-charset 'iso-8859-2)
  
  (define-coding-system-alias 'iso-8859-2 'iso-latin-2)
  (define-coding-system-alias 'latin-2 'iso-latin-2)
  
  (set-language-info-alist
 - "Latin-2" '((charset ascii latin-iso8859-2)
 -           (coding-system iso-latin-2)
 + "Latin-2" '((charset iso-8859-2)
 +           (coding-system iso-latin-2 windows-1250)
             (coding-priority iso-latin-2)
 -           (nonascii-translation . latin-iso8859-2)
 -           (unibyte-syntax . "latin-2")
 +           (nonascii-translation . iso-8859-2)
             (unibyte-display . iso-latin-2)
             (input-method . "latin-2-prefix")
             (documentation . "\
@@@ -96,7 -112,6 +96,7 @@@ character set which supports the follow
  We also have specific language environments for the following languages:
    For Czech, \"Czech\".
    For Croatian, \"Croatian\".
 +  For Polish, \"Polish\".
    For Romanian, \"Romanian\".
    For Slovak, \"Slovak\"."))
   '("European"))
  \f
  ;; Latin-3 (ISO-8859-3)
  
 -(make-coding-system
 - 'iso-latin-3 2 ?3
 - "ISO 2022 based 8-bit encoding for Latin-3 (MIME:ISO-8859-3)."
 - '(ascii latin-iso8859-3 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii latin-iso8859-3)
 -   (mime-charset . iso-8859-3)))
 +(define-coding-system 'iso-latin-3
 +  "ISO 2022 based 8-bit encoding for Latin-3 (MIME:ISO-8859-3)."
 +  :coding-type 'charset
 +  :mnemonic ?3
 +  :charset-list '(iso-8859-3)
 +  :mime-charset 'iso-8859-3)
  
  (define-coding-system-alias 'iso-8859-3 'iso-latin-3)
  (define-coding-system-alias 'latin-3 'iso-latin-3)
  
  (set-language-info-alist
 - "Latin-3" '((charset ascii latin-iso8859-3)
 + "Latin-3" '((charset iso-8859-3)
             (coding-system iso-latin-3)
             (coding-priority iso-latin-3)
 -           (nonascii-translation . latin-iso8859-3)
 -           (unibyte-syntax . "latin-3")
 +           (nonascii-translation . iso-8859-3)
             (unibyte-display . iso-latin-3)
             (input-method . "latin-3-prefix")
             (documentation . "\
@@@ -130,21 -147,23 +130,21 @@@ These languages are supported with the 
  \f
  ;; Latin-4 (ISO-8859-4)
  
 -(make-coding-system
 - 'iso-latin-4 2 ?4
 - "ISO 2022 based 8-bit encoding for Latin-4 (MIME:ISO-8859-4)."
 - '(ascii latin-iso8859-4 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii latin-iso8859-4)
 -   (mime-charset . iso-8859-4)))
 +(define-coding-system 'iso-latin-4
 +  "ISO 2022 based 8-bit encoding for Latin-4 (MIME:ISO-8859-4)."
 +  :coding-type 'charset
 +  :mnemonic ?4
 +  :charset-list '(iso-8859-4)
 +  :mime-charset 'iso-8859-4)
  
  (define-coding-system-alias 'iso-8859-4 'iso-latin-4)
  (define-coding-system-alias 'latin-4 'iso-latin-4)
  
  (set-language-info-alist
 - "Latin-4" '((charset ascii latin-iso8859-4)
 + "Latin-4" '((charset iso-8859-4)
             (coding-system iso-8859-4)
             (coding-priority iso-8859-4)
 -           (nonascii-translation . latin-iso8859-4)
 -           (unibyte-syntax . "latin-4")
 +           (nonascii-translation . iso-8859-4)
             (unibyte-display . iso-8859-4)
             (input-method . "latin-4-postfix")
             (documentation . "\
@@@ -156,95 -175,53 +156,95 @@@ These languages are supported with the 
  \f
  ;; Latin-5 (ISO-8859-9)
  
 -(make-coding-system
 - 'iso-latin-5 2 ?9
 - "ISO 2022 based 8-bit encoding for Latin-5 (MIME:ISO-8859-9)."
 - '(ascii latin-iso8859-9 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii latin-iso8859-9)
 -   (mime-charset . iso-8859-9)))
 +(define-coding-system 'iso-latin-5
 +  "ISO 2022 based 8-bit encoding for Latin-5 (MIME:ISO-8859-9)."
 +  :coding-type 'charset
 +  :mnemonic ?9
 +  :charset-list '(iso-8859-9)
 +  :mime-charset 'iso-8859-9)
  
  (define-coding-system-alias 'iso-8859-9 'iso-latin-5)
  (define-coding-system-alias 'latin-5 'iso-latin-5)
  
  (set-language-info-alist
 - "Latin-5" '((charset ascii latin-iso8859-9)
 + "Latin-5" '((charset iso-8859-9)
             (coding-system iso-latin-5)
             (coding-priority iso-latin-5)
 -           (nonascii-translation . latin-iso8859-9)
 -           (unibyte-syntax . "latin-5")
 +           (nonascii-translation . iso-8859-9)
             (unibyte-display . iso-latin-5)
             (input-method . "latin-5-postfix")
 -           (documentation . "Support for Turkish language."))
 +           (documentation . "Support for Latin-5.\
 +See also the Turkish environment."))
   '("European"))
  
  \f
 +;; Latin-6 (ISO-8859-10)
 +
 +(define-coding-system 'iso-latin-6
 +  "ISO 2022 based 8-bit encoding for Latin-6 (MIME:ISO-8859-10)."
 +  :coding-type 'charset
 +  :mnemonic ?9
 +  :charset-list '(iso-8859-10)
 +  :mime-charset 'iso-8859-10)
 +
 +(define-coding-system-alias 'iso-8859-10 'iso-latin-6)
 +(define-coding-system-alias 'latin-6 'iso-latin-6)
 +
 +(set-language-info-alist
 + "Latin-6" '((charset iso-8859-10)
 +           (coding-system iso-latin-6)
 +           (coding-priority iso-latin-6)
 +           (nonascii-translation . iso-8859-10)
 +           (unibyte-display . iso-latin-6)
 +           ;; Fixme: input method.
 +           (documentation . "Support for generic Latin-6 (Northern European)."))
 + '("European"))
 +
 +\f
 +;; Latin-7 (ISO-8859-13)
 +
 +(define-coding-system 'iso-latin-7
 +  "ISO 2022 based 8-bit encoding for Latin-7 (MIME:ISO-8859-13)."
 +  :coding-type 'charset
 +  :mnemonic ?9
 +  :charset-list '(iso-8859-13)
 +  :mime-charset 'iso-8859-13)
 +
 +(define-coding-system-alias 'iso-8859-13 'iso-latin-7)
 +(define-coding-system-alias 'latin-7 'iso-latin-7)
 +
 +(set-language-info-alist
 + "Latin-7" '((charset iso-8859-13)
 +           (coding-system iso-latin-7)
 +           (coding-priority iso-latin-7)
 +           (nonascii-translation . iso-8859-13)
 +           (unibyte-display . iso-latin-7)
 +           ;; Fixme: input method.
 +           (documentation . "Support for generic Latin-7 (Baltic Rim)."))
 + '("European"))
 +\f
  ;; Latin-8 (ISO-8859-14)
  
 -(make-coding-system
 - 'iso-latin-8 2 ?W                    ; `W' for `Welsh', since `C'
 -                                      ; for `Celtic' is taken.
 - "ISO 2022 based 8-bit encoding for Latin-8 (MIME:ISO-8859-14)."
 - '(ascii latin-iso8859-14 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t t)
 - '((safe-charsets ascii latin-iso8859-14)
 -   (mime-charset . iso-8859-14)))
 +(define-coding-system 'iso-latin-8
 +  "ISO 2022 based 8-bit encoding for Latin-8 (MIME:ISO-8859-14)."
 +  :coding-type 'charset
 +  ;; `W' for `Welsh', since `C' for `Celtic' is taken.
 +  :mnemonic ?W                                
 +  :charset-list '(iso-8859-14)
 +  :mime-charset 'iso-8859-14)
  
  (define-coding-system-alias 'iso-8859-14 'iso-latin-8)
  (define-coding-system-alias 'latin-8 'iso-latin-8)
  
  (set-language-info-alist
 - "Latin-8" '((charset ascii latin-iso8859-14)
 + "Latin-8" '((charset iso-8859-14)
             (coding-system iso-latin-8)
             (coding-priority iso-latin-8)
 -           (nonascii-translation . latin-iso8859-14)
 -           (unibyte-syntax . "latin-8")
 +           (nonascii-translation . iso-8859-14)
             (unibyte-display . iso-latin-8)
             (input-method . "latin-8-prefix")
             ;; Fixme: Welsh/Ga{e}lic greetings
 -           (sample-text . "\e,_"\e(B \e,_p\e(B \e,_^\e(B")
 +           (sample-text . "\e,_"\e(B \e$(D+q\e(B \e$(D*t\e(B")
             (documentation . "\
  This language environment is a generic one for the Latin-8 (ISO-8859-14)
  character set which supports the Celtic languages, including those not
@@@ -254,27 -231,28 +254,27 @@@ covered by other ISO-8859 character set
  \f
  ;; Latin-9 (ISO-8859-15)
  
 -(make-coding-system
 - 'iso-latin-9 2 ?0                    ; `0' for `Latin-0'
 - "ISO 2022 based 8-bit encoding for Latin-9 (MIME:ISO-8859-15)."
 - '(ascii latin-iso8859-15 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t t)
 - '((safe-charsets ascii latin-iso8859-15)
 -   (mime-charset . iso-8859-15)))
 +(define-coding-system 'iso-latin-9
 +  "ISO 2022 based 8-bit encoding for Latin-9 (MIME:ISO-8859-15)."
 +  :coding-type 'charset
 +  ;; `0' for `Latin-0'
 +  :mnemonic ?0
 +  :charset-list '(iso-8859-15)
 +  :mime-charset 'iso-8859-15)
  
  (define-coding-system-alias 'iso-8859-15 'iso-latin-9)
  (define-coding-system-alias 'latin-9 'iso-latin-9)
  (define-coding-system-alias 'latin-0 'iso-latin-9)
  
  (set-language-info-alist
 - "Latin-9" '((charset ascii latin-iso8859-15)
 + "Latin-9" '((charset iso-8859-15)
             (coding-system iso-latin-9)
             (coding-priority iso-latin-9)
 -           (nonascii-translation . latin-iso8859-15)
 -           (unibyte-syntax . "latin-9")
 +           (nonascii-translation . iso-8859-15)
             (unibyte-display . iso-latin-9)
             (input-method . "latin-9-prefix")
             (sample-text
 -            . "AVE. \e,b&(48<=>\e(B \e,b$\e(B")
 +            . "AVE. \e$(D*^+^*v+v)-)M*s\e(B \e$(Q)!\e(B")
             (documentation . "\
  This language environment is a generic one for the Latin-9 (ISO-8859-15)
  character set which supports the same languages as Latin-1 with the
@@@ -282,115 -260,13 +282,115 @@@ addition of the Euro sign and some addi
  Latin-9 is sometimes nicknamed `Latin-0'."))
   '("European"))
  \f
 +(define-coding-system 'windows-1250
 +  "windows-1250 (Central European) encoding (MIME: WINDOWS-1250)"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(windows-1250)
 +  :mime-charset 'windows-1250)
 +(define-coding-system-alias 'cp1250 'windows-1250)
 +
 +(define-coding-system 'windows-1252
 +  "windows-1252 (Western European) encoding (MIME: WINDOWS-1252)"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(windows-1252)
 +  :mime-charset 'windows-1252)
 +(define-coding-system-alias 'cp1252 'windows-1252)
 +
 +(define-coding-system 'windows-1254
 +  "windows-1254 (Turkish) encoding (MIME: WINDOWS-1254)"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(windows-1254)
 +  :mime-charset 'windows-1254)
 +(define-coding-system-alias 'cp1254 'windows-1254)
 +
 +(define-coding-system 'windows-1257
 +  "windows-1257 (Baltic) encoding (MIME: WINDOWS-1257)"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(windows-1257)
 +  :mime-charset 'windows-1257)
 +(define-coding-system-alias 'cp1257 'windows-1257)
 +
 +(define-coding-system 'cp850
 +  "DOS codepage 850 (Western European)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp850)
 +  :mime-charset 'cp850)
 +(define-coding-system-alias 'ibm850 'cp850)
 +
 +(define-coding-system 'cp852
 +  "DOS codepage 852 (Slavic)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp852)
 +  :mime-charset 'cp852)
 +(define-coding-system-alias 'ibm852 'cp852)
 +
 +(define-coding-system 'cp857
 +  "DOS codepage 857 (Turkish)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp857)
 +  :mime-charset 'cp857)
 +(define-coding-system-alias 'ibm857 'cp857)
 +
 +(define-coding-system 'cp858
 +  "Codepage 858 (Multilingual Latin I + Euro)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp858)
 +  :mime-charset 'cp858)
 +
 +(define-coding-system 'cp860
 +  "DOS codepage 860 (Portuguese)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp860)
 +  :mime-charset 'cp860)
 +(define-coding-system-alias 'ibm860 'cp860)
 +
 +(define-coding-system 'cp861
 +  "DOS codepage 861 (Icelandic)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp861)
 +  :mime-charset 'cp861)
 +(define-coding-system-alias 'ibm861 'cp861)
 +
 +(define-coding-system 'cp863
 +  "DOS codepage 863 (French Canadian)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp863)
 +  :mime-charset 'cp863)
 +(define-coding-system-alias 'ibm863 'cp863)
 +
 +(define-coding-system 'cp865
 +  "DOS codepage 865 (Norwegian/Danish)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp865)
 +  :mime-charset 'cp865)
 +(define-coding-system-alias 'ibm865 'cp865)
 +
 +(define-coding-system 'cp437
 +  "DOS codepage 437"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp437)
 +  :mime-charset 'cp437)
 +(define-coding-system-alias 'ibm437 'cp437)
 +\f
  (set-language-info-alist
   "Dutch" '((tutorial . "TUTORIAL.nl")
 -         (charset ascii latin-iso8859-1)
 +         (charset iso-8859-1)
           (coding-system iso-latin-1 iso-latin-9)
           (coding-priority iso-latin-1)
 -         (nonascii-translation . latin-iso8859-1)
 -         (unibyte-syntax . "latin-1")
 +         (nonascii-translation . iso-8859-1)
           (unibyte-display . iso-latin-1)
           (input-method . "dutch")
           (sample-text . "Er is een aantal manieren waarop je dit kan doen")
@@@ -401,15 -277,16 +401,15 @@@ but it selects the Dutch tutorial and i
  
  (set-language-info-alist
   "German" '((tutorial . "TUTORIAL.de")
 -          (charset ascii latin-iso8859-1)
 +          (charset iso-8859-1)
            (coding-system iso-latin-1 iso-latin-9)
 -          (coding-priority iso-latin-1 windows-1252)
 +          (coding-priority iso-latin-1)
 +          (nonascii-translation . iso-8859-1)
            (input-method . "german-postfix")
 -          (nonascii-translation . latin-iso8859-1)
 -          (unibyte-syntax . "latin-1")
            (unibyte-display . iso-latin-1)
            (sample-text . "\
  German (Deutsch Nord) Guten Tag
 -German (Deutsch S\e,A|\e(Bd)    Gr\e,A|_\e(B Gott")
 +German (Deutsch S\e$(D+d\e(Bd)  Gr\e$(D+d)N\e(B Gott")
            (documentation . "\
  This language environment is almost the same as Latin-1,
  but sets the default input method to \"german-postfix\".
@@@ -418,13 -295,14 +418,13 @@@ Additionally, it selects the German tut
  
  (set-language-info-alist
   "French" '((tutorial . "TUTORIAL.fr")
 -          (charset ascii latin-iso8859-1)
 +          (charset iso-8859-1)
            (coding-system iso-latin-1 iso-latin-9)
            (coding-priority iso-latin-1)
 -          (nonascii-translation . latin-iso8859-1)
 -          (unibyte-syntax . "latin-1")
 +          (nonascii-translation . iso-8859-1)
            (unibyte-display . iso-latin-1)
            (input-method . "latin-1-prefix")
 -          (sample-text . "French (Fran\e,Ag\e(Bais)     Bonjour, Salut")
 +          (sample-text . "French (Fran\e$(D+.\e(Bais)   Bonjour, Salut")
            (documentation . "\
  This language environment is almost the same as Latin-1,
  but it selects the French tutorial and input method."))
  
  (set-language-info-alist
   "Italian" '((tutorial . "TUTORIAL.it")
 -          (charset ascii latin-iso8859-1)
 +          (charset iso-8859-1)
            (coding-system iso-latin-1 iso-latin-9)
            (coding-priority iso-latin-1)
 -          (nonascii-translation . latin-iso8859-1)
 -          (unibyte-syntax . "latin-1")
 +          (nonascii-translation . iso-8859-1)
            (unibyte-display . iso-latin-1)
            (input-method . "italian-postfix")
            (sample-text . "Salve, ciao!")
@@@ -446,14 -325,15 +446,14 @@@ Additionally, it selects the Italian tu
   '("European"))
  
  (set-language-info-alist
 - "Slovenian" '((charset . (ascii latin-iso8859-2))
 -            (coding-system . (iso-8859-2))
 + "Slovenian" '((charset iso-8859-2)
 +            (coding-system . (iso-8859-2 windows-1250))
              (coding-priority . (iso-8859-2))
 -            (nonascii-translation . latin-iso8859-2)
 +            (nonascii-translation . iso-8859-2)
              (input-method . "slovenian")
 -            (unibyte-syntax . "latin-2")
              (unibyte-display . iso-8859-2)
              (tutorial . "TUTORIAL.sl")
 -            (sample-text . "\e,B.\e(Belimo vam uspe\e,B9\e(Ben dan!")
 +            (sample-text . "\e$(D*v\e(Belimo vam uspe\e$(D+^\e(Ben dan!")
              (documentation . "\
  This language environment is almost the same as Latin-2,
  but it selects the Slovenian tutorial and input method."))
  
  (set-language-info-alist
   "Spanish" '((tutorial . "TUTORIAL.es")
 -          (charset ascii latin-iso8859-1)
 +          (charset iso-8859-1)
            (coding-system iso-latin-1 iso-latin-9)
            (coding-priority iso-latin-1)
            (input-method . "spanish-postfix")
 -          (nonascii-translation . latin-iso8859-1)
 -          (unibyte-syntax . "latin-1")
 +          (nonascii-translation . iso-8859-1)
            (unibyte-display . iso-latin-1)
 -          (sample-text . "Spanish (Espa\e,Aq\e(Bol)     \e,A!\e(BHola!")
 +          (sample-text . "Spanish (Espa\e$(D+P\e(Bol)   \e$(D"B\e(BHola!")
            (documentation . "\
  This language environment is almost the same as Latin-1,
  but it sets the default input method to \"spanish-postfix\",
@@@ -480,52 -361,52 +480,52 @@@ and it selects the Spanish tutorial.")
  ;; "Latin-3" language environment.
  
  (set-language-info-alist
 - "Turkish" '((charset ascii latin-iso8859-9)
 -           (coding-system iso-latin-5 iso-latin-3)
 + "Turkish" '((charset iso-8859-9)
 +           (coding-system iso-latin-5 windows-1254 iso-latin-3)
             (coding-priority iso-latin-5)
 -           (nonascii-translation . latin-iso8859-9)
 -           (unibyte-syntax . "latin-5")
 +           (nonascii-translation . iso-8859-9)
             (unibyte-display . iso-latin-5)
             (input-method . "turkish-postfix")
 -           (sample-text . "Turkish (T\e,M|\e(Brk\e,Mg\e(Be)       Merhaba")
 -           (documentation . t)
 +           (sample-text . "Turkish (T\e$(D+d\e(Brk\e$(D+.\e(Be)   Merhaba")
             (setup-function . turkish-case-conversion-enable)
 -           (exit-function . turkish-case-conversion-disable)))
 +           (setup-function . turkish-case-conversion-disable)
 +           (documentation . "Support for Turkish.
 +Differs from the Latin-5 environment in using the `turkish-postfix' input
 +method and applying Turkish case rules for the characters i, I, \e$(D)E\e(B, \e$(D*D\e(B.")))
  
  (defun turkish-case-conversion-enable ()
 -  "Set up Turkish case conversion of `i' and `I' into `\e$,1 P\e(B' and `\e$,1 Q\e(B'."
 +  "Set up Turkish case conversion of `i' and `I' into `\e$(D*D\e(B' and `\e$(D)E\e(B'."
    (let ((table (standard-case-table)))
 -    (set-case-syntax-pair ?\e$,1 P\e(B ?i table)
 -    (set-case-syntax-pair ?I ?\e$,1 Q\e(B table)))
 +    (set-case-syntax-pair ?\e$(D*D\e(B ?i table)
 +    (set-case-syntax-pair ?I ?\e$(D)E\e(B table)))
  
  (defun turkish-case-conversion-disable ()
    "Set up normal (non-Turkish) case conversion of `i' into `I'."
    (let ((table (standard-case-table)))
      (set-case-syntax-pair ?I ?i table)
 -    (set-case-syntax ?\e$,1 P\e(B "w" table)
 -    (set-case-syntax ?\e$,1 Q\e(B "w" table)))
 +    (set-case-syntax ?\e$(D*D\e(B "w" table)
 +    (set-case-syntax ?\e$(D)E\e(B "w" table)))
  
  ;; Polish ISO 8859-2 environment.
  ;; Maintainer: Wlodek Bzyl <matwb@univ.gda.pl>
  ;; Keywords: multilingual, Polish
  
  (set-language-info-alist
 - "Polish" '((charset . (ascii latin-iso8859-2))
 -         (coding-system . (iso-8859-2))
 -         (coding-priority . (iso-8859-2))
 + "Polish" '((charset iso-8859-2)
 +         (coding-system iso-8859-2 windows-1250)
 +         (coding-priority iso-8859-2)
           (input-method . "polish-slash")
 -         (nonascii-translation . latin-iso8859-2)
 -         (unibyte-syntax . "latin-2")
 +         (nonascii-translation . iso-8859-2)
           (unibyte-display . iso-8859-2)
           (tutorial . "TUTORIAL.pl")
 -         (sample-text . "P\e,Bs\e(Bjd\e,B<\e(B, ki\e,Bq\e(B-\e,B?\e(Be t\e,Bj\e(B chmurno\e,B6f\e(B w g\e,B31\e(Bb flaszy")
 +         (sample-text . "P\e$(D+Q\e(Bjd\e$(D+u\e(B, ki\e$(D+M\e(B-\e$(D+w\e(Be t\e$(D+8\e(B chmurno\e$(D+\++\e(B w g\e$(D)H+(\e(Bb flaszy")
           (documentation . t))
   '("European"))
  
  (set-language-info-alist
   "Welsh" `((coding-system utf-8 latin-8) ; the input method is Unicode-based
           (coding-priority utf-8 latin-8)
 -         (nonascii-translation . latin-iso8859-14)
 +         (nonascii-translation . iso-8859-14)
           (input-method . "welsh")
           (documentation . "Support for Welsh, using Unicode."))
   '("European"))
  (set-language-info-alist
   "Latin-7" `((coding-system latin-7)
             (coding-priority latin-7)
 -           (nonascii-translation . ,(get 'decode-iso-latin-7
 -                                         'translation-table))
 +           (nonascii-translation . iso-8859-13)
             (input-method . "latin-prefix")
 -           (features code-pages)
             (documentation . "Support for Latin-7, e.g. Latvian, Lithuanian."))
   '("European"))
  
  (set-language-info-alist
 - "Lithuanian" `((coding-system latin-7)
 + "Lithuanian" `((coding-system latin-7 windows-1257)
                (coding-priority latin-7)
 +              (nonascii-translation . iso-8859-13)
                (input-method . "lithuanian-keyboard")
 -              (nonascii-translation . ,(get 'decode-iso-latin-7
 -                                            'translation-table))
 -              (features code-pages)
                (documentation . "Support for Lithuanian."))
   '("European"))
  
  (set-language-info-alist
 - "Latvian" `((coding-system latin-7)
 + "Latvian" `((coding-system latin-7 windows-1257)
             (coding-priority latin-7)
 +           (nonascii-translation . iso-8859-13)
             (input-method . "latvian-keyboard")
 -           (nonascii-translation . ,(get 'decode-iso-latin-7
 -                                         'translation-table))
 -           (features code-pages)
             (documentation . "Support for Latvian."))
   '("European"))
  
  (set-language-info-alist
   "Swedish" '((tutorial . "TUTORIAL.sv")
 -          (charset ascii latin-iso8859-1)
 +          (charset iso-8859-1)
            (coding-system iso-latin-1)
            (coding-priority iso-latin-1)
 -          (nonascii-translation . latin-iso8859-1)
 -          (unibyte-syntax . "latin-1")
 +          (nonascii-translation . iso-8859-1)
            (unibyte-display . iso-latin-1)
            (sample-text . "Goddag Hej")
            (documentation . "Support for Swedish"))
   '("European"))
  
  (set-language-info-alist
 - "Croatian" '((charset . (ascii latin-iso8859-2))
 -            (coding-system . (iso-8859-2))
 -            (coding-priority . (iso-8859-2))
 + "Croatian" '((charset iso-8859-2)
 +            (coding-system iso-8859-2)
 +            (coding-priority iso-8859-2)
              (input-method . "croatian")
 -            (nonascii-translation . latin-iso8859-2)
 -            (unibyte-syntax . "latin-2")
 +            (nonascii-translation . iso-8859-2)
              (unibyte-display . iso-8859-2)
              (documentation . "Support for Croatian with Latin-2 encoding."))
   '("European"))
  
  (set-language-info-alist
   "Brazilian Portuguese" '((tutorial . "TUTORIAL.pt_BR")
 -          (charset ascii latin-iso8859-1)
 +          (charset iso-8859-1)
            (coding-system iso-latin-1 iso-latin-9)
            (coding-priority iso-latin-1)
 -          (nonascii-translation . latin-iso8859-1)
 -          (unibyte-syntax . "latin-1")
 -          (unibyte-display . iso-latin-1)
 +          (nonascii-translation . iso-8859-1)
 +          (unibyte-display . iso-8859-1)
            (input-method . "latin-1-prefix")
            (sample-text . "Oi")
            (documentation . "Support for Brazilian Portuguese."))
   '("European"))
 +
  \f
 -;; Definitions for the Mac Roman character sets and coding system.
 -;; The Mac Roman encoding uses all 128 code points in the range 128 to
 -;; 255 for actual characters.  Emacs decodes them to one of the
 -;; following character sets.
 -;;    ascii, latin-iso8859-1, mule-unicode-0100-24ff,
 -;;    mule-unicode-2500-33ff, mule-unicode-e000-ffff
 -
 -(let
 -    ((encoding-vector (make-vector 256 nil))
 -     (i 0)
 -     (vec     ;; mac-roman (128..255) -> UCS mapping
 -      [ #x00C4        ;; 128:LATIN CAPITAL LETTER A WITH DIAERESIS
 -      #x00C5  ;; 129:LATIN CAPITAL LETTER A WITH RING ABOVE
 -      #x00C7  ;; 130:LATIN CAPITAL LETTER C WITH CEDILLA
 -      #x00C9  ;; 131:LATIN CAPITAL LETTER E WITH ACUTE
 -      #x00D1  ;; 132:LATIN CAPITAL LETTER N WITH TILDE
 -      #x00D6  ;; 133:LATIN CAPITAL LETTER O WITH DIAERESIS
 -      #x00DC  ;; 134:LATIN CAPITAL LETTER U WITH DIAERESIS
 -      #x00E1  ;; 135:LATIN SMALL LETTER A WITH ACUTE
 -      #x00E0  ;; 136:LATIN SMALL LETTER A WITH GRAVE
 -      #x00E2  ;; 137:LATIN SMALL LETTER A WITH CIRCUMFLEX
 -      #x00E4  ;; 138:LATIN SMALL LETTER A WITH DIAERESIS
 -      #x00E3  ;; 139:LATIN SMALL LETTER A WITH TILDE
 -      #x00E5  ;; 140:LATIN SMALL LETTER A WITH RING ABOVE
 -      #x00E7  ;; 141:LATIN SMALL LETTER C WITH CEDILLA
 -      #x00E9  ;; 142:LATIN SMALL LETTER E WITH ACUTE
 -      #x00E8  ;; 143:LATIN SMALL LETTER E WITH GRAVE
 -      #x00EA  ;; 144:LATIN SMALL LETTER E WITH CIRCUMFLEX
 -      #x00EB  ;; 145:LATIN SMALL LETTER E WITH DIAERESIS
 -      #x00ED  ;; 146:LATIN SMALL LETTER I WITH ACUTE
 -      #x00EC  ;; 147:LATIN SMALL LETTER I WITH GRAVE
 -      #x00EE  ;; 148:LATIN SMALL LETTER I WITH CIRCUMFLEX
 -      #x00EF  ;; 149:LATIN SMALL LETTER I WITH DIAERESIS
 -      #x00F1  ;; 150:LATIN SMALL LETTER N WITH TILDE
 -      #x00F3  ;; 151:LATIN SMALL LETTER O WITH ACUTE
 -      #x00F2  ;; 152:LATIN SMALL LETTER O WITH GRAVE
 -      #x00F4  ;; 153:LATIN SMALL LETTER O WITH CIRCUMFLEX
 -      #x00F6  ;; 154:LATIN SMALL LETTER O WITH DIAERESIS
 -      #x00F5  ;; 155:LATIN SMALL LETTER O WITH TILDE
 -      #x00FA  ;; 156:LATIN SMALL LETTER U WITH ACUTE
 -      #x00F9  ;; 157:LATIN SMALL LETTER U WITH GRAVE
 -      #x00FB  ;; 158:LATIN SMALL LETTER U WITH CIRCUMFLEX
 -      #x00FC  ;; 159:LATIN SMALL LETTER U WITH DIAERESIS
 -      #x2020  ;; 160:DAGGER
 -      #x00B0  ;; 161:DEGREE SIGN
 -      #x00A2  ;; 162:CENT SIGN
 -      #x00A3  ;; 163:POUND SIGN
 -      #x00A7  ;; 164:SECTION SIGN
 -      #x2022  ;; 165:BULLET
 -      #x00B6  ;; 166:PILCROW SIGN
 -      #x00DF  ;; 167:LATIN SMALL LETTER SHARP S
 -      #x00AE  ;; 168:REGISTERED SIGN
 -      #x00A9  ;; 169:COPYRIGHT SIGN
 -      #x2122  ;; 170:TRADE MARK SIGN
 -      #x00B4  ;; 171:ACUTE ACCENT
 -      #x00A8  ;; 172:DIAERESIS
 -      #x2260  ;; 173:NOT EQUAL TO
 -      #x00C6  ;; 174:LATIN CAPITAL LETTER AE
 -      #x00D8  ;; 175:LATIN CAPITAL LETTER O WITH STROKE
 -      #x221E  ;; 176:INFINITY
 -      #x00B1  ;; 177:PLUS-MINUS SIGN
 -      #x2264  ;; 178:LESS-THAN OR EQUAL TO
 -      #x2265  ;; 179:GREATER-THAN OR EQUAL TO
 -      #x00A5  ;; 180:YEN SIGN
 -      #x00B5  ;; 181:MICRO SIGN
 -      #x2202  ;; 182:PARTIAL DIFFERENTIAL
 -      #x2211  ;; 183:N-ARY SUMMATION
 -      #x220F  ;; 184:N-ARY PRODUCT
 -      #x03C0  ;; 185:GREEK SMALL LETTER PI
 -      #x222B  ;; 186:INTEGRAL
 -      #x00AA  ;; 187:FEMININE ORDINAL INDICATOR
 -      #x00BA  ;; 188:MASCULINE ORDINAL INDICATOR
 -      #x03A9  ;; 189:GREEK CAPITAL LETTER OMEGA
 -      #x00E6  ;; 190:LATIN SMALL LETTER AE
 -      #x00F8  ;; 191:LATIN SMALL LETTER O WITH STROKE
 -      #x00BF  ;; 192:INVERTED QUESTION MARK
 -      #x00A1  ;; 193:INVERTED EXCLAMATION MARK
 -      #x00AC  ;; 194:NOT SIGN
 -      #x221A  ;; 195:SQUARE ROOT
 -      #x0192  ;; 196:LATIN SMALL LETTER F WITH HOOK
 -      #x2248  ;; 197:ALMOST EQUAL TO
 -      #x2206  ;; 198:INCREMENT
 -      #x00AB  ;; 199:LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
 -      #x00BB  ;; 200:RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
 -      #x2026  ;; 201:HORIZONTAL ELLIPSIS
 -      #x00A0  ;; 202:NO-BREAK SPACE
 -      #x00C0  ;; 203:LATIN CAPITAL LETTER A WITH GRAVE
 -      #x00C3  ;; 204:LATIN CAPITAL LETTER A WITH TILDE
 -      #x00D5  ;; 205:LATIN CAPITAL LETTER O WITH TILDE
 -      #x0152  ;; 206:LATIN CAPITAL LIGATURE OE
 -      #x0153  ;; 207:LATIN SMALL LIGATURE OE
 -      #x2013  ;; 208:EN DASH
 -      #x2014  ;; 209:EM DASH
 -      #x201C  ;; 210:LEFT DOUBLE QUOTATION MARK
 -      #x201D  ;; 211:RIGHT DOUBLE QUOTATION MARK
 -      #x2018  ;; 212:LEFT SINGLE QUOTATION MARK
 -      #x2019  ;; 213:RIGHT SINGLE QUOTATION MARK
 -      #x00F7  ;; 214:DIVISION SIGN
 -      #x25CA  ;; 215:LOZENGE
 -      #x00FF  ;; 216:LATIN SMALL LETTER Y WITH DIAERESIS
 -      #x0178  ;; 217:LATIN CAPITAL LETTER Y WITH DIAERESIS
 -      #x2044  ;; 218:FRACTION SLASH
 -      #x20AC  ;; 219:EURO SIGN
 -      #x2039  ;; 220:SINGLE LEFT-POINTING ANGLE QUOTATION MARK
 -      #x203A  ;; 221:SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
 -      #xFB01  ;; 222:LATIN SMALL LIGATURE FI
 -      #xFB02  ;; 223:LATIN SMALL LIGATURE FL
 -      #x2021  ;; 224:DOUBLE DAGGER
 -      #x00B7  ;; 225:MIDDLE DOT
 -      #x201A  ;; 226:SINGLE LOW-9 QUOTATION MARK
 -      #x201E  ;; 227:DOUBLE LOW-9 QUOTATION MARK
 -      #x2030  ;; 228:PER MILLE SIGN
 -      #x00C2  ;; 229:LATIN CAPITAL LETTER A WITH CIRCUMFLEX
 -      #x00CA  ;; 230:LATIN CAPITAL LETTER E WITH CIRCUMFLEX
 -      #x00C1  ;; 231:LATIN CAPITAL LETTER A WITH ACUTE
 -      #x00CB  ;; 232:LATIN CAPITAL LETTER E WITH DIAERESIS
 -      #x00C8  ;; 233:LATIN CAPITAL LETTER E WITH GRAVE
 -      #x00CD  ;; 234:LATIN CAPITAL LETTER I WITH ACUTE
 -      #x00CE  ;; 235:LATIN CAPITAL LETTER I WITH CIRCUMFLEX
 -      #x00CF  ;; 236:LATIN CAPITAL LETTER I WITH DIAERESIS
 -      #x00CC  ;; 237:LATIN CAPITAL LETTER I WITH GRAVE
 -      #x00D3  ;; 238:LATIN CAPITAL LETTER O WITH ACUTE
 -      #x00D4  ;; 239:LATIN CAPITAL LETTER O WITH CIRCUMFLEX
 -      #xF8FF  ;; 240:Apple logo
 -      #x00D2  ;; 241:LATIN CAPITAL LETTER O WITH GRAVE
 -      #x00DA  ;; 242:LATIN CAPITAL LETTER U WITH ACUTE
 -      #x00DB  ;; 243:LATIN CAPITAL LETTER U WITH CIRCUMFLEX
 -      #x00D9  ;; 244:LATIN CAPITAL LETTER U WITH GRAVE
 -      #x0131  ;; 245:LATIN SMALL LETTER DOTLESS I
 -      #x02C6  ;; 246:MODIFIER LETTER CIRCUMFLEX ACCENT
 -      #x02DC  ;; 247:SMALL TILDE
 -      #x00AF  ;; 248:MACRON
 -      #x02D8  ;; 249:BREVE
 -      #x02D9  ;; 250:DOT ABOVE
 -      #x02DA  ;; 251:RING ABOVE
 -      #x00B8  ;; 252:CEDILLA
 -      #x02DD  ;; 253:DOUBLE ACUTE ACCENT
 -      #x02DB  ;; 254:OGONEK
 -      #x02C7  ;; 255:CARON
 -      ])
 -     translation-table)
 -  (while (< i 128)
 -    (aset encoding-vector i i)
 -    (setq i (1+ i)))
 -  (while (< i 256)
 -    (aset encoding-vector i
 -        (decode-char 'ucs (aref vec (- i 128))))
 -    (setq i (1+ i)))
 -  (setq translation-table
 -      (make-translation-table-from-vector encoding-vector))
 -  (define-translation-table 'mac-roman-decoder translation-table)
 -  (define-translation-table 'mac-roman-encoder
 -    (char-table-extra-slot translation-table 0)))
 -
 -(define-ccl-program decode-mac-roman
 -  `(4
 -    ((loop
 -      (read r1)
 -      (if (r1 < 128)  ;; ASCII
 -        (r0 = ,(charset-id 'ascii))
 -      (if (r1 < 160)
 -          (r0 = ,(charset-id 'eight-bit-control))
 -        (r0 = ,(charset-id 'eight-bit-graphic))))
 -      (translate-character mac-roman-decoder r0 r1)
 -      (write-multibyte-character r0 r1)
 -      (repeat))))
 -  "CCL program to decode Mac Roman")
 -
 -(define-ccl-program encode-mac-roman
 -  `(1
 -    ((loop
 -      (read-multibyte-character r0 r1)
 -      (translate-character ucs-mule-to-mule-unicode r0 r1)
 -      (translate-character mac-roman-encoder r0 r1)
 -      (if (r0 != ,(charset-id 'ascii))
 -        (if (r0 != ,(charset-id 'eight-bit-graphic))
 -            (if (r0 != ,(charset-id 'eight-bit-control))
 -                (r1 = ??))))
 -      (write-repeat r1))))
 -  "CCL program to encode Mac Roman")
 -
 -(make-coding-system
 - 'mac-roman 4 ?M
 - "Mac Roman Encoding (MIME:MACINTOSH)."
 - '(decode-mac-roman . encode-mac-roman)
 - (list (cons 'safe-chars (get 'mac-roman-encoder 'translation-table))
 -       '(valid-codes (0 . 255))
 -       '(mime-charset . macintosh)))          ; per IANA, rfc1345
 +(define-coding-system 'mac-roman
 +  "Mac Roman Encoding (MIME:MACINTOSH)."
 +  :coding-type 'charset
 +  :mnemonic ?M 
 +  :charset-list '(mac-roman)
 +  :mime-charset 'macintosh)
 +
 +(define-coding-system 'next
 +  "NeXTstep encoding"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(next)
 +  :mime-charset 'next)
 +
 +(define-coding-system 'hp-roman8
 +  "Hewlet-Packard roman-8 encoding (MIME:ROMAN-8)"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(hp-roman8)
 +  :mime-charset 'hp-roman8)
 +(define-coding-system-alias 'roman8 'hp-roman8)
 +
 +(define-coding-system 'adobe-standard-encoding
 +  "Adobe `standard' encoding for PostScript"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(adobe-standard-encoding)
 +  :mime-charset 'adobe-standard-encoding)
 +
 +\f
 +;; For automatic composing of diacritics and combining marks.
 +(dolist (range '( ;; combining diacritical marks
 +               (#x0300 #x0314 (tc . bc))
 +               (#x0315        (tr . bl))
 +               (#x0316 #x0319 (bc . tc))
 +               (#x031A        (tr . cl))
 +               (#x031B #x0320 (bc . tc))
 +               (#x0321        (Br . tr))
 +               (#x0322        (Br . tl))
 +               (#x0323 #x0333 (bc . tc))
 +               (#x0334 #x0338 (Bc . Bc))
 +               (#x0339 #x033C (bc . tc))
 +               (#x033D #x033F (tc . bc))
 +               (#x0340        (tl . bc))
 +               (#x0341        (tr . bc))
 +               (#x0342 #x0344 (tc . bc))
 +               (#x0345        (bc . tc))
 +               (#x0346        (tc . bc))
 +               (#x0347 #x0349 (bc . tc))
 +               (#x034A #x034C (tc . bc))
 +               (#x034D #x034E (bc . tc))
 +               ;; combining diacritical marks for symbols
 +               (#x20D0 #x20D1 (tc . bc))
 +               (#x20D2 #x20D3 (Bc . Bc))
 +               (#x20D4 #x20D7 (tc . bc))
 +               (#x20D8 #x20DA (Bc . Bc))
 +               (#x20DB #x20DC (tc . bc))
 +               (#x20DD #x20E0 (Bc . Bc))
 +               (#x20E1        (tc . bc))
 +               (#x20E2 #x20E3 (Bc . Bc))))
 +  (let* ((from (car range))
 +       (to (if (= (length range) 3)
 +               (nth 1 range)
 +             from))
 +       (composition (car (last range))))
 +    (while (<= from to)
 +      (put-char-code-property from 'diacritic-composition composition)
 +      (aset composition-function-table from 'diacritic-composition-function)
 +      (setq from (1+ from)))))
  
  (defconst diacritic-composition-pattern "\\C^\\c^+")
  
@@@ -678,15 -686,13 +678,15 @@@ positions (integers or markers) specify
      (narrow-to-region beg end)
      (goto-char (point-min))
      (while (re-search-forward diacritic-composition-pattern nil t)
 -      (compose-region (match-beginning 0) (match-end 0)))))
 +      (if (= (char-syntax (char-after (match-beginning 0))) ?w)
 +        (compose-region (match-beginning 0) (match-end 0))))))
  
  (defun diacritic-compose-string (string)
    "Compose diacritic characters in STRING and return the resulting string."
    (let ((idx 0))
      (while (setq idx (string-match diacritic-composition-pattern string idx))
 -      (compose-string string idx (match-end 0))
 +      (if (= (char-syntax (aref string idx)) ?w)
 +        (compose-string string idx (match-end 0)))
        (setq idx (match-end 0))))
    string)
  
    (interactive)
    (diacritic-compose-region (point-min) (point-max)))
  
 -(defun diacritic-post-read-conversion (len)
 -  (diacritic-compose-region (point) (+ (point) len))
 -  len)
 -
 -(defun diacritic-composition-function (from to pattern &optional string)
 -  "Compose diacritic text in the region FROM and TO.
 -The text matches the regular expression PATTERN.
 -Optional 4th argument STRING, if non-nil, is a string containing text
 +(defun diacritic-composition-function (pos &optional string)
 +  "Compose diacritic text around POS.
 +Optional 2nd argument STRING, if non-nil, is a string containing text
  to compose.
  
 -The return value is the number of composed characters."
 -  (when (< (1+ from) to)
 -      (if string
 -        (compose-string string from to)
 -      (compose-region from to))
 -      (- to from)))
 -
 -;; Register a function to compose Unicode diacrtics and marks.
 -(let ((patterns '(("\\C^\\c^+" . diacritic-composition-function))))
 -  (let ((c #x300))
 -    (while (<= c #x362)
 -      (aset composition-function-table (decode-char 'ucs c) patterns)
 -      (setq c (1+ c)))
 -    (setq c #x20d0)
 -    (while (<= c #x20e3)
 -      (aset composition-function-table (decode-char 'ucs c) patterns)
 -      (setq c (1+ c)))))
 +The return value is the end position of composed characters,
 +or nil if no characters are composed."
 +  (setq pos (1- pos))
 +  (if string
 +      (if (>= pos 0)
 +        (let ((ch (aref string pos))
 +              start end components ch composition)
 +          (when (= (char-syntax ch) ?w)
 +            (setq start pos
 +                  end (length string)
 +                  components (list ch)
 +                  pos (1+ pos))
 +            (while (and
 +                    (< pos end)
 +                    (setq ch (aref string pos)
 +                          composition
 +                          (get-char-code-property ch
 +                                                  'diacritic-composition)))
 +              (setq components (cons ch (cons composition components))
 +                    pos (1+ pos)))
 +            (compose-string string start pos (nreverse components))
 +            pos)))
 +    (if (>= pos (point-min))
 +      (let ((ch (char-after pos))
 +            start end components composition)
 +        (when (= (char-syntax ch) ?w)
 +          (setq start pos
 +                end (point-max)
 +                components (list ch)
 +                pos (1+ pos))
 +          (while (and
 +                  (< pos end)
 +                  (setq ch (char-after pos)
 +                        composition
 +                        (get-char-code-property ch 'diacritic-composition)))
 +            (setq components (cons ch (cons composition components))
 +                  pos (1+ pos)))
 +          (compose-region start pos (nreverse components))
 +          pos)))))
  
  (provide 'european)
  
index 5546df81d7e0fa6ca84862cf06289ec7b846ce77,21b61b2667cb1d4141bf719c013c36eb3cb0a362..a1b565e76d415e767db61b9d35290674a5edb7b0
@@@ -1,6 -1,6 +1,6 @@@
  ;;; georgian.el --- language support for Georgian -*- no-byte-compile: t -*-
  
- ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  
  ;; Author: Dave Love <fx@gnu.org>
  
  ;;; Code:
  
 +(define-coding-system 'georgian-ps
 +  "Georgian PS encoding"
 +  :coding-type 'charset
 +  :mnemonic ?G
 +  :charset-list '(georgian-ps))
 +
 +(define-coding-system 'georgian-academy
 +  "Georgian Academy encoding"
 +  :coding-type 'charset
 +  :mnemonic ?G
 +  :charset-list '(georgian-academy))
 +
  (set-language-info-alist
   "Georgian" `((coding-system georgian-ps)
              (coding-priority georgian-ps)
              (input-method . "georgian")
 -            (features code-pages)
 -            (nonascii-translation . ,(get 'decode-georgian-ps
 -                                          'translation-table))
 +            (nonascii-translation . georgian-ps)
              (documentation . "Support for georgian-ps character set."))
   '("European"))                               ; fixme: is this appropriate for
                                        ; a non-Latin script?
diff --combined lisp/language/greek.el
index aca46aa6b247f5b64acf8ae9c0ae1df230224f0a,c391319b8852b7ea8f073961e35f006f1ced66cf..1ece8c0fd647e58d080c26f8b4d211743fc6781a
@@@ -1,15 -1,10 +1,15 @@@
  ;;; greek.el --- support for Greek -*- no-byte-compile: t -*-
  
 +;; Copyright (C) 2002 Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
 +
  ;; Keywords: multilingual, Greek
  
  ;; This file is part of GNU Emacs.
  
  ;;; Code:
  
 -(make-coding-system
 - 'greek-iso-8bit 2 ?7
 - "ISO 2022 based 8-bit encoding for Greek (MIME:ISO-8859-7)."
 - '(ascii greek-iso8859-7 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii greek-iso8859-7)
 -   (mime-charset . iso-8859-7)))
 +(define-coding-system 'greek-iso-8bit
 +  "ISO 2022 based 8-bit encoding for Greek (MIME:ISO-8859-7)."
 +  :coding-type 'charset
 +  :mnemonic ?7
 +  :charset-list '(iso-8859-7)
 +  :mime-charset 'iso-8859-7)
  
  (define-coding-system-alias 'iso-8859-7 'greek-iso-8bit)
  
 +(define-coding-system 'windows-1253
 +  "windows-1253 encoding for Greek"
 +  :coding-type 'charset
 +  :mnemonic ?g
 +  :charset-list '(windows-1253)
 +  :mime-charset 'windows-1253)
 +(define-coding-system-alias 'cp1253 'windows-1253)
 +
 +(define-coding-system 'cp737
 +  "Codepage 737 (PC Greek)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp737)
 +  :mime-charset 'cp737)
 +
 +(define-coding-system 'cp851
 +  "DOS codepage 851 (Greek)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp851)
 +  :mime-charset 'cp851)
 +(define-coding-system-alias 'ibm851 'cp851)
 +
 +(define-coding-system 'cp869
 +  "DOS codepage 869 (Greek)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp869)
 +  :mime-charset 'cp869)
 +(define-coding-system-alias 'ibm869 'cp869)
 +
  (set-language-info-alist
 - "Greek" '((charset . (greek-iso8859-7))
 -         (coding-system . (greek-iso-8bit))
 + "Greek" '((charset iso-8859-7)
 +         (coding-system greek-iso-8bit windows-1253 cp851 cp869)
           (coding-priority greek-iso-8bit)
 -         (nonascii-translation . greek-iso8859-7)
 +         (nonascii-translation . iso-8859-7)
           (input-method . "greek")
 -         (unibyte-display . greek-iso-8bit)
           (documentation . t)))
  
  (provide 'greek)
diff --combined lisp/language/hebrew.el
index f9c9aa68b7ba072f96f16648f30648477e595534,715b06190b46c8c217cd7adb0eeae3456545e802..dd72f4360cda84bbff0c1a1c2348b2fefedb2d78
@@@ -1,16 -1,12 +1,16 @@@
  ;;; hebrew.el --- support for Hebrew -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
 +
  ;; Keywords: multilingual, Hebrew
  
  ;; This file is part of GNU Emacs.
  
  ;;; Code:
  
 -(make-coding-system
 - 'hebrew-iso-8bit 2 ?8
 - "ISO 2022 based 8-bit encoding for Hebrew (MIME:ISO-8859-8)."
 - '(ascii hebrew-iso8859-8 nil nil
 -   nil nil nil nil nil nil nil nil t nil nil t)
 - '((safe-charsets ascii hebrew-iso8859-8)
 -   (mime-charset . iso-8859-8)))
 +(define-coding-system 'hebrew-iso-8bit
 +  "ISO 2022 based 8-bit encoding for Hebrew (MIME:ISO-8859-8)."
 +  :coding-type 'charset
 +  :mnemonic ?8
 +  :charset-list '(iso-8859-8)
 +  :mime-charset 'iso-8859-8)
  
  (define-coding-system-alias 'iso-8859-8 'hebrew-iso-8bit)
  
  (define-coding-system-alias 'iso-8859-8-i 'hebrew-iso-8bit)
  
  (set-language-info-alist
 - "Hebrew" '((charset . (hebrew-iso8859-8))
 + "Hebrew" '((charset iso-8859-8)
            (coding-priority hebrew-iso-8bit)
 -          (coding-system . (hebrew-iso-8bit))
 -          (nonascii-translation . hebrew-iso8859-8)
 +          (coding-system hebrew-iso-8bit windows-1255 cp862)
 +          (nonascii-translation . iso-8859-8)
            (input-method . "hebrew")
            (unibyte-display . hebrew-iso-8bit)
            (sample-text . "Hebrew      \e,Hylem\e(B")
  (set-language-info-alist
   "Windows-1255" '((coding-priority windows-1255)
                  (coding-system windows-1255)
 -                (features code-pages)
                  (documentation . "\
  Support for Windows-1255 encoding, e.g. for Yiddish.
  Right-to-left writing is not yet supported.")))
  
 +(define-coding-system 'windows-1255
 +  "windows-1255 (Hebrew) encoding (MIME: WINDOWS-1255)"
 +  :coding-type 'charset
 +  :mnemonic ?h
 +  :charset-list '(windows-1255)
 +  :mime-charset 'windows-1255)
 +(define-coding-system-alias 'cp1255 'windows-1255)
 +
 +(define-coding-system 'cp862
 +  "DOS codepage 862 (Hebrew)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp862)
 +  :mime-charset 'cp862)
 +(define-coding-system-alias 'ibm862 'cp862)
 +
  (provide 'hebrew)
  
  ;;; arch-tag: 3ca04f32-3f1e-498e-af46-8267498ba5d9
index 2693a565f021011d3d788bbf31b58d39610c9d39,521fc2523720aca397f7aa02faaeef7a1d66b7ce..6c03629717255e21a25aa46568861ec98a5119cc
@@@ -1,6 -1,6 +1,6 @@@
  ;;; ind-util.el --- Transliteration and Misc. Tools for Indian Languages -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  
  ;; Maintainer:  KAWABATA, Taichi <kawabata@m17n.org>
@@@ -408,7 -408,7 +408,7 @@@ FUNCTION will be called 15 times.
      ;; trans-char -- nil / string / list of strings
      (when (and char trans-char)
        (if (stringp trans-char) (setq trans-char (list trans-char)))
 -      (if (char-valid-p char) (setq char (char-to-string char)))
 +      (if (characterp char) (setq char (char-to-string char)))
        (puthash char (car trans-char) encode-hash)
        (dolist (trans trans-char)
         (puthash trans char decode-hash)))))
  (defun indian--puthash-c (c trans-c halant hashtbls)
    (indian--map
     (lambda (c trans-c)
 -     (if (char-valid-p c) (setq c (char-to-string c)))
 +     (if (characterp c) (setq c (char-to-string c)))
       (indian--puthash-char (concat c halant) trans-c hashtbls))
     c trans-c))
  
       (indian--map
        (lambda (v trans-v)
        (when (and c trans-c  v trans-v)
 -        (if (char-valid-p c) (setq c (char-to-string c)))
 -        (setq v (if (char-valid-p (cadr v)) (char-to-string (cadr v)) ""))
 +        (if (characterp c) (setq c (char-to-string c)))
 +        (setq v (if (characterp (cadr v)) (char-to-string (cadr v)) ""))
          (if (stringp trans-c) (setq trans-c (list trans-c)))
          (if (stringp trans-v) (setq trans-v (list trans-v)))
          (indian--puthash-char
  
  ;; The followings provide conversion between IS 13194 (ISCII) and UCS.
  
 -(defvar ucs-devanagari-to-is13194-alist
 -  '(;;Unicode vs IS13194  ;; only Devanagari is supported now.
 -    (?\x0900 . "[U+0900]")
 -    (?\x0901 . "\e(5!\e(B")
 -    (?\x0902 . "\e(5"\e(B")
 -    (?\x0903 . "\e(5#\e(B")
 -    (?\x0904 . "[U+0904]")
 -    (?\x0905 . "\e(5$\e(B")
 -    (?\x0906 . "\e(5%\e(B")
 -    (?\x0907 . "\e(5&\e(B")
 -    (?\x0908 . "\e(5'\e(B")
 -    (?\x0909 . "\e(5(\e(B")
 -    (?\x090a . "\e(5)\e(B")
 -    (?\x090b . "\e(5*\e(B")
 -    (?\x090c . "\e(5&i\e(B")
 -    (?\x090d . "\e(5.\e(B")
 -    (?\x090e . "\e(5+\e(B")
 -    (?\x090f . "\e(5,\e(B")
 -    (?\x0910 . "\e(5-\e(B")
 -    (?\x0911 . "\e(52\e(B")
 -    (?\x0912 . "\e(5/\e(B")
 -    (?\x0913 . "\e(50\e(B")
 -    (?\x0914 . "\e(51\e(B")
 -    (?\x0915 . "\e(53\e(B")
 -    (?\x0916 . "\e(54\e(B")
 -    (?\x0917 . "\e(55\e(B")
 -    (?\x0918 . "\e(56\e(B")
 -    (?\x0919 . "\e(57\e(B")
 -    (?\x091a . "\e(58\e(B")
 -    (?\x091b . "\e(59\e(B")
 -    (?\x091c . "\e(5:\e(B")
 -    (?\x091d . "\e(5;\e(B")
 -    (?\x091e . "\e(5<\e(B")
 -    (?\x091f . "\e(5=\e(B")
 -    (?\x0920 . "\e(5>\e(B")
 -    (?\x0921 . "\e(5?\e(B")
 -    (?\x0922 . "\e(5@\e(B")
 -    (?\x0923 . "\e(5A\e(B")
 -    (?\x0924 . "\e(5B\e(B")
 -    (?\x0925 . "\e(5C\e(B")
 -    (?\x0926 . "\e(5D\e(B")
 -    (?\x0927 . "\e(5E\e(B")
 -    (?\x0928 . "\e(5F\e(B")
 -    (?\x0929 . "\e(5G\e(B")
 -    (?\x092a . "\e(5H\e(B")
 -    (?\x092b . "\e(5I\e(B")
 -    (?\x092c . "\e(5J\e(B")
 -    (?\x092d . "\e(5K\e(B")
 -    (?\x092e . "\e(5L\e(B")
 -    (?\x092f . "\e(5M\e(B")
 -    (?\x0930 . "\e(5O\e(B")
 -    (?\x0931 . "\e(5P\e(B")
 -    (?\x0932 . "\e(5Q\e(B")
 -    (?\x0933 . "\e(5R\e(B")
 -    (?\x0934 . "\e(5S\e(B")
 -    (?\x0935 . "\e(5T\e(B")
 -    (?\x0936 . "\e(5U\e(B")
 -    (?\x0937 . "\e(5V\e(B")
 -    (?\x0938 . "\e(5W\e(B")
 -    (?\x0939 . "\e(5X\e(B")
 -    (?\x093a . "[U+093a]")
 -    (?\x093b . "[U+093b]")
 -    (?\x093c . "\e(5i\e(B")
 -    (?\x093d . "\e(5ji\e(B")
 -    (?\x093e . "\e(5Z\e(B")
 -    (?\x093f . "\e(5[\e(B")
 -    (?\x0940 . "\e(5\\e(B")
 -    (?\x0941 . "\e(5]\e(B")
 -    (?\x0942 . "\e(5^\e(B")
 -    (?\x0943 . "\e(5_\e(B")
 -    (?\x0944 . "\e(5_i\e(B")
 -    (?\x0945 . "\e(5c\e(B")
 -    (?\x0946 . "\e(5`\e(B")
 -    (?\x0947 . "\e(5a\e(B")
 -    (?\x0948 . "\e(5b\e(B")
 -    (?\x0949 . "\e(5g\e(B")
 -    (?\x094a . "\e(5d\e(B")
 -    (?\x094b . "\e(5e\e(B")
 -    (?\x094c . "\e(5f\e(B")
 -    (?\x094d . "\e(5h\e(B")
 -    (?\x094e . "[U+094e]")
 -    (?\x094f . "[U+094f]")
 -    (?\x0950 . "\e(5!i\e(B")
 -    (?\x0951 . "\e(5p5\e(B")
 -    (?\x0952 . "\e(5p8\e(B")
 -    (?\x0953 . "[DEVANAGARI GRAVE ACCENT]")
 -    (?\x0954 . "[DEVANAGARI ACUTE ACCENT]")
 -    (?\x0955 . "[U+0955]")
 -    (?\x0956 . "[U+0956]")
 -    (?\x0957 . "[U+0957]")
 -    (?\x0958 . "\e(53i\e(B")
 -    (?\x0959 . "\e(54i\e(B")
 -    (?\x095a . "\e(55i\e(B")
 -    (?\x095b . "\e(5:i\e(B")
 -    (?\x095c . "\e(5?i\e(B")
 -    (?\x095d . "\e(5@i\e(B")
 -    (?\x095e . "\e(5Ii\e(B")
 -    (?\x095f . "\e(5N\e(B")
 -    (?\x0960 . "\e(5*i\e(B")
 -    (?\x0961 . "\e(5'i\e(B")
 -    (?\x0962 . "\e(5[i\e(B")
 -    (?\x0963 . "\e(5ei\e(B")
 -    (?\x0964 . "\e(5j\e(B")
 -    (?\x0965 . "\e(5jj\e(B")
 -    (?\x0966 . "\e(5q\e(B")
 -    (?\x0967 . "\e(5r\e(B")
 -    (?\x0968 . "\e(5s\e(B")
 -    (?\x0969 . "\e(5t\e(B")
 -    (?\x096a . "\e(5u\e(B")
 -    (?\x096b . "\e(5v\e(B")
 -    (?\x096c . "\e(5w\e(B")
 -    (?\x096d . "\e(5x\e(B")
 -    (?\x096e . "\e(5y\e(B")
 -    (?\x096f . "\e(5z\e(B")
 -    (?\x0970 . "[U+0970]")
 -    (?\x0971 . "[U+0971]")
 -    (?\x0972 . "[U+0972]")
 -    (?\x0973 . "[U+0973]")
 -    (?\x0974 . "[U+0974]")
 -    (?\x0975 . "[U+0975]")
 -    (?\x0976 . "[U+0976]")
 -    (?\x0977 . "[U+0977]")
 -    (?\x0978 . "[U+0978]")
 -    (?\x0979 . "[U+0979]")
 -    (?\x097a . "[U+097a]")
 -    (?\x097b . "[U+097b]")
 -    (?\x097c . "[U+097c]")
 -    (?\x097d . "[U+097d]")
 -    (?\x097e . "[U+097e]")
 -    (?\x097f . "[U+097f]")))
 -
 -(defvar ucs-bengali-to-is13194-alist nil)
 -(defvar ucs-assamese-to-is13194-alist nil)
 -(defvar ucs-gurmukhi-to-is13194-alist nil)
 -(defvar ucs-gujarati-to-is13194-alist nil)
 -(defvar ucs-oriya-to-is13194-alist nil)
 -(defvar ucs-tamil-to-is13194-alist nil)
 -(defvar ucs-telugu-to-is13194-alist nil)
 -(defvar ucs-malayalam-to-is13194-alist nil)
 -(defvar ucs-kannada-to-is13194-alist nil)
 -
 -(defvar is13194-default-repartory 'devanagari)
 +(let
 +    ;;Unicode vs IS13194  ;; only Devanagari is supported now.
 +    ((ucs-devanagari-to-is13194-alist
 +      '((?\x0900 . "[U+0900]")
 +      (?\x0901 . "\e(5!\e(B")
 +      (?\x0902 . "\e(5"\e(B")
 +      (?\x0903 . "\e(5#\e(B")
 +      (?\x0904 . "[U+0904]")
 +      (?\x0905 . "\e(5$\e(B")
 +      (?\x0906 . "\e(5%\e(B")
 +      (?\x0907 . "\e(5&\e(B")
 +      (?\x0908 . "\e(5'\e(B")
 +      (?\x0909 . "\e(5(\e(B")
 +      (?\x090a . "\e(5)\e(B")
 +      (?\x090b . "\e(5*\e(B")
 +      (?\x090c . "\e(5&i\e(B")
 +      (?\x090d . "\e(5.\e(B")
 +      (?\x090e . "\e(5+\e(B")
 +      (?\x090f . "\e(5,\e(B")
 +      (?\x0910 . "\e(5-\e(B")
 +      (?\x0911 . "\e(52\e(B")
 +      (?\x0912 . "\e(5/\e(B")
 +      (?\x0913 . "\e(50\e(B")
 +      (?\x0914 . "\e(51\e(B")
 +      (?\x0915 . "\e(53\e(B")
 +      (?\x0916 . "\e(54\e(B")
 +      (?\x0917 . "\e(55\e(B")
 +      (?\x0918 . "\e(56\e(B")
 +      (?\x0919 . "\e(57\e(B")
 +      (?\x091a . "\e(58\e(B")
 +      (?\x091b . "\e(59\e(B")
 +      (?\x091c . "\e(5:\e(B")
 +      (?\x091d . "\e(5;\e(B")
 +      (?\x091e . "\e(5<\e(B")
 +      (?\x091f . "\e(5=\e(B")
 +      (?\x0920 . "\e(5>\e(B")
 +      (?\x0921 . "\e(5?\e(B")
 +      (?\x0922 . "\e(5@\e(B")
 +      (?\x0923 . "\e(5A\e(B")
 +      (?\x0924 . "\e(5B\e(B")
 +      (?\x0925 . "\e(5C\e(B")
 +      (?\x0926 . "\e(5D\e(B")
 +      (?\x0927 . "\e(5E\e(B")
 +      (?\x0928 . "\e(5F\e(B")
 +      (?\x0929 . "\e(5G\e(B")
 +      (?\x092a . "\e(5H\e(B")
 +      (?\x092b . "\e(5I\e(B")
 +      (?\x092c . "\e(5J\e(B")
 +      (?\x092d . "\e(5K\e(B")
 +      (?\x092e . "\e(5L\e(B")
 +      (?\x092f . "\e(5M\e(B")
 +      (?\x0930 . "\e(5O\e(B")
 +      (?\x0931 . "\e(5P\e(B")
 +      (?\x0932 . "\e(5Q\e(B")
 +      (?\x0933 . "\e(5R\e(B")
 +      (?\x0934 . "\e(5S\e(B")
 +      (?\x0935 . "\e(5T\e(B")
 +      (?\x0936 . "\e(5U\e(B")
 +      (?\x0937 . "\e(5V\e(B")
 +      (?\x0938 . "\e(5W\e(B")
 +      (?\x0939 . "\e(5X\e(B")
 +      (?\x093a . "[U+093a]")
 +      (?\x093b . "[U+093b]")
 +      (?\x093c . "\e(5i\e(B")
 +      (?\x093d . "\e(5ji\e(B")
 +      (?\x093e . "\e(5Z\e(B")
 +      (?\x093f . "\e(5[\e(B")
 +      (?\x0940 . "\e(5\\e(B")
 +      (?\x0941 . "\e(5]\e(B")
 +      (?\x0942 . "\e(5^\e(B")
 +      (?\x0943 . "\e(5_\e(B")
 +      (?\x0944 . "\e(5_i\e(B")
 +      (?\x0945 . "\e(5c\e(B")
 +      (?\x0946 . "\e(5`\e(B")
 +      (?\x0947 . "\e(5a\e(B")
 +      (?\x0948 . "\e(5b\e(B")
 +      (?\x0949 . "\e(5g\e(B")
 +      (?\x094a . "\e(5d\e(B")
 +      (?\x094b . "\e(5e\e(B")
 +      (?\x094c . "\e(5f\e(B")
 +      (?\x094d . "\e(5h\e(B")
 +      (?\x094e . "[U+094e]")
 +      (?\x094f . "[U+094f]")
 +      (?\x0950 . "\e(5!i\e(B")
 +      (?\x0951 . "\e(5p5\e(B")
 +      (?\x0952 . "\e(5p8\e(B")
 +      (?\x0953 . "[DEVANAGARI GRAVE ACCENT]")
 +      (?\x0954 . "[DEVANAGARI ACUTE ACCENT]")
 +      (?\x0955 . "[U+0955]")
 +      (?\x0956 . "[U+0956]")
 +      (?\x0957 . "[U+0957]")
 +      (?\x0958 . "\e(53i\e(B")
 +      (?\x0959 . "\e(54i\e(B")
 +      (?\x095a . "\e(55i\e(B")
 +      (?\x095b . "\e(5:i\e(B")
 +      (?\x095c . "\e(5?i\e(B")
 +      (?\x095d . "\e(5@i\e(B")
 +      (?\x095e . "\e(5Ii\e(B")
 +      (?\x095f . "\e(5N\e(B")
 +      (?\x0960 . "\e(5*i\e(B")
 +      (?\x0961 . "\e(5'i\e(B")
 +      (?\x0962 . "\e(5[i\e(B")
 +      (?\x0963 . "\e(5ei\e(B")
 +      (?\x0964 . "\e(5j\e(B")
 +      (?\x0965 . "\e(5jj\e(B")
 +      (?\x0966 . "\e(5q\e(B")
 +      (?\x0967 . "\e(5r\e(B")
 +      (?\x0968 . "\e(5s\e(B")
 +      (?\x0969 . "\e(5t\e(B")
 +      (?\x096a . "\e(5u\e(B")
 +      (?\x096b . "\e(5v\e(B")
 +      (?\x096c . "\e(5w\e(B")
 +      (?\x096d . "\e(5x\e(B")
 +      (?\x096e . "\e(5y\e(B")
 +      (?\x096f . "\e(5z\e(B")
 +      (?\x0970 . "[U+0970]")
 +      (?\x0971 . "[U+0971]")
 +      (?\x0972 . "[U+0972]")
 +      (?\x0973 . "[U+0973]")
 +      (?\x0974 . "[U+0974]")
 +      (?\x0975 . "[U+0975]")
 +      (?\x0976 . "[U+0976]")
 +      (?\x0977 . "[U+0977]")
 +      (?\x0978 . "[U+0978]")
 +      (?\x0979 . "[U+0979]")
 +      (?\x097a . "[U+097a]")
 +      (?\x097b . "[U+097b]")
 +      (?\x097c . "[U+097c]")
 +      (?\x097d . "[U+097d]")
 +      (?\x097e . "[U+097e]")
 +      (?\x097f . "[U+097f]")))
 +     (ucs-bengali-to-is13194-alist nil)
 +     (ucs-assamese-to-is13194-alist nil)
 +     (ucs-gurmukhi-to-is13194-alist nil)
 +     (ucs-gujarati-to-is13194-alist nil)
 +     (ucs-oriya-to-is13194-alist nil)
 +     (ucs-tamil-to-is13194-alist nil)
 +     (ucs-telugu-to-is13194-alist nil)
 +     (ucs-malayalam-to-is13194-alist nil)
 +     (ucs-kannada-to-is13194-alist nil))
 +  (dolist (script '(devanagari bengali assamese gurmukhi gujarati
 +                  oriya tamil telugu malayalam kannada))
 +   (let ((hashtable (intern (concat "is13194-to-ucs-"
 +                                  (symbol-name script) "-hashtbl" )))
 +       (regexp    (intern (concat "is13194-to-ucs-"
 +                                  (symbol-name script) "-regexp"))))
 +     (set hashtable (make-hash-table :test 'equal :size 128))
 +     (dolist (x (eval (intern (concat "ucs-" (symbol-name script)
 +                                    "-to-is13194-alist"))))
 +       (put-char-code-property (car x) 'script script)
 +       (put-char-code-property (car x) 'iscii (cdr x))
 +       (puthash (cdr x) (char-to-string (car x)) (eval hashtable)))
 +      (set regexp (indian-regexp-of-hashtbl-keys (eval hashtable))))))
 +
 +(defvar is13194-default-repertory 'devanagari)
  
  (defvar is13194-repertory-to-ucs-script
 -  `((DEF ?\x40 ,is13194-default-repartory)
 -    (RMN ?\x41 ,is13194-default-repartory)
 +  `((DEF ?\x40 ,is13194-default-repertory)
 +    (RMN ?\x41 ,is13194-default-repertory)
      (DEV ?\x42 devanagari)
      (BNG ?\x43 bengali)
      (TML ?\x44 tamil)
  (defvar is13194-to-ucs-kannada-hashtbl nil)
  (defvar is13194-to-ucs-kannada-regexp nil)
  
 -(mapc
 - (function (lambda (script)
 -   (let ((hashtable (intern (concat "is13194-to-ucs-"
 -                                    (symbol-name script) "-hashtbl" )))
 -         (regexp    (intern (concat "is13194-to-ucs-"
 -                                    (symbol-name script) "-regexp"))))
 -     (set hashtable (make-hash-table :test 'equal :size 128))
 -     (mapc
 -      (function (lambda (x)
 -        (put-char-code-property (decode-char 'ucs (car x))
 -                                'script script)
 -        (put-char-code-property (decode-char 'ucs (car x))
 -                                'iscii (cdr x))
 -        (puthash (cdr x) (char-to-string (decode-char 'ucs (car x)))
 -                 (eval hashtable))))
 -      (eval (intern (concat "ucs-" (symbol-name script)
 -                            "-to-is13194-alist"))))
 -     (set regexp (indian-regexp-of-hashtbl-keys (eval hashtable))))))
 - '(devanagari bengali assamese gurmukhi gujarati
 -   oriya tamil telugu malayalam kannada))
 -
  (defvar ucs-to-is13194-regexp
    ;; only Devanagari is supported now.
 -  (concat "[" (char-to-string (decode-char 'ucs #x0900))
 -          "-" (char-to-string (decode-char 'ucs #x097f)) "]")
 +  (concat "[" (char-to-string #x0900)
 +          "-" (char-to-string #x097f) "]")
    "Regexp that matches to conversion")
  
  (defun ucs-to-iscii-region (from to)
@@@ -784,11 -792,11 +784,11 @@@ Returns new end position.
      (save-restriction
        (narrow-to-region from to)
        (goto-char (point-min))
 -      (let* ((current-repertory is13194-default-repartory))
 -        (while (re-search-forward ucs-to-is13194-regexp nil t)
 -          (replace-match
 -           (get-char-code-property (string-to-char (match-string 0))
 -                                   'iscii))))
 +      (let* ((current-repertory is13194-default-repertory))
 +      (while (re-search-forward ucs-to-is13194-regexp nil t)
 +        (replace-match
 +         (get-char-code-property (string-to-char (match-string 0))
 +                                 'iscii))))
        (point-max))))
  
  (defun iscii-to-ucs-region (from to)
@@@ -800,17 -808,16 +800,17 @@@ Returns new end position.
      (save-restriction
        (narrow-to-region from to)
        (goto-char (point-min))
 -      (let* ((current-repertory is13194-default-repartory)
 -             (current-hashtable
 -              (intern (concat "is13194-to-ucs-"
 -                              (symbol-name current-repertory) "-hashtbl")))
 -             (current-regexp
 -              (intern (concat "is13194-to-ucs-"
 -                              (symbol-name current-repertory) "-regexp"))))
 -        (while (re-search-forward (eval current-regexp) nil t)
 -          (replace-match
 -           (gethash (match-string 0) (eval current-hashtable) ""))))
 +      (let* ((current-repertory is13194-default-repertory)
 +           (current-hashtable
 +            (intern (concat "is13194-to-ucs-"
 +                            (symbol-name current-repertory) "-hashtbl")))
 +           (current-regexp
 +            (intern (concat "is13194-to-ucs-"
 +                            (symbol-name current-repertory) "-regexp")))
 +           (re (eval current-regexp))
 +           (hash (eval current-hashtable)))
 +      (while (re-search-forward re nil t)
 +        (replace-match (gethash (match-string 0) hash ""))))
        (point-max))))
  
  ;;;###autoload
    (interactive "r")
    (save-excursion
      (save-restriction
 -      (let ((pos from) chars (max to))
 -        (narrow-to-region from to)
 -        (while (< pos max)
 -          (setq chars (compose-chars-after pos))
 -          (if chars (setq pos (+ pos chars)) (setq pos (1+ pos))))))))
 +      (let ((pos from) newpos func (max to))
 +      (narrow-to-region from to)
 +      (while (< pos max)
 +        (setq func (aref composition-function-table (char-after pos)))
 +        (if (fboundp func)
 +            (setq newpos (funcall func pos nil)
 +                  pos (if (and (integerp newpos) (> newpos pos))
 +                          newpos (1+ pos)))
 +          (setq pos (1+ pos))))))))
  
  ;;;###autoload
  (defun indian-compose-string (string)
  
  ;;; Backward Compatibility support programs
  
 -;; The followings provides the conversion from old-implementation of
 +;; The following provides the conversion from old-implementation of
  ;; Emacs Devanagari script to UCS.
  
  (defconst indian-2-colum-to-ucs
    '(
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2120   \e$(5!!!"!#!$!%!&!'!(!)!*!+!,!-!.!/\e(B
 -  ("\e$(5!!\e(B" . "\e$,15A\e(B")
 -  ("\e$(5!"\e(B" . "\e$,15B\e(B")
 -  ("\e$(5!#\e(B" . "\e$,15C\e(B")
 -  ("\e$(5!$\e(B" . "\e$,15E\e(B")
 -  ("\e$(5!%\e(B" . "\e$,15F\e(B")
 -  ("\e$(5!&\e(B" . "\e$,15G\e(B")
 -  ("\e$(5!'\e(B" . "\e$,15H\e(B")
 -  ("\e$(5!(\e(B" . "\e$,15I\e(B")
 -  ("\e$(5!)\e(B" . "\e$,15J\e(B")
 -  ("\e$(5!*\e(B" . "\e$,15K\e(B")
 -  ("\e$(5!*"p\e(B" . "\e$,15p6#\e(B")
 -  ("\e$(5!+\e(B" . "\e$,15N\e(B")
 -  ("\e$(5!,\e(B" . "\e$,15O\e(B")
 -  ("\e$(5!-\e(B" . "\e$,15P\e(B")
 -  ("\e$(5!.\e(B" . "\e$,15M\e(B")
 -  ("\e$(5!/\e(B" . "\e$,15R\e(B")
 +  ;;2120   \e$(6!!!"!#!$!%!&!'!(!)!*!+!,!-!.!/\e(B
 +  ("\e$(6!!\e(B" . "\e$,15A\e(B")
 +  ("\e$(6!"\e(B" . "\e$,15B\e(B")
 +  ("\e$(6!#\e(B" . "\e$,15C\e(B")
 +  ("\e$(6!$\e(B" . "\e$,15E\e(B")
 +  ("\e$(6!%\e(B" . "\e$,15F\e(B")
 +  ("\e$(6!&\e(B" . "\e$,15G\e(B")
 +  ("\e$(6!'\e(B" . "\e$,15H\e(B")
 +  ("\e$(6!(\e(B" . "\e$,15I\e(B")
 +  ("\e$(6!)\e(B" . "\e$,15J\e(B")
 +  ("\e$(6!*\e(B" . "\e$,15K\e(B")
 +  ("\e$(6!*"p\e(B" . "\e$,15p6#\e(B")
 +  ("\e$(6!+\e(B" . "\e$,15N\e(B")
 +  ("\e$(6!,\e(B" . "\e$,15O\e(B")
 +  ("\e$(6!-\e(B" . "\e$,15P\e(B")
 +  ("\e$(6!.\e(B" . "\e$,15M\e(B")
 +  ("\e$(6!/\e(B" . "\e$,15R\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2130 \e$(5!0!1!2!3!4!5!6!7!8!9!:!;!<!=!>!?\e(B
 -  ("\e$(5!0\e(B" . "\e$,15S\e(B")
 -  ("\e$(5!1\e(B" . "\e$,15T\e(B")
 -  ("\e$(5!2\e(B" . "\e$,15Q\e(B")
 -  ("\e$(5!3\e(B" . "\e$,15U\e(B")
 -  ("\e$(5!4\e(B" . "\e$,15V\e(B")
 -  ("\e$(5!5\e(B" . "\e$,15W\e(B")
 -  ("\e$(5!6\e(B" . "\e$,15X\e(B")
 -  ("\e$(5!7\e(B" . "\e$,15Y\e(B")
 -  ("\e$(5!8\e(B" . "\e$,15Z\e(B")
 -  ("\e$(5!9\e(B" . "\e$,15[\e(B")
 -  ("\e$(5!:\e(B" . "\e$,15\\e(B")
 -  ("\e$(5!;\e(B" . "\e$,15]\e(B")
 -  ("\e$(5!<\e(B" . "\e$,15^\e(B")
 -  ("\e$(5!=\e(B" . "\e$,15_\e(B")
 -  ("\e$(5!>\e(B" . "\e$,15`\e(B")
 -  ("\e$(5!?\e(B" . "\e$,15a\e(B")
 +  ;;2130 \e$(6!0!1!2!3!4!5!6!7!8!9!:!;!<!=!>!?\e(B
 +  ("\e$(6!0\e(B" . "\e$,15S\e(B")
 +  ("\e$(6!1\e(B" . "\e$,15T\e(B")
 +  ("\e$(6!2\e(B" . "\e$,15Q\e(B")
 +  ("\e$(6!3\e(B" . "\e$,15U\e(B")
 +  ("\e$(6!4\e(B" . "\e$,15V\e(B")
 +  ("\e$(6!5\e(B" . "\e$,15W\e(B")
 +  ("\e$(6!6\e(B" . "\e$,15X\e(B")
 +  ("\e$(6!7\e(B" . "\e$,15Y\e(B")
 +  ("\e$(6!8\e(B" . "\e$,15Z\e(B")
 +  ("\e$(6!9\e(B" . "\e$,15[\e(B")
 +  ("\e$(6!:\e(B" . "\e$,15\\e(B")
 +  ("\e$(6!;\e(B" . "\e$,15]\e(B")
 +  ("\e$(6!<\e(B" . "\e$,15^\e(B")
 +  ("\e$(6!=\e(B" . "\e$,15_\e(B")
 +  ("\e$(6!>\e(B" . "\e$,15`\e(B")
 +  ("\e$(6!?\e(B" . "\e$,15a\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2140 \e$(5!@!A!B!C!D!E!F!G!H!I!J!K!L!M!N!O\e(B
 -  ("\e$(5!@\e(B" . "\e$,15b\e(B")
 -  ("\e$(5!A\e(B" . "\e$,15c\e(B")
 -  ("\e$(5!B\e(B" . "\e$,15d\e(B")
 -  ("\e$(5!C\e(B" . "\e$,15e\e(B")
 -  ("\e$(5!D\e(B" . "\e$,15f\e(B")
 -  ("\e$(5!E\e(B" . "\e$,15g\e(B")
 -  ("\e$(5!F\e(B" . "\e$,15h\e(B")
 -  ("\e$(5!G\e(B" . "\e$,15i\e(B")
 -  ("\e$(5!H\e(B" . "\e$,15j\e(B")
 -  ("\e$(5!I\e(B" . "\e$,15k\e(B")
 -  ("\e$(5!J\e(B" . "\e$,15l\e(B")
 -  ("\e$(5!K\e(B" . "\e$,15m\e(B")
 -  ("\e$(5!L\e(B" . "\e$,15n\e(B")
 -  ("\e$(5!M\e(B" . "\e$,15o\e(B")
 -  ("\e$(5!N\e(B" . "\e$,16?\e(B")
 -  ("\e$(5!O\e(B" . "\e$,15p\e(B")
 +  ;;2140 \e$(6!@!A!B!C!D!E!F!G!H!I!J!K!L!M!N!O\e(B
 +  ("\e$(6!@\e(B" . "\e$,15b\e(B")
 +  ("\e$(6!A\e(B" . "\e$,15c\e(B")
 +  ("\e$(6!B\e(B" . "\e$,15d\e(B")
 +  ("\e$(6!C\e(B" . "\e$,15e\e(B")
 +  ("\e$(6!D\e(B" . "\e$,15f\e(B")
 +  ("\e$(6!E\e(B" . "\e$,15g\e(B")
 +  ("\e$(6!F\e(B" . "\e$,15h\e(B")
 +  ("\e$(6!G\e(B" . "\e$,15i\e(B")
 +  ("\e$(6!H\e(B" . "\e$,15j\e(B")
 +  ("\e$(6!I\e(B" . "\e$,15k\e(B")
 +  ("\e$(6!J\e(B" . "\e$,15l\e(B")
 +  ("\e$(6!K\e(B" . "\e$,15m\e(B")
 +  ("\e$(6!L\e(B" . "\e$,15n\e(B")
 +  ("\e$(6!M\e(B" . "\e$,15o\e(B")
 +  ("\e$(6!N\e(B" . "\e$,16?\e(B")
 +  ("\e$(6!O\e(B" . "\e$,15p\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2150 \e$(5!P!Q!R!S!T!U!V!W!X!Y!Z![!\!]!^!_\e(B
 -  ("\e$(5!P\e(B" . "\e$,15q\e(B")
 -  ("\e$(5!Q\e(B" . "\e$,15r\e(B")
 -  ("\e$(5!R\e(B" . "\e$,15s\e(B")
 -  ("\e$(5!S\e(B" . "\e$,15t\e(B")
 -  ("\e$(5!T\e(B" . "\e$,15u\e(B")
 -  ("\e$(5!U\e(B" . "\e$,15v\e(B")
 -  ("\e$(5!V\e(B" . "\e$,15w\e(B")
 -  ("\e$(5!W\e(B" . "\e$,15x\e(B")
 -  ("\e$(5!X\e(B" . "\e$,15y\e(B")
 -  ("\e$(5!Z\e(B" . "\e$,15~\e(B")
 -  ("\e$(5![\e(B" . "\e$,15\7f\e(B")
 -  ("\e$(5!\\e(B" . "\e$,16 \e(B")
 -  ("\e$(5!]\e(B" . "\e$,16!\e(B")
 -  ("\e$(5!^\e(B" . "\e$,16"\e(B")
 -  ("\e$(5!_\e(B" . "\e$,16#\e(B")
 +  ;;2150 \e$(6!P!Q!R!S!T!U!V!W!X!Y!Z![!\!]!^!_\e(B
 +  ("\e$(6!P\e(B" . "\e$,15q\e(B")
 +  ("\e$(6!Q\e(B" . "\e$,15r\e(B")
 +  ("\e$(6!R\e(B" . "\e$,15s\e(B")
 +  ("\e$(6!S\e(B" . "\e$,15t\e(B")
 +  ("\e$(6!T\e(B" . "\e$,15u\e(B")
 +  ("\e$(6!U\e(B" . "\e$,15v\e(B")
 +  ("\e$(6!V\e(B" . "\e$,15w\e(B")
 +  ("\e$(6!W\e(B" . "\e$,15x\e(B")
 +  ("\e$(6!X\e(B" . "\e$,15y\e(B")
 +  ("\e$(6!Z\e(B" . "\e$,15~\e(B")
 +  ("\e$(6![\e(B" . "\e$,15\7f\e(B")
 +  ("\e$(6!\\e(B" . "\e$,16 \e(B")
 +  ("\e$(6!]\e(B" . "\e$,16!\e(B")
 +  ("\e$(6!^\e(B" . "\e$,16"\e(B")
 +  ("\e$(6!_\e(B" . "\e$,16#\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2160 \e$(5!`!a!b!c!d!e!f!g!h!i!j!k!l!m!n!o\e(B
 -  ("\e$(5!`\e(B" . "\e$,16&\e(B")
 -  ("\e$(5!a\e(B" . "\e$,16'\e(B")
 -  ("\e$(5!b\e(B" . "\e$,16(\e(B")
 -  ("\e$(5!c\e(B" . "\e$,16%\e(B")
 -  ("\e$(5!d\e(B" . "\e$,16*\e(B")
 -  ("\e$(5!e\e(B" . "\e$,16+\e(B")
 -  ("\e$(5!f\e(B" . "\e$,16,\e(B")
 -  ("\e$(5!g\e(B" . "\e$,16)\e(B")
 -  ("\e$(5!h\e(B" . "\e$,16-\e(B")
 -  ("\e$(5!i\e(B" . "\e$,15|\e(B")
 -  ("\e$(5!j\e(B" . "\e$,16D\e(B")
 -  ("\e$(5!j!j\e(B" . "\e$,16E\e(B")
 +  ;;2160 \e$(6!`!a!b!c!d!e!f!g!h!i!j!k!l!m!n!o\e(B
 +  ("\e$(6!`\e(B" . "\e$,16&\e(B")
 +  ("\e$(6!a\e(B" . "\e$,16'\e(B")
 +  ("\e$(6!b\e(B" . "\e$,16(\e(B")
 +  ("\e$(6!c\e(B" . "\e$,16%\e(B")
 +  ("\e$(6!d\e(B" . "\e$,16*\e(B")
 +  ("\e$(6!e\e(B" . "\e$,16+\e(B")
 +  ("\e$(6!f\e(B" . "\e$,16,\e(B")
 +  ("\e$(6!g\e(B" . "\e$,16)\e(B")
 +  ("\e$(6!h\e(B" . "\e$,16-\e(B")
 +  ("\e$(6!i\e(B" . "\e$,15|\e(B")
 +  ("\e$(6!j\e(B" . "\e$,16D\e(B")
 +  ("\e$(6!j!j\e(B" . "\e$,16E\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2170 \e$(5!p!q!r!s!t!u!v!w!x!y!z!{!|!}!~\e(B
 -  ("\e$(5!q\e(B" . "\e$,16F\e(B")
 -  ("\e$(5!r\e(B" . "\e$,16G\e(B")
 -  ("\e$(5!s\e(B" . "\e$,16H\e(B")
 -  ("\e$(5!t\e(B" . "\e$,16I\e(B")
 -  ("\e$(5!u\e(B" . "\e$,16J\e(B")
 -  ("\e$(5!v\e(B" . "\e$,16K\e(B")
 -  ("\e$(5!w\e(B" . "\e$,16L\e(B")
 -  ("\e$(5!x\e(B" . "\e$,16M\e(B")
 -  ("\e$(5!y\e(B" . "\e$,16N\e(B")
 -  ("\e$(5!z\e(B" . "\e$,16O\e(B")
 +  ;;2170 \e$(6!p!q!r!s!t!u!v!w!x!y!z!{!|!}!~\e(B
 +  ("\e$(6!q\e(B" . "\e$,16F\e(B")
 +  ("\e$(6!r\e(B" . "\e$,16G\e(B")
 +  ("\e$(6!s\e(B" . "\e$,16H\e(B")
 +  ("\e$(6!t\e(B" . "\e$,16I\e(B")
 +  ("\e$(6!u\e(B" . "\e$,16J\e(B")
 +  ("\e$(6!v\e(B" . "\e$,16K\e(B")
 +  ("\e$(6!w\e(B" . "\e$,16L\e(B")
 +  ("\e$(6!x\e(B" . "\e$,16M\e(B")
 +  ("\e$(6!y\e(B" . "\e$,16N\e(B")
 +  ("\e$(6!z\e(B" . "\e$,16O\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2220   \e$(5"!"""#"$"%"&"'"(")"*"+","-"."/\e(B
 -  ("\e$(5"!\e(B" . "\e$,16;6-5p\e(B")
 -  ("\e$(5""\e(B" . "\e$,16>6-5p\e(B")
 -  ("\e$(5"#\e(B" . "\e$,15U6-5p\e(B")
 -  ("\e$(5"$\e(B" . "\e$,15W6-5p\e(B")
 -  ("\e$(5"%\e(B" . "\e$,15d6-5p\e(B")
 -  ("\e$(5"&\e(B" . "\e$,15j6-5p\e(B")
 -  ("\e$(5"'\e(B" . "\e$,15k6-5p\e(B")
 -  ("\e$(5")\e(B" . "\e$,15v6-5p\e(B")
 -  ("\e$(5",\e(B" . "\e$,15p6!\e(B")
 -  ("\e$(5"-\e(B" . "\e$,15p6"\e(B")
 -  ("\e$(5".\e(B" . "\e$,15q6!\e(B")
 -  ("\e$(5"/\e(B" . "\e$,15q6"\e(B")
 +  ;;2220   \e$(6"!"""#"$"%"&"'"(")"*"+","-"."/\e(B
 +  ("\e$(6"!\e(B" . "\e$,16;6-5p\e(B")
 +  ("\e$(6""\e(B" . "\e$,16>6-5p\e(B")
 +  ("\e$(6"#\e(B" . "\e$,15U6-5p\e(B")
 +  ("\e$(6"$\e(B" . "\e$,15W6-5p\e(B")
 +  ("\e$(6"%\e(B" . "\e$,15d6-5p\e(B")
 +  ("\e$(6"&\e(B" . "\e$,15j6-5p\e(B")
 +  ("\e$(6"'\e(B" . "\e$,15k6-5p\e(B")
 +  ("\e$(6")\e(B" . "\e$,15v6-5p\e(B")
 +  ("\e$(6",\e(B" . "\e$,15p6!\e(B")
 +  ("\e$(6"-\e(B" . "\e$,15p6"\e(B")
 +  ("\e$(6".\e(B" . "\e$,15q6!\e(B")
 +  ("\e$(6"/\e(B" . "\e$,15q6"\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2230 \e$(5"0"1"2"3"4"5"6"7"8"9":";"<"=">"?\e(B
 -  ("\e$(5"3\e(B" . "\e$,15U6-\e(B")
 -  ("\e$(5"4\e(B" . "\e$,15V6-\e(B")
 -  ("\e$(5"5\e(B" . "\e$,15W6-\e(B")
 -  ("\e$(5"6\e(B" . "\e$,15X6-\e(B")
 -  ("\e$(5"8\e(B" . "\e$,15Z6-\e(B")
 -  ("\e$(5"8"q\e(B" . "\e$,15Z6-5p6-\e(B")
 -  ("\e$(5":\e(B" . "\e$,15\6-\e(B")
 -  ("\e$(5";\e(B" . "\e$,15]6-\e(B")
 -  ("\e$(5"<\e(B" . "\e$,15^6-\e(B")
 -  ("\e$(5"<\e(B" . "\e$,15^6-\e(B")
 +  ;;2230 \e$(6"0"1"2"3"4"5"6"7"8"9":";"<"=">"?\e(B
 +  ("\e$(6"3\e(B" . "\e$,15U6-\e(B")
 +  ("\e$(6"4\e(B" . "\e$,15V6-\e(B")
 +  ("\e$(6"5\e(B" . "\e$,15W6-\e(B")
 +  ("\e$(6"6\e(B" . "\e$,15X6-\e(B")
 +  ("\e$(6"8\e(B" . "\e$,15Z6-\e(B")
 +  ("\e$(6"8"q\e(B" . "\e$,15Z6-5p6-\e(B")
 +  ("\e$(6":\e(B" . "\e$,15\6-\e(B")
 +  ("\e$(6";\e(B" . "\e$,15]6-\e(B")
 +  ("\e$(6"<\e(B" . "\e$,15^6-\e(B")
 +  ("\e$(6"<\e(B" . "\e$,15^6-\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2240 \e$(5"@"A"B"C"D"E"F"G"H"I"J"K"L"M"N"O\e(B
 -  ("\e$(5"A\e(B" . "\e$,15c6-\e(B")
 -  ("\e$(5"B\e(B" . "\e$,15d6-\e(B")
 -  ("\e$(5"C\e(B" . "\e$,15e6-\e(B")
 -  ("\e$(5"E\e(B" . "\e$,15g6-\e(B")
 -  ("\e$(5"F\e(B" . "\e$,15h6-\e(B")
 -  ("\e$(5"G\e(B" . "\e$,15i6-\e(B")
 -  ("\e$(5"H\e(B" . "\e$,15j6-\e(B")
 -  ("\e$(5"I\e(B" . "\e$,15k6-\e(B")
 -  ("\e$(5"J\e(B" . "\e$,15l6-\e(B")
 -  ("\e$(5"J\e(B" . "\e$,15l6-\e(B")
 -  ("\e$(5"K\e(B" . "\e$,15m6-\e(B")
 -  ("\e$(5"L\e(B" . "\e$,15n6-\e(B")
 -  ("\e$(5"M\e(B" . "\e$,15o6-\e(B")
 -  ("\e$(5"N\e(B" . "\e$,16?6-\e(B")
 +  ;;2240 \e$(6"@"A"B"C"D"E"F"G"H"I"J"K"L"M"N"O\e(B
 +  ("\e$(6"A\e(B" . "\e$,15c6-\e(B")
 +  ("\e$(6"B\e(B" . "\e$,15d6-\e(B")
 +  ("\e$(6"C\e(B" . "\e$,15e6-\e(B")
 +  ("\e$(6"E\e(B" . "\e$,15g6-\e(B")
 +  ("\e$(6"F\e(B" . "\e$,15h6-\e(B")
 +  ("\e$(6"G\e(B" . "\e$,15i6-\e(B")
 +  ("\e$(6"H\e(B" . "\e$,15j6-\e(B")
 +  ("\e$(6"I\e(B" . "\e$,15k6-\e(B")
 +  ("\e$(6"J\e(B" . "\e$,15l6-\e(B")
 +  ("\e$(6"J\e(B" . "\e$,15l6-\e(B")
 +  ("\e$(6"K\e(B" . "\e$,15m6-\e(B")
 +  ("\e$(6"L\e(B" . "\e$,15n6-\e(B")
 +  ("\e$(6"M\e(B" . "\e$,15o6-\e(B")
 +  ("\e$(6"N\e(B" . "\e$,16?6-\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2250 \e$(5"P"Q"R"S"T"U"V"W"X"Y"Z"["\"]"^"_\e(B
 -  ("\e$(5"Q\e(B" . "\e$,15r6-\e(B")
 -  ("\e$(5"R\e(B" . "\e$,15s6-\e(B")
 -  ("\e$(5"S\e(B" . "\e$,15t6-\e(B")
 -  ("\e$(5"T\e(B" . "\e$,15u6-\e(B")
 -  ("\e$(5"U\e(B" . "\e$,15v6-\e(B")
 -  ("\e$(5"V\e(B" . "\e$,15w6-\e(B")
 -  ("\e$(5"W\e(B" . "\e$,15x6-\e(B")
 -  ("\e$(5"]\e(B" . "\e$,16-5o\e(B")
 +  ;;2250 \e$(6"P"Q"R"S"T"U"V"W"X"Y"Z"["\"]"^"_\e(B
 +  ("\e$(6"Q\e(B" . "\e$,15r6-\e(B")
 +  ("\e$(6"R\e(B" . "\e$,15s6-\e(B")
 +  ("\e$(6"S\e(B" . "\e$,15t6-\e(B")
 +  ("\e$(6"T\e(B" . "\e$,15u6-\e(B")
 +  ("\e$(6"U\e(B" . "\e$,15v6-\e(B")
 +  ("\e$(6"V\e(B" . "\e$,15w6-\e(B")
 +  ("\e$(6"W\e(B" . "\e$,15x6-\e(B")
 +  ("\e$(6"]\e(B" . "\e$,16-5o\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2260 \e$(5"`"a"b"c"d"e"f"g"h"i"j"k"l"m"n"o\e(B
 -  ("\e$(5"`\e(B" . "\e$,15W6-5p6-\e(B")
 -  ("\e$(5"a\e(B" . "\e$,15X6-5h6-\e(B")
 -  ("\e$(5"c\e(B" . "\e$,15d6-5d6-\e(B")
 -  ("\e$(5"d\e(B" . "\e$,15d6-5p6-\e(B")
 -  ("\e$(5"e\e(B" . "\e$,15g6-5h6-\e(B")
 -  ("\e$(5"f\e(B" . "\e$,15g6-5p6-\e(B")
 -  ("\e$(5"g\e(B" . "\e$,15j6-5d6-\e(B")
 -  ("\e$(5"h\e(B" . "\e$,15v6-5Z6-\e(B")
 -  ("\e$(5"i\e(B" . "\e$,15v6-5p6-\e(B")
 -  ("\e$(5"j\e(B" . "\e$,15v6-5u6-\e(B")
 -  ("\e$(5"k\e(B" . "\e$,15h6-5h6-\e(B")
 -  ("\e$(5"l\e(B" . "\e$,15U6-5w6-\e(B")
 -  ("\e$(5"m\e(B" . "\e$,15\6-5^6-\e(B")
 +  ;;2260 \e$(6"`"a"b"c"d"e"f"g"h"i"j"k"l"m"n"o\e(B
 +  ("\e$(6"`\e(B" . "\e$,15W6-5p6-\e(B")
 +  ("\e$(6"a\e(B" . "\e$,15X6-5h6-\e(B")
 +  ("\e$(6"c\e(B" . "\e$,15d6-5d6-\e(B")
 +  ("\e$(6"d\e(B" . "\e$,15d6-5p6-\e(B")
 +  ("\e$(6"e\e(B" . "\e$,15g6-5h6-\e(B")
 +  ("\e$(6"f\e(B" . "\e$,15g6-5p6-\e(B")
 +  ("\e$(6"g\e(B" . "\e$,15j6-5d6-\e(B")
 +  ("\e$(6"h\e(B" . "\e$,15v6-5Z6-\e(B")
 +  ("\e$(6"i\e(B" . "\e$,15v6-5p6-\e(B")
 +  ("\e$(6"j\e(B" . "\e$,15v6-5u6-\e(B")
 +  ("\e$(6"k\e(B" . "\e$,15h6-5h6-\e(B")
 +  ("\e$(6"l\e(B" . "\e$,15U6-5w6-\e(B")
 +  ("\e$(6"m\e(B" . "\e$,15\6-5^6-\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2270 \e$(5"p"q"r"s"t"u"v"w"x"y"z"{"|"}"~\e(B
 -  ("\e$(5"p\e(B" . "\e$,15p6-\e(B")
 -  ("\e$(5"q\e(B" . "\e$,16-5p\e(B")
 -  ("\e$(5"r\e(B" . "\e$,16-5p\e(B")
 -  ("\e$(5"s\e(B" . "\e$,1686-\e(B")
 -  ("\e$(5"t\e(B" . "\e$,1696-\e(B")
 -  ("\e$(5"u\e(B" . "\e$,16:6-\e(B")
 -  ("\e$(5"y\e(B" . "\e$,16>6-\e(B")
 -  ("\e$(5"z\e(B" . "\e$,16;6-\e(B")
 +  ;;2270 \e$(6"p"q"r"s"t"u"v"w"x"y"z"{"|"}"~\e(B
 +  ("\e$(6"p\e(B" . "\e$,15p6-\e(B")
 +  ("\e$(6"q\e(B" . "\e$,16-5p\e(B")
 +  ("\e$(6"r\e(B" . "\e$,16-5p\e(B")
 +  ("\e$(6"s\e(B" . "\e$,1686-\e(B")
 +  ("\e$(6"t\e(B" . "\e$,1696-\e(B")
 +  ("\e$(6"u\e(B" . "\e$,16:6-\e(B")
 +  ("\e$(6"y\e(B" . "\e$,16>6-\e(B")
 +  ("\e$(6"z\e(B" . "\e$,16;6-\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2320   \e$(5#!#"###$#%#&#'#(#)#*#+#,#-#.#/\e(B
 -  ("\e$(5#!\e(B" . "\e$,160\e(B")
 -  ("\e$(5#&\e(B" . "\e$,15L\e(B")
 -  ("\e$(5#&"p\e(B" . "\e$,15p6$\e(B")
 -  ("\e$(5#'\e(B" . "\e$,16A\e(B")
 -  ("\e$(5#'"p\e(B" . "\e$,15p6C\e(B")
 -  ("\e$(5#*\e(B" . "\e$,16@\e(B")
 -  ("\e$(5#*"p\e(B" . "\e$,15p6B\e(B")
 +  ;;2320   \e$(6#!#"###$#%#&#'#(#)#*#+#,#-#.#/\e(B
 +  ("\e$(6#!\e(B" . "\e$,160\e(B")
 +  ("\e$(6#&\e(B" . "\e$,15L\e(B")
 +  ("\e$(6#&"p\e(B" . "\e$,15p6$\e(B")
 +  ("\e$(6#'\e(B" . "\e$,16A\e(B")
 +  ("\e$(6#'"p\e(B" . "\e$,15p6C\e(B")
 +  ("\e$(6#*\e(B" . "\e$,16@\e(B")
 +  ("\e$(6#*"p\e(B" . "\e$,15p6B\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2330 \e$(5#0#1#2#3#4#5#6#7#8#9#:#;#<#=#>#?\e(B
 -  ("\e$(5#3\e(B" . "\e$,168\e(B")
 -  ("\e$(5#4\e(B" . "\e$,169\e(B")
 -  ("\e$(5#5\e(B" . "\e$,16:\e(B")
 -  ("\e$(5#:\e(B" . "\e$,16;\e(B")
 -  ("\e$(5#?\e(B" . "\e$,16<\e(B")
 +  ;;2330 \e$(6#0#1#2#3#4#5#6#7#8#9#:#;#<#=#>#?\e(B
 +  ("\e$(6#3\e(B" . "\e$,168\e(B")
 +  ("\e$(6#4\e(B" . "\e$,169\e(B")
 +  ("\e$(6#5\e(B" . "\e$,16:\e(B")
 +  ("\e$(6#:\e(B" . "\e$,16;\e(B")
 +  ("\e$(6#?\e(B" . "\e$,16<\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2340 \e$(5#@#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O\e(B
 -  ("\e$(5#@\e(B" . "\e$,16=\e(B")
 -  ("\e$(5#I\e(B" . "\e$,16>\e(B")
 -  ("\e$(5#J\e(B" . "\e$,15}\e(B")
 -  ("\e$(5#K\e(B" . "\e$,16$\e(B")
 -  ("\e$(5#L\e(B" . "\e$,16B\e(B")
 -  ("\e$(5#M\e(B" . "\e$,16C\e(B")
 +  ;;2340 \e$(6#@#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O\e(B
 +  ("\e$(6#@\e(B" . "\e$,16=\e(B")
 +  ("\e$(6#I\e(B" . "\e$,16>\e(B")
 +  ("\e$(6#J\e(B" . "\e$,15}\e(B")
 +  ("\e$(6#K\e(B" . "\e$,16$\e(B")
 +  ("\e$(6#L\e(B" . "\e$,16B\e(B")
 +  ("\e$(6#M\e(B" . "\e$,16C\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2350 \e$(5#P#Q#R#S#T#U#V#W#X#Y#Z#[#\#]#^#_\e(B
 -  ("\e$(5#P\e(B" . "\e$,15n6-5h\e(B")
 -  ("\e$(5#Q\e(B" . "\e$,15n6-5r\e(B")
 -  ("\e$(5#R\e(B" . "\e$,15y6#\e(B")
 +  ;;2350 \e$(6#P#Q#R#S#T#U#V#W#X#Y#Z#[#\#]#^#_\e(B
 +  ("\e$(6#P\e(B" . "\e$,15n6-5h\e(B")
 +  ("\e$(6#Q\e(B" . "\e$,15n6-5r\e(B")
 +  ("\e$(6#R\e(B" . "\e$,15y6#\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2360 \e$(5#`#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o\e(B
 -  ("\e$(5#`\e(B" . "\e$,15r6-5r\e(B")
 -  ("\e$(5#a\e(B" . "\e$,15u6-5h\e(B")
 -  ("\e$(5#b\e(B" . "\e$,15u6-5u\e(B")
 -  ("\e$(5#c\e(B" . "\e$,15v6-5Z\e(B")
 -  ("\e$(5#d\e(B" . "\e$,15v6-5h\e(B")
 -  ("\e$(5#e\e(B" . "\e$,15v6-5l\e(B")
 -  ("\e$(5#f\e(B" . "\e$,15v6-5r\e(B")
 -  ("\e$(5#g\e(B" . "\e$,15v6-5u\e(B")
 -  ("\e$(5#h\e(B" . "\e$,15w6-5_6-5p6-5o\e(B")
 -  ("\e$(5#i\e(B" . "\e$,15w6-5_6-5o\e(B")
 -  ("\e$(5#j\e(B" . "\e$,15w6-5_6-5u\e(B")
 -  ("\e$(5#k\e(B" . "\e$,15w6-5_\e(B")
 -  ("\e$(5#l\e(B" . "\e$,15w6-5`\e(B")
 -  ("\e$(5#m\e(B" . "\e$,15x6-5h\e(B")
 -  ("\e$(5#n\e(B" . "\e$,15x6-5p\e(B")
 +  ;;2360 \e$(6#`#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o\e(B
 +  ("\e$(6#`\e(B" . "\e$,15r6-5r\e(B")
 +  ("\e$(6#a\e(B" . "\e$,15u6-5h\e(B")
 +  ("\e$(6#b\e(B" . "\e$,15u6-5u\e(B")
 +  ("\e$(6#c\e(B" . "\e$,15v6-5Z\e(B")
 +  ("\e$(6#d\e(B" . "\e$,15v6-5h\e(B")
 +  ("\e$(6#e\e(B" . "\e$,15v6-5l\e(B")
 +  ("\e$(6#f\e(B" . "\e$,15v6-5r\e(B")
 +  ("\e$(6#g\e(B" . "\e$,15v6-5u\e(B")
 +  ("\e$(6#h\e(B" . "\e$,15w6-5_6-5p6-5o\e(B")
 +  ("\e$(6#i\e(B" . "\e$,15w6-5_6-5o\e(B")
 +  ("\e$(6#j\e(B" . "\e$,15w6-5_6-5u\e(B")
 +  ("\e$(6#k\e(B" . "\e$,15w6-5_\e(B")
 +  ("\e$(6#l\e(B" . "\e$,15w6-5`\e(B")
 +  ("\e$(6#m\e(B" . "\e$,15x6-5h\e(B")
 +  ("\e$(6#n\e(B" . "\e$,15x6-5p\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2370 \e$(5#p#q#r#s#t#u#v#w#x#y#z#{#|#}#~\e(B
 -  ("\e$(5#p\e(B" . "\e$,15y6-5c\e(B")
 -  ("\e$(5#q\e(B" . "\e$,15y6-5h\e(B")
 -  ("\e$(5#r\e(B" . "\e$,15y6-5n\e(B")
 -  ("\e$(5#s\e(B" . "\e$,15y6-5o\e(B")
 -  ("\e$(5#t\e(B" . "\e$,15y6-5p\e(B")
 -  ("\e$(5#u\e(B" . "\e$,15y6-5r\e(B")
 -  ("\e$(5#v\e(B" . "\e$,15y6-5u\e(B")
 +  ;;2370 \e$(6#p#q#r#s#t#u#v#w#x#y#z#{#|#}#~\e(B
 +  ("\e$(6#p\e(B" . "\e$,15y6-5c\e(B")
 +  ("\e$(6#q\e(B" . "\e$,15y6-5h\e(B")
 +  ("\e$(6#r\e(B" . "\e$,15y6-5n\e(B")
 +  ("\e$(6#s\e(B" . "\e$,15y6-5o\e(B")
 +  ("\e$(6#t\e(B" . "\e$,15y6-5p\e(B")
 +  ("\e$(6#u\e(B" . "\e$,15y6-5r\e(B")
 +  ("\e$(6#v\e(B" . "\e$,15y6-5u\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2420   \e$(5$!$"$#$$$%$&$'$($)$*$+$,$-$.$/\e(B
 -  ("\e$(5$!\e(B" . "\e$,15U6-5d6-5p6-5o\e(B")
 -  ("\e$(5$"\e(B" . "\e$,15U6-5d6-5u\e(B")
 -  ("\e$(5$#\e(B" . "\e$,15U6-5d6-5o\e(B")
 -  ("\e$(5$$\e(B" . "\e$,15U6-5h6-5o\e(B")
 -  ("\e$(5$%\e(B" . "\e$,15U6-5p6-5o\e(B")
 -  ("\e$(5$&\e(B" . "\e$,15U6-5u6-5o\e(B")
 -  ("\e$(5$'\e(B" . "\e$,15U6-5U\e(B")
 -  ("\e$(5$(\e(B" . "\e$,15U6-5d\e(B")
 -  ("\e$(5$)\e(B" . "\e$,15U6-5h\e(B")
 -  ("\e$(5$*\e(B" . "\e$,15U6-5n\e(B")
 -  ("\e$(5$+\e(B" . "\e$,15U6-5o\e(B")
 -  ("\e$(5$,\e(B" . "\e$,15U6-5r\e(B")
 -  ("\e$(5$-\e(B" . "\e$,15U6-5u\e(B")
 -  ("\e$(5$.\e(B" . "\e$,15U6-5w\e(B")
 -  ("\e$(5$/\e(B" . "\e$,15X6-5h\e(B")
 +  ;;2420   \e$(6$!$"$#$$$%$&$'$($)$*$+$,$-$.$/\e(B
 +  ("\e$(6$!\e(B" . "\e$,15U6-5d6-5p6-5o\e(B")
 +  ("\e$(6$"\e(B" . "\e$,15U6-5d6-5u\e(B")
 +  ("\e$(6$#\e(B" . "\e$,15U6-5d6-5o\e(B")
 +  ("\e$(6$$\e(B" . "\e$,15U6-5h6-5o\e(B")
 +  ("\e$(6$%\e(B" . "\e$,15U6-5p6-5o\e(B")
 +  ("\e$(6$&\e(B" . "\e$,15U6-5u6-5o\e(B")
 +  ("\e$(6$'\e(B" . "\e$,15U6-5U\e(B")
 +  ("\e$(6$(\e(B" . "\e$,15U6-5d\e(B")
 +  ("\e$(6$)\e(B" . "\e$,15U6-5h\e(B")
 +  ("\e$(6$*\e(B" . "\e$,15U6-5n\e(B")
 +  ("\e$(6$+\e(B" . "\e$,15U6-5o\e(B")
 +  ("\e$(6$,\e(B" . "\e$,15U6-5r\e(B")
 +  ("\e$(6$-\e(B" . "\e$,15U6-5u\e(B")
 +  ("\e$(6$.\e(B" . "\e$,15U6-5w\e(B")
 +  ("\e$(6$/\e(B" . "\e$,15X6-5h\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2430 \e$(5$0$1$2$3$4$5$6$7$8$9$:$;$<$=$>$?\e(B
 -  ("\e$(5$0\e(B" . "\e$,15Y6-5U6-5d6-5o\e(B")
 -  ("\e$(5$1\e(B" . "\e$,15Y6-5U6-5w6-5u\e(B")
 -  ("\e$(5$2\e(B" . "\e$,15Y6-5U6-5d\e(B")
 -  ("\e$(5$3\e(B" . "\e$,15Y6-5U6-5w\e(B")
 -  ("\e$(5$4\e(B" . "\e$,15Y6-5X6-5p\e(B")
 -  ("\e$(5$5\e(B" . "\e$,15Y6-5U6-5o\e(B")
 -  ("\e$(5$6\e(B" . "\e$,15Y6-5V6-5o\e(B")
 -  ("\e$(5$7\e(B" . "\e$,15Y6-5W6-5o\e(B")
 -  ("\e$(5$8\e(B" . "\e$,15Y6-5X6-5o\e(B")
 -  ("\e$(5$9\e(B" . "\e$,15Y6-5U\e(B")
 -  ("\e$(5$:\e(B" . "\e$,15Y6-5V\e(B")
 -  ("\e$(5$;\e(B" . "\e$,15Y6-5W\e(B")
 -  ("\e$(5$<\e(B" . "\e$,15Y6-5X\e(B")
 -  ("\e$(5$=\e(B" . "\e$,15Y6-5Y\e(B")
 -  ("\e$(5$>\e(B" . "\e$,15Y6-5h\e(B")
 -  ("\e$(5$?\e(B" . "\e$,15Y6-5n\e(B")
 +  ;;2430 \e$(6$0$1$2$3$4$5$6$7$8$9$:$;$<$=$>$?\e(B
 +  ("\e$(6$0\e(B" . "\e$,15Y6-5U6-5d6-5o\e(B")
 +  ("\e$(6$1\e(B" . "\e$,15Y6-5U6-5w6-5u\e(B")
 +  ("\e$(6$2\e(B" . "\e$,15Y6-5U6-5d\e(B")
 +  ("\e$(6$3\e(B" . "\e$,15Y6-5U6-5w\e(B")
 +  ("\e$(6$4\e(B" . "\e$,15Y6-5X6-5p\e(B")
 +  ("\e$(6$5\e(B" . "\e$,15Y6-5U6-5o\e(B")
 +  ("\e$(6$6\e(B" . "\e$,15Y6-5V6-5o\e(B")
 +  ("\e$(6$7\e(B" . "\e$,15Y6-5W6-5o\e(B")
 +  ("\e$(6$8\e(B" . "\e$,15Y6-5X6-5o\e(B")
 +  ("\e$(6$9\e(B" . "\e$,15Y6-5U\e(B")
 +  ("\e$(6$:\e(B" . "\e$,15Y6-5V\e(B")
 +  ("\e$(6$;\e(B" . "\e$,15Y6-5W\e(B")
 +  ("\e$(6$<\e(B" . "\e$,15Y6-5X\e(B")
 +  ("\e$(6$=\e(B" . "\e$,15Y6-5Y\e(B")
 +  ("\e$(6$>\e(B" . "\e$,15Y6-5h\e(B")
 +  ("\e$(6$?\e(B" . "\e$,15Y6-5n\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2440 \e$(5$@$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O\e(B
 -  ("\e$(5$@\e(B" . "\e$,15Y6-5o\e(B")
 -  ("\e$(5$A\e(B" . "\e$,15Z6-5Z\e(B")
 -  ("\e$(5$B\e(B" . "\e$,15Z6-5^\e(B")
 -  ("\e$(5$C\e(B" . "\e$,15[6-5o\e(B")
 -  ("\e$(5$D\e(B" . "\e$,15\6-5p\e(B")
 -  ("\e$(5$E\e(B" . "\e$,15\6-5^\e(B")
 -  ("\e$(5$F\e(B" . "\e$,15^6-5Z\e(B")
 -  ("\e$(5$G\e(B" . "\e$,15^6-5\\e(B")
 -  ("\e$(5$H\e(B" . "\e$,15_6-5U\e(B")
 -  ("\e$(5$I\e(B" . "\e$,15_6-5_\e(B")
 -  ("\e$(5$J\e(B" . "\e$,15_6-5`\e(B")
 -  ("\e$(5$K\e(B" . "\e$,15_6-5o\e(B")
 -  ("\e$(5$L\e(B" . "\e$,15`6-5o\e(B")
 -  ("\e$(5$M\e(B" . "\e$,15a6-5W6-5o\e(B")
 -  ("\e$(5$N\e(B" . "\e$,15a6-5X6-5p\e(B")
 -  ("\e$(5$O\e(B" . "\e$,15a6-5p6-5o\e(B")
 +  ;;2440 \e$(6$@$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O\e(B
 +  ("\e$(6$@\e(B" . "\e$,15Y6-5o\e(B")
 +  ("\e$(6$A\e(B" . "\e$,15Z6-5Z\e(B")
 +  ("\e$(6$B\e(B" . "\e$,15Z6-5^\e(B")
 +  ("\e$(6$C\e(B" . "\e$,15[6-5o\e(B")
 +  ("\e$(6$D\e(B" . "\e$,15\6-5p\e(B")
 +  ("\e$(6$E\e(B" . "\e$,15\6-5^\e(B")
 +  ("\e$(6$F\e(B" . "\e$,15^6-5Z\e(B")
 +  ("\e$(6$G\e(B" . "\e$,15^6-5\\e(B")
 +  ("\e$(6$H\e(B" . "\e$,15_6-5U\e(B")
 +  ("\e$(6$I\e(B" . "\e$,15_6-5_\e(B")
 +  ("\e$(6$J\e(B" . "\e$,15_6-5`\e(B")
 +  ("\e$(6$K\e(B" . "\e$,15_6-5o\e(B")
 +  ("\e$(6$L\e(B" . "\e$,15`6-5o\e(B")
 +  ("\e$(6$M\e(B" . "\e$,15a6-5W6-5o\e(B")
 +  ("\e$(6$N\e(B" . "\e$,15a6-5X6-5p\e(B")
 +  ("\e$(6$O\e(B" . "\e$,15a6-5p6-5o\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2450 \e$(5$P$Q$R$S$T$U$V$W$X$Y$Z$[$\$]$^$_\e(B
 -  ("\e$(5$P\e(B" . "\e$,15a6-5W\e(B")
 -  ("\e$(5$Q\e(B" . "\e$,15a6-5X\e(B")
 -  ("\e$(5$R\e(B" . "\e$,15a6-5a\e(B")
 -  ("\e$(5$S\e(B" . "\e$,15a6-5n\e(B")
 -  ("\e$(5$T\e(B" . "\e$,15a6-5o\e(B")
 +  ;;2450 \e$(6$P$Q$R$S$T$U$V$W$X$Y$Z$[$\$]$^$_\e(B
 +  ("\e$(6$P\e(B" . "\e$,15a6-5W\e(B")
 +  ("\e$(6$Q\e(B" . "\e$,15a6-5X\e(B")
 +  ("\e$(6$R\e(B" . "\e$,15a6-5a\e(B")
 +  ("\e$(6$S\e(B" . "\e$,15a6-5n\e(B")
 +  ("\e$(6$T\e(B" . "\e$,15a6-5o\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2460 \e$(5$`$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o\e(B
 -  ("\e$(5$`\e(B" . "\e$,15b6-5o\e(B")
 -  ("\e$(5$a\e(B" . "\e$,15d6-5d\e(B")
 -  ("\e$(5$b\e(B" . "\e$,15d6-5h\e(B")
 -  ("\e$(5$c\e(B" . "\e$,15f6-5f6-5o\e(B")
 -  ("\e$(5$d\e(B" . "\e$,15f6-5g6-5o\e(B")
 -  ("\e$(5$e\e(B" . "\e$,15f6-5m6-5o\e(B")
 -  ("\e$(5$f\e(B" . "\e$,15f6-5p6-5o\e(B")
 -  ("\e$(5$g\e(B" . "\e$,15f6-5u6-5o\e(B")
 -  ("\e$(5$h\e(B" . "\e$,15f6-5W6-5p\e(B")
 -  ("\e$(5$i\e(B" . "\e$,15f6-5X6-5p\e(B")
 -  ("\e$(5$j\e(B" . "\e$,15f6-5f6-5u\e(B")
 -  ("\e$(5$k\e(B" . "\e$,15f6-5g6-5u\e(B")
 -  ("\e$(5$l\e(B" . "\e$,15f6-5W\e(B")
 -  ("\e$(5$m\e(B" . "\e$,15f6-5X\e(B")
 -  ("\e$(5$n\e(B" . "\e$,15f6-5f\e(B")
 -  ("\e$(5$o\e(B" . "\e$,15f6-5g\e(B")
 +  ;;2460 \e$(6$`$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o\e(B
 +  ("\e$(6$`\e(B" . "\e$,15b6-5o\e(B")
 +  ("\e$(6$a\e(B" . "\e$,15d6-5d\e(B")
 +  ("\e$(6$b\e(B" . "\e$,15d6-5h\e(B")
 +  ("\e$(6$c\e(B" . "\e$,15f6-5f6-5o\e(B")
 +  ("\e$(6$d\e(B" . "\e$,15f6-5g6-5o\e(B")
 +  ("\e$(6$e\e(B" . "\e$,15f6-5m6-5o\e(B")
 +  ("\e$(6$f\e(B" . "\e$,15f6-5p6-5o\e(B")
 +  ("\e$(6$g\e(B" . "\e$,15f6-5u6-5o\e(B")
 +  ("\e$(6$h\e(B" . "\e$,15f6-5W6-5p\e(B")
 +  ("\e$(6$i\e(B" . "\e$,15f6-5X6-5p\e(B")
 +  ("\e$(6$j\e(B" . "\e$,15f6-5f6-5u\e(B")
 +  ("\e$(6$k\e(B" . "\e$,15f6-5g6-5u\e(B")
 +  ("\e$(6$l\e(B" . "\e$,15f6-5W\e(B")
 +  ("\e$(6$m\e(B" . "\e$,15f6-5X\e(B")
 +  ("\e$(6$n\e(B" . "\e$,15f6-5f\e(B")
 +  ("\e$(6$o\e(B" . "\e$,15f6-5g\e(B")
    ;;      0 1 2 3 4 5 6 7 8 9 a b c d e f
 -  ;;2470 \e$(5$p$q$r$s$t$u$v$w$x$y$z${$|$}$~\e(B
 -  ("\e$(5$p\e(B" . "\e$,15f6-5h\e(B")
 -  ("\e$(5$q\e(B" . "\e$,15f6-5l\e(B")
 -  ("\e$(5$r\e(B" . "\e$,15f6-5m\e(B")
 -  ("\e$(5$s\e(B" . "\e$,15f6-5n\e(B")
 -  ("\e$(5$t\e(B" . "\e$,15f6-5o\e(B")
 -  ("\e$(5$u\e(B" . "\e$,15f6-5u\e(B")
 -  ("\e$(5$v\e(B" . "\e$,15g6-5h\e(B")
 -  ("\e$(5$w\e(B" . "\e$,15h6-5h\e(B")
 -  ("\e$(5$x\e(B" . "\e$,15j6-5d\e(B")
 -  ("\e$(5$y\e(B" . "\e$,15j6-5h\e(B")
 -  ("\e$(5$z\e(B" . "\e$,15j6-5r\e(B")
 -  ("\e$(5${\e(B" . "\e$,15l6-5h\e(B")
 -  ("\e$(5$|\e(B" . "\e$,15l6-5l\e(B")
 -  ("\e$(5$}\e(B" . "\e$,15l6-5u\e(B")
 -  ("\e$(5$~\e(B" . "\e$,15m6-5h\e(B")))
 +  ;;2470 \e$(6$p$q$r$s$t$u$v$w$x$y$z${$|$}$~\e(B
 +  ("\e$(6$p\e(B" . "\e$,15f6-5h\e(B")
 +  ("\e$(6$q\e(B" . "\e$,15f6-5l\e(B")
 +  ("\e$(6$r\e(B" . "\e$,15f6-5m\e(B")
 +  ("\e$(6$s\e(B" . "\e$,15f6-5n\e(B")
 +  ("\e$(6$t\e(B" . "\e$,15f6-5o\e(B")
 +  ("\e$(6$u\e(B" . "\e$,15f6-5u\e(B")
 +  ("\e$(6$v\e(B" . "\e$,15g6-5h\e(B")
 +  ("\e$(6$w\e(B" . "\e$,15h6-5h\e(B")
 +  ("\e$(6$x\e(B" . "\e$,15j6-5d\e(B")
 +  ("\e$(6$y\e(B" . "\e$,15j6-5h\e(B")
 +  ("\e$(6$z\e(B" . "\e$,15j6-5r\e(B")
 +  ("\e$(6${\e(B" . "\e$,15l6-5h\e(B")
 +  ("\e$(6$|\e(B" . "\e$,15l6-5l\e(B")
 +  ("\e$(6$}\e(B" . "\e$,15l6-5u\e(B")
 +  ("\e$(6$~\e(B" . "\e$,15m6-5h\e(B")))
  
  (defconst indian-2-column-to-ucs-regexp
 -  "\e$(5!j!j\e(B\\|\e$(5"8"q\e(B\\|[\e$(5#&#'!*#*\e(B]\e$(5"p\e(B\\|[\e$(5!!\e(B-\e$(5$~\e(B]")
 +  "\e$(6!j!j\e(B\\|\e$(6"8"q\e(B\\|[\e$(6#&#'!*#*\e(B]\e$(6"p\e(B\\|[\e$(6!!\e(B-\e$(6$~\e(B]")
  
  (put 'indian-2-column-to-ucs-chartable 'char-table-extra-slots 1)
  (defconst indian-2-column-to-ucs-chartable
    (let ((table (make-char-table 'indian-2-column-to-ucs-chartable))
 -        (alist nil))
 +      (alist nil))
      (dolist (elt indian-2-colum-to-ucs)
        (if (= (length (car elt)) 1)
 -          (aset table (aref (car elt) 0) (cdr elt))
 -        (setq alist (cons elt alist))))
 +        (aset table (aref (car elt) 0) (cdr elt))
 +      (setq alist (cons elt alist))))
      (set-char-table-extra-slot table 0 alist)
      table))
  
 +;;;###autoload
  (defun indian-2-column-to-ucs-region (from to)
    "Convert old Emacs Devanagari characters to UCS."
    (interactive "r")
    (save-excursion
      (save-restriction
        (let ((pos from)
 -            (alist (char-table-extra-slot indian-2-column-to-ucs-chartable 0)))
 -        (narrow-to-region from to)
 -        (decompose-region from to)
 -        (goto-char (point-min))
 -        (while (re-search-forward indian-2-column-to-ucs-regexp nil t)
 -          (let ((len (- (match-end 0) (match-beginning 0)))
 -                subst)
 -            (if (= len 1)
 -                (setq subst (aref indian-2-column-to-ucs-chartable
 +          (alist (char-table-extra-slot indian-2-column-to-ucs-chartable 0)))
 +      (narrow-to-region from to)
 +      (decompose-region from to)
 +      (goto-char (point-min))
 +      (while (re-search-forward indian-2-column-to-ucs-regexp nil t)
 +        (let ((len (- (match-end 0) (match-beginning 0)))
 +              subst)
 +          (if (= len 1)
 +              (setq subst (aref indian-2-column-to-ucs-chartable
                                  (char-after (match-beginning 0))))
 -              (setq subst (cdr (assoc (match-string 0) alist))))
 -            (replace-match (if subst subst "?"))))
 -        (indian-compose-region (point-min) (point-max))))))
 -
 -;;;###autoload
 -(defun indian-glyph-char (index &optional script)
 -  "Return character of charset `indian-glyph' made from glyph index INDEX.
 -The variable `indian-default-script' specifies the script of the glyph.
 -Optional argument SCRIPT, if non-nil, overrides `indian-default-script'.
 -See also the function `indian-char-glyph'."
 -  (or script
 -      (setq script indian-default-script))
 -  (let ((offset (get script 'indian-glyph-code-offset)))
 -    (or (integerp offset)
 -      (error "Invalid script name: %s" script))
 -    (or (and (>= index 0) (< index 256))
 -      (error "Invalid glyph index: %d" index))
 -    (setq index (+ offset index))
 -    (make-char 'indian-glyph (+ (/ index 96) 32) (+ (% index 96) 32))))
 -
 -(defvar indian-glyph-max-char
 -  (indian-glyph-char
 -   255 (aref indian-script-table (1- (length indian-script-table))))
 -  "The maximum valid code of characters in the charset `indian-glyph'.")
 -
 -;;;###autoload
 -(defun indian-char-glyph (char)
 -  "Return information about the glyph code for CHAR of `indian-glyph' charset.
 -The value is (INDEX . SCRIPT), where INDEX is the glyph index
 -in the font that Indian script name SCRIPT specifies.
 -See also the function `indian-glyph-char'."
 -  (let ((split (split-char char))
 -      code)
 -    (or (eq (car split) 'indian-glyph)
 -      (error "Charset of `%c' is not indian-glyph" char))
 -    (or (<= char indian-glyph-max-char)
 -      (error "Invalid indian-glyph char: %d" char))
 -    (setq code (+ (* (- (nth 1 split) 32) 96) (nth 2 split) -32))
 -    (cons (% code 256) (aref indian-script-table (/ code 256)))))
 +            (setq subst (cdr (assoc (match-string 0) alist))))
 +          (replace-match (if subst subst "?"))))
 +      (indian-compose-region (point-min) (point-max))))))
  
  (provide 'ind-util)
  
diff --combined lisp/language/indian.el
index 9c0425c96d06736dd857388c11e11d592aa1f0a8,0fed075f553029638730b47407df12e47a949f34..522769c15848866041c3fe6ce5f3677df30fb0b2
@@@ -1,8 -1,8 +1,8 @@@
  ;;; indian.el --- Indian languages support -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 1997, 1999, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  
  ;;; Code:
  
 -(make-coding-system
 - 'in-is13194 2 ?D
 - "8-bit encoding for ASCII (MSB=0) and IS13194-Devanagari (MSB=1)."
 - '(ascii indian-is13194 nil nil
 -   nil ascii-eol)
 - `((safe-chars . ,(let ((table (make-char-table 'safe-chars nil)))
 -                  (set-char-table-range table 'indian-is13194 t)
 -                  (dotimes (i 127)
 -                    (aset table i t)
 -                    (aset table (decode-char 'ucs (+ #x900 i)) t))
 -                  table))
 -   (post-read-conversion . in-is13194-post-read-conversion)
 -   (pre-write-conversion . in-is13194-pre-write-conversion)))
 -
 -(define-coding-system-alias 'devanagari 'in-is13194)
 +(define-coding-system 'in-is13194-devanagari
 +  "8-bit encoding for ASCII (MSB=0) and IS13194-Devanagari (MSB=1)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?D
 +  :designation [ascii indian-is13194 nil nil]
 +  :charset-list '(ascii indian-is13194)
 +  :post-read-conversion 'in-is13194-post-read-conversion
 +  :pre-write-conversion 'in-is13194-pre-write-conversion)
 +
 +(define-coding-system-alias 'devanagari 'in-is13194-devanagari)
  
  (defvar indian-font-foundry 'cdac
    "Font foundry for Indian characters.
@@@ -155,9 -160,18 +155,9 @@@ Each Indian language environment sets t
  to one of `indian-script-table' (which see).
  The default value is `devanagari'.")
  
 -(define-ccl-program ccl-encode-indian-glyph-font
 -  `(0
 -    ;; Shorten (r1 = (((((r1 - 32) * 96) + r2) - 32) % 256))
 -    (r1 = ((((r1 * 96) + r2) - ,(+ (* 32 96) 32)) % 256))))
 -
 -(setq font-ccl-encoder-alist
 -      (cons (cons "-CDAC" 'ccl-encode-indian-glyph-font)
 -          font-ccl-encoder-alist))
 -
 -(setq font-ccl-encoder-alist
 -      (cons (cons "-AKRUTI" 'ccl-encode-indian-glyph-font)
 -          font-ccl-encoder-alist))
 +(defvar indian-composable-pattern
 +  (make-char-table nil)
 +  "Char table of regexps for composable Indian character sequence.")
  
  (provide 'indian)
  
index 590167ad560a3581a808c96b1ecd71b912858ffd,b9b0eeb2a1446c4201cf59a4cca4b4e1c2ce0e0a..eea0e5eb4d27530bf4037b75adaa6a24696f5836
@@@ -1,14 -1,11 +1,14 @@@
  ;;; japanese.el --- support for Japanese -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multilingual, Japanese
  
  
  ;;; Code:
  
 -(make-coding-system
 - 'iso-2022-jp 2 ?J
 - "ISO 2022 based 7bit encoding for Japanese (MIME:ISO-2022-JP)."
 - '((ascii japanese-jisx0208-1978 japanese-jisx0208
 -        latin-jisx0201 japanese-jisx0212) nil nil nil
 -   short ascii-eol ascii-cntl seven)
 - '((safe-charsets ascii japanese-jisx0208-1978 japanese-jisx0208
 -                latin-jisx0201 japanese-jisx0212)
 -   (mime-charset . iso-2022-jp)))
 +;;; Load translation tables for CP932.
 +(load "international/cp51932")
 +(load "international/eucjp-ms")
 +
 +(define-coding-system 'iso-2022-jp
 +  "ISO 2022 based 7bit encoding for Japanese (MIME:ISO-2022-JP)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?J
 +  :designation [(ascii japanese-jisx0208-1978 japanese-jisx0208
 +                     latin-jisx0201)
 +              nil nil nil]
 +  :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation)
 +  :charset-list '(ascii japanese-jisx0208
 +                      japanese-jisx0208-1978 latin-jisx0201)
 +  :mime-charset 'iso-2022-jp
 +  :suitable-for-keyboard t)
  
  (define-coding-system-alias 'junet 'iso-2022-jp)
  
 -(make-coding-system
 - 'iso-2022-jp-2 2 ?J
 - "ISO 2022 based 7bit encoding for CJK, Latin-1, and Greek (MIME:ISO-2022-JP-2)."
 - '((ascii japanese-jisx0208-1978 japanese-jisx0208
 -        latin-jisx0201 japanese-jisx0212
 -        chinese-gb2312 korean-ksc5601) nil
 -        (nil latin-iso8859-1 greek-iso8859-7) nil
 - short ascii-eol ascii-cntl seven nil single-shift nil nil nil init-bol)
 - '((safe-charsets ascii japanese-jisx0208-1978 japanese-jisx0208
 -                latin-jisx0201 japanese-jisx0212
 -                chinese-gb2312 korean-ksc5601
 -                latin-iso8859-1 greek-iso8859-7)
 -   (mime-charset . iso-2022-jp-2)))
 -
 -(make-coding-system
 - 'japanese-shift-jis 1 ?S
 - "Shift-JIS 8-bit encoding for Japanese (MIME:SHIFT_JIS)."
 - nil
 - '((safe-charsets ascii japanese-jisx0208 japanese-jisx0208-1978
 -                latin-jisx0201 katakana-jisx0201)
 -   (mime-charset . shift_jis)
 -   (charset-origin-alist (japanese-jisx0208 "SJIS" encode-sjis-char)
 -                       (katakana-jisx0201 "SJIS" encode-sjis-char))))
 +(define-coding-system 'iso-2022-jp-2
 +  "ISO 2022 based 7bit encoding for CJK, Latin-1, Greek (MIME:ISO-2022-JP-2)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?J
 +  :designation [(ascii japanese-jisx0208-1978 japanese-jisx0208
 +                     latin-jisx0201 japanese-jisx0212
 +                     chinese-gb2312 korean-ksc5601)
 +              nil
 +              (nil latin-iso8859-1 greek-iso8859-7)
 +              nil]
 +  :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation single-shift
 +               init-at-bol)
 +  :charset-list '(ascii japanese-jisx0208 japanese-jisx0212
 +                      latin-jisx0201 japanese-jisx0208-1978
 +                      chinese-gb2312 korean-ksc5601
 +                      latin-iso8859-1 greek-iso8859-7)
 +  :mime-charset 'iso-2022-jp-2
 +  :suitable-for-keyboard t)
 +
 +(let ((map                    ; JIS           vs      CP932
 +       '((#x301C . #xFF5E)    ; WAVE DASH             FULLWIDTH TILDE
 +       (#x2014 . #x2015)      ; EM DASH               HORIZONTAL BAR
 +       (#x2016 . #x2225)      ; DOUBLE VERTICAL LINE  PARALLEL TO
 +       (#x2212 . #xFF0D)      ; MINUS SIGN            FULLWIDTH HYPHEN-MINUS
 +       (#x00A2 . #xFFE0)      ; CENT SIGN             FULLWIDTH CENT SIGN
 +       (#x00A3 . #xFFE1)      ; POUND SIGN            FULLWIDTH POUND SIGN
 +       (#x00AC . #xFFE2)      ; NOT SIGN              FULLWIDTH NOT SIGN
 +       (#x00A6 . #xFFE4)      ; BROKEN LINE           FULLWIDTH BROKEN LINE
 +       )))
 +  (define-translation-table 'japanese-ucs-jis-to-cp932-map map)
 +  (mapc #'(lambda (x) (let ((tmp (car x)))
 +                      (setcar x (cdr x)) (setcdr x tmp)))
 +      map)
 +  (define-translation-table 'japanese-ucs-cp932-to-jis-map map))
 +
 +;; U+2014 (EM DASH) vs U+2015 (HORIZONTAL BAR)
 +(define-translation-table 'japanese-ucs-glibc-to-jis-map '((#x2015 . #x2014)))
 +(define-translation-table 'japanese-ucs-jis-to-glibc-map '((#x2014 . #x2015)))
 +
 +(define-coding-system 'japanese-shift-jis
 +  "Shift-JIS 8-bit encoding for Japanese (MIME:SHIFT_JIS)"
 +  :coding-type 'shift-jis
 +  :mnemonic ?S
 +  :charset-list '(ascii katakana-jisx0201 japanese-jisx0208)
 +  :mime-charset 'shift_jis)
  
  (define-coding-system-alias 'shift_jis 'japanese-shift-jis)
  (define-coding-system-alias 'sjis 'japanese-shift-jis)
  (define-coding-system-alias 'cp932 'japanese-shift-jis)
  
 -(make-coding-system
 - 'japanese-iso-7bit-1978-irv 2 ?j
 - "ISO 2022 based 7-bit encoding for Japanese JISX0208-1978 and JISX0201-Roman."
 - '((ascii japanese-jisx0208-1978 japanese-jisx0208
 -        latin-jisx0201 japanese-jisx0212 katakana-jisx0201 t) nil nil nil
 -   short ascii-eol ascii-cntl seven nil nil use-roman use-oldjis)
 - '(ascii japanese-jisx0208-1978 japanese-jisx0208 latin-jisx0201))
 +(define-coding-system 'japanese-cp932
 +  "CP932 (Microsoft shift-jis)"
 +  :coding-type 'charset
 +  :mnemonic ?S
 +  :charset-list '(ascii katakana-sjis cp932-2-byte))
 +
 +(define-coding-system-alias 'cp932 'japanese-cp932)
 +
 +(define-coding-system 'japanese-iso-7bit-1978-irv
 +  "ISO 2022 based 7-bit encoding for Japanese JISX0208-1978 and JISX0201-Roman."
 +  :coding-type 'iso-2022
 +  :mnemonic ?j
 +  :designation [(latin-jisx0201 japanese-jisx0208-1978 japanese-jisx0208
 +                              japanese-jisx0212 katakana-jisx0201)
 +              nil nil nil]
 +  :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation
 +               use-roman use-oldjis)
 +  :charset-list '(ascii latin-jisx0201 japanese-jisx0208-1978 japanese-jisx0208
 +                      japanese-jisx0212))
  
  (define-coding-system-alias 'iso-2022-jp-1978-irv 'japanese-iso-7bit-1978-irv)
  (define-coding-system-alias 'old-jis 'japanese-iso-7bit-1978-irv)
  
 -(make-coding-system
 - 'japanese-iso-8bit 2 ?E
 - "ISO 2022 based EUC encoding for Japanese (MIME:EUC-JP)."
 - '(ascii japanese-jisx0208 katakana-jisx0201 japanese-jisx0212
 -   short ascii-eol ascii-cntl nil nil single-shift)
 - '((safe-charsets ascii latin-jisx0201 japanese-jisx0208 japanese-jisx0208-1978
 -               katakana-jisx0201 japanese-jisx0212)
 -   (mime-charset . euc-jp)))
 +(define-coding-system 'japanese-iso-8bit
 +  "ISO 2022 based EUC encoding for Japanese (MIME:EUC-JP)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?E
 +  :designation [ascii japanese-jisx0208 katakana-jisx0201 japanese-jisx0212]
 +  :flags '(short ascii-at-eol ascii-at-cntl single-shift)
 +  :charset-list '(ascii latin-jisx0201 japanese-jisx0208
 +                      katakana-jisx0201 japanese-jisx0212
 +                      japanese-jisx0208-1978)
 +  :mime-charset 'euc-jp)
  
  (define-coding-system-alias 'euc-japan-1990 'japanese-iso-8bit)
  (define-coding-system-alias 'euc-japan 'japanese-iso-8bit)
  (define-coding-system-alias 'euc-jp 'japanese-iso-8bit)
  
 +(define-coding-system 'eucjp-ms
 +  "eucJP-ms (like EUC-JP but with CP932 extension).
 +eucJP-ms is defined in <http://www.opengroup.or.jp/jvc/cde/appendix.html>."
 +  :coding-type 'iso-2022
 +  :mnemonic ?E
 +  :designation [ascii japanese-jisx0208 katakana-jisx0201 japanese-jisx0212]
 +  :flags '(short ascii-at-eol ascii-at-cntl single-shift)
 +  :charset-list '(ascii latin-jisx0201 japanese-jisx0208
 +                      katakana-jisx0201 japanese-jisx0212)
 +  :decode-translation-table 'eucjp-ms-decode
 +  :encode-translation-table 'eucjp-ms-encode)
 +
 +(define-coding-system 'iso-2022-jp-2004
 +  "ISO 2022 based 7bit encoding for JIS X 0213:2004 (MIME:ISO-2022-JP-2004)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?J
 +  :designation [(ascii japanese-jisx0208 japanese-jisx0213.2004-1
 +                     japanese-jisx0213-1 japanese-jisx0213-2)
 +              nil nil nil]
 +  :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation)
 +               ;; init-at-bol)
 +  :charset-list '(ascii japanese-jisx0208 japanese-jisx0213.2004-1
 +                      japanese-jisx0213-1 japanese-jisx0213-2)
 +  :mime-charset 'iso-2022-jp-2004
 +  :suitable-for-keyboard t)
 +
 +(define-coding-system-alias 'iso-2022-jp-3 'iso-2022-jp-2004)
 +
 +(define-coding-system 'euc-jis-2004
 +  "ISO 2022 based EUC encoding for JIS X 0213 (MIME:EUC-JIS-2004)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?E
 +  :designation [ascii japanese-jisx0213.2004-1 katakana-jisx0201
 +                      japanese-jisx0213-2]
 +  :flags '(short ascii-at-eol ascii-at-cntl single-shift)
 +  :charset-list '(ascii latin-jisx0201 japanese-jisx0213.2004-1
 +                        japanese-jisx0213-1 katakana-jisx0201
 +                        japanese-jisx0213-2)
 +  :mime-charset 'euc-jis-2004)
 +
 +(define-coding-system-alias 'euc-jisx0213 'euc-jis-2004)
 +
 +(define-coding-system 'japanese-shift-jis-2004
 +  "Shift_JIS 8-bit encodinf for Japanese (MIME:SHIFT_JIS-2004)"
 +  :coding-type 'shift-jis
 +  :mnemonic ?S
 +  :charset-list '(ascii katakana-jisx0201 
 +                        japanese-jisx0213.2004-1 japanese-jisx0213-2))
 +
 +(define-coding-system-alias 'shift_jis-2004 'japanese-shift-jis-2004)
 +
  (set-language-info-alist
   "Japanese" '((setup-function . setup-japanese-environment-internal)
              (tutorial . "TUTORIAL.ja")
 -            (charset japanese-jisx0208 japanese-jisx0208-1978
 +            (charset japanese-jisx0208
                       japanese-jisx0212 latin-jisx0201 katakana-jisx0201
 -                     japanese-jisx0213-1 japanese-jisx0213-2)
 +                     japanese-jisx0213.2004-1 japanese-jisx0213-1 
 +                     japanese-jisx0213-2 japanese-jisx0208-1978)
              (coding-system iso-2022-jp japanese-iso-8bit
 -                           japanese-shift-jis japanese-iso-7bit-1978-irv)
 +                           japanese-shift-jis japanese-iso-7bit-1978-irv
 +                             iso-2022-jp-2004 japanese-shift-jis-2004
 +                             euc-jis-2004)
              (coding-priority iso-2022-jp japanese-iso-8bit
 -                             japanese-shift-jis iso-2022-jp-2)
 +                             japanese-shift-jis 
 +                               iso-2022-jp-2004 euc-jis-2004 
 +                               japanese-shift-jis-2004
 +                               iso-2022-jp-2)
              (input-method . "japanese")
              (features japan-util)
              (sample-text . "Japanese (\e$BF|K\8l\e(B)   \e$B$3$s$K$A$O\e(B, \e(I:]FAJ\e(B")
              (documentation . t)))
  
 +(let ((map
 +       ;; JISX0213-1 vs Unicode
 +       '((#x2477 . [#x304B #x309A])
 +       (#x2478 . [#x304D #x309A])
 +       (#x2479 . [#x304F #x309A])
 +       (#x247a . [#x3051 #x309A])
 +       (#x247b . [#x3053 #x309A])
 +       (#x2577 . [#x30AB #x309A])
 +       (#x2578 . [#x30AD #x309A])
 +       (#x2579 . [#x30AF #x309A])
 +       (#x257a . [#x30B1 #x309A])
 +       (#x257b . [#x30B3 #x309A])
 +       (#x257c . [#x30BB #x309A])
 +       (#x257d . [#x30C4 #x309A])
 +       (#x257e . [#x30C8 #x309A])
 +       (#x2678 . [#x31F7 #x309A])
 +       (#x2b44 . [#x00E6 #x0300])
 +       (#x2b48 . [#x0254 #x0300])
 +       (#x2b49 . [#x0254 #x0301])
 +       (#x2b4a . [#x028C #x0300])
 +       (#x2b4b . [#x028C #x0301])
 +       (#x2b4c . [#x0259 #x0300])
 +       (#x2b4d . [#x0259 #x0301])
 +       (#x2b4e . [#x025A #x0300])
 +       (#x2b4f . [#x025A #x0301])
 +       (#x2b65 . [#x02E9 #x02E5])
 +       (#x2b66 . [#x02E5 #x02E9])))
 +      table)
 +  (dolist (elt map)
 +    (setcar elt (decode-char 'japanese-jisx0213-1 (car elt))))
 +  (setq table (make-translation-table-from-alist map))
 +  (define-translation-table 'jisx0213-to-unicode table)
 +  (define-translation-table 'unicode-to-jisx0213
 +    (char-table-extra-slot table 0)))
 +
  (provide 'japanese)
  
  ;;; arch-tag: 450f5537-9d53-4d5e-b731-4cf116d8cbc9
diff --combined lisp/language/kannada.el
index 895c272b44e91e81c9e8d6c5424dc19a2c66d907,309f2785f5f055ed9b55c77e7a23df2204f15e06..7fe61328c7c1781efe8c4026b809070f1ddfd22c
@@@ -1,6 -1,6 +1,6 @@@
  ;;; kannada.el --- Support for Kannada -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Maintainer:  CHOWKSEY, Kailash C. <klchxbec@m-net.arbornet.org>
  ;; Keywords: multilingual, Indian, Kannada
                (features knd-util)
                (sample-text
                 . (kannada-compose-string
 -                  (copy-sequence "Kannada (\e4\e$,43Ov#4z\e0\e$,1>u\e1\e4\e$,44Kv#4zv#4M\e0\e$,1?(?M?(\e1\e4\e$,43sv#4z\e0\e$,1?!\e1\e(B)     \e4\e$,44Kv#4z\e0\e$,1?(\e1\e4\e$,44hv#4zv#4\7f\e0\e$,1?.\e1\e4\e$,44qv#4{v#3Q\e0\e$,1?8?M>u?>\e1\e4\e$,44av#4z\e0\e$,1?0\e1\e(B")))
 +                  (copy-sequence "Kannada (\e$,1>u?(?M?(?!\e(B) \e$,1?(?.?8?M>u?>?0\e(B")))
                (documentation . "\
  Kannada language and script is supported in this language
  environment.")) 
   '("Indian"))
  
 +;; For automatic composition.
 +(set-char-table-range composition-function-table '(#x0c80 . #x0cff)
 +                    'kannada-composition-function)
 +
  (provide 'kannada)
  
  ;;; arch-tag: 880ba90b-f6f5-4131-bc1d-930705b78416
index 38610c3989c324ad54f9d688cd53c94d2544858f,dd8a722c706a573be863b7826b4711bab36eef18..c84e265619ceaf4bb08d50155e6f6270cc518acf
@@@ -1,6 -1,6 +1,6 @@@
  ;;; knd-util.el --- Support for composing Kannada characters
  
- ;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Maintainer:  Maintainer:  CHOWKSEY, Kailash C. <klchxbec@m-net.arbornet.org>
  ;; Keywords: multilingual, Kannada
        dummy)
        (function (lambda (x y) (> (length x) (length y))))))))
  
 -(defun kannada-composition-function (from to pattern &optional string)
 -  "Compose Kannada characters in REGION, or STRING if specified.
 -Assume that the REGION or STRING must fully match the composable
 -PATTERN regexp."
 -  (if string (kannada-compose-syllable-string string)
 -    (kannada-compose-syllable-region from to))
 -  (- to from))
 -
 -;; Register a function to compose Kannada characters.
 -(mapc
 - (function (lambda (ucs)
 -   (aset composition-function-table (decode-char 'ucs ucs)
 -       (list (cons kannada-composable-pattern
 -                     'kannada-composition-function)))))
 - (kannada-range #x0c80 #x0cff))
 +;;;###autoload
 +(defun kannada-composition-function (pos &optional string)
 +  "Compose Kannada characters after the position POS.
 +If STRING is not nil, it is a string, and POS is an index to the string.
 +In this case, compose characters after POS of the string."
 +  (if string
 +      ;; Not yet implemented.
 +      nil
 +    (goto-char pos)
 +    (if (looking-at kannada-composable-pattern)
 +      (prog1 (match-end 0)
 +        (kannada-compose-syllable-region pos (match-end 0))))))
  
  ;; Notes on conversion steps.
  
@@@ -295,8 -298,8 +295,8 @@@ Default value contains only the basic r
  
  (defun knd-charseq (from &optional to)
    (if (null to) (setq to from))
 -  (mapcar (function (lambda (x) (indian-glyph-char x 'kannada)))
 -          (kannada-range from to)))
 +  (number-sequence (decode-char 'kannada-cdac from)
 +                 (decode-char 'kannada-cdac to)))
  
  (defvar knd-glyph-cv
    (append
diff --combined lisp/language/korean.el
index 5a2ff9fdb1963ec7ae2a0b676917f27f7f117bc2,3cf291eb5894c70e3bf048c1d60b015e0d9f6ffe..d6eca4a5c5ef8b06a81056e38edb4d0bb1e1eca2
@@@ -1,14 -1,11 +1,14 @@@
  ;;; korean.el --- support for Korean -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multilingual, Korean
  
  
  ;;; Code:
  
 -(make-coding-system
 - 'korean-iso-8bit 2 ?K
 - "ISO 2022 based EUC encoding for Korean KSC5601 (MIME:EUC-KR)."
 - '(ascii korean-ksc5601 nil nil
 -   nil ascii-eol ascii-cntl)
 - '((safe-charsets ascii korean-ksc5601)
 -   (mime-charset . euc-kr)))
 +(define-coding-system 'korean-iso-8bit
 +  "ISO 2022 based EUC encoding for Korean KSC5601 (MIME:EUC-KR)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?K
 +  :designation [ascii korean-ksc5601 nil nil]
 +  :charset-list '(ascii korean-ksc5601)
 +  :mime-charset 'euc-kr)
  
  (define-coding-system-alias 'euc-kr 'korean-iso-8bit)
  (define-coding-system-alias 'euc-korea 'korean-iso-8bit)
  (define-coding-system-alias 'cp949 'korean-iso-8bit)
  
 -(make-coding-system
 - 'iso-2022-kr 2 ?k
 - "ISO 2022 based 7-bit encoding for Korean KSC5601 (MIME:ISO-2022-KR)."
 - '(ascii (nil korean-ksc5601) nil nil
 -       nil ascii-eol ascii-cntl seven locking-shift nil nil nil nil nil
 -       designation-bol)
 - '((safe-charsets ascii korean-ksc5601)
 -   (mime-charset . iso-2022-kr)))
 +(define-coding-system 'iso-2022-kr
 +  "ISO 2022 based 7-bit encoding for Korean KSC5601 (MIME:ISO-2022-KR)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?k
 +  :designation [ascii (nil korean-ksc5601) nil nil]
 +  :flags '(ascii-at-eol ascii-at-cntl 7-bit designation locking-shift
 +                      designation-bol)
 +  :charset-list '(ascii korean-ksc5601)
 +  :mime-charset 'iso-2022-kr
 +  :suitable-for-keyboard t)
  
  (define-coding-system-alias 'korean-iso-7bit-lock 'iso-2022-kr)
  
index dcbdf7eb4aaebd273c3b21d89d08c68d6fff7929,cbb2f09a35bdb3391d99d731ac6fb3afc35fd54b..359f4f8772494cba1f27caa95fc660a923b6e82c
@@@ -1,15 -1,12 +1,15 @@@
  ;;; lao-util.el --- utilities for Lao -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
 -;; Keywords: multilingual, Lao
 +;; Keywords: multilingual, Lao, i18n
  
  ;; This file is part of GNU Emacs.
  
           (?\e(1{\e(B invalid nil)
           (?\e(1|\e(B consonant "LETTER NHOR NHUU" "MOUSE")
           (?\e(1}\e(B consonant "LETTER MHOR MHAR" "DOG")
 -         (?\e(1~\e(B invalid nil)
 -         ;; Unicode equivalents
 -         (?\e$,1D!\e(B consonant "LETTER KOR  KAI'" "CHICKEN")
 -         (?\e$,1D"\e(B consonant "LETTER KHOR KHAI'" "EGG")
 -         (?\e$,1D$\e(B consonant "LETTER QHOR QHWARGN" "BUFFALO")
 -         (?\e$,1D'\e(B consonant "LETTER NGOR NGUU" "SNAKE")
 -         (?\e$,1D(\e(B consonant "LETTER JOR JUA" "BUDDHIST NOVICE")
 -         (?\e$,1D*\e(B consonant "LETTER XOR X\"ARNG" "ELEPHANT")
 -         (?\e$,1D-\e(B consonant "LETTER YOR YUNG" "MOSQUITO")
 -         (?\e$,1D4\e(B consonant "LETTER DOR DANG" "NOSE")
 -         (?\e$,1D5\e(B consonant "LETTER TOR TAR" "EYE")
 -         (?\e$,1D6\e(B consonant "LETTER THOR THUNG" "TO ASK,QUESTION")
 -         (?\e$,1D7\e(B consonant "LETTER DHOR DHARM" "FLAG")
 -         (?\e$,1D9\e(B consonant "LETTER NOR NOK" "BIRD")
 -         (?\e$,1D:\e(B consonant "LETTER BOR BED" "FISHHOOK")
 -         (?\e$,1D;\e(B consonant "LETTER POR PAR" "FISH")
 -         (?\e$,1D<\e(B consonant "LETTER HPOR HPER\"" "BEE")
 -         (?\e$,1D=\e(B consonant "LETTER FHOR FHAR" "WALL")
 -         (?\e$,1D>\e(B consonant "LETTER PHOR PHUU" "MOUNTAIN")
 -         (?\e$,1D?\e(B consonant "LETTER FOR FAI" "FIRE")
 -         (?\e$,1DA\e(B consonant "LETTER MOR MAR\"" "HORSE")
 -         (?\e$,1DB\e(B consonant "LETTER GNOR GNAR" "MEDICINE")
 -         (?\e$,1DC\e(B consonant "LETTER ROR ROD" "CAR")
 -         (?\e$,1DE\e(B consonant "LETTER LOR LIING" "MONKEY")
 -         (?\e$,1DG\e(B consonant "LETTER WOR WII" "HAND FAN")
 -         (?\e$,1DJ\e(B consonant "LETTER SOR SEA" "TIGER")
 -         (?\e$,1DK\e(B consonant "LETTER HHOR HHAI" "JAR")
 -         (?\e$,1DM\e(B consonant "LETTER OR OOW" "TAKE")
 -         (?\e$,1DN\e(B consonant "LETTER HOR HEA" "BOAT")
 -         (?\e$,1DO\e(B special "ELLIPSIS")
 -         (?\e$,1DP\e(B vowel-base "VOWEL SIGN SARA A")
 -         (?\e$,1DQ\e(B vowel-upper "VOWEL SIGN MAI KAN")
 -         (?\e$,1DR\e(B vowel-base "VOWEL SIGN SARA AR")
 -         (?\e$,1DS\e(B vowel-base "VOWEL SIGN SARA AM")
 -         (?\e$,1DT\e(B vowel-upper "VOWEL SIGN SARA I")
 -         (?\e$,1DU\e(B vowel-upper "VOWEL SIGN SARA II")
 -         (?\e$,1DV\e(B vowel-upper "VOWEL SIGN SARA EU")
 -         (?\e$,1DW\e(B vowel-upper "VOWEL SIGN SARA UR")
 -         (?\e$,1DX\e(B vowel-lower "VOWEL SIGN SARA U")
 -         (?\e$,1DY\e(B vowel-lower "VOWEL SIGN SARA UU")
 -         (?\e$,1D[\e(B vowel-upper "VOWEL SIGN MAI KONG")
 -         (?\e$,1D\\e(B semivowel-lower "SEMIVOWEL SIGN LO")
 -         (?\e$,1D]\e(B vowel-base "SEMIVOWEL SIGN SARA IA")
 -         (?\e$,1D`\e(B vowel-base "VOWEL SIGN SARA EE")
 -         (?\e$,1Da\e(B vowel-base "VOWEL SIGN SARA AA")
 -         (?\e$,1Db\e(B vowel-base "VOWEL SIGN SARA OO")
 -         (?\e$,1Dc\e(B vowel-base "VOWEL SIGN SARA EI MAI MUAN\"")
 -         (?\e$,1Dd\e(B vowel-base "VOWEL SIGN SARA AI MAI MAY")
 -         (?\e$,1Df\e(B special "KO LA (REPETITION)")
 -         (?\e$,1Dh\e(B tone "TONE MAI EK")
 -         (?\e$,1Di\e(B tone "TONE MAI THO")
 -         (?\e$,1Dj\e(B tone "TONE MAI TI")
 -         (?\e$,1Dk\e(B tone "TONE MAI JADTAWAR")
 -         (?\e$,1Dl\e(B tone "CANCELLATION MARK")
 -         (?\e$,1Dm\e(B vowel-upper "VOWEL SIGN SARA OR")
 -         (?\e$,1Dp\e(B special "DIGIT ZERO")
 -         (?\e$,1Dq\e(B special "DIGIT ONE")
 -         (?\e$,1Dr\e(B special "DIGIT TWO")
 -         (?\e$,1Ds\e(B special "DIGIT THREE")
 -         (?\e$,1Dt\e(B special "DIGIT FOUR")
 -         (?\e$,1Du\e(B special "DIGIT FIVE")
 -         (?\e$,1Dv\e(B special "DIGIT SIX")
 -         (?\e$,1Dw\e(B special "DIGIT SEVEN")
 -         (?\e$,1Dx\e(B special "DIGIT EIGHT")
 -         (?\e$,1Dy\e(B special "DIGIT NINE")
 -         (?\e$,1D|\e(B consonant "LETTER NHOR NHUU" "MOUSE")
 -         (?\e$,1D}\e(B consonant "LETTER MHOR MHAR" "DOG")))
 +         (?\e(1~\e(B invalid nil)))
        elm)
    (while l
      (setq elm (car l) l (cdr l))
  ;; CV -> C, CT -> C, CVT -> C, Cv -> C, CvT -> C
  ;;                                   v         v
  ;;                             T
 -;;        V         T          V                   T
 -;; CsV -> C, CsT -> C, CsVT -> C, Csv -> C, CvT -> C
 -;;        s         s          s         s         s
 -;;                                       v         v
 +;;        V         T          V                    T
 +;; CsV -> C, CsT -> C, CsVT -> C, Csv -> C, CsvT -> C
 +;;        s         s          s         s          s
 +;;                                       v          v
  
  
  ;; where C: consonant, V: vowel upper, v: vowel lower,
      ("\e(1d\e(B" (?\e(1d\e(B 0))
      ("\e(1c\e(B" (?\e(1c\e(B 0))
      ("\e(1`[R\e(B" (?\e(1`\e(B 0 ?\e(1[\e(B ?\e(1R\e(B))
 -    ("\e(1S\e(B" (0 ?\e(1S\e(B))
 -
 -    ;; Unicode equivalents
 -    ("\e$,1DP\e(B" (0 ?\e$,1DP\e(B) (0 ?\e$,1DQ\e(B))
 -    ("\e$,1DR\e(B" (0 ?\e$,1DR\e(B))
 -    ("\e$,1DT\e(B" (0 ?\e$,1DU\e(B))
 -    ("\e$,1DU\e(B" (0 ?\e$,1DU\e(B))
 -    ("\e$,1DV\e(B" (0 ?\e$,1DV\e(B))
 -    ("\e$,1DW\e(B" (0 ?\e$,1DW\e(B))
 -    ("\e$,1DX\e(B" (0 ?\e$,1DX\e(B))
 -    ("\e$,1DY\e(B" (0 ?\e$,1DY\e(B))
 -    ("\e$,1D`DP\e(B" (?\e$,1D`\e(B 0 ?\e$,1DP\e(B) (?\e$,1D`\e(B 0 ?\e$,1DQ\e(B))
 -    ("\e$,1D`\e(B" (?\e$,1D`\e(B 0))
 -    ("\e$,1DaDP\e(B" (?\e$,1Da\e(B 0 ?\e$,1DP\e(B) (?\e$,1Da\e(B 0 ?\e$,1DQ\e(B))
 -    ("\e$,1Da\e(B" (?\e$,1Da\e(B 0))
 -    ("\e$,1DbDP\e(B" (?\e$,1Db\e(B 0 ?\e$,1DP\e(B) (0 ?\e$,1D[\e(B) (?\e$,1D-\e(B ?\e$,1Db\e(B 0 ?\e$,1DQ\e(B) (?\e$,1DG\e(B ?\e$,1Db\e(B 0 ?\e$,1DQ\e(B))
 -    ("\e$,1Db\e(B" (?\e$,1Db\e(B 0))
 -    ("\e$,1D`DRDP\e(B" (?\e$,1D`\e(B 0 ?\e$,1DR\e(B ?\e$,1DP\e(B) (0 ?\e$,1DQ\e(B ?\e$,1DM\e(B))
 -    ("\e$,1Dm\e(B" (0 ?\e$,1Dm\e(B) (0 ?\e$,1DM\e(B))
 -    ("\e$,1D`DT\e(B" (?\e$,1D`\e(B 0 ?\e$,1DT\e(B))
 -    ("\e$,1D`DU\e(B" (?\e$,1D`\e(B 0 ?\e$,1DU\e(B))
 -    ("\e$,1D[DGDP\e(B" (0 ?\e$,1D[\e(B ?\e$,1DG\e(B ?\e$,1DP\e(B) (0 ?\e$,1DQ\e(B ?\e$,1DG\e(B))
 -    ("\e$,1D[DG\e(B" (0 ?\e$,1D[\e(B ?\e$,1DG\e(B) (0 ?\e$,1DG\e(B))
 -    ("\e$,1D`DQD]DP\e(B" (?\e$,1D`\e(B 0 ?\e$,1DQ\e(B ?\e$,1D]\e(B ?\e$,1DP\e(B) (0 ?\e$,1DQ\e(B ?\e$,1D]\e(B))
 -    ("\e$,1D`DQD]\e(B" (?\e$,1D`\e(B 0 ?\e$,1DQ\e(B ?\e$,1D]\e(B) (0 ?\e$,1D]\e(B))
 -    ("\e$,1D`DVDM\e(B" (?\e$,1D`\e(B 0 ?\e$,1DV\e(B ?\e$,1DM\e(B))
 -    ("\e$,1D`DWDM\e(B" (?\e$,1D`\e(B 0 ?\e$,1DW\e(B ?\e$,1DM\e(B))
 -    ("\e$,1Dd\e(B" (?\e$,1Dd\e(B 0))
 -    ("\e$,1Dc\e(B" (?\e$,1Dc\e(B 0))
 -    ("\e$,1D`D[DR\e(B" (?\e$,1D`\e(B 0 ?\e$,1D[\e(B ?\e$,1DR\e(B))
 -    ("\e$,1DS\e(B" (0 ?\e$,1DS\e(B)))
 +    ("\e(1S\e(B" (0 ?\e(1S\e(B)))
    "Alist of Lao vowel string vs the corresponding re-ordering rule.
  Each element has this form:
        (VOWEL NO-MAA-SAKOD-RULE WITH-MAA-SAKOD-RULE (MAA-SAKOD-0 RULE-0) ...)
@@@ -492,20 -585,24 +492,20 @@@ syllable.  In that case, FROM and TO ar
        lao-str)))
  
  ;;;###autoload
 -(defun lao-post-read-conversion (len)
 -  (lao-compose-region (point) (+ (point) len))
 -  len)
 -
 -;;;###autoload
 -(defun lao-composition-function (from to pattern &optional string)
 -  "Compose Lao text in the region FROM and TO.
 -The text matches the regular expression PATTERN.
 -Optional 4th argument STRING, if non-nil, is a string containing text
 -to compose.
 -
 -The return value is number of composed characters."
 -  (if (< (1+ from) to)
 -      (progn
 -      (if string
 -          (compose-string string from to)
 -        (compose-region from to))
 -      (- to from))))
 +(defun lao-composition-function (pos &optional string)
 +  (setq pos (1- pos))
 +  (with-category-table lao-category-table
 +    (if string
 +      (if (and (>= pos 0)
 +               (eq (string-match lao-composition-pattern string pos) pos))
 +          (prog1 (match-end 0)
 +            (compose-string string pos (match-end 0))))
 +      (if (>= pos (point-min))
 +        (save-excursion
 +          (goto-char pos)
 +          (if (looking-at lao-composition-pattern)
 +              (prog1 (match-end 0)
 +                (compose-region pos (match-end 0)))))))))
  
  ;;;###autoload
  (defun lao-compose-region (from to)
diff --combined lisp/language/lao.el
index ed290d988ef57dabb0daeaa1b8380abbf463ca0f,e4158f682ad489837127aaa68447718de288202f..1f5a994575beb9f19df784d37d3bad2768bc670e
@@@ -1,12 -1,9 +1,12 @@@
  ;;; lao.el --- support for Lao -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
  ;; Copyright (C) 2001  Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: multilingual, Lao
  
  
  ;;; Code:
  
 -(make-coding-system
 - 'lao 2 ?L
 - "8-bit encoding for ASCII (MSB=0) and LAO (MSB=1)."
 - '(ascii lao nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii lao)
 -   (post-read-conversion . lao-post-read-conversion)))
 +(define-coding-system 'lao
 +  "8-bit encoding for ASCII (MSB=0) and LAO (MSB=1)."
 +  :coding-type 'charset
 +  :mnemonic ?L
 +  :charset-list '(lao))
  
  (set-language-info-alist
   "Lao" '((charset lao)
         (coding-system lao)
         (coding-priority lao)
         (input-method . "lao")
 -       (nonascii-translation . lao)
         (unibyte-display . lao)
         (features lao-util)
         (documentation . t)))
  
 -(aset use-default-ascent ?\e(1;\e(B t)
 -(aset use-default-ascent ?\e$,1D;\e(B t)
 -(aset use-default-ascent ?\e(1=\e(B t)
 -(aset use-default-ascent ?\e$,1D=\e(B t)
 -(aset use-default-ascent ?\e(1?\e(B t)
 -(aset use-default-ascent ?\e$,1D?\e(B t)
 -(aset use-default-ascent ?\e(1B\e(B t)
 -(aset use-default-ascent ?\e$,1DB\e(B t)
 -(aset ignore-relative-composition ?\e(1\\e(B t)
 -(aset ignore-relative-composition ?\e$,1D\\e(B t)
 -
 -;; Register a function to compose Lao characters.
 -(let ((patterns '(("\\c0\\c9?\\(\\(\\c2\\|\\c3\\)\\c4?\\|\\c4\\)?"
 -       . lao-composition-function))))
 -  (aset composition-function-table (make-char 'lao) patterns)
 -  (dotimes (i (1+ (- #xeff #xe80)))
 -    (aset composition-function-table (decode-char 'ucs (+ i #xe80)) patterns)))
 +;; For automatic composition.
 +(let ((chars "\e(1QTUVWXY[\hijklm\e(B"))
 +  (dotimes (i (length chars))
 +    (aset composition-function-table (aref chars i)
 +        'lao-composition-function)))
  
  (provide 'lao)
  
index bab94a2a2d8b3cddd3e193c89f06357e718e5056,bc2a9614714e15f8bf45f972b8de44d629f4f207..0f6025e976d6594e29ee78ad94690a1a4c8fcef9
@@@ -1,6 -1,6 +1,6 @@@
  ;;; malayalam.el --- Support for Malayalam -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Maintainer:  KAWABATA, Taichi <kawabata@m17n.org>
  ;; Keywords: multilingual, Indian, Malayalam
  South Indian language Malayalam is supported in this language environment."))
   '("Indian"))
  
 +;; For automatic composition.
 +(set-char-table-range composition-function-table '(#x0d00 . #x0d7f)
 +                    'malayalam-composition-function)
 +
 +
  (provide 'malayalam)
  
  ;;; arch-tag: 5f500e53-1e4f-4bb2-aa93-ad8736f0349f
index ce6432482424fce14b29b33154129459ee8eeca9,1d90e2d9a0c8efe44ecb3f9d1590e28bc49cae5b..166a0a5d2a56cb6e4be31451a9a8acf3d4b05971
@@@ -1,7 -1,7 +1,7 @@@
  ;;; misc-lang.el --- support for miscellaneous languages (characters) -*- no-byte-compile: t -*-
  
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  IPA is International Phonetic Alphabet for English, French, German
  and Italian.")))
  
 +;; This is for Arabic.  But, as we still don't have Arabic language
 +;; support, we at least define a coding system here.
 +
 +(define-coding-system 'iso-8859-6
 +  "ISO-8859-6 based encoding (MIME:ISO-8859-6)."
 +  :coding-type 'charset
 +  :mnemonic ?6
 +  :charset-list '(iso-8859-6)
 +  :mime-charset 'iso-8859-6)
 +
  (provide 'misc-lang)
  
  ;;; arch-tag: 6953585c-1a1a-4c09-be82-a2518afb6074
index 4d40f0dcb42974107d40d7a1d5c3e452f88e41b4,aac0951eaec9f6d3cd15619f2680ace8d943fe12..86890c59dfe42625ac28d4e2d3d998f8de56eee5
@@@ -1,6 -1,6 +1,6 @@@
  ;;; mlm-util.el --- support for composing malayalam characters  -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Maintainer:  KAWABATA, Taichi <kawabata@m17n.org>
  ;; Keywords: multilingual, Malayalam
  
  
  ;;;###autoload
 -(defun malayalam-composition-function (from to pattern  &optional string)
 -  "Compose Malayalam characters in REGION, or STRING if specified.
 -Assume that the REGION or STRING must fully match the composable
 -PATTERN regexp."
 -  (if string (malayalam-compose-syllable-string string)
 -    (malayalam-compose-syllable-region from to))
 -  (- to from))
 -
 -;; Register a function to compose Malayalam characters.
 -(mapc
 - (function (lambda (ucs)
 -   (aset composition-function-table (decode-char 'ucs ucs)
 -       (list (cons malayalam-composable-pattern
 -                     'malayalam-composition-function)))))
 - (nconc '(#x0d02 #x0d03) (malayalam-range #x0d05 #x0d39)))
 +(defun malayalam-composition-function (pos  &optional string)
 +  "Compose Malayalam characters after the position POS.
 +If STRING is not nil, it is a string, and POS is an index to the string.
 +In this case, compose characters after POS of the string."
 +  (if string
 +      ;; Not yet implemented.
 +      nil
 +    (goto-char pos)
 +    (if (looking-at malayalam-composable-pattern)
 +      (prog1 (match-end 0)
 +        (malayalam-compose-syllable-region pos (match-end 0))))))
  
  ;; Notes on conversion steps.
  
          (narrow-to-region from to)
          (goto-char (point-min))
          ;; char-glyph-conversion
 -        (while (re-search-forward mlm-char-glyph-regexp nil t)
 -          (setq match-str (match-string 0))
 -          (setq glyph-str
 -                (concat glyph-str (gethash match-str mlm-char-glyph-hash))))
 +        (while (not (eobp))
 +        (if (looking-at mlm-char-glyph-regexp)
 +            (progn
 +              (setq match-str (match-string 0)
 +                    glyph-str
 +                    (concat glyph-str
 +                            (gethash match-str mlm-char-glyph-hash)))
 +              (goto-char (match-end 0)))
 +          (setq glyph-str (concat glyph-str (string (following-char))))
 +          (forward-char 1)))
          (when (string-match mlm-glyph-reorder-key-glyphs glyph-str)
            ;; glyph reordering
            (setq glyph-reorder-regexps mlm-glyph-reordering-regexp-list)
index 79f8e7d87b87626068dadfadc214ae4090bb82e4,9776fe23464a8a24e2b24c4a699b6af86565109c..6bc7154ef467192ce4c782419675671c38e3cb64
@@@ -1,10 -1,10 +1,10 @@@
  ;;; romanian.el --- support for Romanian -*- coding: iso-latin-2; no-byte-compile: t -*-
  
- ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation.
  
  ;; Author:    Dan Nicolaescu <done@ece.arizona.edu>
 -;; Keywords: multilingual, Romanian
 +;; Keywords: multilingual, Romanian, i18n
  
  ;; This file is part of GNU Emacs.
  
  
  ;;; Commentary:
  
 -;; Romanian ISO 8859-2 environment.
 +;; Romanian ISO 8859-2 environment plus 8859-16 coding system.
  
  ;;; Code:
  
  (set-language-info-alist
 - "Romanian" '((charset . (ascii latin-iso8859-2))
 -            (coding-system . (iso-8859-2))
 -            (coding-priority . (iso-8859-2))
 -            (nonascii-translation . latin-iso8859-2)
 + "Romanian" '((charset iso-8859-2)
 +            (coding-system iso-8859-2 iso-latin-10)
 +            (coding-priority iso-8859-2)
 +            (nonascii-translation . iso-8859-2)
              (input-method . "latin-2-postfix")
 -            (unibyte-syntax . "latin-2")
              (unibyte-display . iso-8859-2)
              (tutorial . "TUTORIAL.ro")
              (sample-text . "Bunã ziua, bine aþi venit!")
 -            (documentation . t))
 +            (documentation . "Rmoanian environment using Latin-2 encoding.
 +An environment for generic Latin-10 encoding is also available."))
   '("European"))
  
 +(define-coding-system 'iso-latin-10
 +  "ISO 2022 based 8-bit encoding for Latin-10."
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(iso-8859-16)
 +  :mime-charset 'iso-8859-16)
 +
 +(define-coding-system-alias 'iso-8859-16 'iso-latin-10)
 +(define-coding-system-alias 'latin-10 'iso-latin-10)
 +
  (provide 'romanian)
  
  ;;; arch-tag: a0bf93ee-2f02-4678-a477-c08acc35366b
diff --combined lisp/language/slovak.el
index 3fe6fc0acb03b51a3c3f4059cc78f8279499b3e2,06d10731e859de88e4e51981b112822b46e383a2..b480bdc80bb27ffa3f55075124d55e9983b3b1a9
@@@ -1,6 -1,6 +1,6 @@@
  ;;; slovak.el --- support for Slovak -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation.
  
  ;; Authors:    Tibor \e,B)\e(Bimko <tibor.simko@fmph.uniba.sk>,
@@@ -35,8 -35,9 +35,8 @@@
   "Slovak" '((charset . (ascii latin-iso8859-2))
            (coding-system . (iso-8859-2))
            (coding-priority . (iso-8859-2))
 -          (nonascii-translation . latin-iso8859-2)
 +          (nonascii-translation . iso-8859-2)
            (input-method . "slovak")
 -          (unibyte-syntax . "latin-2")
            (unibyte-display . iso-8859-2)
            (tutorial . "TUTORIAL.sk")
            (sample-text . "Prajeme V\e,Ba\e(Bm pr\e,Bm\e(Bjemn\e,B}\e(B de\e,Br\e(B!")
diff --combined lisp/language/tamil.el
index 9be6490fe696791f8a0b132bf91137e826cfd3d8,e4a495ca635dfe9686e31ed4ad91e7df52ffd8de..aff0769a039a8529a8ab8d6490c85b42ec81c1df
@@@ -1,6 -1,6 +1,6 @@@
  ;;; tamil.el --- Support for Tamil -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
- ;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Maintainer: KAWABATA, Taichi <batta@beige.ocn.ne.jp>
  ;; Keywords: multilingual, Indian, Tamil
@@@ -38,9 -38,6 +38,9 @@@
  South Indian Language Tamil supported in this language environment."))
   '("Indian"))
  
 +;; For automatic composition.
 +(set-char-table-range composition-function-table '(#x0b80 . #x0bff)
 +                    'tamil-composition-function)
  (provide 'tamil)
  
  ;;; arch-tag: 2201ac78-7d1e-4674-9bcb-9923c7a2bd9c
index 8dcfca2c3dbf1c47759889667ed643e9dba46eb9,3ce0ef696d2c76b82efc96d5a13e31c3a23bcc58..4493ea518723e18b4b27ec47427d332819f886b9
@@@ -1,13 -1,13 +1,13 @@@
  ;;; thai-util.el --- utilities for Thai -*- coding: iso-2022-7bit; -*-
  
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
 -;;   Registration Number H14PRO021
 +;;   Registration Number H13PRO009
- ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  
 -;; Keywords: mule, multilingual, thai
 +;; Keywords: mule, multilingual, Thai, i18n
  
  ;; This file is part of GNU Emacs.
  
    "\\cc\\(\\cu\\|\\cI\\cU\\|\\cv\\ct?\\)\\|\\cv\\ct\\|\\cI\\cU"
    "Regular expression matching a Thai composite sequence.")
  
 -(defun thai-self-insert-command (&optional n)
 -  "Insert the Thai character you type.
 -The character will be composed with the surrounding Thai character
 -if necessary."
 -  (interactive "*p")
 -  (let ((pos (point))
 -      category-set ch)
 -    (self-insert-command n)
 -    (or thai-auto-composition-mode
 -      (thai-auto-composition (1- (point)) (point) 0))))
 -
  (let ((l '((?\e,T!\e(B consonant "LETTER KO KAI")                               ; 0xA1
           (?\e,T"\e(B consonant "LETTER KHO KHAI")                               ; 0xA2
           (?\e,T#\e(B consonant "LETTER KHO KHUAT")                              ; 0xA3
           (?\e,T|\e(B invalid nil)                                               ; 0xFC
           (?\e,T}\e(B invalid nil)                                               ; 0xFD
           (?\e,T~\e(B invalid nil)                                               ; 0xFE
 -
 -         ;; Unicode equivalents
 -         (?\e$,1Ba\e(B consonant "LETTER KO KAI")
 -         (?\e$,1Bb\e(B consonant "LETTER KHO KHAI")
 -         (?\e$,1Bc\e(B consonant "LETTER KHO KHUAT")
 -         (?\e$,1Bd\e(B consonant "LETTER KHO KHWAI")
 -         (?\e$,1Be\e(B consonant "LETTER KHO KHON")
 -         (?\e$,1Bf\e(B consonant "LETTER KHO RAKHANG")
 -         (?\e$,1Bg\e(B consonant "LETTER NGO NGU")
 -         (?\e$,1Bh\e(B consonant "LETTER CHO CHAN")
 -         (?\e$,1Bi\e(B consonant "LETTER CHO CHING")
 -         (?\e$,1Bj\e(B consonant "LETTER CHO CHANG")
 -         (?\e$,1Bk\e(B consonant "LETTER SO SO")
 -         (?\e$,1Bl\e(B consonant "LETTER CHO CHOE")
 -         (?\e$,1Bm\e(B consonant "LETTER YO YING")
 -         (?\e$,1Bn\e(B consonant "LETTER DO CHADA")
 -         (?\e$,1Bo\e(B consonant "LETTER TO PATAK")
 -         (?\e$,1Bp\e(B consonant "LETTER THO THAN")
 -         (?\e$,1Bq\e(B consonant "LETTER THO NANGMONTHO")
 -         (?\e$,1Br\e(B consonant "LETTER THO PHUTHAO")
 -         (?\e$,1Bs\e(B consonant "LETTER NO NEN")
 -         (?\e$,1Bt\e(B consonant "LETTER DO DEK")
 -         (?\e$,1Bu\e(B consonant "LETTER TO TAO")
 -         (?\e$,1Bv\e(B consonant "LETTER THO THUNG")
 -         (?\e$,1Bw\e(B consonant "LETTER THO THAHAN")
 -         (?\e$,1Bx\e(B consonant "LETTER THO THONG")
 -         (?\e$,1By\e(B consonant "LETTER NO NU")
 -         (?\e$,1Bz\e(B consonant "LETTER BO BAIMAI")
 -         (?\e$,1B{\e(B consonant "LETTER PO PLA")
 -         (?\e$,1B|\e(B consonant "LETTER PHO PHUNG")
 -         (?\e$,1B}\e(B consonant "LETTER FO FA")
 -         (?\e$,1B~\e(B consonant "LETTER PHO PHAN")
 -         (?\e$,1B\7f\e(B consonant "LETTER FO FAN")
 -         (?\e$,1C \e(B consonant "LETTER PHO SAMPHAO")
 -         (?\e$,1C!\e(B consonant "LETTER MO MA")
 -         (?\e$,1C"\e(B consonant "LETTER YO YAK")
 -         (?\e$,1C#\e(B consonant "LETTER RO RUA")
 -         (?\e$,1C$\e(B vowel-base "LETTER RU (Pali vowel letter)")
 -         (?\e$,1C%\e(B consonant "LETTER LO LING")
 -         (?\e$,1C&\e(B vowel-base "LETTER LU (Pali vowel letter)")
 -         (?\e$,1C'\e(B consonant "LETTER WO WAEN")
 -         (?\e$,1C(\e(B consonant "LETTER SO SALA")
 -         (?\e$,1C)\e(B consonant "LETTER SO RUSI")
 -         (?\e$,1C*\e(B consonant "LETTER SO SUA")
 -         (?\e$,1C+\e(B consonant "LETTER HO HIP")
 -         (?\e$,1C,\e(B consonant "LETTER LO CHULA")
 -         (?\e$,1C-\e(B consonant "LETTER O ANG")
 -         (?\e$,1C.\e(B consonant "LETTER HO NOK HUK")
 -         (?\e$,1C/\e(B special "PAI YAN NOI (abbreviation)")
 -         (?\e$,1C0\e(B vowel-base "VOWEL SIGN SARA A")
 -         (?\e$,1C1\e(B vowel-upper "VOWEL SIGN MAI HAN-AKAT N/S-T")
 -         (?\e$,1C2\e(B vowel-base "VOWEL SIGN SARA AA")
 -         (?\e$,1C3\e(B vowel-base "VOWEL SIGN SARA AM")
 -         (?\e$,1C4\e(B vowel-upper "VOWEL SIGN SARA I N/S-T")
 -         (?\e$,1C5\e(B vowel-upper "VOWEL SIGN SARA II N/S-T")
 -         (?\e$,1C6\e(B vowel-upper "VOWEL SIGN SARA UE N/S-T")
 -         (?\e$,1C7\e(B vowel-upper "VOWEL SIGN SARA UEE N/S-T")
 -         (?\e$,1C8\e(B vowel-lower "VOWEL SIGN SARA U N/S-B")
 -         (?\e$,1C9\e(B vowel-lower "VOWEL SIGN SARA UU N/S-B")
 -         (?\e$,1C:\e(B vowel-lower "VOWEL SIGN PHINTHU N/S-B (Pali virama)")
 -         (?\e$,1C?\e(B special "BAHT SIGN (currency symbol)")
 -         (?\e$,1C@\e(B vowel-base "VOWEL SIGN SARA E")
 -         (?\e$,1CA\e(B vowel-base "VOWEL SIGN SARA AE")
 -         (?\e$,1CB\e(B vowel-base "VOWEL SIGN SARA O")
 -         (?\e$,1CC\e(B vowel-base "VOWEL SIGN SARA MAI MUAN")
 -         (?\e$,1CD\e(B vowel-base "VOWEL SIGN SARA MAI MALAI")
 -         (?\e$,1CE\e(B vowel-base "LAK KHANG YAO")
 -         (?\e$,1CF\e(B special "MAI YAMOK (repetion)")
 -         (?\e$,1CG\e(B sign-upper "VOWEL SIGN MAI TAI KHU N/S-T")
 -         (?\e$,1CH\e(B tone "TONE MAI EK N/S-T")
 -         (?\e$,1CI\e(B tone "TONE MAI THO N/S-T")
 -         (?\e$,1CJ\e(B tone "TONE MAI TRI N/S-T")
 -         (?\e$,1CK\e(B tone "TONE MAI CHATTAWA N/S-T")
 -         (?\e$,1CL\e(B sign-upper "THANTHAKHAT N/S-T (cancellation mark)")
 -         (?\e$,1CM\e(B sign-upper "NIKKHAHIT N/S-T (final nasal)")
 -         (?\e$,1CN\e(B sign-upper "YAMAKKAN N/S-T")
 -         (?\e$,1CO\e(B special "FONRMAN")
 -         (?\e$,1CP\e(B special "DIGIT ZERO")
 -         (?\e$,1CQ\e(B special "DIGIT ONE")
 -         (?\e$,1CR\e(B special "DIGIT TWO")
 -         (?\e$,1CS\e(B special "DIGIT THREE")
 -         (?\e$,1CT\e(B special "DIGIT FOUR")
 -         (?\e$,1CU\e(B special "DIGIT FIVE")
 -         (?\e$,1CV\e(B special "DIGIT SIX")
 -         (?\e$,1CW\e(B special "DIGIT SEVEN")
 -         (?\e$,1CX\e(B special "DIGIT EIGHT")
 -         (?\e$,1CY\e(B special "DIGIT NINE")
 -         (?\e$,1CZ\e(B special "ANGKHANKHU (ellipsis)")
 -         (?\e$,1C[\e(B special "KHOMUT (beginning of religious texts)")
           ))
        elm)
    (while l
          (ptype (nth 1 elm)))
        (put-char-code-property char 'phonetic-type ptype)
        (cond ((eq ptype 'consonant)
 -           (modify-category-entry char ?c thai-category-table)
 -           (global-set-key (vector char) 'thai-self-insert-command))
 +           (modify-category-entry char ?c thai-category-table))
            ((memq ptype '(vowel-upper vowel-lower))
             (modify-category-entry char ?v thai-category-table)
 -           (if (or (= char ?\e,TT\e(B) (= char ?\e$,1C4\e(B))
 +           (if (= char ?\e,TT\e(B)
                 ;; Give category `I' to "SARA I".
 -               (modify-category-entry char ?I thai-category-table))
 -           (global-set-key (vector char) 'thai-self-insert-command))
 +               (modify-category-entry char ?I thai-category-table)))
            ((eq ptype 'tone)
             (modify-category-entry char ?t thai-category-table)
 -           (modify-category-entry char ?u thai-category-table)
 -           (global-set-key (vector char) 'thai-self-insert-command))
 +           (modify-category-entry char ?u thai-category-table))
            ((eq ptype 'sign-upper)
             (modify-category-entry char ?u thai-category-table)
 -           (if (or (= char ?\e,Tl\e(B) (= char ?\e$,1CL\e(B))
 +           (if (= char ?\e,Tl\e(B)
                 ;; Give category `U' to "THANTHAKHAT".
 -               (modify-category-entry char ?U thai-category-table))
 -           (global-set-key (vector char) 'thai-self-insert-command)))
 +               (modify-category-entry char ?U thai-category-table))))
        (put-char-code-property char 'name (nth 2 elm)))))
  
  (defun thai-compose-syllable (beg end &optional category-set string)
@@@ -229,20 -333,57 +229,20 @@@ positions (integers or markers) specify
    (thai-compose-region (point-min) (point-max)))
  
  ;;;###autoload
 -(defun thai-post-read-conversion (len)
 -  (thai-compose-region (point) (+ (point) len))
 -  len)
 -
 -;;;###autoload
 -(defun thai-composition-function (from to pattern &optional string)
 -  "Compose Thai text in the region FROM and TO.
 -The text matches the regular expression PATTERN.
 -Optional 4th argument STRING, if non-nil, is a string containing text
 -to compose.
 -
 -The return value is number of composed characters."
 -  (when (and (not thai-auto-composition-mode)
 -           (< (1+ from) to))
 -    (with-category-table thai-category-table
 -      (if string
 -        (if (eq (string-match thai-composition-pattern string from) from)
 -            (thai-compose-syllable from (match-end 0) nil string))
 -      (if (save-excursion
 -            (goto-char from)
 -            (and (looking-at thai-composition-pattern)
 -                 (setq to (match-end 0))))
 -          (thai-compose-syllable from to))))))
 -
 -(defun thai-auto-composition (beg end len)
 +(defun thai-composition-function (pos &optional string)
 +  (setq pos (1- pos))
    (with-category-table thai-category-table
 -    (let (category-set)
 -      (while (and (> beg (point-min))
 -                (setq category-set (char-category-set (char-after (1- beg))))
 -                (or (aref category-set ?v) (aref category-set ?u)))
 -        (setq beg (1- beg)))
 -      (if (and (> beg (point-min))
 -             (aref (char-category-set (char-after (1- beg))) ?c))
 -        (setq beg (1- beg)))
 -      (while (and (< end (point-max))
 -                (setq category-set (char-category-set (char-after end)))
 -                (or (aref category-set ?v) (aref category-set ?u)))
 -      (setq end (1+ end)))
 -      (if (< beg end)
 -        (thai-compose-region beg end)))))
 -
 -(put 'thai-auto-composition-mode 'permanent-local t)
 -
 -;;;###autoload
 -(define-minor-mode thai-auto-composition-mode
 -  "Minor mode for automatically correct Thai character composition."
 -  :group 'mule
 -  (cond ((null thai-auto-composition-mode)
 -       (remove-hook 'after-change-functions 'thai-auto-composition))
 -      (t
 -       (add-hook 'after-change-functions 'thai-auto-composition))))
 +    (if string
 +      (if (and (>= pos 0)
 +               (eq (string-match thai-composition-pattern string pos) pos))
 +          (prog1 (match-end 0)
 +            (thai-compose-syllable pos (match-end 0) nil string)))
 +      (if (>= pos (point-min))
 +        (progn
 +          (goto-char pos)
 +          (if (looking-at thai-composition-pattern)
 +              (prog1 (match-end 0)
 +                (thai-compose-syllable pos (match-end 0)))))))))
  
  ;; Thai-word-mode requires functions in the feature `thai-word'.
  (require 'thai-word)
diff --combined lisp/language/thai.el
index 0c346c7594b37c5c199b9697ba4b038640d88693,67d8734c48214d73689a9f1356cee741f9e7c5db..facdbba50dd88ac4fa9b3e95fef17859f3976700
@@@ -1,16 -1,13 +1,16 @@@
  ;;; thai.el --- support for Thai -*- coding: iso-2022-7bit; no-byte-compile: t -*-
  
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
 +;; Copyright (C) 2005
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  ;; Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
- ;;   2006  Free Software Foundation, Inc.
+ ;;   2006, 2007  Free Software Foundation, Inc.
  
 -;; Keywords: multilingual, Thai
 +;; Keywords: multilingual, Thai, i18n
  
  ;; This file is part of GNU Emacs.
  
  
  ;;; Code:
  
 -(make-coding-system
 - 'thai-tis620 2 ?T
 - "8-bit encoding for ASCII (MSB=0) and Thai TIS620 (MSB=1)."
 - '(ascii thai-tis620 nil nil
 -   nil nil nil nil nil nil nil nil nil nil nil t)
 - '((safe-charsets ascii thai-tis620)
 -   (mime-charset . tis-620)
 -   (post-read-conversion . thai-post-read-conversion)))
 +(define-coding-system 'thai-tis620
 +  "8-bit encoding for ASCII (MSB=0) and Thai TIS620 (MSB=1)."
 +  :coding-type 'charset
 +  :mnemonic ?T
 +  :charset-list '(tis620-2533))
  
  (define-coding-system-alias 'th-tis620 'thai-tis620)
  (define-coding-system-alias 'tis620 'thai-tis620)
@@@ -48,9 -48,9 +48,9 @@@
  (set-language-info-alist
   "Thai" '((tutorial . "TUTORIAL.th")
          (charset thai-tis620)
 -        (coding-system thai-tis620)
 +        (coding-system thai-tis620 iso-8859-11 cp874)
          (coding-priority thai-tis620)
 -        (nonascii-translation . thai-tis620)
 +        (nonascii-translation . tis620-2533)
          (input-method . "thai-kesmanee")
          (unibyte-display . thai-tis620)
          (features thai-util)
          (exit-function . exit-thai-language-environment-internal)
          (sample-text
           . (thai-compose-string
 -            (copy-sequence "Thai (\e,T@RIRd7B\e(B)              \e,TJ\e0GQ\e1J\e04U\e1$\e0CQ\e1:\e(B, \e,TJ\e0GQ\e1J\e04U\e1\e0$h\e1P\e(B")))
 +            (copy-sequence "Thai (\e,T@RIRd7B\e(B)              \e,TJGQJ4U$CQ:\e(B, \e,TJGQJ4U$hP\e(B")))
          (documentation . t)))
  
 -
 -;; Register a function to compose Thai characters.
 -(let ((patterns '(("\\c0?\\(\\c2\\|\\c3\\|\\c4\\)+"
 -                 . thai-composition-function))))
 -  (aset composition-function-table (make-char 'thai-tis620) patterns)
 -  (dotimes (i (1+ (- #xe7f #xe00)))
 -    (aset composition-function-table (decode-char 'ucs (+ i #xe00)) patterns)))
 +(define-coding-system 'cp874
 +  "DOS codepage 874 (Thai)"
 +  :coding-type 'charset
 +  :mnemonic ?D
 +  :charset-list '(cp874)
 +  :mime-charset 'cp874)
 +(define-coding-system-alias 'ibm874 'cp874)
 +
 +(define-coding-system 'iso-8859-11
 +  "ISO/IEC 8859/11 (Latin/Thai)
 +This is the same as `thai-tis620' with the addition of no-break-space."
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :mime-charset 'iso-8859-11 ; not actually registered as of 2002-05-24
 +  :charset-list '(iso-8859-11))
 +
 +;; For automatic composition.
 +(let ((chars "\e,TQTUVWXYZghijklmn\e(B"))
 +  (dotimes (i (length chars))
 +    (aset composition-function-table (aref chars i)
 +        'thai-composition-function)))
  
  (provide 'thai)
  
index 012456da6e7c45b19915806005d20163d89eb9be,d79a20a024e306cebafd791494af16d99a09acb2..a318ff0ab3f48cb50c8987d442230797f9288831
@@@ -1,9 -1,9 +1,9 @@@
  ;;; tibet-util.el --- utilities for Tibetan   -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
  
  ;;; Code:
  
  (defconst tibetan-obsolete-glyphs
 -  `(("\e$(7!=\e(B" . "\e$(8!=\e(B")                       ; 2 col <-> 1 col
 -    ("\e$(7!?\e(B" . "\e$(8!?\e(B")
 -    ("\e$(7!@\e(B" . "\e$(8!@\e(B")
 -    ("\e$(7!A\e(B" . "\e$(8!A\e(B")
 -    ("\e$(7"`\e(B" . "\e$(8"`\e(B")
 -    ("\e$(7!;\e(B" . "\e$(8!;\e(B")
 -    ("\e$(7!D\e(B" . "\e$(8!D\e(B")
 +  `(("\e$(7!=\e(B" . "\e$(7!=\e(B")                       ; 2 col <-> 1 col
 +    ("\e$(7!?\e(B" . "\e$(7!?\e(B")
 +    ("\e$(7!@\e(B" . "\e$(7!@\e(B")
 +    ("\e$(7!A\e(B" . "\e$(7!A\e(B")
 +    ("\e$(7"`\e(B" . "\e$(7"`\e(B")
 +    ("\e$(7!;\e(B" . "\e$(7!;\e(B")
 +    ("\e$(7!D\e(B" . "\e$(7!D\e(B")
      ;; Yes these are dirty. But ...
      ("\e$(7!>\e(B \e$(7!>\e(B" . ,(compose-string "\e$(7!>\e(B \e$(7!>\e(B" 0 3 [?\e$(7!>\e(B (Br . Bl) ?  (Br . Bl) ?\e$(7!>\e(B]))
      ("\e$(7!4!5!5\e(B" . ,(compose-string
@@@ -141,7 -141,7 +141,7 @@@ The returned string has no composition 
  ;;;
  ;;; Here are examples of the words "bsgrubs" and "hfauM"
  ;;;
 -;;;            \e4\e$(7"7\e0"7\e1\e4%qx!"U\e0"G###C"U\e1\e4"7\e0"7\e1\e4"G\e0"G\e1\e(B            \e4\e$(7"Hx!"Rx!"Ur'"_\e0"H"R"U"_\e1\e(B
 +;;;            \e$(7"7"G###C"U"7"G\e(B            \e$(7"H"R"U"_\e(B
  ;;;
  ;;;                             M
  ;;;             b s b s         h
      ;; If 'a follows a consonant, turn it into the subjoined form.
      ;; * Disabled by Tomabechi 2000/06/09 *
      ;; Because in Unicode, \e$(7"A\e(B may follow directly a consonant without
 -    ;; any intervening vowel, as in \e4\e$(7"9\e0"9\e1\e4""\e0"""Q\e1\e4"A\e0"A\e1!;\e(B=\e4\e$(7"9\e0"9\e1\e(B \e4\e$(7""\e0""\e1\e(B \e4\e$(7"A\e0"A\e1\e(B not \e4\e$(7"9\e0"9\e1\e(B \e4\e$(7""\e0""\e1\e(B \e$(7"Q\e(B \e4\e$(7"A\e0"A\e1\e(B
 +    ;; any intervening vowel, as in \e$(7"9"""Q"A!;\e(B=\e$(7"9\e(B \e$(7""\e(B \e$(7"A\e(B not \e$(7"9\e(B \e$(7""\e(B \e$(7"Q\e(B \e$(7"A\e(B
      ;;(if (and (= char ?\e$(7"A\e(B)
      ;;             (aref (char-category-set (car last)) ?0))
      ;;        (setq char ?\e$(7"R\e(B)) ;; modified for new font by Tomabechi 1999/12/10
  
       ;; Compose lower vowel sign vertically under.
       ((aref (char-category-set char) ?3)
 -      (if (eq char ?\e$(7"Q\e(B)                ;; `\e$(7"Q\e(B' should not visible when composed.
 +      (if (or (eq char ?\e$(7"Q\e(B) ;; `\e$(7"Q\e(B' and `\e$,1FP\e(B' should not visible when composed.
 +            (eq char #xF70))
          (setq rule nil)
        (setq rule stack-under)))
       ;; Transform ra-mgo (superscribed r) if followed by a subjoined
@@@ -316,17 -315,11 +316,17 @@@ are decomposed into normal Tibetan char
      new))
  
  ;;;###autoload
 -(defun tibetan-composition-function (from to pattern &optional string)
 +(defun tibetan-composition-function (pos &optional string)
 +  (setq pos (1- pos))
    (if string
 -      (tibetan-compose-string string)
 -    (tibetan-compose-region from to))
 -  (- to from))
 +      ;; Not yet implemented.
 +      nil
 +    (if (>= pos (point-min))
 +      (save-excursion
 +        (goto-char pos)
 +        (if (looking-at tibetan-composable-pattern)
 +            (prog1 (match-end 0)
 +              (tibetan-compose-region pos (match-end 0))))))))
  
  ;;;
  ;;; This variable is used to avoid repeated decomposition.
diff --combined lisp/language/tibetan.el
index 6256382d870a6901bbbb2156d70b2ed8e39ca305,94dc50bc15d5ee415b67892cd6aafa7cdaffb3da..2e020d24fdb6d49ddfe994131510f059be8d3d51
@@@ -1,15 -1,12 +1,15 @@@
  ;;; tibetan.el --- support for Tibetan language -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
 -;; Keywords: multilingual, Tibetan
 +;; Keywords: multilingual, Tibetan, i18n
  
  ;; This file is part of GNU Emacs.
  
  ;;;
  
  
 -(make-coding-system
 - 'tibetan-iso-8bit 2 ?Q
 - "8-bit encoding for ASCII (MSB=0) and TIBETAN (MSB=1)."
 - '(ascii tibetan nil nil
 -   nil nil)
 - '((safe-charsets ascii tibetan)
 -   (post-read-conversion . tibetan-post-read-conversion)
 -   (pre-write-conversion . tibetan-pre-write-conversion)))
 +(define-coding-system 'tibetan-iso-8bit
 +  "8-bit encoding for ASCII (MSB=0) and TIBETAN (MSB=1)."
 +  :coding-type 'iso-2022
 +  :mnemonic ?Q
 +  :designation [ascii tibetan nil nil]
 +  :charset-list '(ascii tibetan))
  
  (define-coding-system-alias 'tibetan 'tibetan-iso-8bit)
  
             (input-method . "tibetan-wylie")
             (features tibet-util)
             (documentation . t)
 -           (sample-text
 -            . (tibetan-compose-string
 -               (copy-sequence
 -"Tibetan (\e4\e$(7"7r'"]\e0"7"]\e1\e4"2\e0"2\e1!;\e4%P\e0"G#!"Q\e1\e4"2\e0"2\e1!;\e(B) \e$(7!4!5!5!>\e4"7\e0"7\e1\e4$P\e0"!#C"Q\e1!;\e4"Er'"S\e0"E"S\e1\e4"G\e0"G\e1!;\e4"7\e0"7\e1\e4"2r'"[\e0"2"[\e1!;\e4"Dr'"[\e0"D"[\e1\e4"#\e0"#\e1\e4"G\e0"G\e1!>\e4"Ir'"]r'"_\e0"I"]"_\e1!;\e4"9\e0"9"Q\e1!;\e4"/r'"S\e0"/"S\e1!;\e4"5\e0"5"Q\e1\e4#2x!#9r'"[\e0"2#9"[\e1!;\e4"Hx!"Rx!"Ur'"c\e0"H"A"U"c\e1!>\e(B")))))
 -
 +           (sample-text "Tibetan (\e$(7"7"]"2!;"G#!"Q"2!;\e(B) \e$(7!4!5!5!>"7"!#C"Q!;"E"S"G!;"7"2"[!;"D"["#"G!>"I"]"_!;"9"Q!;"/"S!;"5"Q"2#9"[!;"H"A"U"c!>\e(B")))
  
  ;; `\e$(7"A\e(B' is included in the pattern for subjoined consonants because we
  ;; treat it specially in tibetan-add-components.
  ;; \e$(7"A\e(B is removed from the class of subjoined. Tomabechi 2000/06/08
  ;; (for Unicode support)
  (defconst tibetan-composable-pattern
 -  "[\e$(7"!\e(B-\e$(7"J"K\e(B][\e$(7#!\e(B-\e$(7#J#K#L#M\e(B]*[\e$(7"Q"R"S\e(B-\e$(7"^"a"b"e\e(B]*[\e$(7"_"c"d"g\e(B-\e$(7"l!I!e!g\e(B]*"
 +  "[\e$(7"!\e(B-\e$(7"J"K\e(B][\e$(7#!\e(B-\e$(7#J#K#L#M\e(B]*[\e$,1FP\e$(7"Q"R"S\e(B-\e$(7"^"a"b"e\e(B]*[\e$(7"_"c"d"g\e(B-\e$(7"l!I!e!g\e(B]*"
    "Regexp matching a composable sequence of Tibetan characters.")
  
 -;; Register a function to compose Tibetan characters.
 -(aset composition-function-table (make-char 'tibetan)
 -      (list (cons tibetan-composable-pattern 'tibetan-composition-function)))
 -
  ;;;
  ;;; Definitions of conversion data.
  ;;;
@@@ -604,16 -611,6 +604,16 @@@ This also matches some punctuation char
  (defvar tibetan-decomposed nil)
  (defvar tibetan-decomposed-temp nil)
  
 +
 +;; For automatic composition.
 +(dolist (range '((?\e$(7#!\e(B . ?\e$(7#J\e(B) "\e$(7#K#L#M"Q"R\e(B" (?\e$(7"S\e(B . ?\e$(7"^\e(B) "\e$(7"a"b"e"_"c"d\e(B" (?\e$(7"g\e(B . ?\e$(7"l\e(B) "\e$(7!I!e!g\e(B"))
 +  (if (stringp range)
 +      (dotimes (i (length range))
 +      (aset composition-function-table (aref range i)
 +            'tibetan-composition-function))
 +    (set-char-table-range composition-function-table range
 +                        'tibetan-composition-function)))
 +
  (provide 'tibetan)
  
  ;;; arch-tag: 8d37c8d7-f95d-450f-9ec2-819e61fc79a7
index b655d3c19449894170cd943e51b8402ab84281b7,31e2e97d4349c3e241b85d29d80186cc20f14351..8df9bdd4dffa86940be121e1f44c44763c033430
@@@ -1,6 -1,6 +1,6 @@@
  ;;; tml-util.el --- support for composing tamil characters  -*-coding: iso-2022-7bit;-*-
  
- ;; Copyright (C) 2001, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;; Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Maintainer: KAWABATA, Taichi <kawabata@m17n.org>
  ;; Keywords: multilingual, Indian, Tamil
        (function (lambda (x y) (> (length x) (length y))))))))
  
  
 -;;;###autoload
 -(defun tamil-composition-function (from to pattern  &optional string)
 -  "Compose Tamil characters in REGION, or STRING if specified.
 -Assume that the REGION or STRING must fully match the composable 
 -PATTERN regexp."
 -  (if string (tamil-compose-syllable-string string)
 -    (tamil-compose-syllable-region from to))
 -  (- to from))
 -
 -;; Register a function to compose Tamil characters.
 -(mapc
 - (function (lambda (ucs)
 -   (aset composition-function-table (decode-char 'ucs ucs)
 -       (list (cons tamil-composable-pattern
 -                     'tamil-composition-function)))))
 - (nconc '(#x0b82 #x0b83) (tamil-range #x0b85 #x0bb9)))
 -
  ;; Notes on conversion steps.
  
  ;; 1. chars to glyphs
  
  (defvar tml-char-glyph
    '(;; various signs
 -    ;;("\e$,1<"\e(B" . "")
 +    ("\e$,1<"\e(B" . "\e$,4)b\e(B")       ;; not good
      ("\e$,1<#\e(B" . "\e$,4*G\e(B")
      ;; Independent Vowels
      ("\e$,1<%\e(B" . "\e$,4*<\e(B")
          (narrow-to-region from to)
          (goto-char (point-min))
          ;; char-glyph-conversion
 -        (while (re-search-forward tml-char-glyph-regexp nil t)
 -          (setq match-str (match-string 0))
 -          (setq glyph-str
 -                (concat glyph-str (gethash match-str tml-char-glyph-hash))))
 +        (while (not (eobp))
 +        (if (looking-at tml-char-glyph-regexp)
 +            (progn
 +              (setq match-str (match-string 0)
 +                    glyph-str
 +                    (concat glyph-str
 +                            (gethash match-str tml-char-glyph-hash)))
 +              (goto-char (match-end 0)))
 +          (setq glyph-str (concat glyph-str (string (following-char))))
 +          (forward-char 1)))
 +      (or glyph-str
 +          (aset glyph-str 0 (following-char)))
          ;; glyph reordering
          (when (string-match tml-glyph-reorder-key-glyphs glyph-str)
            (if (string-match (car tml-glyph-reordering-regexp-list)
                   glyph-str))))
          (compose-region from to glyph-str)))))
  
 +;;;###autoload
 +(defun tamil-composition-function (pos  &optional string)
 +  "Compose Tamil characters after the position POS.
 +If STRING is not nil, it is a string, and POS is an index to the string.
 +In this case, compose characters after POS of the string."
 +  (if string
 +      ;; Not yet implemented.
 +      nil
 +    (goto-char pos)
 +    (if (looking-at tamil-composable-pattern)
 +      (prog1 (match-end 0)
 +        (tamil-compose-syllable-region pos (match-end 0))))))
 +
  (provide 'tml-util)
  
  ;;; arch-tag: 4d1c9737-e7b1-44cf-a040-4f64c50e773e
index aae98bba251ff6e2a4645d45a98f3406c4ef44f1,2bd3419ecc8187b3d54db398034fca8ce8321010..ad4b75da04f6940412728d92dc7960a53d10dba8
@@@ -1,6 -1,6 +1,6 @@@
  ;;; utf-8-lang.el --- generic UTF-8 language environment -*- no-byte-compile: t -*-
  
- ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  
  ;; Author: Dave Love <fx@gnu.org>
  ;;; Code:
  
  (set-language-info-alist
 - "UTF-8" `((coding-system mule-utf-8)
 -         (coding-priority mule-utf-8)
 -         (setup-function
 -          . (lambda ()
 -              ;; Use Unicode font under Windows.  Jason Rumney fecit.
 -              (if (and (fboundp 'w32-add-charset-info)
 -                       (not (boundp 'w32-unicode-charset-defined)))
 -                  (w32-add-charset-info "iso10646-1" 'w32-charset-ansi t))))
 + "UTF-8" `((coding-system utf-8)
 +         (coding-priority utf-8)
 +;; Presumably not relevant now.
 +;;       (setup-function
 +;;        . (lambda ()
 +;;            ;; Use Unicode font under Windows.  Jason Rumney fecit.
 +;;            (if (and (fboundp 'w32-add-charset-info)
 +;;                     (not (boundp 'w32-unicode-charset-defined)))
 +;;                (w32-add-charset-info "iso10646-1" 'w32-charset-ansi t))))
  ;; Is this appropriate?
  ;;       (exit-function
  ;;        . (lambda ()
@@@ -47,8 -46,8 +47,8 @@@
  ;;                              w32-charset-info-alist)))))
           (input-method . "rfc1345")   ; maybe not the best choice
           (documentation . "\
 -This language environment is a generic one for a subset of the Unicode
 -character set encoded in UTF-8."))
 +This language environment is a generic one for the Unicode character set
 +encoded in UTF-8."))
   nil)
  
  (provide 'utf-8-lang)
index 17e6f576951e6d80da88ec4ecdf62708b764c829,2a1cc0fd67908d73fb12c4598b1a23e5fc8278e5..3ea53621c95c9a404d4082b2f825a120823bfadb
@@@ -1,14 -1,11 +1,14 @@@
  ;;; viet-util.el --- utilities for Vietnamese  -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
  ;; Keywords: mule, multilingual, Vietnamese
  
@@@ -48,7 -45,8 +48,7 @@@
  ;;;###autoload
  (defun viet-encode-viscii-char (char)
    "Return VISCII character code of CHAR if appropriate."
 -  (aref (char-table-extra-slot viet-viscii-nonascii-translation-table 0)
 -      char))
 +  (encode-char char 'viscii))
  
  ;; VIQR is a menmonic encoding specification for Vietnamese.
  ;; It represents diacritical marks by ASCII characters as follows:
index 22141b6d0e3cabc500efe5f0f6af05530de762cd,191637fb1a408000d1be957b8b76d39284f8c4c0..75f84ca55ecb79b4d49e64f9054832154b86630c
@@@ -1,16 -1,13 +1,16 @@@
  ;;; vietnamese.el --- support for Vietnamese -*- coding: iso-2022-7bit; -*-
  
- ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006
+ ;;   2005, 2006, 2007
  ;;   National Institute of Advanced Industrial Science and Technology (AIST)
  ;;   Registration Number H14PRO021
 +;; Copyright (C) 2003
 +;;   National Institute of Advanced Industrial Science and Technology (AIST)
 +;;   Registration Number H13PRO009
  
 -;; Keywords: multilingual, Vietnamese
 +;; Keywords: multilingual, Vietnamese, i18n
  
  ;; This file is part of GNU Emacs.
  
  
  ;;; Code:
  
 -(defvar viet-viscii-decode-table
 -  [;; VISCII is a full 8-bit code.
 -   0 1 ?\e,2F\e(B 3 4 ?\e,2G\e(B ?\e,2g\e(B 7 8 9 10 11 12 13 14 15
 -   16 17 18 19 ?\e,2V\e(B 21 22 23 24 ?\e,2[\e(B 26 27 28 29 ?\e,2\\e(B 31
 -   32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 -   48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
 -   64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
 -   80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 -   96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
 -   112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 -   ?\e,2U\e(B ?\e,2!\e(B ?\e,2"\e(B ?\e,2#\e(B ?\e,2$\e(B ?\e,2%\e(B ?\e,2&\e(B ?\e,2'\e(B ?\e,2(\e(B ?\e,2)\e(B ?\e,2*\e(B ?\e,2+\e(B ?\e,2,\e(B ?\e,2-\e(B ?\e,2.\e(B ?\e,2/\e(B
 -   ?\e,20\e(B ?\e,21\e(B ?\e,22\e(B ?\e,25\e(B ?\e,2~\e(B ?\e,2>\e(B ?\e,26\e(B ?\e,27\e(B ?\e,28\e(B ?\e,2v\e(B ?\e,2w\e(B ?\e,2o\e(B ?\e,2|\e(B ?\e,2{\e(B ?\e,2x\e(B ?\e,2O\e(B
 -   ?\e,2u\e(B ?\e,1!\e(B ?\e,1"\e(B ?\e,1#\e(B ?\e,1$\e(B ?\e,1%\e(B ?\e,1&\e(B ?\e,1'\e(B ?\e,1(\e(B ?\e,1)\e(B ?\e,1*\e(B ?\e,1+\e(B ?\e,1,\e(B ?\e,1-\e(B ?\e,1.\e(B ?\e,1/\e(B
 -   ?\e,10\e(B ?\e,11\e(B ?\e,12\e(B ?\e,2^\e(B ?\e,2=\e(B ?\e,15\e(B ?\e,16\e(B ?\e,17\e(B ?\e,18\e(B ?\e,2q\e(B ?\e,2Q\e(B ?\e,2W\e(B ?\e,2X\e(B ?\e,1=\e(B ?\e,1>\e(B ?\e,2_\e(B
 -   ?\e,2`\e(B ?\e,2a\e(B ?\e,2b\e(B ?\e,2c\e(B ?\e,2d\e(B ?\e,2e\e(B ?\e,1F\e(B ?\e,1G\e(B ?\e,2h\e(B ?\e,2i\e(B ?\e,2j\e(B ?\e,2k\e(B ?\e,2l\e(B ?\e,2m\e(B ?\e,2n\e(B ?\e,1O\e(B
 -   ?\e,2p\e(B ?\e,1Q\e(B ?\e,2r\e(B ?\e,2s\e(B ?\e,2t\e(B ?\e,1U\e(B ?\e,1V\e(B ?\e,1W\e(B ?\e,1X\e(B ?\e,2y\e(B ?\e,2z\e(B ?\e,1[\e(B ?\e,1\\e(B ?\e,2}\e(B ?\e,1^\e(B ?\e,1_\e(B
 -   ?\e,1`\e(B ?\e,1a\e(B ?\e,1b\e(B ?\e,1c\e(B ?\e,1d\e(B ?\e,1e\e(B ?\e,1f\e(B ?\e,1g\e(B ?\e,1h\e(B ?\e,1i\e(B ?\e,1j\e(B ?\e,1k\e(B ?\e,1l\e(B ?\e,1m\e(B ?\e,1n\e(B ?\e,1o\e(B
 -   ?\e,1p\e(B ?\e,1q\e(B ?\e,1r\e(B ?\e,1s\e(B ?\e,1t\e(B ?\e,1u\e(B ?\e,1v\e(B ?\e,1w\e(B ?\e,1x\e(B ?\e,1y\e(B ?\e,1z\e(B ?\e,1{\e(B ?\e,1|\e(B ?\e,1}\e(B ?\e,1~\e(B ?\e,2f\e(B ]
 -  "Vietnamese VISCII decoding table.")
 -
 -(let ((table (make-translation-table-from-vector viet-viscii-decode-table)))
 -  (define-translation-table 'viet-viscii-nonascii-translation-table table)
 -  (define-translation-table 'viet-viscii-encode-table
 -    (char-table-extra-slot table 0)))
 -
 -;;;
 -;;; VSCII is a pre-version of TCVN-5712 and deprecated
 -;;;
 -(defvar viet-vscii-decode-table
 -  [;; VSCII is a full 8-bit code.
 -   0 ?\e,2z\e(B ?\e,2x\e(B 3 ?\e,2W\e(B ?\e,2X\e(B ?\e,2f\e(B 7 8 9 10 11 12 13 14 15
 -   16 ?\e,2Q\e(B ?\e,2_\e(B ?\e,2O\e(B ?\e,2V\e(B ?\e,2[\e(B ?\e,2}\e(B ?\e,2\\e(B 24 25 26 27 28 29 30 31
 -   32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 -   48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
 -   64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
 -   80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 -   96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
 -   112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 -   ?\e,2`\e(B ?\e,2d\e(B ?\e,2c\e(B ?\e,2a\e(B ?\e,2U\e(B ?\e,2#\e(B ?\e,2'\e(B ?\e,2h\e(B ?\e,2k\e(B ?\e,2(\e(B ?\e,2i\e(B ?\e,2)\e(B ?\e,2.\e(B ?\e,2l\e(B ?\e,2o\e(B ?\e,2n\e(B
 -   ?\e,2m\e(B ?\e,28\e(B ?\e,2r\e(B ?\e,2v\e(B ?\e,2u\e(B ?\e,2s\e(B ?\e,2w\e(B ?\e,25\e(B ?\e,26\e(B ?\e,27\e(B ?\e,2^\e(B ?\e,2>\e(B ?\e,2~\e(B ?\e,2y\e(B ?\e,2|\e(B ?\e,2{\e(B
 -   160 ?\e,2e\e(B ?\e,2b\e(B ?\e,2j\e(B ?\e,2t\e(B ?\e,2=\e(B ?\e,2_\e(B ?\e,2p\e(B ?\e,1e\e(B ?\e,1b\e(B ?\e,1j\e(B ?\e,1t\e(B ?\e,1=\e(B ?\e,1y\e(B ?\e,1p\e(B ?\e,2"\e(B
 -   192 193 194 195 196 ?\e,1`\e(B ?\e,1d\e(B ?\e,1c\e(B ?\e,1a\e(B ?\e,1U\e(B ?\e,2F\e(B ?\e,1"\e(B ?\e,1F\e(B ?\e,1G\e(B ?\e,1!\e(B ?\e,2G\e(B
 -   ?\e,2!\e(B ?\e,2%\e(B ?\e,2&\e(B ?\e,2g\e(B ?\e,2%\e(B ?\e,2+\e(B ?\e,1#\e(B ?\e,1%\e(B ?\e,1&\e(B ?\e,1g\e(B ?\e,1$\e(B ?\e,1'\e(B ?\e,1h\e(B ?\e,2,\e(B ?\e,1k\e(B ?\e,1(\e(B
 -   ?\e,1i\e(B ?\e,1)\e(B ?\e,1+\e(B ?\e,1,\e(B ?\e,1-\e(B ?\e,1*\e(B ?\e,1.\e(B ?\e,1l\e(B ?\e,1o\e(B ?\e,2-\e(B ?\e,2*\e(B ?\e,20\e(B ?\e,1n\e(B ?\e,1m\e(B ?\e,18\e(B ?\e,1r\e(B
 -   ?\e,21\e(B ?\e,1v\e(B ?\e,1u\e(B ?\e,1s\e(B ?\e,1w\e(B ?\e,10\e(B ?\e,11\e(B ?\e,12\e(B ?\e,1/\e(B ?\e,15\e(B ?\e,16\e(B ?\e,17\e(B ?\e,1^\e(B ?\e,1>\e(B ?\e,1~\e(B ?\e,1y\e(B
 -   ?\e,22\e(B ?\e,1|\e(B ?\e,1{\e(B ?\e,1z\e(B ?\e,1x\e(B ?\e,1W\e(B ?\e,1X\e(B ?\e,1f\e(B ?\e,1Q\e(B ?\e,1q\e(B ?\e,1O\e(B ?\e,1V\e(B ?\e,1[\e(B ?\e,1}\e(B ?\e,1\\e(B ?\e,2/\e(B]
 -  "Vietnamese VSCII decoding table.")
 -
 -(let ((table (make-translation-table-from-vector viet-vscii-decode-table)))
 -  (define-translation-table 'viet-vscii-nonascii-translation-table table)
 -  (define-translation-table 'viet-vscii-encode-table
 -    (char-table-extra-slot table 0)))
 -
 -;; Does not support combining characters in the range [176, 180]
 -(defvar viet-tcvn-decode-table
 -  [;; TCVN is a full 8-bit code.
 -   0 ?\e,2z\e(B ?\e,2x\e(B 3 ?\e,2W\e(B ?\e,2X\e(B ?\e,2f\e(B 7 8 9 10 11 12 13 14 15
 -   16 ?\e,2Q\e(B ?\e,2q\e(B ?\e,2O\e(B ?\e,2V\e(B ?\e,2[\e(B ?\e,2}\e(B ?\e,2\\e(B 24 25 26 27 28 29 30 31
 -   32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 -   48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
 -   64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
 -   80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 -   96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
 -   112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 -   ?\e,2`\e(B ?\e,2d\e(B ?\e,2c\e(B ?\e,2a\e(B ?\e,2U\e(B ?\e,2#\e(B ?\e,2'\e(B ?\e,2h\e(B ?\e,2k\e(B ?\e,2(\e(B ?\e,2i\e(B ?\e,2)\e(B ?\e,2.\e(B ?\e,2l\e(B ?\e,2o\e(B ?\e,2n\e(B
 -   ?\e,2m\e(B ?\e,28\e(B ?\e,2r\e(B ?\e,2v\e(B ?\e,2u\e(B ?\e,2s\e(B ?\e,2w\e(B ?\e,25\e(B ?\e,26\e(B ?\e,27\e(B ?\e,2^\e(B ?\e,2>\e(B ?\e,2~\e(B ?\e,2y\e(B ?\e,2|\e(B ?\e,2{\e(B
 -   160 ?\e,2e\e(B ?\e,2b\e(B ?\e,2j\e(B ?\e,2t\e(B ?\e,2=\e(B ?\e,2_\e(B ?\e,2p\e(B ?\e,1e\e(B ?\e,1b\e(B ?\e,1j\e(B ?\e,1t\e(B ?\e,1=\e(B ?\e,1_\e(B ?\e,1p\e(B ?\e,2"\e(B
 -   176 177 178 179 180 ?\e,1`\e(B ?\e,1d\e(B ?\e,1c\e(B ?\e,1a\e(B ?\e,1U\e(B ?\e,2F\e(B ?\e,1"\e(B ?\e,1F\e(B ?\e,1G\e(B ?\e,1!\e(B ?\e,2G\e(B
 -   ?\e,2!\e(B ?\e,2%\e(B ?\e,2&\e(B ?\e,2g\e(B ?\e,2$\e(B ?\e,2+\e(B ?\e,1#\e(B ?\e,1%\e(B ?\e,1&\e(B ?\e,1g\e(B ?\e,1$\e(B ?\e,1'\e(B ?\e,1h\e(B ?\e,2,\e(B ?\e,1k\e(B ?\e,1(\e(B
 -   ?\e,1i\e(B ?\e,1)\e(B ?\e,1+\e(B ?\e,1,\e(B ?\e,1-\e(B ?\e,1*\e(B ?\e,1.\e(B ?\e,1l\e(B ?\e,1o\e(B ?\e,2-\e(B ?\e,2*\e(B ?\e,20\e(B ?\e,1n\e(B ?\e,1m\e(B ?\e,18\e(B ?\e,1r\e(B
 -   ?\e,21\e(B ?\e,1v\e(B ?\e,1u\e(B ?\e,1s\e(B ?\e,1w\e(B ?\e,10\e(B ?\e,11\e(B ?\e,12\e(B ?\e,1/\e(B ?\e,15\e(B ?\e,16\e(B ?\e,17\e(B ?\e,1^\e(B ?\e,1>\e(B ?\e,1~\e(B ?\e,1y\e(B
 -   ?\e,22\e(B ?\e,1|\e(B ?\e,1{\e(B ?\e,1z\e(B ?\e,1x\e(B ?\e,1W\e(B ?\e,1X\e(B ?\e,1f\e(B ?\e,1Q\e(B ?\e,1q\e(B ?\e,1O\e(B ?\e,1V\e(B ?\e,1[\e(B ?\e,1}\e(B ?\e,1\\e(B ?\e,2/\e(B]
 -  "Vietnamese TCVN-5712 decoding table.")
 -
 -(let ((table (make-translation-table-from-vector viet-tcvn-decode-table)))
 -  (define-translation-table 'viet-tcvn-nonascii-translation-table table)
 -  (define-translation-table 'viet-tcvn-encode-table
 -    (char-table-extra-slot table 0)))
 -
 -;; (defvar viet-vps-decode-table
 -;;   [;; VPS is a full 8-bit code.
 -;;    0 1 ?\e,2U\e(B ?\e,2'\e(B ?\e,2#\e(B ?\e,2)\e(B ?\e,2.\e(B 7 8 9 10 11 12 13 14 15
 -;;    ?\e,28\e(B ?\e,2w\e(B ?\e,25\e(B ?\e,2~\e(B ?\e,2x\e(B ?\e,2q\e(B 22 23 24 ?\e,2\\e(B 26 27 ?\e,2g\e(B ?\e,2f\e(B 30 31
 -;;    32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 -;;    48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
 -;;    64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
 -;;    80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 -;;    96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
 -;;    112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 -;;    ?\e,2`\e(B ?\e,2d\e(B ?\e,2c\e(B ?\e,2$\e(B ?\e,2%\e(B ?\e,2&\e(B ?\e,1w\e(B ?\e,12\e(B ?\e,2e\e(B ?\e,1*\e(B ?\e,1+\e(B ?\e,1,\e(B ?\e,1.\e(B ?\e,2!\e(B ?\e,2"\e(B ?\e,2F\e(B
 -;;    ?\e,2*\e(B 145 146 ?\e,2+\e(B ?\e,2,\e(B ?\e,2-\e(B ?\e,2/\e(B ?\e,20\e(B ?\e,21\e(B ?\e,22\e(B ?\e,1}\e(B ?\e,1V\e(B ?\e,1\\e(B ?\e,2>\e(B ?\e,26\e(B ?\e,27\e(B
 -;;    160 ?\e,1!\e(B ?\e,1"\e(B ?\e,1F\e(B ?\e,1G\e(B ?\e,1#\e(B ?\e,2^\e(B ?\e,1>\e(B ?\e,2y\e(B ?\e,16\e(B ?\e,17\e(B ?\e,1^\e(B ?\e,2{\e(B ?\e,2Q\e(B ?\e,1~\e(B ?\e,2W\e(B
 -;;    ?\e,11\e(B ?\e,2X\e(B ?\e,2O\e(B ?\e,2[\e(B ?\e,2m\e(B ?\e,2l\e(B ?\e,15\e(B ?\e,2o\e(B ?\e,2n\e(B ?\e,2s\e(B ?\e,1X\e(B ?\e,1f\e(B ?\e,2r\e(B ?\e,2v\e(B ?\e,2u\e(B ?\e,1q\e(B
 -;;    ?\e,1%\e(B ?\e,2a\e(B ?\e,2b\e(B ?\e,1$\e(B ?\e,1&\e(B ?\e,1g\e(B ?\e,1'\e(B ?\e,1p\e(B ?\e,1k\e(B ?\e,2i\e(B ?\e,2j\e(B ?\e,1)\e(B ?\e,1o\e(B ?\e,1-\e(B ?\e,18\e(B ?\e,1[\e(B
 -;;    ?\e,2_\e(B ?\e,2|\e(B ?\e,10\e(B ?\e,1/\e(B ?\e,2t\e(B ?\e,1v\e(B ?\e,1=\e(B ?\e,2h\e(B ?\e,1W\e(B ?\e,1Q\e(B ?\e,2z\e(B ?\e,1{\e(B ?\e,1_\e(B ?\e,2}\e(B ?\e,2k\e(B 223
 -;;    ?\e,1`\e(B ?\e,1a\e(B ?\e,1b\e(B ?\e,1c\e(B ?\e,1d\e(B ?\e,1U\e(B ?\e,1e\e(B 231 ?\e,1h\e(B ?\e,1i\e(B ?\e,1j\e(B ?\e,1(\e(B ?\e,1l\e(B ?\e,1m\e(B 238 ?\e,1n\e(B
 -;;    ?\e,2G\e(B ?\e,2p\e(B ?\e,1r\e(B ?\e,1s\e(B ?\e,1t\e(B ?\e,1u\e(B 246 ?\e,2=\e(B ?\e,1x\e(B ?\e,1y\e(B ?\e,1z\e(B ?\e,1|\e(B 252 ?\e,2V\e(B ?\e,2(\e(B ?\e,1O\e(B]
 -;;   "Vietnamese VPS decoding table.")
 -;;
 -;; (let ((table (make-translation-table-from-vector viet-vps-decode-table)))
 -;;   (define-translation-table 'viet-vps-nonascii-translation-table table)
 -;;   (define-translation-table 'viet-vps-encode-table
 -;;     (char-table-extra-slot table 0)))
 -
 -(define-ccl-program ccl-decode-viscii
 -  `(3
 -    ((loop
 -      (r0 = 0)
 -      (read r1)
 -      (translate-character viet-viscii-nonascii-translation-table r0 r1)
 -      (write-multibyte-character r0 r1)
 -      (repeat))))
 -  "CCL program to decode VISCII 1.1")
 -
 -(define-ccl-program ccl-encode-viscii
 -  `(1
 -    ((loop
 -      (read-multibyte-character r0 r1)
 -      (translate-character viet-viscii-encode-table r0 r1)
 -      (write-repeat r1))))
 -  "CCL program to encode VISCII 1.1")
 -
 -(define-ccl-program ccl-encode-viscii-font
 -  `(0
 -    ;; In:  R0:vietnamese-viscii-lower/vietnamese-viscii-upper
 -    ;;      R1:position code
 -    ;; Out: R1:font code point
 -    (translate-character viet-viscii-encode-table r0 r1))
 -  "CCL program to encode Vietnamese chars to VISCII 1.1 font")
 -
 -(define-ccl-program ccl-decode-vscii
 -  `(3
 -    ((loop
 -      (r0 = 0)
 -      (read r1)
 -      (translate-character viet-vscii-nonascii-translation-table r0 r1)
 -      (write-multibyte-character r0 r1)
 -      (repeat))))
 -  "CCL program to decode VSCII-1.")
 -
 -(define-ccl-program ccl-encode-vscii
 -  `(1
 -    ((loop
 -      (read-multibyte-character r0 r1)
 -      (translate-character viet-vscii-encode-table r0 r1)
 -      (write-repeat r1))))
 -  "CCL program to encode VSCII-1.")
 -
 -(define-ccl-program ccl-encode-vscii-font
 -  `(0
 -    ;; In:  R0:vietnamese-viscii-lower/vietnamese-viscii-upper
 -    ;;      R1:position code
 -    ;; Out: R1:font code point
 -    (translate-character viet-vscii-encode-table r0 r1))
 -  "CCL program to encode Vietnamese chars to VSCII-1 font.")
 -
 -(define-ccl-program ccl-decode-tcvn
 -  `(3
 -    ((loop
 -      (r0 = 0)
 -      (read r1)
 -      (translate-character viet-tcvn-nonascii-translation-table r0 r1)
 -      (write-multibyte-character r0 r1)
 -      (repeat))))
 -  "CCL program to decode TCVN-5712.")
 -
 -(define-ccl-program ccl-encode-tcvn
 -  `(1
 -    ((loop
 -      (read-multibyte-character r0 r1)
 -      (translate-character viet-tcvn-encode-table r0 r1)
 -      (write-repeat r1))))
 -  "CCL program to encode TCVN-5712.")
 -
 -(define-ccl-program ccl-encode-tcvn-font
 -  `(0
 -    ;; In:  R0:vietnamese-viscii-lower/vietnamese-viscii-upper
 -    ;;      R1:position code
 -    ;; Out: R1:font code point
 -    (translate-character viet-tcvn-encode-table r0 r1))
 -  "CCL program to encode Vietnamese chars to TCVN-5712 font.")
 -
 -;; (define-ccl-program ccl-decode-vps
 -;;   `(3
 -;;     ((loop
 -;;     (r0 = 0)
 -;;     (read r1)
 -;;     (translate-character viet-vps-nonascii-translation-table r0 r1)
 -;;     (write-multibyte-character r0 r1)
 -;;     (repeat))))
 -;;   "CCL program to decode VPS.")
 -;;
 -;; (define-ccl-program ccl-encode-vps
 -;;   `(1
 -;;     ((loop
 -;;     (read-multibyte-character r0 r1)
 -;;     (translate-character viet-vps-encode-table r0 r1)
 -;;     (write-repeat r1))))
 -;;   "CCL program to encode VPS.")
 -;;
 -;; (define-ccl-program ccl-encode-vps-font
 -;;   `(0
 -;;     ;; In:  R0:vietnamese-viscii-lower/vietnamese-viscii-upper
 -;;     ;;      R1:position code
 -;;     ;; Out: R1:font code point
 -;;     (translate-character viet-vps-encode-table r0 r1))
 -;;   "CCL program to encode Vietnamese chars to VPS font.")
 -
 -(make-coding-system
 - 'vietnamese-viscii 4 ?V
 - "8-bit encoding for Vietnamese VISCII 1.1 (MIME:VISCII)"
 - '(ccl-decode-viscii . ccl-encode-viscii)
 - '((safe-charsets ascii vietnamese-viscii-lower vietnamese-viscii-upper)
 -   (mime-charset . viscii)
 -   (valid-codes (0 . 255))))
 +(define-coding-system 'vietnamese-viscii
 +  "8-bit encoding for Vietnamese VISCII 1.1 (MIME:VISCII)."
 +  :coding-type 'charset
 +  :mnemonic ?V
 +  :charset-list '(viscii)
 +  :mime-charset 'viscii
 +  :suitable-for-file-name t)
  
  (define-coding-system-alias 'viscii 'vietnamese-viscii)
  
 -(make-coding-system
 - 'vietnamese-vscii 4 ?v
 - "8-bit encoding for Vietnamese VSCII-1"
 - '(ccl-decode-vscii . ccl-encode-vscii)
 - '((safe-charsets ascii vietnamese-viscii-lower vietnamese-viscii-upper)
 -   (valid-codes (0 . 255))))
 +(define-coding-system 'vietnamese-vscii
 +  "8-bit encoding for Vietnamese VSCII-1."
 +  :coding-type 'charset
 +  :mnemonic ?v
 +  :charset-list '(vscii)
 +  :suitable-for-file-name t)
  
  (define-coding-system-alias 'vscii 'vietnamese-vscii)
  
 -(make-coding-system
 - 'vietnamese-tcvn 4 ?t
 - "8-bit encoding for Vietnamese TCVN-5712"
 - '(ccl-decode-tcvn . ccl-encode-tcvn)
 - '((safe-charsets ascii vietnamese-viscii-lower vietnamese-viscii-upper)
 -   (valid-codes (0 . 255))))
 -
 -(define-coding-system-alias 'tcvn 'vietnamese-tcvn)
 -(define-coding-system-alias 'tcvn-5712 'vietnamese-tcvn)
 -
  ;; (make-coding-system
  ;;  'vietnamese-vps 4 ?p
  ;;  "8-bit encoding for Vietnamese VPS"
  ;;
  ;; (define-coding-system-alias 'vps 'vietnamese-vps)
  
 -(make-coding-system
 - 'vietnamese-viqr 0 ?q
 - "Vietnamese latin transcription (VIQR)"
 - nil
 - '((safe-charsets ascii vietnamese-viscii-lower vietnamese-viscii-upper)
 -   (post-read-conversion . viqr-post-read-conversion)
 -   (pre-write-conversion . viqr-pre-write-conversion)
 -   (charset-origin-alist
 -    (vietnamese-viscii-lower "VISCII" viet-encode-viscii-char)
 -    (vietnamese-viscii-upper "VISCII" viet-encode-viscii-char))))
 -
 +(define-coding-system 'vietnamese-viqr
 +  "Vietnamese latin transcription (VIQR)."
 +  :coding-type 'utf-8
 +  :mnemonic ?q
 +  :charset-list '(ascii viscii)
 +  :post-read-conversion 'viqr-post-read-conversion
 +  :pre-write-conversion 'viqr-pre-write-conversion)
  
  (define-coding-system-alias 'viqr 'vietnamese-viqr)
  
 -(setq font-ccl-encoder-alist
 -      (cons '("viscii" . ccl-encode-viscii-font) font-ccl-encoder-alist))
 -
 -(setq font-ccl-encoder-alist
 -      (cons '("vscii" . ccl-encode-vscii-font) font-ccl-encoder-alist))
 -
 -(setq font-ccl-encoder-alist
 -      (cons '("tcvn" . ccl-encode-tcvn-font) font-ccl-encoder-alist))
 -
  (set-language-info-alist
 - "Vietnamese" `((charset vietnamese-viscii-lower vietnamese-viscii-upper)
 -              (nonascii-translation
 -               . ,(get 'viet-viscii-nonascii-translation-table
 -                       'translation-table))
 -              (coding-system vietnamese-viscii vietnamese-vscii vietnamese-tcvn
 -                             vietnamese-viqr)
 + "Vietnamese" `((charset viscii)
 +              (coding-system vietnamese-viscii vietnamese-vscii
 +                              vietnamese-tcvn vietnamese-viqr windows-1258)
 +              (nonascii-translation . viscii)
                (coding-priority vietnamese-viscii)
                (input-method . "vietnamese-viqr")
                (unibyte-display . vietnamese-viscii)
                (sample-text . "Vietnamese (Ti\e,1*\e(Bng Vi\e,1.\e(Bt)     Ch\e,1`\e(Bo b\e,1U\e(Bn")
                (documentation . "\
  For Vietnamese, Emacs uses special charsets internally.
 -They can be decoded from and encoded to VISCII, VSCII, TCVN-5712, and
 -VIQR.  VSCII is deprecated in favour of TCVN-5712.  Current setting
 -puts higher priority to the coding system VISCII than TCVN-5712.  If
 -you prefer TCVN-5712, please do: (prefer-coding-system 'vietnamese-tcvn).
 -There are two Vietnamese input methods: VIQR and Telex, VIQR is the
 -default setting.")
 -              ))
 +They can be decoded from and encoded to VISCII, VSCII, TCVN-5712, VIQR
 +and windows-1258.  VSCII is deprecated in favour of TCVN-5712.  The
 +Current setting gives higher priority to the coding system VISCII than
 +TCVN-5712.  If you prefer TCVN-5712, please do: (prefer-coding-system
 +'vietnamese-tcvn).  There are two Vietnamese input methods: VIQR and
 +Telex, VIQR is the default setting.")))
 +
 +(define-coding-system 'windows-1258
 +  "windows-1258 encoding for Vietnamese (MIME: WINDOWS-1258)"
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(windows-1258)
 +  :mime-charset 'windows-1258)
 +(define-coding-system-alias 'cp1258 'windows-1258)
 +
 +(define-coding-system 'vietnamese-tcvn
 +  "8-bit encoding for Vietnamese TCVN-5712"
 +  :coding-type 'charset
 +  :mnemonic ?t
 +  :charset-list '(tcvn-5712)
 +  :suitable-for-file-name t)
 +(define-coding-system-alias 'tcvn 'vietnamese-tcvn)
 +(define-coding-system-alias 'tcvn-5712 'vietnamese-tcvn)
  
  (provide 'vietnamese)
  
diff --combined lisp/ldefs-boot.el
index 277e647d16fddbec5def8a4c0ee6bbc497430254,30d43d80abf1b3e3e29399553f2335d53dbaf761..16aa6c42d7d809ceffea2f99924f74ea3cb6a16a
@@@ -4,7 -4,7 +4,7 @@@
  \f
  ;;;### (autoloads (5x5-crack 5x5-crack-xor-mutate 5x5-crack-mutating-best
  ;;;;;;  5x5-crack-mutating-current 5x5-crack-randomly 5x5) "5x5"
- ;;;;;;  "play/5x5.el" (17786 56015))
+ ;;;;;;  "play/5x5.el" (17843 45625))
  ;;; Generated autoloads from play/5x5.el
  
  (autoload (quote 5x5) "5x5" "\
@@@ -63,14 -63,14 +63,14 @@@ should return a grid vector array that 
  
  ;;;***
  \f
- ;;;### (autoloads nil "abbrev" "abbrev.el" (17781 39501))
+ ;;;### (autoloads nil "abbrev" "abbrev.el" (17843 45609))
  ;;; Generated autoloads from abbrev.el
  (put 'abbrev-mode 'safe-local-variable 'booleanp)
  
  ;;;***
  \f
  ;;;### (autoloads (list-one-abbrev-table) "abbrevlist" "abbrevlist.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from abbrevlist.el
  
  (autoload (quote list-one-abbrev-table) "abbrevlist" "\
@@@ -81,7 -81,7 +81,7 @@@ Display alphabetical listing of ABBREV-
  ;;;***
  \f
  ;;;### (autoloads (ada-mode ada-add-extensions) "ada-mode" "progmodes/ada-mode.el"
- ;;;;;;  (17770 2412))
+ ;;;;;;  (17843 45626))
  ;;; Generated autoloads from progmodes/ada-mode.el
  
  (autoload (quote ada-add-extensions) "ada-mode" "\
@@@ -142,7 -142,7 +142,7 @@@ If you use ada-xref.el
  ;;;***
  \f
  ;;;### (autoloads (ada-header) "ada-stmt" "progmodes/ada-stmt.el"
- ;;;;;;  (17751 22876))
+ ;;;;;;  (17843 45626))
  ;;; Generated autoloads from progmodes/ada-stmt.el
  
  (autoload (quote ada-header) "ada-stmt" "\
@@@ -153,7 -153,7 +153,7 @@@ Insert a descriptive header at the top 
  ;;;***
  \f
  ;;;### (autoloads (ada-find-file) "ada-xref" "progmodes/ada-xref.el"
- ;;;;;;  (17780 18172))
+ ;;;;;;  (17843 45626))
  ;;; Generated autoloads from progmodes/ada-xref.el
  
  (autoload (quote ada-find-file) "ada-xref" "\
@@@ -168,7 -168,7 +168,7 @@@ Completion is available
  ;;;;;;  change-log-mode add-change-log-entry-other-window add-change-log-entry
  ;;;;;;  find-change-log prompt-for-change-log-name add-log-mailing-address
  ;;;;;;  add-log-full-name add-log-current-defun-function) "add-log"
- ;;;;;;  "add-log.el" (17781 39501))
+ ;;;;;;  "add-log.el" (17844 62922))
  ;;; Generated autoloads from add-log.el
  
  (defvar add-log-current-defun-function nil "\
@@@ -306,7 -306,7 +306,7 @@@ Fix any old-style date entries in the c
  \f
  ;;;### (autoloads (defadvice ad-activate ad-add-advice ad-disable-advice
  ;;;;;;  ad-enable-advice ad-default-compilation-action ad-redefinition-action)
- ;;;;;;  "advice" "emacs-lisp/advice.el" (17785 34467))
+ ;;;;;;  "advice" "emacs-lisp/advice.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/advice.el
  
  (defvar ad-redefinition-action (quote warn) "\
@@@ -434,7 -434,7 +434,7 @@@ See Info node `(elisp)Advising Function
  \f
  ;;;### (autoloads (align-newline-and-indent align-unhighlight-rule
  ;;;;;;  align-highlight-rule align-current align-entire align-regexp
- ;;;;;;  align) "align" "align.el" (17794 48602))
+ ;;;;;;  align) "align" "align.el" (17843 45609))
  ;;; Generated autoloads from align.el
  
  (autoload (quote align) "align" "\
@@@ -524,7 -524,7 +524,7 @@@ A replacement function for `newline-and
  ;;;***
  \f
  ;;;### (autoloads (outlineify-sticky allout-mode) "allout" "allout.el"
- ;;;;;;  (17780 18171))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from allout.el
  
  (put (quote allout-show-bodies) (quote safe-local-variable) (if (fboundp (quote booleanp)) (quote booleanp) (quote (lambda (x) (member x (quote (t nil)))))))
@@@ -827,7 -827,7 +827,7 @@@ setup for auto-startup
  ;;;***
  \f
  ;;;### (autoloads (ange-ftp-hook-function ange-ftp-reread-dir) "ange-ftp"
- ;;;;;;  "net/ange-ftp.el" (17385 8494))
+ ;;;;;;  "net/ange-ftp.el" (17843 45624))
  ;;; Generated autoloads from net/ange-ftp.el
  
  (defalias (quote ange-ftp-re-read-dir) (quote ange-ftp-reread-dir))
@@@ -849,7 -849,7 +849,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (animate-birthday-present animate-sequence animate-string)
- ;;;;;;  "animate" "play/animate.el" (17385 8495))
+ ;;;;;;  "animate" "play/animate.el" (17843 45625))
  ;;; Generated autoloads from play/animate.el
  
  (autoload (quote animate-string) "animate" "\
@@@ -877,7 -877,7 +877,7 @@@ You can specify the one's name by NAME
  ;;;***
  \f
  ;;;### (autoloads (ansi-color-process-output ansi-color-for-comint-mode-on)
- ;;;;;;  "ansi-color" "ansi-color.el" (17385 8481))
+ ;;;;;;  "ansi-color" "ansi-color.el" (17843 45609))
  ;;; Generated autoloads from ansi-color.el
  
  (autoload (quote ansi-color-for-comint-mode-on) "ansi-color" "\
@@@ -903,7 -903,7 +903,7 @@@ This is a good function to put in `comi
  ;;;***
  \f
  ;;;### (autoloads (antlr-set-tabs antlr-mode antlr-show-makefile-rules)
- ;;;;;;  "antlr-mode" "progmodes/antlr-mode.el" (17485 5461))
+ ;;;;;;  "antlr-mode" "progmodes/antlr-mode.el" (17838 18033))
  ;;; Generated autoloads from progmodes/antlr-mode.el
  
  (autoload (quote antlr-show-makefile-rules) "antlr-mode" "\
@@@ -942,7 -942,7 +942,7 @@@ Used in `antlr-mode'.  Also a useful fu
  ;;;### (autoloads (appt-activate appt-make-list appt-delete appt-add
  ;;;;;;  appt-display-diary appt-display-duration appt-display-mode-line
  ;;;;;;  appt-msg-window appt-visible appt-audible appt-message-warning-time
- ;;;;;;  appt-issue-message) "appt" "calendar/appt.el" (17686 46252))
+ ;;;;;;  appt-issue-message) "appt" "calendar/appt.el" (17843 45615))
  ;;; Generated autoloads from calendar/appt.el
  
  (defvar appt-issue-message t "\
@@@ -1030,7 -1030,7 +1030,7 @@@ ARG is positive, otherwise off
  \f
  ;;;### (autoloads (apropos-documentation apropos-value apropos apropos-documentation-property
  ;;;;;;  apropos-command apropos-variable apropos-read-pattern) "apropos"
- ;;;;;;  "apropos.el" (17743 18143))
+ ;;;;;;  "apropos.el" (17843 45609))
  ;;; Generated autoloads from apropos.el
  
  (autoload (quote apropos-read-pattern) "apropos" "\
@@@ -1126,8 -1126,8 +1126,8 @@@ Returns list of symbols and documentati
  
  ;;;***
  \f
- ;;;### (autoloads (archive-mode) "arc-mode" "arc-mode.el" (17781
- ;;;;;;  39501))
+ ;;;### (autoloads (archive-mode) "arc-mode" "arc-mode.el" (17843
+ ;;;;;;  45609))
  ;;; Generated autoloads from arc-mode.el
  
  (autoload (quote archive-mode) "arc-mode" "\
@@@ -1147,7 -1147,7 +1147,7 @@@ archive
  
  ;;;***
  \f
- ;;;### (autoloads (array-mode) "array" "array.el" (17781 39501))
+ ;;;### (autoloads (array-mode) "array" "array.el" (17843 45609))
  ;;; Generated autoloads from array.el
  
  (autoload (quote array-mode) "array" "\
@@@ -1218,8 -1218,8 +1218,8 @@@ Entering array mode calls the function 
  
  ;;;***
  \f
- ;;;### (autoloads (artist-mode) "artist" "textmodes/artist.el" (17520
- ;;;;;;  49737))
+ ;;;### (autoloads (artist-mode) "artist" "textmodes/artist.el" (17843
+ ;;;;;;  45629))
  ;;; Generated autoloads from textmodes/artist.el
  
  (autoload (quote artist-mode) "artist" "\
@@@ -1424,8 -1424,8 +1424,8 @@@ Keymap summar
  
  ;;;***
  \f
- ;;;### (autoloads (asm-mode) "asm-mode" "progmodes/asm-mode.el" (17495
- ;;;;;;  43955))
+ ;;;### (autoloads (asm-mode) "asm-mode" "progmodes/asm-mode.el" (17843
+ ;;;;;;  45626))
  ;;; Generated autoloads from progmodes/asm-mode.el
  
  (autoload (quote asm-mode) "asm-mode" "\
@@@ -1469,7 -1469,7 +1469,7 @@@ This command is obsolete
  ;;;***
  \f
  ;;;### (autoloads (autoarg-kp-mode autoarg-mode) "autoarg" "autoarg.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from autoarg.el
  
  (defvar autoarg-mode nil "\
@@@ -1523,7 -1523,7 +1523,7 @@@ etc. to supply digit arguments
  ;;;***
  \f
  ;;;### (autoloads (autoconf-mode) "autoconf" "progmodes/autoconf.el"
- ;;;;;;  (17788 21816))
+ ;;;;;;  (17843 45626))
  ;;; Generated autoloads from progmodes/autoconf.el
  
  (autoload (quote autoconf-mode) "autoconf" "\
@@@ -1534,7 -1534,7 +1534,7 @@@ Major mode for editing Autoconf configu
  ;;;***
  \f
  ;;;### (autoloads (auto-insert-mode define-auto-insert auto-insert)
- ;;;;;;  "autoinsert" "autoinsert.el" (17781 39501))
+ ;;;;;;  "autoinsert" "autoinsert.el" (17843 45609))
  ;;; Generated autoloads from autoinsert.el
  
  (autoload (quote auto-insert) "autoinsert" "\
@@@ -1573,7 -1573,7 +1573,7 @@@ insert a template for the file dependin
  \f
  ;;;### (autoloads (batch-update-autoloads update-directory-autoloads
  ;;;;;;  update-file-autoloads) "autoload" "emacs-lisp/autoload.el"
- ;;;;;;  (17601 9092))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/autoload.el
  
  (autoload (quote update-file-autoloads) "autoload" "\
@@@ -1608,7 -1608,7 +1608,7 @@@ Calls `update-directory-autoloads' on t
  \f
  ;;;### (autoloads (global-auto-revert-mode turn-on-auto-revert-tail-mode
  ;;;;;;  auto-revert-tail-mode turn-on-auto-revert-mode auto-revert-mode)
- ;;;;;;  "autorevert" "autorevert.el" (17515 24179))
+ ;;;;;;  "autorevert" "autorevert.el" (17843 45609))
  ;;; Generated autoloads from autorevert.el
  
  (autoload (quote auto-revert-mode) "autorevert" "\
@@@ -1660,11 -1660,10 +1660,10 @@@ This function is designed to be added t
  Non-nil if Global-Auto-Revert mode is enabled.
  See the command `global-auto-revert-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `global-auto-revert-mode'.")
- (custom-autoload (quote global-auto-revert-mode) "autorevert")
+ either customize it (see the info node `Easy Customization')
+ or call the function `global-auto-revert-mode'.")
  
- (put (quote global-auto-revert-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote global-auto-revert-mode) "autorevert" nil)
  
  (autoload (quote global-auto-revert-mode) "autorevert" "\
  Revert any buffer when file on disk changes.
@@@ -1678,7 -1677,7 +1677,7 @@@ Use `auto-revert-mode' to revert a part
  ;;;***
  \f
  ;;;### (autoloads (mouse-avoidance-mode mouse-avoidance-mode) "avoid"
- ;;;;;;  "avoid.el" (17781 39501))
+ ;;;;;;  "avoid.el" (17843 45609))
  ;;; Generated autoloads from avoid.el
  
  (defvar mouse-avoidance-mode nil "\
@@@ -1719,7 -1718,7 +1718,7 @@@ definition of \"random distance\".
  ;;;***
  \f
  ;;;### (autoloads (backquote) "backquote" "emacs-lisp/backquote.el"
- ;;;;;;  (17385 8489))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/backquote.el
  
  (autoload (quote backquote) "backquote" "\
@@@ -1744,7 -1743,7 +1743,7 @@@ Vectors work just like lists.  Nested b
  ;;;***
  \f
  ;;;### (autoloads (display-battery-mode battery) "battery" "battery.el"
- ;;;;;;  (17742 7456))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from battery.el
   (put 'battery-mode-line-string 'risky-local-variable t)
  
@@@ -1776,7 -1775,7 +1775,7 @@@ seconds
  ;;;***
  \f
  ;;;### (autoloads (benchmark benchmark-run-compiled benchmark-run)
- ;;;;;;  "benchmark" "emacs-lisp/benchmark.el" (17385 8489))
+ ;;;;;;  "benchmark" "emacs-lisp/benchmark.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/benchmark.el
  
  (autoload (quote benchmark-run) "benchmark" "\
@@@ -1808,8 -1807,8 +1807,8 @@@ non-interactive use see also `benchmark
  
  ;;;***
  \f
- ;;;### (autoloads (bibtex-mode) "bibtex" "textmodes/bibtex.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (bibtex-mode) "bibtex" "textmodes/bibtex.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from textmodes/bibtex.el
  
  (autoload (quote bibtex-mode) "bibtex" "\
@@@ -1871,7 -1870,7 +1870,7 @@@ if that value is non-nil
  \f
  ;;;### (autoloads (binhex-decode-region binhex-decode-region-external
  ;;;;;;  binhex-decode-region-internal) "binhex" "gnus/binhex.el"
- ;;;;;;  (17385 8492))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from gnus/binhex.el
  
  (defconst binhex-begin-line "^:...............................................................$")
@@@ -1894,8 -1893,8 +1893,8 @@@ Binhex decode region between START and 
  
  ;;;***
  \f
- ;;;### (autoloads (blackbox) "blackbox" "play/blackbox.el" (17385
- ;;;;;;  8495))
+ ;;;### (autoloads (blackbox) "blackbox" "play/blackbox.el" (17843
+ ;;;;;;  45625))
  ;;; Generated autoloads from play/blackbox.el
  
  (autoload (quote blackbox) "blackbox" "\
@@@ -2017,7 -2016,7 +2016,7 @@@ a reflection
  ;;;### (autoloads (bookmark-bmenu-list bookmark-load bookmark-save
  ;;;;;;  bookmark-write bookmark-delete bookmark-insert bookmark-rename
  ;;;;;;  bookmark-insert-location bookmark-relocate bookmark-jump
- ;;;;;;  bookmark-set) "bookmark" "bookmark.el" (17385 8482))
+ ;;;;;;  bookmark-set) "bookmark" "bookmark.el" (17843 45609))
  ;;; Generated autoloads from bookmark.el
   (define-key ctl-x-map "rb" 'bookmark-jump)
   (define-key ctl-x-map "rm" 'bookmark-set)
@@@ -2207,7 -2206,7 +2206,7 @@@ deletion, or > if it is flagged for dis
  ;;;;;;  browse-url browse-url-of-region browse-url-of-dired-file
  ;;;;;;  browse-url-of-buffer browse-url-of-file browse-url-url-at-point
  ;;;;;;  browse-url-galeon-program browse-url-firefox-program browse-url-browser-function)
- ;;;;;;  "browse-url" "net/browse-url.el" (17785 34467))
+ ;;;;;;  "browse-url" "net/browse-url.el" (17843 45624))
  ;;; Generated autoloads from net/browse-url.el
  
  (defvar browse-url-browser-function (cond ((memq system-type (quote (windows-nt ms-dos cygwin))) (quote browse-url-default-windows-browser)) ((memq system-type (quote (darwin))) (quote browse-url-default-macosx-browser)) (t (quote browse-url-default-browser))) "\
@@@ -2538,8 -2537,8 +2537,8 @@@ Default to the URL around or before poi
  
  ;;;***
  \f
- ;;;### (autoloads (snarf-bruces bruce) "bruce" "play/bruce.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (snarf-bruces bruce) "bruce" "play/bruce.el" (17843
+ ;;;;;;  45625))
  ;;; Generated autoloads from play/bruce.el
  
  (autoload (quote bruce) "bruce" "\
@@@ -2555,7 -2554,7 +2554,7 @@@ Return a vector containing the lines fr
  ;;;***
  \f
  ;;;### (autoloads (bs-show bs-customize bs-cycle-previous bs-cycle-next)
- ;;;;;;  "bs" "bs.el" (17748 43063))
+ ;;;;;;  "bs" "bs.el" (17843 45609))
  ;;; Generated autoloads from bs.el
  
  (autoload (quote bs-cycle-next) "bs" "\
@@@ -2596,8 -2595,8 +2595,8 @@@ name of buffer configuration
  ;;;***
  \f
  ;;;### (autoloads (insert-text-button make-text-button insert-button
- ;;;;;;  make-button define-button-type) "button" "button.el" (17786
- ;;;;;;  60297))
+ ;;;;;;  make-button define-button-type) "button" "button.el" (17843
+ ;;;;;;  45609))
  ;;; Generated autoloads from button.el
  
  (defvar button-map (let ((map (make-sparse-keymap))) (define-key map "\r" (quote push-button)) (define-key map [mouse-2] (quote push-button)) map) "\
@@@ -2685,7 -2684,7 +2684,7 @@@ Also see `make-text-button'
  ;;;;;;  batch-byte-compile-if-not-done display-call-tree byte-compile
  ;;;;;;  compile-defun byte-compile-file byte-recompile-directory
  ;;;;;;  byte-force-recompile byte-compile-warnings-safe-p) "bytecomp"
- ;;;;;;  "emacs-lisp/bytecomp.el" (17775 9245))
+ ;;;;;;  "emacs-lisp/bytecomp.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/bytecomp.el
  (put 'byte-compile-dynamic 'safe-local-variable 'booleanp)
  (put 'byte-compile-dynamic-docstrings 'safe-local-variable 'booleanp)
@@@ -2789,7 -2788,7 +2788,7 @@@ and corresponding effects
  
  ;;;***
  \f
- ;;;### (autoloads nil "cal-dst" "calendar/cal-dst.el" (17748 43063))
+ ;;;### (autoloads nil "cal-dst" "calendar/cal-dst.el" (17843 45615))
  ;;; Generated autoloads from calendar/cal-dst.el
  
  (put (quote calendar-daylight-savings-starts) (quote risky-local-variable) t)
  ;;;***
  \f
  ;;;### (autoloads (list-yahrzeit-dates) "cal-hebrew" "calendar/cal-hebrew.el"
- ;;;;;;  (17386 33146))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from calendar/cal-hebrew.el
  
  (autoload (quote list-yahrzeit-dates) "cal-hebrew" "\
@@@ -2814,7 -2813,7 +2813,7 @@@ from the cursor position
  ;;;### (autoloads (defmath calc-embedded-activate calc-embedded calc-grab-rectangle
  ;;;;;;  calc-grab-region full-calc-keypad calc-keypad calc-eval quick-calc
  ;;;;;;  full-calc calc calc-dispatch calc-settings-file) "calc" "calc/calc.el"
- ;;;;;;  (17671 12179))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from calc/calc.el
  
  (defvar calc-settings-file (convert-standard-filename "~/.calc.el") "\
@@@ -2892,8 -2891,8 +2891,8 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads (calculator) "calculator" "calculator.el" (17385
- ;;;;;;  8482))
+ ;;;### (autoloads (calculator) "calculator" "calculator.el" (17843
+ ;;;;;;  45609))
  ;;; Generated autoloads from calculator.el
  
  (autoload (quote calculator) "calculator" "\
@@@ -2921,7 -2920,7 +2920,7 @@@ See the documentation for `calculator-m
  ;;;;;;  mark-holidays-in-calendar view-calendar-holidays-initially
  ;;;;;;  calendar-remove-frame-by-deleting mark-diary-entries-in-calendar
  ;;;;;;  view-diary-entries-initially calendar-offset) "calendar"
- ;;;;;;  "calendar/calendar.el" (17734 1777))
+ ;;;;;;  "calendar/calendar.el" (17843 45615))
  ;;; Generated autoloads from calendar/calendar.el
  
  (defvar calendar-offset 0 "\
@@@ -3494,7 -3493,7 +3493,7 @@@ movement commands will not work correct
  ;;;***
  \f
  ;;;### (autoloads (canlock-verify canlock-insert-header) "canlock"
- ;;;;;;  "gnus/canlock.el" (17385 8492))
+ ;;;;;;  "gnus/canlock.el" (17843 45616))
  ;;; Generated autoloads from gnus/canlock.el
  
  (autoload (quote canlock-insert-header) "canlock" "\
@@@ -3511,15 -3510,15 +3510,15 @@@ it fails
  
  ;;;***
  \f
- ;;;### (autoloads nil "cc-compat" "progmodes/cc-compat.el" (17794
- ;;;;;;  54379))
+ ;;;### (autoloads nil "cc-compat" "progmodes/cc-compat.el" (17843
+ ;;;;;;  45626))
  ;;; Generated autoloads from progmodes/cc-compat.el
  (put 'c-indent-level 'safe-local-variable 'integerp)
  
  ;;;***
  \f
  ;;;### (autoloads (c-guess-basic-syntax) "cc-engine" "progmodes/cc-engine.el"
- ;;;;;;  (17796 15986))
+ ;;;;;;  (17843 45626))
  ;;; Generated autoloads from progmodes/cc-engine.el
  
  (autoload (quote c-guess-basic-syntax) "cc-engine" "\
@@@ -3531,7 -3530,7 +3530,7 @@@ Return the syntactic context of the cur
  \f
  ;;;### (autoloads (pike-mode idl-mode java-mode objc-mode c++-mode
  ;;;;;;  c-mode c-initialize-cc-mode) "cc-mode" "progmodes/cc-mode.el"
- ;;;;;;  (17797 52285))
+ ;;;;;;  (17843 45627))
  ;;; Generated autoloads from progmodes/cc-mode.el
  
  (autoload (quote c-initialize-cc-mode) "cc-mode" "\
@@@ -3689,7 -3688,7 +3688,7 @@@ Key bindings
  ;;;***
  \f
  ;;;### (autoloads (c-set-offset c-add-style c-set-style) "cc-styles"
- ;;;;;;  "progmodes/cc-styles.el" (17794 54380))
+ ;;;;;;  "progmodes/cc-styles.el" (17843 45627))
  ;;; Generated autoloads from progmodes/cc-styles.el
  
  (autoload (quote c-set-style) "cc-styles" "\
@@@ -3740,14 -3739,14 +3739,14 @@@ and exists only for compatibility reaso
  
  ;;;***
  \f
- ;;;### (autoloads nil "cc-subword" "progmodes/cc-subword.el" (17794
- ;;;;;;  54380))
+ ;;;### (autoloads nil "cc-subword" "progmodes/cc-subword.el" (17843
+ ;;;;;;  45627))
  ;;; Generated autoloads from progmodes/cc-subword.el
   (autoload 'c-subword-mode "cc-subword" "Mode enabling subword movement and editing keys." t)
  
  ;;;***
  \f
- ;;;### (autoloads nil "cc-vars" "progmodes/cc-vars.el" (17794 54380))
+ ;;;### (autoloads nil "cc-vars" "progmodes/cc-vars.el" (17843 45627))
  ;;; Generated autoloads from progmodes/cc-vars.el
  (put 'c-basic-offset 'safe-local-variable 'integerp)
  (put 'c-backslash-column 'safe-local-variable 'integerp)
  \f
  ;;;### (autoloads (ccl-execute-with-args check-ccl-program define-ccl-program
  ;;;;;;  declare-ccl-program ccl-dump ccl-compile) "ccl" "international/ccl.el"
- ;;;;;;  (17792 9561))
+ ;;;;;;  (17843 45618))
  ;;; Generated autoloads from international/ccl.el
  
  (autoload (quote ccl-compile) "ccl" "\
@@@ -4016,7 -4015,7 +4015,7 @@@ See the documentation of `define-ccl-pr
  ;;;***
  \f
  ;;;### (autoloads (cfengine-mode) "cfengine" "progmodes/cfengine.el"
- ;;;;;;  (17669 23128))
+ ;;;;;;  (17843 45627))
  ;;; Generated autoloads from progmodes/cfengine.el
  
  (autoload (quote cfengine-mode) "cfengine" "\
@@@ -4038,7 -4037,7 +4037,7 @@@ to the action header
  ;;;;;;  checkdoc-comments checkdoc-continue checkdoc-start checkdoc-current-buffer
  ;;;;;;  checkdoc-eval-current-buffer checkdoc-message-interactive
  ;;;;;;  checkdoc-interactive checkdoc) "checkdoc" "emacs-lisp/checkdoc.el"
- ;;;;;;  (17740 981))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/checkdoc.el
  
  (autoload (quote checkdoc) "checkdoc" "\
@@@ -4221,8 -4220,8 +4220,8 @@@ checking of documentation strings
  ;;;***
  \f
  ;;;### (autoloads (encode-hz-buffer encode-hz-region decode-hz-buffer
- ;;;;;;  decode-hz-region) "china-util" "language/china-util.el" (17792
- ;;;;;;  9562))
+ ;;;;;;  decode-hz-region) "china-util" "language/china-util.el" (17843
+ ;;;;;;  45620))
  ;;; Generated autoloads from language/china-util.el
  
  (autoload (quote decode-hz-region) "china-util" "\
@@@ -4250,7 -4249,7 +4249,7 @@@ Encode the text in the current buffer t
  ;;;***
  \f
  ;;;### (autoloads (command-history list-command-history repeat-matching-complex-command)
- ;;;;;;  "chistory" "chistory.el" (17781 39501))
+ ;;;;;;  "chistory" "chistory.el" (17843 45609))
  ;;; Generated autoloads from chistory.el
  
  (autoload (quote repeat-matching-complex-command) "chistory" "\
@@@ -4289,7 -4288,7 +4288,7 @@@ and runs the normal hook `command-histo
  
  ;;;***
  \f
- ;;;### (autoloads nil "cl" "emacs-lisp/cl.el" (17785 34467))
+ ;;;### (autoloads nil "cl" "emacs-lisp/cl.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/cl.el
  
  (defvar custom-print-functions nil "\
@@@ -4305,7 -4304,7 +4304,7 @@@ a future Emacs interpreter will be abl
  ;;;***
  \f
  ;;;### (autoloads (common-lisp-indent-function) "cl-indent" "emacs-lisp/cl-indent.el"
- ;;;;;;  (17729 22475))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/cl-indent.el
  
  (autoload (quote common-lisp-indent-function) "cl-indent" "\
@@@ -4316,7 -4315,7 +4315,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (c-macro-expand) "cmacexp" "progmodes/cmacexp.el"
- ;;;;;;  (17394 12937))
+ ;;;;;;  (17843 45627))
  ;;; Generated autoloads from progmodes/cmacexp.el
  
  (autoload (quote c-macro-expand) "cmacexp" "\
@@@ -4336,8 -4335,8 +4335,8 @@@ For use inside Lisp programs, see also 
  
  ;;;***
  \f
- ;;;### (autoloads (run-scheme) "cmuscheme" "cmuscheme.el" (17786
- ;;;;;;  56014))
+ ;;;### (autoloads (run-scheme) "cmuscheme" "cmuscheme.el" (17843
+ ;;;;;;  45609))
  ;;; Generated autoloads from cmuscheme.el
  
  (autoload (quote run-scheme) "cmuscheme" "\
@@@ -4356,11 -4355,71 +4355,11 @@@ is run)
  \(fn CMD)" t nil)
   (add-hook 'same-window-buffer-names "*scheme*")
  
 -;;;***
 -\f
 -;;;### (autoloads (cp-make-coding-system) "code-pages" "international/code-pages.el"
 -;;;;;;  (17843 45618))
 -;;; Generated autoloads from international/code-pages.el
 -
 -(autoload (quote cp-make-coding-system) "code-pages" "\
 -Make coding system NAME for and 8-bit, extended-ASCII character set.
 -V is a 128-long vector of characters to translate the upper half of
 -the character set.  DOC-STRING and MNEMONIC are used as the
 -corresponding args of `make-coding-system'.  If MNEMONIC isn't given,
 -?* is used.
 -Return an updated `non-iso-charset-alist'.
 -
 -\(fn NAME V &optional DOC-STRING MNEMONIC)" nil (quote macro))
 -(autoload-coding-system 'cp437 '(require 'code-pages))
 -(autoload-coding-system 'cp737 '(require 'code-pages))
 -(autoload-coding-system 'cp775 '(require 'code-pages))
 -(autoload-coding-system 'cp850 '(require 'code-pages))
 -(autoload-coding-system 'cp851 '(require 'code-pages))
 -(autoload-coding-system 'cp852 '(require 'code-pages))
 -(autoload-coding-system 'cp855 '(require 'code-pages))
 -(autoload-coding-system 'cp857 '(require 'code-pages))
 -(autoload-coding-system 'cp858 '(require 'code-pages))
 -(autoload-coding-system 'cp860 '(require 'code-pages))
 -(autoload-coding-system 'cp861 '(require 'code-pages))
 -(autoload-coding-system 'cp862 '(require 'code-pages))
 -(autoload-coding-system 'cp863 '(require 'code-pages))
 -(autoload-coding-system 'cp864 '(require 'code-pages))
 -(autoload-coding-system 'cp865 '(require 'code-pages))
 -(autoload-coding-system 'cp866 '(require 'code-pages))
 -(autoload-coding-system 'cp869 '(require 'code-pages))
 -(autoload-coding-system 'cp874 '(require 'code-pages))
 -(autoload-coding-system 'windows-1250 '(require 'code-pages))
 -(autoload-coding-system 'cp1250 '(require 'code-pages))
 -(autoload-coding-system 'windows-1253 '(require 'code-pages))
 -(autoload-coding-system 'cp1253 '(require 'code-pages))
 -(autoload-coding-system 'windows-1254 '(require 'code-pages))
 -(autoload-coding-system 'cp1254 '(require 'code-pages))
 -(autoload-coding-system 'windows-1255 '(require 'code-pages))
 -(autoload-coding-system 'cp1255 '(require 'code-pages))
 -(autoload-coding-system 'windows-1256 '(require 'code-pages))
 -(autoload-coding-system 'cp1256 '(require 'code-pages))
 -(autoload-coding-system 'windows-1257 '(require 'code-pages))
 -(autoload-coding-system 'cp1257 '(require 'code-pages))
 -(autoload-coding-system 'windows-1258 '(require 'code-pages))
 -(autoload-coding-system 'cp1258 '(require 'code-pages))
 -(autoload-coding-system 'next '(require 'code-pages))
 -(autoload-coding-system 'koi8-t '(require 'code-pages))
 -(autoload-coding-system 'iso-8859-16 '(require 'code-pages))
 -(autoload-coding-system 'iso-8859-6 '(require 'code-pages))
 -(autoload-coding-system 'iso-8859-10 '(require 'code-pages))
 -(autoload-coding-system 'iso-8859-13 '(require 'code-pages))
 -(autoload-coding-system 'georgian-ps '(require 'code-pages))
 -(autoload-coding-system 'cp720 '(require 'code-pages))
 -(autoload-coding-system 'cp1125 '(require 'code-pages))
 -(autoload-coding-system 'mik '(require 'code-pages))
 -(autoload-coding-system 'pt154 '(require 'code-pages))
 -(autoload-coding-system 'iso-8859-11 '(require 'code-pages))
 -
  ;;;***
  \f
  ;;;### (autoloads (codepage-setup cp-supported-codepages cp-offset-for-codepage
  ;;;;;;  cp-language-for-codepage cp-charset-for-codepage cp-make-coding-systems-for-codepage)
- ;;;;;;  "codepage" "international/codepage.el" (17792 9561))
+ ;;;;;;  "codepage" "international/codepage.el" (17843 45618))
  ;;; Generated autoloads from international/codepage.el
  
  (autoload (quote cp-make-coding-systems-for-codepage) "codepage" "\
@@@ -4419,7 -4478,7 +4418,7 @@@ read/written by MS-DOS software, or fo
  ;;;### (autoloads (comint-redirect-results-list-from-process comint-redirect-results-list
  ;;;;;;  comint-redirect-send-command-to-process comint-redirect-send-command
  ;;;;;;  comint-run make-comint make-comint-in-buffer) "comint" "comint.el"
- ;;;;;;  (17800 14415))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from comint.el
  
  (defvar comint-output-filter-functions (quote (comint-postoutput-scroll-to-bottom comint-watch-for-password-prompt)) "\
@@@ -4509,8 -4568,8 +4508,8 @@@ REGEXP-GROUP is the regular expression 
  
  ;;;***
  \f
- ;;;### (autoloads (compare-windows) "compare-w" "compare-w.el" (17781
- ;;;;;;  39501))
+ ;;;### (autoloads (compare-windows) "compare-w" "compare-w.el" (17843
+ ;;;;;;  45609))
  ;;; Generated autoloads from compare-w.el
  
  (autoload (quote compare-windows) "compare-w" "\
@@@ -4547,7 -4606,7 +4546,7 @@@ on third call it again advances points 
  ;;;;;;  compilation-shell-minor-mode compilation-mode compilation-start
  ;;;;;;  compile compilation-disable-input compile-command compilation-search-path
  ;;;;;;  compilation-ask-about-save compilation-window-height compilation-mode-hook)
- ;;;;;;  "compile" "progmodes/compile.el" (17767 19634))
+ ;;;;;;  "compile" "progmodes/compile.el" (17843 45627))
  ;;; Generated autoloads from progmodes/compile.el
  
  (defvar compilation-mode-hook nil "\
@@@ -4626,12 -4685,12 +4625,12 @@@ Compile the program including the curre
  Runs COMMAND, a shell command, in a separate process asynchronously
  with output going to the buffer `*compilation*'.
  
- If optional second arg COMINT is t the buffer will be in Comint mode with
- `compilation-shell-minor-mode'.
  You can then use the command \\[next-error] to find the next error message
  and move to the source code that caused it.
  
+ If optional second arg COMINT is t the buffer will be in Comint mode with
+ `compilation-shell-minor-mode'.
  Interactively, prompts for the command if `compilation-read-command' is
  non-nil; otherwise uses `compile-command'.  With prefix arg, always prompts.
  Additionally, with universal prefix arg, compilation buffer will be in
@@@ -4709,7 -4768,7 +4708,7 @@@ This is the value of `next-error-functi
  ;;;***
  \f
  ;;;### (autoloads (partial-completion-mode) "complete" "complete.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from complete.el
  
  (defvar partial-completion-mode nil "\
@@@ -4751,7 -4810,7 +4750,7 @@@ second TAB brings up the `*Completions*
  ;;;***
  \f
  ;;;### (autoloads (dynamic-completion-mode) "completion" "completion.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from completion.el
  
  (defvar dynamic-completion-mode nil "\
@@@ -4773,7 -4832,7 +4772,7 @@@ Enable dynamic word-completion
  ;;;### (autoloads (decompose-composite-char compose-last-chars compose-chars-after
  ;;;;;;  find-composition compose-chars decompose-string compose-string
  ;;;;;;  decompose-region compose-region encode-composition-rule)
- ;;;;;;  "composite" "composite.el" (17792 9561))
+ ;;;;;;  "composite" "composite.el" (17843 45609))
  ;;; Generated autoloads from composite.el
  
  (defconst reference-point-alist (quote ((tl . 0) (tc . 1) (tr . 2) (Bl . 3) (Bc . 4) (Br . 5) (bl . 6) (bc . 7) (br . 8) (cl . 9) (cc . 10) (cr . 11) (top-left . 0) (top-center . 1) (top-right . 2) (base-left . 3) (base-center . 4) (base-right . 5) (bottom-left . 6) (bottom-center . 7) (bottom-right . 8) (center-left . 9) (center-center . 10) (center-right . 11) (ml . 3) (mc . 10) (mr . 5) (mid-left . 3) (mid-center . 10) (mid-right . 5))) "\
@@@ -4995,7 -5054,7 +4994,7 @@@ Optional 3rd arg WITH-COMPOSITION-RULE 
  ;;;### (autoloads (conf-xdefaults-mode conf-ppd-mode conf-colon-mode
  ;;;;;;  conf-space-keywords conf-space-mode conf-javaprop-mode conf-windows-mode
  ;;;;;;  conf-unix-mode conf-mode) "conf-mode" "textmodes/conf-mode.el"
- ;;;;;;  (17679 3707))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/conf-mode.el
  
  (autoload (quote conf-mode) "conf-mode" "\
@@@ -5151,7 -5210,7 +5150,7 @@@ For details see `conf-mode'.  Example
  ;;;***
  \f
  ;;;### (autoloads (shuffle-vector cookie-snarf cookie-insert cookie)
- ;;;;;;  "cookie1" "play/cookie1.el" (17786 56015))
+ ;;;;;;  "cookie1" "play/cookie1.el" (17843 45625))
  ;;; Generated autoloads from play/cookie1.el
  
  (autoload (quote cookie) "cookie1" "\
@@@ -5183,7 -5242,7 +5182,7 @@@ Randomly permute the elements of VECTO
  ;;;***
  \f
  ;;;### (autoloads (copyright copyright-fix-years copyright-update)
- ;;;;;;  "copyright" "emacs-lisp/copyright.el" (17385 8489))
+ ;;;;;;  "copyright" "emacs-lisp/copyright.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/copyright.el
  
  (autoload (quote copyright-update) "copyright" "\
@@@ -5211,7 -5270,7 +5210,7 @@@ Insert a copyright by $ORGANIZATION not
  ;;;***
  \f
  ;;;### (autoloads (cperl-perldoc-at-point cperl-perldoc cperl-mode)
- ;;;;;;  "cperl-mode" "progmodes/cperl-mode.el" (17781 39502))
+ ;;;;;;  "cperl-mode" "progmodes/cperl-mode.el" (17843 45627))
  ;;; Generated autoloads from progmodes/cperl-mode.el
  
  (autoload (quote cperl-mode) "cperl-mode" "\
@@@ -5402,7 -5461,7 +5401,7 @@@ Run a `perldoc' on the word around poin
  ;;;***
  \f
  ;;;### (autoloads (cpp-parse-edit cpp-highlight-buffer) "cpp" "progmodes/cpp.el"
- ;;;;;;  (17394 12937))
+ ;;;;;;  (17843 45627))
  ;;; Generated autoloads from progmodes/cpp.el
  
  (autoload (quote cpp-highlight-buffer) "cpp" "\
@@@ -5421,7 -5480,7 +5420,7 @@@ Edit display information for cpp condit
  ;;;***
  \f
  ;;;### (autoloads (crisp-mode crisp-mode) "crisp" "emulation/crisp.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emulation/crisp.el
  
  (defvar crisp-mode nil "\
@@@ -5445,7 -5504,7 +5444,7 @@@ With ARG, turn CRiSP mode on if ARG is 
  ;;;***
  \f
  ;;;### (autoloads (completing-read-multiple) "crm" "emacs-lisp/crm.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/crm.el
  
  (autoload (quote completing-read-multiple) "crm" "\
@@@ -5481,7 -5540,7 +5480,7 @@@ INHERIT-INPUT-METHOD
  ;;;***
  \f
  ;;;### (autoloads (cua-selection-mode cua-mode) "cua-base" "emulation/cua-base.el"
- ;;;;;;  (17782 59544))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emulation/cua-base.el
  
  (defvar cua-mode nil "\
@@@ -5543,12 -5602,29 +5542,29 @@@ Enable CUA selection mode without the C
  ;;;;;;  custom-save-all custom-file customize-browse custom-buffer-create-other-window
  ;;;;;;  custom-buffer-create customize-apropos-groups customize-apropos-faces
  ;;;;;;  customize-apropos-options customize-apropos customize-saved
- ;;;;;;  customize-rogue customize-customized customize-face-other-window
+ ;;;;;;  customize-rogue customize-unsaved customize-face-other-window
  ;;;;;;  customize-face customize-changed-options customize-option-other-window
  ;;;;;;  customize-option customize-group-other-window customize-group
  ;;;;;;  customize-mode customize customize-save-variable customize-set-variable
- ;;;;;;  customize-set-value) "cus-edit" "cus-edit.el" (17752 39351))
+ ;;;;;;  customize-set-value custom-menu-sort-alphabetically custom-buffer-sort-alphabetically
+ ;;;;;;  custom-browse-sort-alphabetically) "cus-edit" "cus-edit.el"
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from cus-edit.el
+ (defvar custom-browse-sort-alphabetically nil "\
+ If non-nil, sort customization group alphabetically in `custom-browse'.")
+ (custom-autoload (quote custom-browse-sort-alphabetically) "cus-edit" t)
+ (defvar custom-buffer-sort-alphabetically nil "\
+ If non-nil, sort each customization group alphabetically in Custom buffer.")
+ (custom-autoload (quote custom-buffer-sort-alphabetically) "cus-edit" t)
+ (defvar custom-menu-sort-alphabetically nil "\
+ If non-nil, sort each customization group alphabetically in menus.")
+ (custom-autoload (quote custom-menu-sort-alphabetically) "cus-edit" t)
   (add-hook 'same-window-regexps "\\`\\*Customiz.*\\*\\'")
  
  (autoload (quote customize-set-value) "cus-edit" "\
@@@ -5707,8 -5783,8 +5723,8 @@@ suggest to customize that face, if it'
  
  \(fn &optional FACE)" t nil)
  
- (autoload (quote customize-customized) "cus-edit" "\
- Customize all user options set since the last save in this session.
+ (autoload (quote customize-unsaved) "cus-edit" "\
+ Customize all user options set in this session but not saved.
  
  \(fn)" t nil)
  
@@@ -5836,7 -5912,7 +5852,7 @@@ The format is suitable for use with `ea
  ;;;***
  \f
  ;;;### (autoloads (custom-reset-faces custom-theme-reset-faces custom-set-faces
- ;;;;;;  custom-declare-face) "cus-face" "cus-face.el" (17385 8483))
+ ;;;;;;  custom-declare-face) "cus-face" "cus-face.el" (17843 45609))
  ;;; Generated autoloads from cus-face.el
  
  (autoload (quote custom-declare-face) "cus-face" "\
@@@ -5906,7 -5982,7 +5922,7 @@@ This means reset FACE to its value in F
  ;;;***
  \f
  ;;;### (autoloads (customize-create-theme) "cus-theme" "cus-theme.el"
- ;;;;;;  (17632 41885))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from cus-theme.el
  
  (autoload (quote customize-create-theme) "cus-theme" "\
@@@ -5917,7 -5993,7 +5933,7 @@@ Create a custom theme
  ;;;***
  \f
  ;;;### (autoloads (cvs-status-mode) "cvs-status" "cvs-status.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from cvs-status.el
  
  (autoload (quote cvs-status-mode) "cvs-status" "\
@@@ -5928,7 -6004,7 +5944,7 @@@ Mode used for cvs status output
  ;;;***
  \f
  ;;;### (autoloads (global-cwarn-mode turn-on-cwarn-mode cwarn-mode)
- ;;;;;;  "cwarn" "progmodes/cwarn.el" (17394 12937))
+ ;;;;;;  "cwarn" "progmodes/cwarn.el" (17843 45627))
  ;;; Generated autoloads from progmodes/cwarn.el
  
  (autoload (quote cwarn-mode) "cwarn" "\
@@@ -5954,11 -6030,10 +5970,10 @@@ This function is designed to be added t
  Non-nil if Global-Cwarn mode is enabled.
  See the command `global-cwarn-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `global-cwarn-mode'.")
- (custom-autoload (quote global-cwarn-mode) "cwarn")
+ either customize it (see the info node `Easy Customization')
+ or call the function `global-cwarn-mode'.")
  
- (put (quote global-cwarn-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote global-cwarn-mode) "cwarn" nil)
  
  (autoload (quote global-cwarn-mode) "cwarn" "\
  Toggle Cwarn mode in every buffer.
@@@ -5972,7 -6047,7 +5987,7 @@@ in which `turn-on-cwarn-mode-if-enabled
  \f
  ;;;### (autoloads (standard-display-cyrillic-translit cyrillic-encode-alternativnyj-char
  ;;;;;;  cyrillic-encode-koi8-r-char) "cyril-util" "language/cyril-util.el"
- ;;;;;;  (17788 21816))
+ ;;;;;;  (17843 45620))
  ;;; Generated autoloads from language/cyril-util.el
  
  (autoload (quote cyrillic-encode-koi8-r-char) "cyril-util" "\
@@@ -6001,7 -6076,7 +6016,7 @@@ If the argument is nil, we return the d
  ;;;***
  \f
  ;;;### (autoloads (dabbrev-expand dabbrev-completion) "dabbrev" "dabbrev.el"
- ;;;;;;  (17385 8483))
+ ;;;;;;  (17843 45609))
  ;;; Generated autoloads from dabbrev.el
   (define-key esc-map "/" 'dabbrev-expand)
   (define-key esc-map [?\C-/] 'dabbrev-completion)
@@@ -6045,8 -6120,8 +6060,8 @@@ See also `dabbrev-abbrev-char-regexp' a
  
  ;;;***
  \f
- ;;;### (autoloads (dcl-mode) "dcl-mode" "progmodes/dcl-mode.el" (17394
- ;;;;;;  12937))
+ ;;;### (autoloads (dcl-mode) "dcl-mode" "progmodes/dcl-mode.el" (17843
+ ;;;;;;  45627))
  ;;; Generated autoloads from progmodes/dcl-mode.el
  
  (autoload (quote dcl-mode) "dcl-mode" "\
@@@ -6173,7 -6248,7 +6188,7 @@@ There is some minimal font-lock suppor
  ;;;***
  \f
  ;;;### (autoloads (cancel-debug-on-entry debug-on-entry debug) "debug"
- ;;;;;;  "emacs-lisp/debug.el" (17440 13082))
+ ;;;;;;  "emacs-lisp/debug.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/debug.el
  
  (setq debugger (quote debug))
@@@ -6217,7 -6292,7 +6232,7 @@@ To specify a nil argument interactively
  ;;;***
  \f
  ;;;### (autoloads (decipher-mode decipher) "decipher" "play/decipher.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45625))
  ;;; Generated autoloads from play/decipher.el
  
  (autoload (quote decipher) "decipher" "\
@@@ -6246,8 -6321,8 +6261,8 @@@ The most useful commands are
  ;;;***
  \f
  ;;;### (autoloads (delimit-columns-rectangle delimit-columns-region
- ;;;;;;  delimit-columns-customize) "delim-col" "delim-col.el" (17781
- ;;;;;;  39501))
+ ;;;;;;  delimit-columns-customize) "delim-col" "delim-col.el" (17843
+ ;;;;;;  45609))
  ;;; Generated autoloads from delim-col.el
  
  (autoload (quote delimit-columns-customize) "delim-col" "\
@@@ -6271,8 -6346,8 +6286,8 @@@ START and END delimits the corners of t
  
  ;;;***
  \f
- ;;;### (autoloads (delphi-mode) "delphi" "progmodes/delphi.el" (17604
- ;;;;;;  60390))
+ ;;;### (autoloads (delphi-mode) "delphi" "progmodes/delphi.el" (17843
+ ;;;;;;  45627))
  ;;; Generated autoloads from progmodes/delphi.el
  
  (autoload (quote delphi-mode) "delphi" "\
@@@ -6322,8 -6397,8 +6337,8 @@@ no args, if that value is non-nil
  
  ;;;***
  \f
- ;;;### (autoloads (delete-selection-mode) "delsel" "delsel.el" (17385
- ;;;;;;  8483))
+ ;;;### (autoloads (delete-selection-mode) "delsel" "delsel.el" (17843
+ ;;;;;;  45609))
  ;;; Generated autoloads from delsel.el
  
  (defalias (quote pending-delete-mode) (quote delete-selection-mode))
  Non-nil if Delete-Selection mode is enabled.
  See the command `delete-selection-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `delete-selection-mode'.")
- (custom-autoload (quote delete-selection-mode) "delsel")
+ either customize it (see the info node `Easy Customization')
+ or call the function `delete-selection-mode'.")
  
- (put (quote delete-selection-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote delete-selection-mode) "delsel" nil)
  
  (autoload (quote delete-selection-mode) "delsel" "\
  Toggle Delete Selection mode.
@@@ -6353,7 -6427,7 +6367,7 @@@ any selection
  ;;;***
  \f
  ;;;### (autoloads (derived-mode-init-mode-variables define-derived-mode)
- ;;;;;;  "derived" "emacs-lisp/derived.el" (17785 34467))
+ ;;;;;;  "derived" "emacs-lisp/derived.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/derived.el
  
  (autoload (quote define-derived-mode) "derived" "\
@@@ -6418,7 -6492,7 +6432,7 @@@ the first time the mode is used
  ;;;***
  \f
  ;;;### (autoloads (describe-char describe-text-properties) "descr-text"
- ;;;;;;  "descr-text.el" (17780 18171))
+ ;;;;;;  "descr-text.el" (17843 45609))
  ;;; Generated autoloads from descr-text.el
  
  (autoload (quote describe-text-properties) "descr-text" "\
@@@ -6444,7 -6518,7 +6458,7 @@@ as well as widgets, buttons, overlays, 
  ;;;### (autoloads (desktop-revert desktop-save-in-desktop-dir desktop-change-dir
  ;;;;;;  desktop-load-default desktop-read desktop-remove desktop-save
  ;;;;;;  desktop-clear desktop-locals-to-save desktop-save-mode) "desktop"
- ;;;;;;  "desktop.el" (17670 57734))
+ ;;;;;;  "desktop.el" (17843 45609))
  ;;; Generated autoloads from desktop.el
  
  (defvar desktop-save-mode nil "\
@@@ -6627,7 -6701,7 +6641,7 @@@ Revert to the last loaded desktop
  \f
  ;;;### (autoloads (gnus-article-outlook-deuglify-article gnus-outlook-deuglify-article
  ;;;;;;  gnus-article-outlook-repair-attribution gnus-article-outlook-unwrap-lines)
- ;;;;;;  "deuglify" "gnus/deuglify.el" (17797 50970))
+ ;;;;;;  "deuglify" "gnus/deuglify.el" (17843 45616))
  ;;; Generated autoloads from gnus/deuglify.el
  
  (autoload (quote gnus-article-outlook-unwrap-lines) "deuglify" "\
@@@ -6660,7 -6734,7 +6674,7 @@@ Deuglify broken Outlook (Express) artic
  ;;;***
  \f
  ;;;### (autoloads (devanagari-post-read-conversion devanagari-compose-region)
- ;;;;;;  "devan-util" "language/devan-util.el" (17792 9562))
+ ;;;;;;  "devan-util" "language/devan-util.el" (17843 45620))
  ;;; Generated autoloads from language/devan-util.el
  
  (defconst devanagari-consonant "[\x51ad5-\x51af9\x51b38-\x51b3f]")
@@@ -6678,7 -6752,7 +6692,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (diary-mode diary-mail-entries diary) "diary-lib"
- ;;;;;;  "calendar/diary-lib.el" (17520 49736))
+ ;;;;;;  "calendar/diary-lib.el" (17843 45615))
  ;;; Generated autoloads from calendar/diary-lib.el
  
  (autoload (quote diary) "diary-lib" "\
@@@ -6724,7 -6798,7 +6738,7 @@@ Major mode for editing the diary file
  ;;;***
  \f
  ;;;### (autoloads (diff-backup diff diff-command diff-switches) "diff"
- ;;;;;;  "diff.el" (17683 64071))
+ ;;;;;;  "diff.el" (17843 45609))
  ;;; Generated autoloads from diff.el
  
  (defvar diff-switches "-c" "\
@@@ -6758,7 -6832,7 +6772,7 @@@ With prefix arg, prompt for diff switch
  ;;;***
  \f
  ;;;### (autoloads (diff-minor-mode diff-mode) "diff-mode" "diff-mode.el"
- ;;;;;;  (17771 26718))
+ ;;;;;;  (17838 18032))
  ;;; Generated autoloads from diff-mode.el
  
  (autoload (quote diff-mode) "diff-mode" "\
@@@ -6788,7 -6862,7 +6802,7 @@@ Minor mode for viewing/editing context 
  ;;;;;;  dired dired-copy-preserve-time dired-dwim-target dired-keep-marker-symlink
  ;;;;;;  dired-keep-marker-hardlink dired-keep-marker-copy dired-keep-marker-rename
  ;;;;;;  dired-trivial-filenames dired-ls-F-marks-symlinks dired-listing-switches)
- ;;;;;;  "dired" "dired.el" (17780 18171))
+ ;;;;;;  "dired" "dired.el" (17843 45609))
  ;;; Generated autoloads from dired.el
  
  (defvar dired-listing-switches "-al" "\
@@@ -6993,7 -7067,7 +7007,7 @@@ Keybindings
  ;;;;;;  dired-run-shell-command dired-do-shell-command dired-clean-directory
  ;;;;;;  dired-do-print dired-do-touch dired-do-chown dired-do-chgrp
  ;;;;;;  dired-do-chmod dired-compare-directories dired-backup-diff
- ;;;;;;  dired-diff) "dired-aux" "dired-aux.el" (17742 7456))
+ ;;;;;;  dired-diff) "dired-aux" "dired-aux.el" (17843 45609))
  ;;; Generated autoloads from dired-aux.el
  
  (autoload (quote dired-diff) "dired-aux" "\
@@@ -7405,7 -7479,7 +7419,7 @@@ true then the type of the file linked t
  
  ;;;***
  \f
- ;;;### (autoloads (dired-jump) "dired-x" "dired-x.el" (17656 37701))
+ ;;;### (autoloads (dired-jump) "dired-x" "dired-x.el" (17843 45609))
  ;;; Generated autoloads from dired-x.el
  
  (autoload (quote dired-jump) "dired-x" "\
@@@ -7419,7 -7493,7 +7433,7 @@@ buffer and try again
  
  ;;;***
  \f
- ;;;### (autoloads (dirtrack) "dirtrack" "dirtrack.el" (17781 39501))
+ ;;;### (autoloads (dirtrack) "dirtrack" "dirtrack.el" (17843 45609))
  ;;; Generated autoloads from dirtrack.el
  
  (autoload (quote dirtrack) "dirtrack" "\
@@@ -7438,8 -7512,8 +7452,8 @@@ You can enable directory tracking by ad
  
  ;;;***
  \f
- ;;;### (autoloads (disassemble) "disass" "emacs-lisp/disass.el" (17385
- ;;;;;;  8489))
+ ;;;### (autoloads (disassemble) "disass" "emacs-lisp/disass.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emacs-lisp/disass.el
  
  (autoload (quote disassemble) "disass" "\
@@@ -7457,7 -7531,7 +7471,7 @@@ redefine OBJECT if it is a symbol
  ;;;;;;  standard-display-graphic standard-display-g1 standard-display-ascii
  ;;;;;;  standard-display-default standard-display-8bit describe-current-display-table
  ;;;;;;  describe-display-table set-display-table-slot display-table-slot
- ;;;;;;  make-display-table) "disp-table" "disp-table.el" (17781 39501))
+ ;;;;;;  make-display-table) "disp-table" "disp-table.el" (17843 45609))
  ;;; Generated autoloads from disp-table.el
  
  (autoload (quote make-display-table) "disp-table" "\
@@@ -7558,7 -7632,7 +7572,7 @@@ for users who call this function in `.e
  ;;;***
  \f
  ;;;### (autoloads (dissociated-press) "dissociate" "play/dissociate.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45625))
  ;;; Generated autoloads from play/dissociate.el
  
  (autoload (quote dissociated-press) "dissociate" "\
@@@ -7574,7 -7648,7 +7588,7 @@@ Default is 2
  
  ;;;***
  \f
- ;;;### (autoloads (dnd-protocol-alist) "dnd" "dnd.el" (17709 24917))
+ ;;;### (autoloads (dnd-protocol-alist) "dnd" "dnd.el" (17843 45609))
  ;;; Generated autoloads from dnd.el
  
  (defvar dnd-protocol-alist (quote (("^file:///" . dnd-open-local-file) ("^file://" . dnd-open-file) ("^file:" . dnd-open-local-file) ("^\\(https?\\|ftp\\|file\\|nfs\\)://" . dnd-open-file))) "\
@@@ -7595,7 -7669,7 +7609,7 @@@ if some action was made, or nil if the 
  ;;;***
  \f
  ;;;### (autoloads (dns-mode-soa-increment-serial dns-mode) "dns-mode"
- ;;;;;;  "textmodes/dns-mode.el" (17632 41886))
+ ;;;;;;  "textmodes/dns-mode.el" (17843 45630))
  ;;; Generated autoloads from textmodes/dns-mode.el
  
  (autoload (quote dns-mode) "dns-mode" "\
@@@ -7619,7 -7693,7 +7633,7 @@@ Locate SOA record and increment the ser
  
  ;;;***
  \f
- ;;;### (autoloads (doctor) "doctor" "play/doctor.el" (17786 56015))
+ ;;;### (autoloads (doctor) "doctor" "play/doctor.el" (17843 45625))
  ;;; Generated autoloads from play/doctor.el
  
  (autoload (quote doctor) "doctor" "\
@@@ -7630,7 -7704,7 +7644,7 @@@ Switch to *doctor* buffer and start giv
  ;;;***
  \f
  ;;;### (autoloads (double-mode double-mode) "double" "double.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from double.el
  
  (defvar double-mode nil "\
@@@ -7651,7 -7725,7 +7665,7 @@@ when pressed twice.  See variable `doub
  
  ;;;***
  \f
- ;;;### (autoloads (dunnet) "dunnet" "play/dunnet.el" (17743 18144))
+ ;;;### (autoloads (dunnet) "dunnet" "play/dunnet.el" (17843 45625))
  ;;; Generated autoloads from play/dunnet.el
  
  (autoload (quote dunnet) "dunnet" "\
@@@ -7662,7 -7736,7 +7676,7 @@@ Switch to *dungeon* buffer and start ga
  ;;;***
  \f
  ;;;### (autoloads (gnus-earcon-display) "earcon" "gnus/earcon.el"
- ;;;;;;  (17385 8492))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from gnus/earcon.el
  
  (autoload (quote gnus-earcon-display) "earcon" "\
@@@ -7674,7 -7748,7 +7688,7 @@@ Play sounds in message buffers
  \f
  ;;;### (autoloads (easy-mmode-defsyntax easy-mmode-defmap easy-mmode-define-keymap
  ;;;;;;  define-global-minor-mode define-minor-mode) "easy-mmode"
- ;;;;;;  "emacs-lisp/easy-mmode.el" (17772 35829))
+ ;;;;;;  "emacs-lisp/easy-mmode.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/easy-mmode.el
  
  (defalias (quote easy-mmode-define-minor-mode) (quote define-minor-mode))
@@@ -7722,7 -7796,7 +7736,7 @@@ For example, you could writ
  (defalias (quote easy-mmode-define-global-mode) (quote define-global-minor-mode))
  
  (autoload (quote define-global-minor-mode) "easy-mmode" "\
- Make GLOBAL-MODE out of the buffer-local minor MODE.
+ Make a global mode GLOBAL-MODE corresponding to buffer-local minor MODE.
  TURN-ON is a function that will be called with no args in every buffer
    and that should try to turn MODE on if applicable for that buffer.
  KEYS is a list of CL-style keyword arguments.  As the minor mode
@@@ -7766,8 -7840,8 +7780,8 @@@ CSS contains a list of syntax specifica
  ;;;***
  \f
  ;;;### (autoloads (easy-menu-change easy-menu-create-menu easy-menu-do-define
- ;;;;;;  easy-menu-define) "easymenu" "emacs-lisp/easymenu.el" (17785
- ;;;;;;  34467))
+ ;;;;;;  easy-menu-define) "easymenu" "emacs-lisp/easymenu.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emacs-lisp/easymenu.el
  
  (put (quote easy-menu-define) (quote lisp-indent-function) (quote defun))
@@@ -7894,6 -7968,10 +7908,10 @@@ should contain a submenu named NAME
  ITEMS is a list of menu items, as in `easy-menu-define'.
  These items entirely replace the previous items in that submenu.
  
+ If MAP is specified, it should normally be a keymap; nil stands for the local
+ menu-bar keymap.  It can also be a symbol, which has earlier been used as the
+ first argument in a call to `easy-menu-define', or the value of such a symbol.
  If the menu located by PATH has no submenu named NAME, add one.
  If the optional argument BEFORE is present, add it just before
  the submenu named BEFORE, otherwise add it at the end of the menu.
  To implement dynamic menus, either call this from
  `menu-bar-update-hook' or use a menu filter.
  
- \(fn PATH NAME ITEMS &optional BEFORE)" nil nil)
+ \(fn PATH NAME ITEMS &optional BEFORE MAP)" nil nil)
  
  ;;;***
  \f
  ;;;;;;  ebnf-eps-directory ebnf-spool-region ebnf-spool-buffer ebnf-spool-file
  ;;;;;;  ebnf-spool-directory ebnf-print-region ebnf-print-buffer
  ;;;;;;  ebnf-print-file ebnf-print-directory ebnf-customize) "ebnf2ps"
- ;;;;;;  "progmodes/ebnf2ps.el" (17780 18172))
+ ;;;;;;  "progmodes/ebnf2ps.el" (17843 45627))
  ;;; Generated autoloads from progmodes/ebnf2ps.el
  
  (autoload (quote ebnf-customize) "ebnf2ps" "\
@@@ -8171,8 -8249,8 +8189,8 @@@ See `ebnf-style-database' documentation
  ;;;;;;  ebrowse-tags-find-declaration-other-window ebrowse-tags-find-definition
  ;;;;;;  ebrowse-tags-view-definition ebrowse-tags-find-declaration
  ;;;;;;  ebrowse-tags-view-declaration ebrowse-member-mode ebrowse-electric-choose-tree
- ;;;;;;  ebrowse-tree-mode) "ebrowse" "progmodes/ebrowse.el" (17601
- ;;;;;;  9092))
+ ;;;;;;  ebrowse-tree-mode) "ebrowse" "progmodes/ebrowse.el" (17827
+ ;;;;;;  37447))
  ;;; Generated autoloads from progmodes/ebrowse.el
  
  (autoload (quote ebrowse-tree-mode) "ebrowse" "\
@@@ -8323,7 -8401,7 +8341,7 @@@ Display statistics for a class tree
  ;;;***
  \f
  ;;;### (autoloads (electric-buffer-list) "ebuff-menu" "ebuff-menu.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from ebuff-menu.el
  
  (autoload (quote electric-buffer-list) "ebuff-menu" "\
@@@ -8348,7 -8426,7 +8366,7 @@@ Run hooks in `electric-buffer-menu-mode
  ;;;***
  \f
  ;;;### (autoloads (Electric-command-history-redo-expression) "echistory"
- ;;;;;;  "echistory.el" (17781 39501))
+ ;;;;;;  "echistory.el" (17843 45610))
  ;;; Generated autoloads from echistory.el
  
  (autoload (quote Electric-command-history-redo-expression) "echistory" "\
@@@ -8361,7 -8439,7 +8379,7 @@@ With prefix arg NOCONFIRM, execute curr
  \f
  ;;;### (autoloads (edebug-all-forms edebug-all-defs edebug-eval-top-level-form
  ;;;;;;  edebug-basic-spec edebug-all-forms edebug-all-defs) "edebug"
- ;;;;;;  "emacs-lisp/edebug.el" (17632 41885))
+ ;;;;;;  "emacs-lisp/edebug.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/edebug.el
  
  (defvar edebug-all-defs nil "\
@@@ -8434,7 -8512,7 +8452,7 @@@ Toggle edebugging of all forms
  ;;;;;;  ediff-merge-directory-revisions ediff-merge-directories-with-ancestor
  ;;;;;;  ediff-merge-directories ediff-directories3 ediff-directory-revisions
  ;;;;;;  ediff-directories ediff-buffers3 ediff-buffers ediff-backup
- ;;;;;;  ediff-files3 ediff-files) "ediff" "ediff.el" (17752 39351))
+ ;;;;;;  ediff-files3 ediff-files) "ediff" "ediff.el" (17843 45610))
  ;;; Generated autoloads from ediff.el
  
  (autoload (quote ediff-files) "ediff" "\
@@@ -8672,7 -8750,7 +8690,7 @@@ With optional NODE, goes to that node
  ;;;***
  \f
  ;;;### (autoloads (ediff-customize) "ediff-help" "ediff-help.el"
- ;;;;;;  (17403 27596))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from ediff-help.el
  
  (autoload (quote ediff-customize) "ediff-help" "\
@@@ -8682,7 -8760,7 +8700,7 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads nil "ediff-hook" "ediff-hook.el" (17403 27596))
+ ;;;### (autoloads nil "ediff-hook" "ediff-hook.el" (17843 45610))
  ;;; Generated autoloads from ediff-hook.el
  
  (defvar ediff-window-setup-function)
  ;;;***
  \f
  ;;;### (autoloads (ediff-show-registry) "ediff-mult" "ediff-mult.el"
- ;;;;;;  (17726 28398))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from ediff-mult.el
  
  (autoload (quote ediff-show-registry) "ediff-mult" "\
@@@ -8708,7 -8786,7 +8726,7 @@@ Display Ediff's registry
  ;;;***
  \f
  ;;;### (autoloads (ediff-toggle-use-toolbar ediff-toggle-multiframe)
- ;;;;;;  "ediff-util" "ediff-util.el" (17679 3707))
+ ;;;;;;  "ediff-util" "ediff-util.el" (17843 45610))
  ;;; Generated autoloads from ediff-util.el
  
  (autoload (quote ediff-toggle-multiframe) "ediff-util" "\
@@@ -8729,7 -8807,7 +8747,7 @@@ To change the default, set the variabl
  \f
  ;;;### (autoloads (format-kbd-macro read-kbd-macro edit-named-kbd-macro
  ;;;;;;  edit-last-kbd-macro edit-kbd-macro) "edmacro" "edmacro.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from edmacro.el
  
  (defvar edmacro-eight-bits nil "\
@@@ -8782,7 -8860,7 +8800,7 @@@ or nil, use a compact 80-column format
  ;;;***
  \f
  ;;;### (autoloads (edt-emulation-on edt-set-scroll-margins) "edt"
- ;;;;;;  "emulation/edt.el" (17794 54379))
+ ;;;;;;  "emulation/edt.el" (17843 45615))
  ;;; Generated autoloads from emulation/edt.el
  
  (autoload (quote edt-set-scroll-margins) "edt" "\
@@@ -8800,7 -8878,7 +8818,7 @@@ Turn on EDT Emulation
  ;;;***
  \f
  ;;;### (autoloads (electric-helpify with-electric-help) "ehelp" "ehelp.el"
- ;;;;;;  (17771 1419))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from ehelp.el
  
  (autoload (quote with-electric-help) "ehelp" "\
@@@ -8838,7 -8916,7 +8856,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (turn-on-eldoc-mode eldoc-mode eldoc-minor-mode-string)
- ;;;;;;  "eldoc" "emacs-lisp/eldoc.el" (17785 34467))
+ ;;;;;;  "eldoc" "emacs-lisp/eldoc.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/eldoc.el
  
  (defvar eldoc-minor-mode-string " ElDoc" "\
@@@ -8876,8 -8954,8 +8894,8 @@@ Emacs Lisp mode) that support Eldoc."
  
  ;;;***
  \f
- ;;;### (autoloads (elide-head) "elide-head" "elide-head.el" (17781
- ;;;;;;  39501))
+ ;;;### (autoloads (elide-head) "elide-head" "elide-head.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from elide-head.el
  
  (autoload (quote elide-head) "elide-head" "\
@@@ -8893,7 -8971,7 +8911,7 @@@ This is suitable as an entry on `find-f
  ;;;***
  \f
  ;;;### (autoloads (elint-initialize) "elint" "emacs-lisp/elint.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/elint.el
  
  (autoload (quote elint-initialize) "elint" "\
@@@ -8904,8 -8982,8 +8922,8 @@@ Initialize elint
  ;;;***
  \f
  ;;;### (autoloads (elp-results elp-instrument-package elp-instrument-list
- ;;;;;;  elp-instrument-function) "elp" "emacs-lisp/elp.el" (17385
- ;;;;;;  8490))
+ ;;;;;;  elp-instrument-function) "elp" "emacs-lisp/elp.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emacs-lisp/elp.el
  
  (autoload (quote elp-instrument-function) "elp" "\
@@@ -8939,7 -9017,7 +8957,7 @@@ displayed
  ;;;***
  \f
  ;;;### (autoloads (report-emacs-bug) "emacsbug" "mail/emacsbug.el"
- ;;;;;;  (17743 18143))
+ ;;;;;;  (17843 45621))
  ;;; Generated autoloads from mail/emacsbug.el
  
  (autoload (quote report-emacs-bug) "emacsbug" "\
@@@ -9032,7 -9110,7 +9050,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (encoded-kbd-mode) "encoded-kb" "international/encoded-kb.el"
- ;;;;;;  (17792 9561))
+ ;;;;;;  (17843 45618))
  ;;; Generated autoloads from international/encoded-kb.el
  
  (defvar encoded-kbd-mode nil "\
@@@ -9061,7 -9139,7 +9079,7 @@@ as a multilingual text encoded in a cod
  ;;;***
  \f
  ;;;### (autoloads (enriched-decode enriched-encode enriched-mode)
- ;;;;;;  "enriched" "textmodes/enriched.el" (17786 56015))
+ ;;;;;;  "enriched" "textmodes/enriched.el" (17843 45630))
  ;;; Generated autoloads from textmodes/enriched.el
  
  (autoload (quote enriched-mode) "enriched" "\
@@@ -9092,7 -9170,7 +9110,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (erc-handle-irc-url erc erc-select-read-args) "erc"
- ;;;;;;  "erc/erc.el" (17792 9561))
+ ;;;;;;  "erc/erc.el" (17839 38671))
  ;;; Generated autoloads from erc/erc.el
  
  (autoload (quote erc-select-read-args) "erc" "\
@@@ -9128,27 -9206,33 +9146,33 @@@ Otherwise, connect to HOST:PORT as USE
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-autoaway" "erc/erc-autoaway.el" (17761
- ;;;;;;  54014))
+ ;;;### (autoloads nil "erc-autoaway" "erc/erc-autoaway.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from erc/erc-autoaway.el
   (autoload 'erc-autoaway-mode "erc-autoaway")
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-button" "erc/erc-button.el" (17447 52274))
+ ;;;### (autoloads nil "erc-button" "erc/erc-button.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-button.el
   (autoload 'erc-button-mode "erc-button" nil t)
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-compat" "erc/erc-compat.el" (17761 54014))
+ ;;;### (autoloads nil "erc-capab" "erc/erc-capab.el" (17843 45616))
+ ;;; Generated autoloads from erc/erc-capab.el
+  (autoload 'erc-capab-identify-mode "erc-capab" nil t)
+ ;;;***
\f
+ ;;;### (autoloads nil "erc-compat" "erc/erc-compat.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-compat.el
   (autoload 'erc-define-minor-mode "erc-compat")
  
  ;;;***
  \f
  ;;;### (autoloads (erc-ctcp-query-DCC pcomplete/erc-mode/DCC erc-cmd-DCC)
- ;;;;;;  "erc-dcc" "erc/erc-dcc.el" (17785 34467))
+ ;;;;;;  "erc-dcc" "erc/erc-dcc.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-dcc.el
  
  (autoload (quote erc-cmd-DCC) "erc-dcc" "\
@@@ -9180,7 -9264,7 +9204,7 @@@ that subcommand
  ;;;;;;  erc-ezb-add-session erc-ezb-end-of-session-list erc-ezb-init-session-list
  ;;;;;;  erc-ezb-identify erc-ezb-notice-autodetect erc-ezb-lookup-action
  ;;;;;;  erc-ezb-get-login erc-cmd-ezb) "erc-ezbounce" "erc/erc-ezbounce.el"
- ;;;;;;  (17789 35159))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from erc/erc-ezbounce.el
  
  (autoload (quote erc-cmd-ezb) "erc-ezbounce" "\
@@@ -9242,8 -9326,8 +9266,8 @@@ Add EZBouncer convenience functions to 
  
  ;;;***
  \f
- ;;;### (autoloads (erc-fill) "erc-fill" "erc/erc-fill.el" (17761
- ;;;;;;  54014))
+ ;;;### (autoloads (erc-fill) "erc-fill" "erc/erc-fill.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from erc/erc-fill.el
   (autoload 'erc-fill-mode "erc-fill" nil t)
  
@@@ -9255,15 -9339,15 +9279,15 @@@ You can put this on `erc-insert-modify-
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-hecomplete" "erc/erc-hecomplete.el" (17391
- ;;;;;;  39324))
+ ;;;### (autoloads nil "erc-hecomplete" "erc/erc-hecomplete.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from erc/erc-hecomplete.el
   (autoload 'erc-hecomplete-mode "erc-hecomplete" nil t)
  
  ;;;***
  \f
  ;;;### (autoloads (erc-identd-stop erc-identd-start) "erc-identd"
- ;;;;;;  "erc/erc-identd.el" (17601 9092))
+ ;;;;;;  "erc/erc-identd.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-identd.el
   (autoload 'erc-identd-mode "erc-identd")
  
@@@ -9285,7 -9369,7 +9309,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (erc-create-imenu-index) "erc-imenu" "erc/erc-imenu.el"
- ;;;;;;  (17601 9092))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from erc/erc-imenu.el
  
  (autoload (quote erc-create-imenu-index) "erc-imenu" "\
@@@ -9295,14 -9379,14 +9319,14 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-join" "erc/erc-join.el" (17468 10541))
+ ;;;### (autoloads nil "erc-join" "erc/erc-join.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-join.el
   (autoload 'erc-autojoin-mode "erc-join" nil t)
  
  ;;;***
  \f
  ;;;### (autoloads (erc-save-buffer-in-logs erc-logging-enabled) "erc-log"
- ;;;;;;  "erc/erc-log.el" (17761 54014))
+ ;;;;;;  "erc/erc-log.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-log.el
   (autoload 'erc-log-mode "erc-log" nil t)
  
@@@ -9334,7 -9418,7 +9358,7 @@@ You can save every individual message b
  ;;;### (autoloads (erc-delete-dangerous-host erc-add-dangerous-host
  ;;;;;;  erc-delete-keyword erc-add-keyword erc-delete-fool erc-add-fool
  ;;;;;;  erc-delete-pal erc-add-pal) "erc-match" "erc/erc-match.el"
- ;;;;;;  (17632 41885))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from erc/erc-match.el
   (autoload 'erc-match-mode "erc-match")
  
@@@ -9378,10 -9462,16 +9402,16 @@@ Delete dangerous-host interactively to 
  
  \(fn)" t nil)
  
+ ;;;***
\f
+ ;;;### (autoloads nil "erc-menu" "erc/erc-menu.el" (17843 45616))
+ ;;; Generated autoloads from erc/erc-menu.el
+  (autoload 'erc-menu-mode "erc-menu" nil t)
  ;;;***
  \f
  ;;;### (autoloads (erc-cmd-WHOLEFT) "erc-netsplit" "erc/erc-netsplit.el"
- ;;;;;;  (17468 10541))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from erc/erc-netsplit.el
   (autoload 'erc-netsplit-mode "erc-netsplit")
  
@@@ -9393,7 -9483,7 +9423,7 @@@ Show who's gone
  ;;;***
  \f
  ;;;### (autoloads (erc-server-select erc-determine-network) "erc-networks"
- ;;;;;;  "erc/erc-networks.el" (17761 54014))
+ ;;;;;;  "erc/erc-networks.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-networks.el
  
  (autoload (quote erc-determine-network) "erc-networks" "\
@@@ -9411,7 -9501,7 +9441,7 @@@ Interactively select a server to connec
  ;;;***
  \f
  ;;;### (autoloads (pcomplete/erc-mode/NOTIFY erc-cmd-NOTIFY) "erc-notify"
- ;;;;;;  "erc/erc-notify.el" (17391 39324))
+ ;;;;;;  "erc/erc-notify.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-notify.el
   (autoload 'erc-notify-mode "erc-notify" nil t)
  
@@@ -9429,33 -9519,33 +9459,33 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-page" "erc/erc-page.el" (17391 39324))
+ ;;;### (autoloads nil "erc-page" "erc/erc-page.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-page.el
   (autoload 'erc-page-mode "erc-page")
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-pcomplete" "erc/erc-pcomplete.el" (17601
- ;;;;;;  9092))
+ ;;;### (autoloads nil "erc-pcomplete" "erc/erc-pcomplete.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from erc/erc-pcomplete.el
   (autoload 'erc-completion-mode "erc-pcomplete" nil t)
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-replace" "erc/erc-replace.el" (17761 54014))
+ ;;;### (autoloads nil "erc-replace" "erc/erc-replace.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-replace.el
   (autoload 'erc-replace-mode "erc-replace")
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-ring" "erc/erc-ring.el" (17391 39324))
+ ;;;### (autoloads nil "erc-ring" "erc/erc-ring.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-ring.el
   (autoload 'erc-ring-mode "erc-ring" nil t)
  
  ;;;***
  \f
  ;;;### (autoloads (erc-nickserv-identify erc-nickserv-identify-mode)
- ;;;;;;  "erc-services" "erc/erc-services.el" (17391 39324))
+ ;;;;;;  "erc-services" "erc/erc-services.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-services.el
   (autoload 'erc-services-mode "erc-services" nil t)
  
@@@ -9472,14 -9562,14 +9502,14 @@@ When called interactively, read the pas
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-sound" "erc/erc-sound.el" (17761 54014))
+ ;;;### (autoloads nil "erc-sound" "erc/erc-sound.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-sound.el
   (autoload 'erc-sound-mode "erc-sound")
  
  ;;;***
  \f
  ;;;### (autoloads (erc-speedbar-browser) "erc-speedbar" "erc/erc-speedbar.el"
- ;;;;;;  (17391 39324))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from erc/erc-speedbar.el
  
  (autoload (quote erc-speedbar-browser) "erc-speedbar" "\
@@@ -9490,20 -9580,20 +9520,20 @@@ This will add a speedbar major display 
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-spelling" "erc/erc-spelling.el" (17618
- ;;;;;;  8193))
+ ;;;### (autoloads nil "erc-spelling" "erc/erc-spelling.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from erc/erc-spelling.el
   (autoload 'erc-spelling-mode "erc-spelling" nil t)
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-stamp" "erc/erc-stamp.el" (17785 34467))
+ ;;;### (autoloads nil "erc-stamp" "erc/erc-stamp.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-stamp.el
   (autoload 'erc-timestamp-mode "erc-stamp" nil t)
  
  ;;;***
  \f
- ;;;### (autoloads nil "erc-track" "erc/erc-track.el" (17761 54014))
+ ;;;### (autoloads nil "erc-track" "erc/erc-track.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-track.el
   (autoload 'erc-track-mode "erc-track" nil t)
   (autoload 'erc-track-when-inactive-mode "erc-track" nil t)
  ;;;***
  \f
  ;;;### (autoloads (erc-truncate-buffer erc-truncate-buffer-to-size)
- ;;;;;;  "erc-truncate" "erc/erc-truncate.el" (17743 18143))
+ ;;;;;;  "erc-truncate" "erc/erc-truncate.el" (17843 45616))
  ;;; Generated autoloads from erc/erc-truncate.el
   (autoload 'erc-truncate-mode "erc-truncate" nil t)
  
@@@ -9531,7 -9621,7 +9561,7 @@@ Meant to be used in hooks, like `erc-in
  ;;;***
  \f
  ;;;### (autoloads (erc-xdcc-add-file) "erc-xdcc" "erc/erc-xdcc.el"
- ;;;;;;  (17391 39324))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from erc/erc-xdcc.el
  
  (autoload (quote erc-xdcc-add-file) "erc-xdcc" "\
@@@ -9541,8 -9631,8 +9571,8 @@@ Add a file to `erc-xdcc-files'
  
  ;;;***
  \f
- ;;;### (autoloads (eshell-mode) "esh-mode" "eshell/esh-mode.el" (17385
- ;;;;;;  8492))
+ ;;;### (autoloads (eshell-mode) "esh-mode" "eshell/esh-mode.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from eshell/esh-mode.el
  
  (autoload (quote eshell-mode) "esh-mode" "\
@@@ -9554,8 -9644,8 +9584,8 @@@ Emacs shell interactive mode
  
  ;;;***
  \f
- ;;;### (autoloads (eshell-test) "esh-test" "eshell/esh-test.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (eshell-test) "esh-test" "eshell/esh-test.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from eshell/esh-test.el
  
  (autoload (quote eshell-test) "esh-test" "\
@@@ -9566,7 -9656,7 +9596,7 @@@ Test Eshell to verify that it works as 
  ;;;***
  \f
  ;;;### (autoloads (eshell-report-bug eshell-command-result eshell-command
- ;;;;;;  eshell) "eshell" "eshell/eshell.el" (17786 56015))
+ ;;;;;;  eshell) "eshell" "eshell/eshell.el" (17843 45616))
  ;;; Generated autoloads from eshell/eshell.el
  
  (autoload (quote eshell) "eshell" "\
@@@ -9612,7 -9702,7 +9642,7 @@@ Please include any configuration detail
  ;;;;;;  visit-tags-table tags-table-mode find-tag-default-function
  ;;;;;;  find-tag-hook tags-add-tables tags-compression-info-list
  ;;;;;;  tags-table-list tags-case-fold-search) "etags" "progmodes/etags.el"
- ;;;;;;  (17408 40149))
+ ;;;;;;  (17843 45627))
  ;;; Generated autoloads from progmodes/etags.el
  
  (defvar tags-file-name nil "\
@@@ -9627,7 -9717,7 +9657,7 @@@ Use the `etags' program to make a tags 
  A value of t means case-insensitive, a value of nil means case-sensitive.
  Any other value means use the setting of `case-fold-search'.")
  
- (custom-autoload (quote tags-case-fold-search) "etags")
+ (custom-autoload (quote tags-case-fold-search) "etags" t)
  
  (defvar tags-table-list nil "\
  *List of file names of tags tables to search.
@@@ -9636,7 -9726,7 +9666,7 @@@ To switch to a new list of tags tables
  If you set this variable, do not also set `tags-file-name'.
  Use the `etags' program to make a tags table file.")
  
- (custom-autoload (quote tags-table-list) "etags")
+ (custom-autoload (quote tags-table-list) "etags" t)
  
  (defvar tags-compression-info-list (quote ("" ".Z" ".bz2" ".gz" ".tgz")) "\
  *List of extensions tried by etags when jka-compr is used.
@@@ -9645,7 -9735,7 +9675,7 @@@ These extensions will be tried only if 
  \(i.e. via customize of `auto-compression-mode' or by calling the function
  `auto-compression-mode').")
  
- (custom-autoload (quote tags-compression-info-list) "etags")
+ (custom-autoload (quote tags-compression-info-list) "etags" t)
  
  (defvar tags-add-tables (quote ask-user) "\
  *Control whether to add a new tags table to the current list.
@@@ -9653,14 -9743,14 +9683,14 @@@ t means do; nil means don't (always sta
  Any other value means ask the user whether to add a new tags table
  to the current list (as opposed to starting a new list).")
  
- (custom-autoload (quote tags-add-tables) "etags")
+ (custom-autoload (quote tags-add-tables) "etags" t)
  
  (defvar find-tag-hook nil "\
  *Hook to be run by \\[find-tag] after finding a tag.  See `run-hooks'.
  The value in the buffer in which \\[find-tag] is done is used,
  not the value in the buffer \\[find-tag] goes to.")
  
- (custom-autoload (quote find-tag-hook) "etags")
+ (custom-autoload (quote find-tag-hook) "etags" t)
  
  (defvar find-tag-default-function nil "\
  *A function of no arguments used by \\[find-tag] to pick a default tag.
@@@ -9668,7 -9758,7 +9698,7 @@@ If nil, and the symbol that is the valu
  has a `find-tag-default-function' property (see `put'), that is used.
  Otherwise, `find-tag-default' is used.")
  
- (custom-autoload (quote find-tag-default-function) "etags")
+ (custom-autoload (quote find-tag-default-function) "etags" t)
  
  (autoload (quote tags-table-mode) "etags" "\
  Major mode for tags table file buffers.
@@@ -9914,7 -10004,7 +9944,7 @@@ for \\[find-tag] (which see)
  ;;;;;;  ethio-fidel-to-sera-buffer ethio-fidel-to-sera-region ethio-sera-to-fidel-marker
  ;;;;;;  ethio-sera-to-fidel-mail ethio-sera-to-fidel-mail-or-marker
  ;;;;;;  ethio-sera-to-fidel-buffer ethio-sera-to-fidel-region setup-ethiopic-environment-internal)
- ;;;;;;  "ethio-util" "language/ethio-util.el" (17792 9562))
+ ;;;;;;  "ethio-util" "language/ethio-util.el" (17843 45620))
  ;;; Generated autoloads from language/ethio-util.el
  
  (autoload (quote setup-ethiopic-environment-internal) "ethio-util" "\
@@@ -10109,7 -10199,7 +10139,7 @@@ Transcribe Ethiopic characters in ASCI
  \f
  ;;;### (autoloads (eudc-load-eudc eudc-query-form eudc-expand-inline
  ;;;;;;  eudc-get-phone eudc-get-email eudc-set-server) "eudc" "net/eudc.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45624))
  ;;; Generated autoloads from net/eudc.el
  
  (autoload (quote eudc-set-server) "eudc" "\
@@@ -10165,7 -10255,7 +10195,7 @@@ This does nothing except loading eudc b
  \f
  ;;;### (autoloads (eudc-display-jpeg-as-button eudc-display-jpeg-inline
  ;;;;;;  eudc-display-sound eudc-display-mail eudc-display-url eudc-display-generic-binary)
- ;;;;;;  "eudc-bob" "net/eudc-bob.el" (17786 56015))
+ ;;;;;;  "eudc-bob" "net/eudc-bob.el" (17843 45624))
  ;;; Generated autoloads from net/eudc-bob.el
  
  (autoload (quote eudc-display-generic-binary) "eudc-bob" "\
@@@ -10201,7 -10291,7 +10231,7 @@@ Display a button for the JPEG DATA
  ;;;***
  \f
  ;;;### (autoloads (eudc-try-bbdb-insert eudc-insert-record-at-point-into-bbdb)
- ;;;;;;  "eudc-export" "net/eudc-export.el" (17786 56015))
+ ;;;;;;  "eudc-export" "net/eudc-export.el" (17843 45624))
  ;;; Generated autoloads from net/eudc-export.el
  
  (autoload (quote eudc-insert-record-at-point-into-bbdb) "eudc-export" "\
@@@ -10218,7 -10308,7 +10248,7 @@@ Call `eudc-insert-record-at-point-into-
  ;;;***
  \f
  ;;;### (autoloads (eudc-edit-hotlist) "eudc-hotlist" "net/eudc-hotlist.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45624))
  ;;; Generated autoloads from net/eudc-hotlist.el
  
  (autoload (quote eudc-edit-hotlist) "eudc-hotlist" "\
@@@ -10228,8 -10318,8 +10258,8 @@@ Edit the hotlist of directory servers i
  
  ;;;***
  \f
- ;;;### (autoloads (ewoc-create) "ewoc" "emacs-lisp/ewoc.el" (17785
- ;;;;;;  34467))
+ ;;;### (autoloads (ewoc-create) "ewoc" "emacs-lisp/ewoc.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emacs-lisp/ewoc.el
  
  (autoload (quote ewoc-create) "ewoc" "\
@@@ -10258,7 -10348,7 +10288,7 @@@ fourth arg NOSEP non-nil inhibits this
  ;;;### (autoloads (executable-make-buffer-file-executable-if-script-p
  ;;;;;;  executable-self-display executable-set-magic executable-interpret
  ;;;;;;  executable-command-find-posix-p) "executable" "progmodes/executable.el"
- ;;;;;;  (17394 12937))
+ ;;;;;;  (17843 45627))
  ;;; Generated autoloads from progmodes/executable.el
  
  (autoload (quote executable-command-find-posix-p) "executable" "\
@@@ -10300,7 -10390,7 +10330,7 @@@ file modes
  ;;;***
  \f
  ;;;### (autoloads (expand-jump-to-next-slot expand-jump-to-previous-slot
- ;;;;;;  expand-add-abbrevs) "expand" "expand.el" (17781 39501))
+ ;;;;;;  expand-add-abbrevs) "expand" "expand.el" (17843 45610))
  ;;; Generated autoloads from expand.el
  
  (autoload (quote expand-add-abbrevs) "expand" "\
@@@ -10343,7 -10433,7 +10373,7 @@@ This is used only in conjunction with `
  
  ;;;***
  \f
- ;;;### (autoloads (f90-mode) "f90" "progmodes/f90.el" (17781 39502))
+ ;;;### (autoloads (f90-mode) "f90" "progmodes/f90.el" (17843 45627))
  ;;; Generated autoloads from progmodes/f90.el
  
  (autoload (quote f90-mode) "f90" "\
@@@ -10410,7 -10500,7 +10440,7 @@@ with no args, if that value is non-nil
  ;;;;;;  facemenu-remove-all facemenu-remove-face-props facemenu-set-read-only
  ;;;;;;  facemenu-set-intangible facemenu-set-invisible facemenu-set-face-from-menu
  ;;;;;;  facemenu-set-background facemenu-set-foreground facemenu-set-face)
- ;;;;;;  "facemenu" "facemenu.el" (17780 31980))
+ ;;;;;;  "facemenu" "facemenu.el" (17843 45610))
  ;;; Generated autoloads from facemenu.el
   (define-key global-map "\M-o" 'facemenu-keymap)
   (autoload 'facemenu-keymap "facemenu" "Keymap for face-changing commands." t 'keymap)
@@@ -10578,7 -10668,7 +10608,7 @@@ argument BUFFER-NAME is nil, it default
  ;;;***
  \f
  ;;;### (autoloads (turn-on-fast-lock fast-lock-mode) "fast-lock"
- ;;;;;;  "obsolete/fast-lock.el" (17786 56015))
+ ;;;;;;  "obsolete/fast-lock.el" (17843 45625))
  ;;; Generated autoloads from obsolete/fast-lock.el
  
  (autoload (quote fast-lock-mode) "fast-lock" "\
@@@ -10673,7 -10763,7 +10703,7 @@@ you can set `feedmail-queue-reminder-al
  ;;;***
  \f
  ;;;### (autoloads (ffap-bindings dired-at-point ffap-at-mouse ffap-menu
- ;;;;;;  find-file-at-point ffap-next) "ffap" "ffap.el" (17781 39501))
+ ;;;;;;  find-file-at-point ffap-next) "ffap" "ffap.el" (17838 18033))
  ;;; Generated autoloads from ffap.el
  
  (autoload (quote ffap-next) "ffap" "\
@@@ -10732,7 -10822,7 +10762,7 @@@ Evaluate the forms in variable `ffap-bi
  ;;;### (autoloads (file-cache-minibuffer-complete file-cache-add-directory-recursively
  ;;;;;;  file-cache-add-directory-using-locate file-cache-add-directory-using-find
  ;;;;;;  file-cache-add-file file-cache-add-directory-list file-cache-add-directory)
- ;;;;;;  "filecache" "filecache.el" (17781 39501))
+ ;;;;;;  "filecache" "filecache.el" (17843 45610))
  ;;; Generated autoloads from filecache.el
  
  (autoload (quote file-cache-add-directory) "filecache" "\
@@@ -10791,8 -10881,8 +10821,8 @@@ the name is considered already unique; 
  
  ;;;***
  \f
- ;;;### (autoloads (filesets-init) "filesets" "filesets.el" (17714
- ;;;;;;  34817))
+ ;;;### (autoloads (filesets-init) "filesets" "filesets.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from filesets.el
  
  (autoload (quote filesets-init) "filesets" "\
@@@ -10803,7 -10893,7 +10833,7 @@@ Set up hooks, load the cache file -- i
  
  ;;;***
  \f
- ;;;### (autoloads nil "fill" "textmodes/fill.el" (17743 45092))
+ ;;;### (autoloads nil "fill" "textmodes/fill.el" (17843 45630))
  ;;; Generated autoloads from textmodes/fill.el
  (put 'colon-double-space 'safe-local-variable 'booleanp)
  
  \f
  ;;;### (autoloads (find-grep-dired find-name-dired find-dired find-grep-options
  ;;;;;;  find-ls-subdir-switches find-ls-option) "find-dired" "find-dired.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from find-dired.el
  
  (defvar find-ls-option (if (eq system-type (quote berkeley-unix)) (quote ("-ls" . "-gilsb")) (quote ("-exec ls -ld {} \\;" . "-ld"))) "\
@@@ -10872,7 -10962,7 +10902,7 @@@ Thus ARG can also contain additional gr
  \f
  ;;;### (autoloads (ff-mouse-find-other-file-other-window ff-mouse-find-other-file
  ;;;;;;  ff-find-other-file ff-get-other-file) "find-file" "find-file.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from find-file.el
  
  (defvar ff-special-constructs (quote (("^#\\s *\\(include\\|import\\)\\s +[<\"]\\(.*\\)[>\"]" lambda nil (buffer-substring (match-beginning 2) (match-end 2))))) "\
@@@ -10966,7 -11056,7 +10996,7 @@@ Visit the file you click on in another 
  ;;;;;;  find-variable find-variable-noselect find-function-other-frame
  ;;;;;;  find-function-other-window find-function find-function-noselect
  ;;;;;;  find-function-search-for-symbol find-library) "find-func"
- ;;;;;;  "emacs-lisp/find-func.el" (17786 56015))
+ ;;;;;;  "emacs-lisp/find-func.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/find-func.el
  
  (autoload (quote find-library) "find-func" "\
@@@ -11120,7 -11210,7 +11150,7 @@@ Define some key bindings for the find-f
  ;;;***
  \f
  ;;;### (autoloads (find-lisp-find-dired-filter find-lisp-find-dired-subdirectories
- ;;;;;;  find-lisp-find-dired) "find-lisp" "find-lisp.el" (17781 39501))
+ ;;;;;;  find-lisp-find-dired) "find-lisp" "find-lisp.el" (17843 45610))
  ;;; Generated autoloads from find-lisp.el
  
  (autoload (quote find-lisp-find-dired) "find-lisp" "\
@@@ -11141,7 -11231,7 +11171,7 @@@ Change the filter on a find-lisp-find-d
  ;;;***
  \f
  ;;;### (autoloads (finder-by-keyword finder-commentary finder-list-keywords)
- ;;;;;;  "finder" "finder.el" (17476 4797))
+ ;;;;;;  "finder" "finder.el" (17843 45610))
  ;;; Generated autoloads from finder.el
  
  (autoload (quote finder-list-keywords) "finder" "\
@@@ -11163,7 -11253,7 +11193,7 @@@ Find packages matching a given keyword
  ;;;***
  \f
  ;;;### (autoloads (enable-flow-control-on enable-flow-control) "flow-ctrl"
- ;;;;;;  "flow-ctrl.el" (17781 39501))
+ ;;;;;;  "flow-ctrl.el" (17843 45610))
  ;;; Generated autoloads from flow-ctrl.el
  
  (autoload (quote enable-flow-control) "flow-ctrl" "\
@@@ -11185,7 -11275,7 +11215,7 @@@ to get the effect of a C-q
  ;;;***
  \f
  ;;;### (autoloads (fill-flowed fill-flowed-encode) "flow-fill" "gnus/flow-fill.el"
- ;;;;;;  (17476 4798))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from gnus/flow-fill.el
  
  (autoload (quote fill-flowed-encode) "flow-fill" "\
@@@ -11201,7 -11291,7 +11231,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (flymake-mode-off flymake-mode-on flymake-mode)
- ;;;;;;  "flymake" "progmodes/flymake.el" (17770 2412))
+ ;;;;;;  "flymake" "progmodes/flymake.el" (17843 45627))
  ;;; Generated autoloads from progmodes/flymake.el
  
  (autoload (quote flymake-mode) "flymake" "\
@@@ -11225,7 -11315,7 +11255,7 @@@ Turn flymake mode off
  \f
  ;;;### (autoloads (flyspell-buffer flyspell-region flyspell-mode-off
  ;;;;;;  turn-off-flyspell turn-on-flyspell flyspell-mode flyspell-prog-mode)
- ;;;;;;  "flyspell" "textmodes/flyspell.el" (17786 56015))
+ ;;;;;;  "flyspell" "textmodes/flyspell.el" (17843 45630))
  ;;; Generated autoloads from textmodes/flyspell.el
  
  (autoload (quote flyspell-prog-mode) "flyspell" "\
@@@ -11294,7 -11384,7 +11324,7 @@@ Flyspell whole buffer
  \f
  ;;;### (autoloads (follow-delete-other-windows-and-split follow-mode
  ;;;;;;  turn-off-follow-mode turn-on-follow-mode) "follow" "follow.el"
- ;;;;;;  (17743 18143))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from follow.el
  
  (autoload (quote turn-on-follow-mode) "follow" "\
@@@ -11368,8 -11458,8 +11398,8 @@@ in your `~/.emacs' file, replacing [f7
  
  ;;;***
  \f
- ;;;### (autoloads (footnote-mode) "footnote" "mail/footnote.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (footnote-mode) "footnote" "mail/footnote.el" (17843
+ ;;;;;;  45621))
  ;;; Generated autoloads from mail/footnote.el
  
  (autoload (quote footnote-mode) "footnote" "\
@@@ -11390,7 -11480,7 +11420,7 @@@ key          bindin
  ;;;***
  \f
  ;;;### (autoloads (forms-find-file-other-window forms-find-file forms-mode)
- ;;;;;;  "forms" "forms.el" (17781 39501))
+ ;;;;;;  "forms" "forms.el" (17843 45610))
  ;;; Generated autoloads from forms.el
  
  (autoload (quote forms-mode) "forms" "\
@@@ -11427,7 -11517,7 +11457,7 @@@ Visit a file in Forms mode in other win
  ;;;***
  \f
  ;;;### (autoloads (fortran-mode fortran-tab-mode-default) "fortran"
- ;;;;;;  "progmodes/fortran.el" (17781 39502))
+ ;;;;;;  "progmodes/fortran.el" (17843 45628))
  ;;; Generated autoloads from progmodes/fortran.el
  
  (defvar fortran-tab-mode-default nil "\
@@@ -11513,7 -11603,7 +11543,7 @@@ with no args, if that value is non-nil
  ;;;***
  \f
  ;;;### (autoloads (fortune fortune-to-signature fortune-compile fortune-from-region
- ;;;;;;  fortune-add-fortune) "fortune" "play/fortune.el" (17385 8495))
+ ;;;;;;  fortune-add-fortune) "fortune" "play/fortune.el" (17843 45625))
  ;;; Generated autoloads from play/fortune.el
  
  (autoload (quote fortune-add-fortune) "fortune" "\
@@@ -11563,7 -11653,7 +11593,7 @@@ and choose the directory as the fortune
  ;;;***
  \f
  ;;;### (autoloads (gdb-enable-debug gdba) "gdb-ui" "progmodes/gdb-ui.el"
- ;;;;;;  (17780 18172))
+ ;;;;;;  (17844 62923))
  ;;; Generated autoloads from progmodes/gdb-ui.el
  
  (autoload (quote gdba) "gdb-ui" "\
@@@ -11619,15 -11709,15 +11649,15 @@@ detailed description of this mode
  \(fn COMMAND-LINE)" t nil)
  
  (defvar gdb-enable-debug nil "\
- Non-nil means record the process input and output in `gdb-debug-ring'.")
+ Non-nil means record the process input and output in `gdb-debug-log'.")
  
  (custom-autoload (quote gdb-enable-debug) "gdb-ui" t)
  
  ;;;***
  \f
  ;;;### (autoloads (generic-make-keywords-list generic-mode generic-mode-internal
- ;;;;;;  define-generic-mode) "generic" "emacs-lisp/generic.el" (17785
- ;;;;;;  34467))
+ ;;;;;;  define-generic-mode) "generic" "emacs-lisp/generic.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emacs-lisp/generic.el
  
  (defvar generic-mode-list nil "\
@@@ -11702,7 -11792,7 +11732,7 @@@ regular expression that can be used as 
  ;;;***
  \f
  ;;;### (autoloads (glasses-mode) "glasses" "progmodes/glasses.el"
- ;;;;;;  (17788 21816))
+ ;;;;;;  (17843 45628))
  ;;; Generated autoloads from progmodes/glasses.el
  
  (autoload (quote glasses-mode) "glasses" "\
@@@ -11715,7 -11805,7 +11745,7 @@@ at places they belong to
  ;;;***
  \f
  ;;;### (autoloads (gmm-tool-bar-from-list gmm-widget-p gmm-error
- ;;;;;;  gmm-message) "gmm-utils" "gnus/gmm-utils.el" (17714 34817))
+ ;;;;;;  gmm-message) "gmm-utils" "gnus/gmm-utils.el" (17843 45616))
  ;;; Generated autoloads from gnus/gmm-utils.el
  
  (autoload (quote gmm-message) "gmm-utils" "\
@@@ -11762,7 -11852,7 +11792,7 @@@ DEFAULT-MAP specifies the default key m
  ;;;***
  \f
  ;;;### (autoloads (gnus gnus-other-frame gnus-slave gnus-no-server
- ;;;;;;  gnus-slave-no-server) "gnus" "gnus/gnus.el" (17767 19634))
+ ;;;;;;  gnus-slave-no-server) "gnus" "gnus/gnus.el" (17843 45617))
  ;;; Generated autoloads from gnus/gnus.el
  (when (fboundp 'custom-autoload)
   (custom-autoload 'gnus-select-method "gnus"))
@@@ -11815,7 -11905,7 +11845,7 @@@ prompt the user for the name of an NNT
  ;;;;;;  gnus-agent-get-undownloaded-list gnus-agent-delete-group
  ;;;;;;  gnus-agent-rename-group gnus-agent-possibly-save-gcc gnus-agentize
  ;;;;;;  gnus-slave-unplugged gnus-plugged gnus-unplugged) "gnus-agent"
- ;;;;;;  "gnus/gnus-agent.el" (17767 19633))
+ ;;;;;;  "gnus/gnus-agent.el" (17843 45616))
  ;;; Generated autoloads from gnus/gnus-agent.el
  
  (autoload (quote gnus-unplugged) "gnus-agent" "\
@@@ -11906,7 -11996,7 +11936,7 @@@ If CLEAN, obsolete (ignore)
  ;;;***
  \f
  ;;;### (autoloads (gnus-article-prepare-display) "gnus-art" "gnus/gnus-art.el"
- ;;;;;;  (17767 19634))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from gnus/gnus-art.el
  
  (autoload (quote gnus-article-prepare-display) "gnus-art" "\
@@@ -11917,7 -12007,7 +11947,7 @@@ Make the current buffer look like a nic
  ;;;***
  \f
  ;;;### (autoloads (gnus-audio-play) "gnus-audio" "gnus/gnus-audio.el"
- ;;;;;;  (17788 21815))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from gnus/gnus-audio.el
  
  (autoload (quote gnus-audio-play) "gnus-audio" "\
@@@ -11929,8 -12019,8 +11959,8 @@@ Play a sound FILE through the speaker
  \f
  ;;;### (autoloads (gnus-cache-delete-group gnus-cache-rename-group
  ;;;;;;  gnus-cache-generate-nov-databases gnus-cache-generate-active
- ;;;;;;  gnus-jog-cache) "gnus-cache" "gnus/gnus-cache.el" (17385
- ;;;;;;  8493))
+ ;;;;;;  gnus-jog-cache) "gnus-cache" "gnus/gnus-cache.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from gnus/gnus-cache.el
  
  (autoload (quote gnus-jog-cache) "gnus-cache" "\
@@@ -11972,7 -12062,7 +12002,7 @@@ supported
  ;;;***
  \f
  ;;;### (autoloads (gnus-delay-initialize gnus-delay-send-queue gnus-delay-article)
- ;;;;;;  "gnus-delay" "gnus/gnus-delay.el" (17385 8493))
+ ;;;;;;  "gnus-delay" "gnus/gnus-delay.el" (17843 45616))
  ;;; Generated autoloads from gnus/gnus-delay.el
  
  (autoload (quote gnus-delay-article) "gnus-delay" "\
@@@ -12008,7 -12098,7 +12038,7 @@@ Checking delayed messages is skipped i
  ;;;***
  \f
  ;;;### (autoloads (gnus-user-format-function-D gnus-user-format-function-d)
- ;;;;;;  "gnus-diary" "gnus/gnus-diary.el" (17797 50970))
+ ;;;;;;  "gnus-diary" "gnus/gnus-diary.el" (17843 45616))
  ;;; Generated autoloads from gnus/gnus-diary.el
  
  (autoload (quote gnus-user-format-function-d) "gnus-diary" "\
@@@ -12024,7 -12114,7 +12054,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (turn-on-gnus-dired-mode) "gnus-dired" "gnus/gnus-dired.el"
- ;;;;;;  (17385 8493))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from gnus/gnus-dired.el
  
  (autoload (quote turn-on-gnus-dired-mode) "gnus-dired" "\
@@@ -12035,7 -12125,7 +12065,7 @@@ Convenience method to turn on gnus-dire
  ;;;***
  \f
  ;;;### (autoloads (gnus-draft-reminder) "gnus-draft" "gnus/gnus-draft.el"
- ;;;;;;  (17698 30385))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from gnus/gnus-draft.el
  
  (autoload (quote gnus-draft-reminder) "gnus-draft" "\
@@@ -12047,8 -12137,8 +12077,8 @@@ Reminder user if there are unsent draft
  \f
  ;;;### (autoloads (gnus-convert-png-to-face gnus-convert-face-to-png
  ;;;;;;  gnus-face-from-file gnus-x-face-from-file gnus-insert-random-x-face-header
- ;;;;;;  gnus-random-x-face) "gnus-fun" "gnus/gnus-fun.el" (17476
- ;;;;;;  4800))
+ ;;;;;;  gnus-random-x-face) "gnus-fun" "gnus/gnus-fun.el" (17843
+ ;;;;;;  45616))
  ;;; Generated autoloads from gnus/gnus-fun.el
  
  (autoload (quote gnus-random-x-face) "gnus-fun" "\
@@@ -12087,7 -12177,7 +12117,7 @@@ FILE should be a PNG file that's 48x48 
  ;;;***
  \f
  ;;;### (autoloads (gnus-fetch-group-other-frame gnus-fetch-group)
- ;;;;;;  "gnus-group" "gnus/gnus-group.el" (17767 19634))
+ ;;;;;;  "gnus-group" "gnus/gnus-group.el" (17843 45617))
  ;;; Generated autoloads from gnus/gnus-group.el
  
  (autoload (quote gnus-fetch-group) "gnus-group" "\
@@@ -12104,7 -12194,7 +12134,7 @@@ Pop up a frame and enter GROUP
  ;;;***
  \f
  ;;;### (autoloads (gnus-batch-score) "gnus-kill" "gnus/gnus-kill.el"
- ;;;;;;  (17788 21815))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-kill.el
  
  (defalias (quote gnus-batch-kill) (quote gnus-batch-score))
@@@ -12119,7 -12209,7 +12149,7 @@@ Usage: emacs -batch -l ~/.emacs -l gnu
  \f
  ;;;### (autoloads (gnus-mailing-list-mode gnus-mailing-list-insinuate
  ;;;;;;  turn-on-gnus-mailing-list-mode) "gnus-ml" "gnus/gnus-ml.el"
- ;;;;;;  (17551 7908))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-ml.el
  
  (autoload (quote turn-on-gnus-mailing-list-mode) "gnus-ml" "\
@@@ -12144,7 -12234,7 +12174,7 @@@ Minor mode for providing mailing-list c
  \f
  ;;;### (autoloads (gnus-group-split-fancy gnus-group-split gnus-group-split-update
  ;;;;;;  gnus-group-split-setup) "gnus-mlspl" "gnus/gnus-mlspl.el"
- ;;;;;;  (17385 8493))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-mlspl.el
  
  (autoload (quote gnus-group-split-setup) "gnus-mlspl" "\
@@@ -12245,7 -12335,7 +12275,7 @@@ Calling (gnus-group-split-fancy nil ni
  ;;;***
  \f
  ;;;### (autoloads (gnus-change-server) "gnus-move" "gnus/gnus-move.el"
- ;;;;;;  (17788 21815))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-move.el
  
  (autoload (quote gnus-change-server) "gnus-move" "\
@@@ -12257,7 -12347,7 +12287,7 @@@ Update the .newsrc.eld file to reflect 
  ;;;***
  \f
  ;;;### (autoloads (gnus-button-reply gnus-button-mailto gnus-msg-mail)
- ;;;;;;  "gnus-msg" "gnus/gnus-msg.el" (17385 8493))
+ ;;;;;;  "gnus-msg" "gnus/gnus-msg.el" (17843 45617))
  ;;; Generated autoloads from gnus/gnus-msg.el
  
  (autoload (quote gnus-msg-mail) "gnus-msg" "\
@@@ -12282,7 -12372,7 +12312,7 @@@ Like `message-reply'
  ;;;***
  \f
  ;;;### (autoloads (gnus-nocem-load-cache gnus-nocem-scan-groups)
- ;;;;;;  "gnus-nocem" "gnus/gnus-nocem.el" (17788 21815))
+ ;;;;;;  "gnus-nocem" "gnus/gnus-nocem.el" (17843 45617))
  ;;; Generated autoloads from gnus/gnus-nocem.el
  
  (autoload (quote gnus-nocem-scan-groups) "gnus-nocem" "\
@@@ -12299,7 -12389,7 +12329,7 @@@ Load the NoCeM cache
  \f
  ;;;### (autoloads (gnus-treat-newsgroups-picon gnus-treat-mail-picon
  ;;;;;;  gnus-treat-from-picon) "gnus-picon" "gnus/gnus-picon.el"
- ;;;;;;  (17385 8493))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-picon.el
  
  (autoload (quote gnus-treat-from-picon) "gnus-picon" "\
@@@ -12326,7 -12416,7 +12356,7 @@@ If picons are already displayed, remov
  ;;;;;;  gnus-sorted-nintersection gnus-sorted-range-intersection
  ;;;;;;  gnus-sorted-intersection gnus-intersection gnus-sorted-complement
  ;;;;;;  gnus-sorted-ndifference gnus-sorted-difference) "gnus-range"
- ;;;;;;  "gnus/gnus-range.el" (17385 8493))
+ ;;;;;;  "gnus/gnus-range.el" (17843 45617))
  ;;; Generated autoloads from gnus/gnus-range.el
  
  (autoload (quote gnus-sorted-difference) "gnus-range" "\
@@@ -12394,7 -12484,7 +12424,7 @@@ Add NUM into sorted LIST by side effect
  ;;;***
  \f
  ;;;### (autoloads (gnus-registry-install-hooks gnus-registry-initialize)
- ;;;;;;  "gnus-registry" "gnus/gnus-registry.el" (17704 4325))
+ ;;;;;;  "gnus-registry" "gnus/gnus-registry.el" (17843 45617))
  ;;; Generated autoloads from gnus/gnus-registry.el
  
  (autoload (quote gnus-registry-initialize) "gnus-registry" "\
@@@ -12410,8 -12500,8 +12440,8 @@@ Install the registry hooks
  ;;;***
  \f
  ;;;### (autoloads (gnus-sieve-article-add-rule gnus-sieve-generate
- ;;;;;;  gnus-sieve-update) "gnus-sieve" "gnus/gnus-sieve.el" (17476
- ;;;;;;  4800))
+ ;;;;;;  gnus-sieve-update) "gnus-sieve" "gnus/gnus-sieve.el" (17843
+ ;;;;;;  45617))
  ;;; Generated autoloads from gnus/gnus-sieve.el
  
  (autoload (quote gnus-sieve-update) "gnus-sieve" "\
@@@ -12439,7 -12529,7 +12469,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (gnus-batch-brew-soup) "gnus-soup" "gnus/gnus-soup.el"
- ;;;;;;  (17788 21815))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-soup.el
  
  (autoload (quote gnus-batch-brew-soup) "gnus-soup" "\
@@@ -12459,7 -12549,7 +12489,7 @@@ Note -- this function hasn't been imple
  ;;;***
  \f
  ;;;### (autoloads (gnus-update-format) "gnus-spec" "gnus/gnus-spec.el"
- ;;;;;;  (17385 8493))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-spec.el
  
  (autoload (quote gnus-update-format) "gnus-spec" "\
@@@ -12470,8 -12560,8 +12500,8 @@@ Update the format specification near po
  ;;;***
  \f
  ;;;### (autoloads (gnus-fixup-nnimap-unread-after-getting-new-news
- ;;;;;;  gnus-declare-backend) "gnus-start" "gnus/gnus-start.el" (17767
- ;;;;;;  19634))
+ ;;;;;;  gnus-declare-backend) "gnus-start" "gnus/gnus-start.el" (17843
+ ;;;;;;  45617))
  ;;; Generated autoloads from gnus/gnus-start.el
  
  (autoload (quote gnus-declare-backend) "gnus-start" "\
@@@ -12487,7 -12577,7 +12517,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (gnus-add-configuration) "gnus-win" "gnus/gnus-win.el"
- ;;;;;;  (17385 8493))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/gnus-win.el
  
  (autoload (quote gnus-add-configuration) "gnus-win" "\
@@@ -12497,7 -12587,7 +12527,7 @@@ Add the window configuration CONF to `g
  
  ;;;***
  \f
- ;;;### (autoloads (gomoku) "gomoku" "play/gomoku.el" (17767 19634))
+ ;;;### (autoloads (gomoku) "gomoku" "play/gomoku.el" (17843 45626))
  ;;; Generated autoloads from play/gomoku.el
  
  (autoload (quote gomoku) "gomoku" "\
@@@ -12524,7 -12614,7 +12554,7 @@@ Use \\[describe-mode] for more info
  ;;;***
  \f
  ;;;### (autoloads (goto-address goto-address-at-point) "goto-addr"
- ;;;;;;  "net/goto-addr.el" (17579 53341))
+ ;;;;;;  "net/goto-addr.el" (17843 45624))
  ;;; Generated autoloads from net/goto-addr.el
  
  (define-obsolete-function-alias (quote goto-address-at-mouse) (quote goto-address-at-point) "22.1")
@@@ -12554,7 -12644,7 +12584,7 @@@ Also fontifies the buffer appropriatel
  \f
  ;;;### (autoloads (rgrep lgrep grep-find grep grep-mode grep-compute-defaults
  ;;;;;;  grep-process-setup grep-setup-hook grep-find-command grep-command
- ;;;;;;  grep-window-height) "grep" "progmodes/grep.el" (17645 64048))
+ ;;;;;;  grep-window-height) "grep" "progmodes/grep.el" (17843 45628))
  ;;; Generated autoloads from progmodes/grep.el
  
  (defvar grep-window-height nil "\
@@@ -12691,7 -12781,7 +12721,7 @@@ This command shares argument histories 
  
  ;;;***
  \f
- ;;;### (autoloads (gs-load-image) "gs" "gs.el" (17385 8485))
+ ;;;### (autoloads (gs-load-image) "gs" "gs.el" (17843 45610))
  ;;; Generated autoloads from gs.el
  
  (autoload (quote gs-load-image) "gs" "\
@@@ -12705,7 -12795,7 +12735,7 @@@ the form \"WINDOW-ID PIXMAP-ID\".  Valu
  ;;;***
  \f
  ;;;### (autoloads (gdb-script-mode bashdb jdb pdb perldb xdb dbx
- ;;;;;;  sdb gdb) "gud" "progmodes/gud.el" (17785 34467))
+ ;;;;;;  sdb gdb) "gud" "progmodes/gud.el" (17843 45628))
  ;;; Generated autoloads from progmodes/gud.el
  
  (autoload (quote gdb) "gud" "\
@@@ -12795,8 -12885,8 +12825,8 @@@ Major mode for editing GDB script
  
  ;;;***
  \f
- ;;;### (autoloads (handwrite) "handwrite" "play/handwrite.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (handwrite) "handwrite" "play/handwrite.el" (17843
+ ;;;;;;  45626))
  ;;; Generated autoloads from play/handwrite.el
  
  (autoload (quote handwrite) "handwrite" "\
@@@ -12844,7 -12934,7 +12874,7 @@@ to be updated
  ;;;### (autoloads (scan-buf-previous-region scan-buf-next-region
  ;;;;;;  scan-buf-move-to-region help-at-pt-display-when-idle help-at-pt-set-timer
  ;;;;;;  help-at-pt-cancel-timer display-local-help help-at-pt-kbd-string
- ;;;;;;  help-at-pt-string) "help-at-pt" "help-at-pt.el" (17709 24917))
+ ;;;;;;  help-at-pt-string) "help-at-pt" "help-at-pt.el" (17843 45610))
  ;;; Generated autoloads from help-at-pt.el
  
  (autoload (quote help-at-pt-string) "help-at-pt" "\
@@@ -12974,7 -13064,7 +13004,7 @@@ different regions.  With numeric argume
  ;;;### (autoloads (describe-categories describe-syntax describe-variable
  ;;;;;;  variable-at-point describe-function-1 describe-simplify-lib-file-name
  ;;;;;;  help-C-file-name describe-function) "help-fns" "help-fns.el"
- ;;;;;;  (17797 50969))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from help-fns.el
  
  (autoload (quote describe-function) "help-fns" "\
@@@ -13031,7 -13121,7 +13061,7 @@@ BUFFER should be a buffer or a buffer n
  ;;;***
  \f
  ;;;### (autoloads (three-step-help) "help-macro" "help-macro.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from help-macro.el
  
  (defvar three-step-help nil "\
@@@ -13047,7 -13137,7 +13077,7 @@@ A value of nil means skip the middle st
  \f
  ;;;### (autoloads (help-xref-on-pp help-insert-xref-button help-xref-button
  ;;;;;;  help-make-xrefs help-setup-xref help-mode-finish help-mode-setup
- ;;;;;;  help-mode) "help-mode" "help-mode.el" (17604 60389))
+ ;;;;;;  help-mode) "help-mode" "help-mode.el" (17843 45610))
  ;;; Generated autoloads from help-mode.el
  
  (autoload (quote help-mode) "help-mode" "\
@@@ -13130,7 -13220,7 +13160,7 @@@ Add xrefs for symbols in `pp's output b
  ;;;***
  \f
  ;;;### (autoloads (Helper-help Helper-describe-bindings) "helper"
- ;;;;;;  "emacs-lisp/helper.el" (17785 34467))
+ ;;;;;;  "emacs-lisp/helper.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/helper.el
  
  (autoload (quote Helper-describe-bindings) "helper" "\
@@@ -13146,7 -13236,7 +13176,7 @@@ Provide help for current mode
  ;;;***
  \f
  ;;;### (autoloads (hexlify-buffer hexl-find-file hexl-mode) "hexl"
- ;;;;;;  "hexl.el" (17776 24487))
+ ;;;;;;  "hexl.el" (17844 62922))
  ;;; Generated autoloads from hexl.el
  
  (autoload (quote hexl-mode) "hexl" "\
@@@ -13243,7 -13333,7 +13273,7 @@@ This discards the buffer's undo informa
  ;;;### (autoloads (hi-lock-write-interactive-patterns hi-lock-unface-buffer
  ;;;;;;  hi-lock-face-phrase-buffer hi-lock-face-buffer hi-lock-line-face-buffer
  ;;;;;;  global-hi-lock-mode hi-lock-mode) "hi-lock" "hi-lock.el"
- ;;;;;;  (17385 8485))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from hi-lock.el
  
  (autoload (quote hi-lock-mode) "hi-lock" "\
@@@ -13296,11 -13386,10 +13326,10 @@@ is found.  A mode is excluded if it's i
  Non-nil if Global-Hi-Lock mode is enabled.
  See the command `global-hi-lock-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `global-hi-lock-mode'.")
- (custom-autoload (quote global-hi-lock-mode) "hi-lock")
+ either customize it (see the info node `Easy Customization')
+ or call the function `global-hi-lock-mode'.")
  
- (put (quote global-hi-lock-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote global-hi-lock-mode) "hi-lock" nil)
  
  (autoload (quote global-hi-lock-mode) "hi-lock" "\
  Toggle Hi-Lock mode in every buffer.
@@@ -13369,7 -13458,7 +13398,7 @@@ be found in variable `hi-lock-interacti
  ;;;***
  \f
  ;;;### (autoloads (hide-ifdef-lines hide-ifdef-read-only hide-ifdef-initially
- ;;;;;;  hide-ifdef-mode) "hideif" "progmodes/hideif.el" (17520 49736))
+ ;;;;;;  hide-ifdef-mode) "hideif" "progmodes/hideif.el" (17843 45628))
  ;;; Generated autoloads from progmodes/hideif.el
  
  (autoload (quote hide-ifdef-mode) "hideif" "\
@@@ -13409,22 -13498,22 +13438,22 @@@ how the hiding is done
  (defvar hide-ifdef-initially nil "\
  *Non-nil means call `hide-ifdefs' when Hide-Ifdef mode is first activated.")
  
- (custom-autoload (quote hide-ifdef-initially) "hideif")
+ (custom-autoload (quote hide-ifdef-initially) "hideif" t)
  
  (defvar hide-ifdef-read-only nil "\
  *Set to non-nil if you want buffer to be read-only while hiding text.")
  
- (custom-autoload (quote hide-ifdef-read-only) "hideif")
+ (custom-autoload (quote hide-ifdef-read-only) "hideif" t)
  
  (defvar hide-ifdef-lines nil "\
  *Non-nil means hide the #ifX, #else, and #endif lines.")
  
- (custom-autoload (quote hide-ifdef-lines) "hideif")
+ (custom-autoload (quote hide-ifdef-lines) "hideif" t)
  
  ;;;***
  \f
  ;;;### (autoloads (hs-minor-mode) "hideshow" "progmodes/hideshow.el"
- ;;;;;;  (17771 26718))
+ ;;;;;;  (17843 45628))
  ;;; Generated autoloads from progmodes/hideshow.el
  
  (defvar hs-special-modes-alist (quote ((c-mode "{" "}" "/[*/]" nil hs-c-like-adjust-block-beginning) (c++-mode "{" "}" "/[*/]" nil hs-c-like-adjust-block-beginning) (bibtex-mode ("^@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil hs-c-like-adjust-block-beginning))) "\
@@@ -13482,7 -13571,7 +13511,7 @@@ Key bindings
  ;;;;;;  highlight-compare-buffers highlight-changes-rotate-faces
  ;;;;;;  highlight-changes-previous-change highlight-changes-next-change
  ;;;;;;  highlight-changes-mode highlight-changes-remove-highlight)
- ;;;;;;  "hilit-chg" "hilit-chg.el" (17781 39501))
+ ;;;;;;  "hilit-chg" "hilit-chg.el" (17843 45610))
  ;;; Generated autoloads from hilit-chg.el
  
  (autoload (quote highlight-changes-remove-highlight) "hilit-chg" "\
@@@ -13612,7 -13701,7 +13641,7 @@@ variable `highlight-changes-global-chan
  ;;;;;;  hippie-expand-ignore-buffers hippie-expand-max-buffers hippie-expand-no-restriction
  ;;;;;;  hippie-expand-dabbrev-as-symbol hippie-expand-dabbrev-skip-space
  ;;;;;;  hippie-expand-verbose hippie-expand-try-functions-list) "hippie-exp"
- ;;;;;;  "hippie-exp.el" (17781 39501))
+ ;;;;;;  "hippie-exp.el" (17843 45610))
  ;;; Generated autoloads from hippie-exp.el
  
  (defvar hippie-expand-try-functions-list (quote (try-complete-file-name-partially try-complete-file-name try-expand-all-abbrevs try-expand-list try-expand-line try-expand-dabbrev try-expand-dabbrev-all-buffers try-expand-dabbrev-from-kill try-complete-lisp-symbol-partially try-complete-lisp-symbol)) "\
@@@ -13685,7 -13774,7 +13714,7 @@@ argument VERBOSE non-nil makes the func
  ;;;***
  \f
  ;;;### (autoloads (global-hl-line-mode hl-line-mode) "hl-line" "hl-line.el"
- ;;;;;;  (17656 37701))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from hl-line.el
  
  (autoload (quote hl-line-mode) "hl-line" "\
@@@ -13726,7 -13815,7 +13755,7 @@@ Global-Hl-Line mode uses the functions 
  ;;;***
  \f
  ;;;### (autoloads (list-holidays holidays) "holidays" "calendar/holidays.el"
- ;;;;;;  (17427 10521))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from calendar/holidays.el
  
  (autoload (quote holidays) "holidays" "\
@@@ -13763,7 -13852,7 +13792,7 @@@ The optional LABEL is used to label th
  ;;;***
  \f
  ;;;### (autoloads (hscroll-global-mode hscroll-mode turn-on-hscroll)
- ;;;;;;  "hscroll" "obsolete/hscroll.el" (17786 56015))
+ ;;;;;;  "hscroll" "obsolete/hscroll.el" (17843 45625))
  ;;; Generated autoloads from obsolete/hscroll.el
  
  (autoload (quote turn-on-hscroll) "hscroll" "\
@@@ -13789,8 -13878,8 +13818,8 @@@ Also see `automatic-hscrolling'
  
  ;;;***
  \f
- ;;;### (autoloads (html2text) "html2text" "gnus/html2text.el" (17740
- ;;;;;;  981))
+ ;;;### (autoloads (html2text) "html2text" "gnus/html2text.el" (17843
+ ;;;;;;  45617))
  ;;; Generated autoloads from gnus/html2text.el
  
  (autoload (quote html2text) "html2text" "\
@@@ -13822,7 -13911,7 +13851,7 @@@ Convert HTML to plain text in the curre
  ;;;;;;  ibuffer-backward-filter-group ibuffer-forward-filter-group
  ;;;;;;  ibuffer-toggle-filter-group ibuffer-mouse-toggle-filter-group
  ;;;;;;  ibuffer-interactive-filter-by-mode ibuffer-mouse-filter-by-mode
- ;;;;;;  ibuffer-auto-mode) "ibuf-ext" "ibuf-ext.el" (17698 30385))
+ ;;;;;;  ibuffer-auto-mode) "ibuf-ext" "ibuf-ext.el" (17843 45610))
  ;;; Generated autoloads from ibuf-ext.el
  
  (autoload (quote ibuffer-auto-mode) "ibuf-ext" "\
@@@ -14188,8 -14277,8 +14217,8 @@@ defaults to one
  ;;;***
  \f
  ;;;### (autoloads (define-ibuffer-filter define-ibuffer-op define-ibuffer-sorter
- ;;;;;;  define-ibuffer-column) "ibuf-macs" "ibuf-macs.el" (17476
- ;;;;;;  4797))
+ ;;;;;;  define-ibuffer-column) "ibuf-macs" "ibuf-macs.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from ibuf-macs.el
  
  (autoload (quote define-ibuffer-column) "ibuf-macs" "\
@@@ -14278,7 -14367,7 +14307,7 @@@ bound to the current value of the filte
  ;;;***
  \f
  ;;;### (autoloads (ibuffer ibuffer-other-window ibuffer-list-buffers)
- ;;;;;;  "ibuffer" "ibuffer.el" (17647 30728))
+ ;;;;;;  "ibuffer" "ibuffer.el" (17843 45610))
  ;;; Generated autoloads from ibuffer.el
  
  (autoload (quote ibuffer-list-buffers) "ibuffer" "\
@@@ -14319,7 -14408,7 +14348,7 @@@ FORMATS is the value to use for `ibuffe
  \f
  ;;;### (autoloads (icalendar-import-buffer icalendar-import-file
  ;;;;;;  icalendar-export-region icalendar-export-file) "icalendar"
- ;;;;;;  "calendar/icalendar.el" (17797 50970))
+ ;;;;;;  "calendar/icalendar.el" (17843 45615))
  ;;; Generated autoloads from calendar/icalendar.el
  
  (autoload (quote icalendar-export-file) "icalendar" "\
@@@ -14364,15 -14453,15 +14393,15 @@@ NON-MARKING determines whether diary ev
  non-marking.
  
  Return code t means that importing worked well, return code nil
- means that an error has occured.  Error messages will be in the
+ means that an error has occurred.  Error messages will be in the
  buffer `*icalendar-errors*'.
  
  \(fn &optional DIARY-FILE DO-NOT-ASK NON-MARKING)" t nil)
  
  ;;;***
  \f
- ;;;### (autoloads (icomplete-mode) "icomplete" "icomplete.el" (17772
- ;;;;;;  23868))
+ ;;;### (autoloads (icomplete-mode) "icomplete" "icomplete.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from icomplete.el
  
  (defvar icomplete-mode nil "\
@@@ -14392,7 -14481,7 +14421,7 @@@ With a numeric argument, turn Icomplet
  
  ;;;***
  \f
- ;;;### (autoloads (icon-mode) "icon" "progmodes/icon.el" (17394 12938))
+ ;;;### (autoloads (icon-mode) "icon" "progmodes/icon.el" (17843 45628))
  ;;; Generated autoloads from progmodes/icon.el
  
  (autoload (quote icon-mode) "icon" "\
@@@ -14433,7 -14522,7 +14462,7 @@@ with no args, if that value is non-nil
  ;;;***
  \f
  ;;;### (autoloads (idlwave-shell) "idlw-shell" "progmodes/idlw-shell.el"
- ;;;;;;  (17763 7936))
+ ;;;;;;  (17843 45628))
  ;;; Generated autoloads from progmodes/idlw-shell.el
  
  (autoload (quote idlwave-shell) "idlw-shell" "\
@@@ -14459,7 -14548,7 +14488,7 @@@ See also the variable `idlwave-shell-pr
  ;;;***
  \f
  ;;;### (autoloads (idlwave-mode) "idlwave" "progmodes/idlwave.el"
- ;;;;;;  (17789 35159))
+ ;;;;;;  (17843 45628))
  ;;; Generated autoloads from progmodes/idlwave.el
  
  (autoload (quote idlwave-mode) "idlwave" "\
@@@ -14594,8 -14683,8 +14623,8 @@@ The main features of this mode ar
  ;;;;;;  ido-find-alternate-file ido-find-file-other-window ido-find-file
  ;;;;;;  ido-find-file-in-dir ido-switch-buffer-other-frame ido-insert-buffer
  ;;;;;;  ido-kill-buffer ido-display-buffer ido-switch-buffer-other-window
- ;;;;;;  ido-switch-buffer ido-mode ido-mode) "ido" "ido.el" (17796
- ;;;;;;  10831))
+ ;;;;;;  ido-switch-buffer ido-mode ido-mode) "ido" "ido.el" (17845
+ ;;;;;;  22160))
  ;;; Generated autoloads from ido.el
  
  (defvar ido-mode nil "\
@@@ -14856,7 -14945,7 +14885,7 @@@ DEF, if non-nil, is the default value
  
  ;;;***
  \f
- ;;;### (autoloads (ielm) "ielm" "ielm.el" (17781 39501))
+ ;;;### (autoloads (ielm) "ielm" "ielm.el" (17843 45610))
  ;;; Generated autoloads from ielm.el
   (add-hook 'same-window-buffer-names "*ielm*")
  
@@@ -14869,7 -14958,7 +14898,7 @@@ Switches to the buffer `*ielm*', or cre
  ;;;***
  \f
  ;;;### (autoloads (iimage-mode turn-on-iimage-mode) "iimage" "iimage.el"
- ;;;;;;  (17771 26718))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from iimage.el
  
  (autoload (quote turn-on-iimage-mode) "iimage" "\
@@@ -14885,10 -14974,10 +14914,10 @@@ Toggle inline image minor mode
  ;;;***
  \f
  ;;;### (autoloads (defimage find-image remove-images insert-sliced-image
- ;;;;;;  insert-image put-image create-image image-type-available-p
- ;;;;;;  image-type image-type-from-file-name image-type-from-file-header
- ;;;;;;  image-type-from-buffer image-type-from-data) "image" "image.el"
- ;;;;;;  (17800 14311))
+ ;;;;;;  insert-image put-image create-image image-type-auto-detected-p
+ ;;;;;;  image-type-available-p image-type image-type-from-file-name
+ ;;;;;;  image-type-from-file-header image-type-from-buffer image-type-from-data)
+ ;;;;;;  "image" "image.el" (17843 45610))
  ;;; Generated autoloads from image.el
  
  (autoload (quote image-type-from-data) "image" "\
@@@ -14936,6 -15025,15 +14965,15 @@@ Image types are symbols like `xbm' or `
  
  \(fn TYPE)" nil nil)
  
+ (autoload (quote image-type-auto-detected-p) "image" "\
+ Return t iff the current buffer contains an auto-detectable image.
+ Whether image types are auto-detectable or not depends on the setting
+ of the variable `image-type-auto-detectable'.
+ This function is intended to be used from `magic-mode-alist' (which see).
+ \(fn)" nil nil)
  (autoload (quote create-image) "image" "\
  Create an image.
  FILE-OR-DATA is an image file name or image data.
@@@ -15050,7 -15148,7 +15088,7 @@@ Example
  \f
  ;;;### (autoloads (auto-image-file-mode insert-image-file image-file-name-regexp
  ;;;;;;  image-file-name-regexps image-file-name-extensions) "image-file"
- ;;;;;;  "image-file.el" (17385 8485))
+ ;;;;;;  "image-file.el" (17843 45610))
  ;;; Generated autoloads from image-file.el
  
  (defvar image-file-name-extensions (quote ("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm")) "\
@@@ -15063,7 -15161,7 +15101,7 @@@ setting this variable directly does no
  `auto-image-file-mode' is re-enabled; this happens automatically when
  the variable is set using \\[customize].")
  
- (custom-autoload (quote image-file-name-extensions) "image-file")
+ (custom-autoload (quote image-file-name-extensions) "image-file" nil)
  
  (defvar image-file-name-regexps nil "\
  *List of regexps matching image-file filenames.
@@@ -15075,7 -15173,7 +15113,7 @@@ enabled, setting this variable directl
  `auto-image-file-mode' is re-enabled; this happens automatically when
  the variable is set using \\[customize].")
  
- (custom-autoload (quote image-file-name-regexps) "image-file")
+ (custom-autoload (quote image-file-name-regexps) "image-file" nil)
  
  (autoload (quote image-file-name-regexp) "image-file" "\
  Return a regular expression matching image-file filenames.
@@@ -15093,11 -15191,10 +15131,10 @@@ the command `insert-file-contents'
  Non-nil if Auto-Image-File mode is enabled.
  See the command `auto-image-file-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `auto-image-file-mode'.")
- (custom-autoload (quote auto-image-file-mode) "image-file")
+ either customize it (see the info node `Easy Customization')
+ or call the function `auto-image-file-mode'.")
  
- (put (quote auto-image-file-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote auto-image-file-mode) "image-file" nil)
  
  (autoload (quote auto-image-file-mode) "image-file" "\
  Toggle visiting of image files as images.
@@@ -15113,7 -15210,7 +15150,7 @@@ Image files are those whose name has a
  ;;;***
  \f
  ;;;### (autoloads (image-mode-maybe image-minor-mode image-mode)
- ;;;;;;  "image-mode" "image-mode.el" (17656 37701))
+ ;;;;;;  "image-mode" "image-mode.el" (17843 45610))
  ;;; Generated autoloads from image-mode.el
   (push '("\\.jpe?g\\'"    . image-mode) auto-mode-alist)
   (push '("\\.png\\'"      . image-mode) auto-mode-alist)
@@@ -15151,7 -15248,7 +15188,7 @@@ information on these modes
  ;;;***
  \f
  ;;;### (autoloads (imenu imenu-add-menubar-index imenu-add-to-menubar
- ;;;;;;  imenu-sort-function) "imenu" "imenu.el" (17781 39501))
+ ;;;;;;  imenu-sort-function) "imenu" "imenu.el" (17843 45610))
  ;;; Generated autoloads from imenu.el
  
  (defvar imenu-sort-function nil "\
@@@ -15266,7 -15363,7 +15303,7 @@@ for more information
  \f
  ;;;### (autoloads (indian-char-glyph indian-glyph-char in-is13194-pre-write-conversion
  ;;;;;;  in-is13194-post-read-conversion indian-compose-string indian-compose-region)
- ;;;;;;  "ind-util" "language/ind-util.el" (17788 21816))
+ ;;;;;;  "ind-util" "language/ind-util.el" (17843 45620))
  ;;; Generated autoloads from language/ind-util.el
  
  (autoload (quote indian-compose-region) "ind-util" "\
@@@ -15309,7 -15406,7 +15346,7 @@@ See also the function `indian-glyph-cha
  \f
  ;;;### (autoloads (inferior-lisp inferior-lisp-prompt inferior-lisp-load-command
  ;;;;;;  inferior-lisp-program inferior-lisp-filter-regexp) "inf-lisp"
- ;;;;;;  "progmodes/inf-lisp.el" (17536 30816))
+ ;;;;;;  "progmodes/inf-lisp.el" (17843 45628))
  ;;; Generated autoloads from progmodes/inf-lisp.el
  
  (defvar inferior-lisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'" "\
@@@ -15318,12 -15415,12 +15355,12 @@@ Input matching this regexp is not save
  mode.  Default is whitespace followed by 0 or 1 single-letter colon-keyword
  \(as in :a, :c, etc.)")
  
- (custom-autoload (quote inferior-lisp-filter-regexp) "inf-lisp")
+ (custom-autoload (quote inferior-lisp-filter-regexp) "inf-lisp" t)
  
  (defvar inferior-lisp-program "lisp" "\
  *Program name for invoking an inferior Lisp in Inferior Lisp mode.")
  
- (custom-autoload (quote inferior-lisp-program) "inf-lisp")
+ (custom-autoload (quote inferior-lisp-program) "inf-lisp" t)
  
  (defvar inferior-lisp-load-command "(load \"%s\")\n" "\
  *Format-string for building a Lisp expression to load a file.
@@@ -15334,7 -15431,7 +15371,7 @@@ The string \"(progn (load \\\"%s\\\" :v
  produces cosmetically superior output for this application,
  but it works only in Common Lisp.")
  
- (custom-autoload (quote inferior-lisp-load-command) "inf-lisp")
+ (custom-autoload (quote inferior-lisp-load-command) "inf-lisp" t)
  
  (defvar inferior-lisp-prompt "^[^> \n]*>+:? *" "\
  Regexp to recognize prompts in the Inferior Lisp mode.
@@@ -15352,7 -15449,7 +15389,7 @@@ kcl: \"^>+ *\
  
  This is a fine thing to set in your .emacs file or through Custom.")
  
- (custom-autoload (quote inferior-lisp-prompt) "inf-lisp")
+ (custom-autoload (quote inferior-lisp-prompt) "inf-lisp" t)
  
  (defvar inferior-lisp-mode-hook (quote nil) "\
  *Hook for customising Inferior Lisp mode.")
@@@ -15376,7 -15473,7 +15413,7 @@@ of `inferior-lisp-program').  Runs the 
  ;;;### (autoloads (Info-speedbar-browser Info-goto-emacs-key-command-node
  ;;;;;;  Info-goto-emacs-command-node Info-mode info-apropos Info-index
  ;;;;;;  Info-directory Info-on-current-buffer info-standalone info-emacs-manual
- ;;;;;;  info info-other-window) "info" "info.el" (17798 49643))
+ ;;;;;;  info info-other-window) "info" "info.el" (17843 45610))
  ;;; Generated autoloads from info.el
  
  (autoload (quote info-other-window) "info" "\
@@@ -15542,7 -15639,7 +15579,7 @@@ This will add a speedbar major display 
  \f
  ;;;### (autoloads (info-complete-file info-complete-symbol info-lookup-file
  ;;;;;;  info-lookup-symbol info-lookup-reset) "info-look" "info-look.el"
- ;;;;;;  (17771 1419))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from info-look.el
  
  (autoload (quote info-lookup-reset) "info-look" "\
@@@ -15590,7 -15687,7 +15627,7 @@@ Perform completion on file preceding po
  ;;;***
  \f
  ;;;### (autoloads (info-xref-check-all-custom info-xref-check-all
- ;;;;;;  info-xref-check) "info-xref" "info-xref.el" (17520 49736))
+ ;;;;;;  info-xref-check) "info-xref" "info-xref.el" (17843 45610))
  ;;; Generated autoloads from info-xref.el
  
  (autoload (quote info-xref-check) "info-xref" "\
@@@ -15617,7 -15714,7 +15654,7 @@@ quite a while
  ;;;***
  \f
  ;;;### (autoloads (batch-info-validate Info-validate Info-split Info-tagify)
- ;;;;;;  "informat" "informat.el" (17781 39501))
+ ;;;;;;  "informat" "informat.el" (17843 45610))
  ;;; Generated autoloads from informat.el
  
  (autoload (quote Info-tagify) "informat" "\
@@@ -15658,7 -15755,7 +15695,7 @@@ For example, invoke \"emacs -batch -f b
  \f
  ;;;### (autoloads (isearch-process-search-multibyte-characters isearch-toggle-input-method
  ;;;;;;  isearch-toggle-specified-input-method) "isearch-x" "international/isearch-x.el"
- ;;;;;;  (17792 9561))
+ ;;;;;;  (17843 45618))
  ;;; Generated autoloads from international/isearch-x.el
  
  (autoload (quote isearch-toggle-specified-input-method) "isearch-x" "\
@@@ -15678,8 -15775,8 +15715,8 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads (isearchb-activate) "isearchb" "isearchb.el" (17794
- ;;;;;;  48602))
+ ;;;### (autoloads (isearchb-activate) "isearchb" "isearchb.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from isearchb.el
  
  (autoload (quote isearchb-activate) "isearchb" "\
@@@ -15693,7 -15790,7 +15730,7 @@@ accessed via isearchb
  ;;;***
  \f
  ;;;### (autoloads (iso-accents-mode) "iso-acc" "obsolete/iso-acc.el"
- ;;;;;;  (17385 8495))
+ ;;;;;;  (17843 45625))
  ;;; Generated autoloads from obsolete/iso-acc.el
  
  (autoload (quote iso-accents-mode) "iso-acc" "\
@@@ -15726,7 -15823,7 +15763,7 @@@ and a negative argument disables it
  ;;;### (autoloads (iso-cvt-define-menu iso-cvt-write-only iso-cvt-read-only
  ;;;;;;  iso-sgml2iso iso-iso2sgml iso-iso2duden iso-iso2gtex iso-gtex2iso
  ;;;;;;  iso-tex2iso iso-iso2tex iso-german iso-spanish) "iso-cvt"
- ;;;;;;  "international/iso-cvt.el" (17788 21815))
+ ;;;;;;  "international/iso-cvt.el" (17843 45618))
  ;;; Generated autoloads from international/iso-cvt.el
  
  (autoload (quote iso-spanish) "iso-cvt" "\
@@@ -15810,7 -15907,7 +15847,7 @@@ Add submenus to the File menu, to conve
  ;;;***
  \f
  ;;;### (autoloads nil "iso-transl" "international/iso-transl.el"
- ;;;;;;  (17788 21815))
+ ;;;;;;  (17843 45618))
  ;;; Generated autoloads from international/iso-transl.el
   (or key-translation-map (setq key-translation-map (make-sparse-keymap)))
   (define-key key-translation-map "\C-x8" 'iso-transl-ctl-x-8-map)
  ;;;;;;  ispell-region ispell-change-dictionary ispell-kill-ispell
  ;;;;;;  ispell-help ispell-pdict-save ispell-word ispell-local-dictionary-alist
  ;;;;;;  ispell-personal-dictionary) "ispell" "textmodes/ispell.el"
- ;;;;;;  (17743 18144))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/ispell.el
  (put 'ispell-check-comments 'safe-local-variable (lambda (a) (memq a '(nil t exclusive))))
  
@@@ -15849,11 -15946,11 +15886,11 @@@ re-start Emacs."
  
  (setq ispell-dictionary-alist-2 (quote (("czech" "[A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" "[^A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" "" nil ("-B") nil iso-8859-2) ("dansk" "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]" "[']" nil ("-C") nil iso-8859-1) ("deutsch" "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1) ("deutsch8" "[a-zA-Z\304\326\334\344\366\337\374]" "[^a-zA-Z\304\326\334\344\366\337\374]" "[']" t ("-C" "-d" "deutsch") "~latin1" iso-8859-1) ("english" "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1))))
  
- (setq ispell-dictionary-alist-3 (quote (("esperanto" "[A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]" "[^A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]" "[-']" t ("-C") "~latin3" iso-8859-3) ("esperanto-tex" "[A-Za-z^\\]" "[^A-Za-z^\\]" "[-'`\"]" t ("-C" "-d" "esperanto") "~tex" iso-8859-3) ("francais7" "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil iso-8859-1) ("francais" "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" "[-'.@]" t nil "~list" iso-8859-1) ("francais-tex" "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" "[-'^`\".@]" t nil "~tex" iso-8859-1))))
+ (setq ispell-dictionary-alist-3 (quote (("esperanto" "[A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]" "[^A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]" "[-']" t ("-C") "~latin3" iso-8859-3) ("esperanto-tex" "[A-Za-z^\\]" "[^A-Za-z^\\]" "[-'`\"]" t ("-C" "-d" "esperanto") "~tex" iso-8859-3) ("francais7" "[A-Za-z]" "[^A-Za-z]" "[`'^-]" t nil nil iso-8859-1) ("francais" "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" "[-'.@]" t nil "~list" iso-8859-1) ("francais-tex" "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" "[-'^`\".@]" t nil "~tex" iso-8859-1))))
  
  (setq ispell-dictionary-alist-4 (quote (("german" "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1) ("german8" "[a-zA-Z\304\326\334\344\366\337\374]" "[^a-zA-Z\304\326\334\344\366\337\374]" "[']" t ("-C" "-d" "german") "~latin1" iso-8859-1) ("italiano" "[A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" "[^A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" "[-.]" nil ("-B" "-d" "italian") "~tex" iso-8859-1) ("nederlands" "[A-Za-z\300\301\302\303\304\305\307\310\311\312\313\314\315\316\317\322\323\324\325\326\331\332\333\334\340\341\342\343\344\345\347\350\351\352\353\354\355\356\357\361\362\363\364\365\366\371\372\373\374]" "[^A-Za-z\300\301\302\303\304\305\307\310\311\312\313\314\315\316\317\322\323\324\325\326\331\332\333\334\340\341\342\343\344\345\347\350\351\352\353\354\355\356\357\361\362\363\364\365\366\371\372\373\374]" "[']" t ("-C") nil iso-8859-1) ("nederlands8" "[A-Za-z\300\301\302\303\304\305\307\310\311\312\313\314\315\316\317\322\323\324\325\326\331\332\333\334\340\341\342\343\344\345\347\350\351\352\353\354\355\356\357\361\362\363\364\365\366\371\372\373\374]" "[^A-Za-z\300\301\302\303\304\305\307\310\311\312\313\314\315\316\317\322\323\324\325\326\331\332\333\334\340\341\342\343\344\345\347\350\351\352\353\354\355\356\357\361\362\363\364\365\366\371\372\373\374]" "[']" t ("-C") nil iso-8859-1))))
  
- (setq ispell-dictionary-alist-5 (quote (("norsk" "[A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" "[^A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" "[\"]" nil nil "~list" iso-8859-1) ("norsk7-tex" "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]" "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1) ("polish" "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" "." nil nil nil iso-8859-2) ("portugues" "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" "[']" t ("-C") "~latin1" iso-8859-1))))
+ (setq ispell-dictionary-alist-5 (quote (("norsk" "[A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" "[^A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" "[\"]" nil nil "~list" iso-8859-1) ("norsk7-tex" "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]" "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1) ("polish" "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" "[.]" nil nil nil iso-8859-2) ("portugues" "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" "[']" t ("-C") "~latin1" iso-8859-1))))
  
  (setq ispell-dictionary-alist-6 (quote (("russian" "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" "" nil nil nil koi8-r) ("russianw" "[\300\301\302\303\304\305\250\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\334\333\332\335\336\337\340\341\342\343\344\345\270\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\374\373\372\375\376\377]" "[^\300\301\302\303\304\305\250\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\334\333\332\335\336\337\340\341\342\343\344\345\270\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\374\373\372\375\376\377]" "" nil nil nil windows-1251) ("slovak" "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" "" nil ("-B") nil iso-8859-2) ("slovenian" "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" "" nil ("-B" "-d" "slovenian") nil iso-8859-2) ("svenska" "[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" "[']" nil ("-C") "~list" iso-8859-1))))
  
@@@ -16111,19 -16208,18 +16148,18 @@@ You can bind this to the key C-c i in G
  
  ;;;***
  \f
- ;;;### (autoloads (iswitchb-mode) "iswitchb" "iswitchb.el" (17440
- ;;;;;;  13082))
+ ;;;### (autoloads (iswitchb-mode) "iswitchb" "iswitchb.el" (17827
+ ;;;;;;  37446))
  ;;; Generated autoloads from iswitchb.el
  
  (defvar iswitchb-mode nil "\
  Non-nil if Iswitchb mode is enabled.
  See the command `iswitchb-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `iswitchb-mode'.")
- (custom-autoload (quote iswitchb-mode) "iswitchb")
+ either customize it (see the info node `Easy Customization')
+ or call the function `iswitchb-mode'.")
  
- (put (quote iswitchb-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote iswitchb-mode) "iswitchb" nil)
  
  (autoload (quote iswitchb-mode) "iswitchb" "\
  Toggle Iswitchb global minor mode.
@@@ -16138,7 -16234,7 +16174,7 @@@ This mode enables switching between buf
  ;;;### (autoloads (read-hiragana-string japanese-zenkaku-region japanese-hankaku-region
  ;;;;;;  japanese-hiragana-region japanese-katakana-region japanese-zenkaku
  ;;;;;;  japanese-hankaku japanese-hiragana japanese-katakana setup-japanese-environment-internal)
- ;;;;;;  "japan-util" "language/japan-util.el" (17792 9562))
+ ;;;;;;  "japan-util" "language/japan-util.el" (17843 45620))
  ;;; Generated autoloads from language/japan-util.el
  
  (autoload (quote setup-japanese-environment-internal) "japan-util" "\
@@@ -16216,7 -16312,7 +16252,7 @@@ If non-nil, second arg INITIAL-INPUT i
  ;;;***
  \f
  ;;;### (autoloads (jka-compr-uninstall jka-compr-handler) "jka-compr"
- ;;;;;;  "jka-compr.el" (17781 39501))
+ ;;;;;;  "jka-compr.el" (17843 45610))
  ;;; Generated autoloads from jka-compr.el
  
  (defvar jka-compr-inhibit nil "\
@@@ -16241,7 -16337,7 +16277,7 @@@ by `jka-compr-installed'
  \f
  ;;;### (autoloads (keypad-setup keypad-numlock-shifted-setup keypad-shifted-setup
  ;;;;;;  keypad-numlock-setup keypad-setup) "keypad" "emulation/keypad.el"
- ;;;;;;  (17385 8491))
+ ;;;;;;  (17838 18033))
  ;;; Generated autoloads from emulation/keypad.el
  
  (defvar keypad-setup nil "\
@@@ -16249,33 -16345,33 +16285,33 @@@ Specifies the keypad setup for unshifte
  When selecting the plain numeric keypad setup, the character returned by the
  decimal key must be specified.")
  
- (custom-autoload (quote keypad-setup) "keypad")
+ (custom-autoload (quote keypad-setup) "keypad" nil)
  
  (defvar keypad-numlock-setup nil "\
  Specifies the keypad setup for unshifted keypad keys when NumLock is on.
  When selecting the plain numeric keypad setup, the character returned by the
  decimal key must be specified.")
  
- (custom-autoload (quote keypad-numlock-setup) "keypad")
+ (custom-autoload (quote keypad-numlock-setup) "keypad" nil)
  
  (defvar keypad-shifted-setup nil "\
  Specifies the keypad setup for shifted keypad keys when NumLock is off.
  When selecting the plain numeric keypad setup, the character returned by the
  decimal key must be specified.")
  
- (custom-autoload (quote keypad-shifted-setup) "keypad")
+ (custom-autoload (quote keypad-shifted-setup) "keypad" nil)
  
  (defvar keypad-numlock-shifted-setup nil "\
  Specifies the keypad setup for shifted keypad keys when NumLock is off.
  When selecting the plain numeric keypad setup, the character returned by the
  decimal key must be specified.")
  
- (custom-autoload (quote keypad-numlock-shifted-setup) "keypad")
+ (custom-autoload (quote keypad-numlock-shifted-setup) "keypad" nil)
  
  (autoload (quote keypad-setup) "keypad" "\
- Set keypad bindings in function-key-map according to SETUP.
+ Set keypad bindings in `function-key-map' according to SETUP.
  If optional second argument NUMLOCK is non-nil, the NumLock On bindings
- are changed. Otherwise, the NumLock Off bindings are changed.
+ are changed.  Otherwise, the NumLock Off bindings are changed.
  If optional third argument SHIFT is non-nil, the shifted keypad
  keys are bound.
  
@@@ -16297,7 -16393,7 +16333,7 @@@ the decimal key on the keypad is mappe
  ;;;***
  \f
  ;;;### (autoloads (kinsoku) "kinsoku" "international/kinsoku.el"
- ;;;;;;  (17792 9561))
+ ;;;;;;  (17843 45618))
  ;;; Generated autoloads from international/kinsoku.el
  
  (autoload (quote kinsoku) "kinsoku" "\
@@@ -16318,8 -16414,8 +16354,8 @@@ the context of text formatting
  
  ;;;***
  \f
- ;;;### (autoloads (kkc-region) "kkc" "international/kkc.el" (17792
- ;;;;;;  9561))
+ ;;;### (autoloads (kkc-region) "kkc" "international/kkc.el" (17843
+ ;;;;;;  45618))
  ;;; Generated autoloads from international/kkc.el
  
  (defvar kkc-after-update-conversion-functions nil "\
@@@ -16344,7 -16440,7 +16380,7 @@@ and the return value is the length of t
  ;;;### (autoloads (kmacro-end-call-mouse kmacro-end-and-call-macro
  ;;;;;;  kmacro-end-or-call-macro kmacro-start-macro-or-insert-counter
  ;;;;;;  kmacro-call-macro kmacro-end-macro kmacro-start-macro) "kmacro"
- ;;;;;;  "kmacro.el" (17770 2412))
+ ;;;;;;  "kmacro.el" (17838 18033))
  ;;; Generated autoloads from kmacro.el
   (global-set-key "\C-x(" 'kmacro-start-macro)
   (global-set-key "\C-x)" 'kmacro-end-macro)
@@@ -16417,7 -16513,7 +16453,7 @@@ the current value of `kmacro-counter')
  
  When defining/executing macro, inserts macro counter and increments
  the counter with ARG or 1 if missing.  With \\[universal-argument],
- inserts previous kmacro-counter (but do not modify counter).
+ inserts previous `kmacro-counter' (but do not modify counter).
  
  The macro counter can be modified via \\[kmacro-set-counter] and \\[kmacro-add-counter].
  The format of the counter can be modified via \\[kmacro-set-format].
@@@ -16451,7 -16547,7 +16487,7 @@@ If kbd macro currently being defined en
  \f
  ;;;### (autoloads (kannada-post-read-conversion kannada-compose-string
  ;;;;;;  kannada-compose-region) "knd-util" "language/knd-util.el"
- ;;;;;;  (17788 21816))
+ ;;;;;;  (17843 45620))
  ;;; Generated autoloads from language/knd-util.el
  
  (defconst kannada-consonant "[\x51f75-\x51fb9]")
@@@ -16474,7 -16570,7 +16510,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (setup-korean-environment-internal) "korea-util"
- ;;;;;;  "language/korea-util.el" (17792 9562))
+ ;;;;;;  "language/korea-util.el" (17843 45620))
  ;;; Generated autoloads from language/korea-util.el
  
  (defvar default-korean-keyboard (if (string-match "3" (or (getenv "HANGUL_KEYBOARD_TYPE") "")) "3" "") "\
@@@ -16489,7 -16585,7 +16525,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (lm lm-test-run) "landmark" "play/landmark.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45626))
  ;;; Generated autoloads from play/landmark.el
  
  (defalias (quote landmark-repeat) (quote lm-test-run))
@@@ -16523,8 -16619,8 +16559,8 @@@ Use \\[describe-mode] for more info
  \f
  ;;;### (autoloads (lao-compose-region lao-composition-function lao-post-read-conversion
  ;;;;;;  lao-transcribe-roman-to-lao-string lao-transcribe-single-roman-syllable-to-lao
- ;;;;;;  lao-compose-string) "lao-util" "language/lao-util.el" (17792
- ;;;;;;  9562))
+ ;;;;;;  lao-compose-string) "lao-util" "language/lao-util.el" (17843
+ ;;;;;;  45620))
  ;;; Generated autoloads from language/lao-util.el
  
  (autoload (quote lao-compose-string) "lao-util" "\
@@@ -16573,7 -16669,7 +16609,7 @@@ Not documente
  \f
  ;;;### (autoloads (latexenc-find-file-coding-system latexenc-coding-system-to-inputenc
  ;;;;;;  latexenc-inputenc-to-coding-system latex-inputenc-coding-alist)
- ;;;;;;  "latexenc" "international/latexenc.el" (17664 20313))
+ ;;;;;;  "latexenc" "international/latexenc.el" (17843 45618))
  ;;; Generated autoloads from international/latexenc.el
  
  (defvar latex-inputenc-coding-alist (quote (("ansinew" . windows-1252) ("applemac" . mac-roman) ("ascii" . us-ascii) ("cp1250" . windows-1250) ("cp1252" . windows-1252) ("cp1257" . cp1257) ("cp437de" . cp437) ("cp437" . cp437) ("cp850" . cp850) ("cp852" . cp852) ("cp858" . cp858) ("cp865" . cp865) ("latin1" . iso-8859-1) ("latin2" . iso-8859-2) ("latin3" . iso-8859-3) ("latin4" . iso-8859-4) ("latin5" . iso-8859-5) ("latin9" . iso-8859-15) ("next" . next) ("utf8" . utf-8) ("utf8x" . utf-8))) "\
@@@ -16605,7 -16701,7 +16641,7 @@@ coding system names is determined from 
  ;;;***
  \f
  ;;;### (autoloads (latin1-display-ucs-per-lynx latin1-display latin1-display)
- ;;;;;;  "latin1-disp" "international/latin1-disp.el" (17788 21815))
+ ;;;;;;  "latin1-disp" "international/latin1-disp.el" (17843 45619))
  ;;; Generated autoloads from international/latin1-disp.el
  
  (defvar latin1-display nil "\
@@@ -16649,7 -16745,7 +16685,7 @@@ use either \\[customize] or the functio
  ;;;***
  \f
  ;;;### (autoloads (turn-on-lazy-lock lazy-lock-mode) "lazy-lock"
- ;;;;;;  "obsolete/lazy-lock.el" (17385 8495))
+ ;;;;;;  "obsolete/lazy-lock.el" (17843 45625))
  ;;; Generated autoloads from obsolete/lazy-lock.el
  
  (autoload (quote lazy-lock-mode) "lazy-lock" "\
@@@ -16717,7 -16813,7 +16753,7 @@@ Unconditionally turn on Lazy Lock mode
  ;;;***
  \f
  ;;;### (autoloads (ld-script-mode) "ld-script" "progmodes/ld-script.el"
- ;;;;;;  (17788 21816))
+ ;;;;;;  (17843 45628))
  ;;; Generated autoloads from progmodes/ld-script.el
  
  (add-to-list (quote auto-mode-alist) (quote ("\\.ld[si]?\\>" . ld-script-mode)))
@@@ -16732,7 -16828,7 +16768,7 @@@ A major mode to edit GNU ld script file
  ;;;***
  \f
  ;;;### (autoloads (ledit-from-lisp-mode ledit-mode) "ledit" "ledit.el"
- ;;;;;;  (17781 39501))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from ledit.el
  
  (defconst ledit-save-files t "\
@@@ -16767,7 -16863,7 +16803,7 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads (life) "life" "play/life.el" (17674 51268))
+ ;;;### (autoloads (life) "life" "play/life.el" (17843 45626))
  ;;; Generated autoloads from play/life.el
  
  (autoload (quote life) "life" "\
@@@ -16780,8 -16876,8 +16816,8 @@@ generations (this defaults to 1)
  
  ;;;***
  \f
- ;;;### (autoloads (unload-feature) "loadhist" "loadhist.el" (17781
- ;;;;;;  39501))
+ ;;;### (autoloads (unload-feature) "loadhist" "loadhist.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from loadhist.el
  
  (autoload (quote unload-feature) "loadhist" "\
@@@ -16804,7 -16900,7 +16840,7 @@@ such as redefining an Emacs function
  ;;;***
  \f
  ;;;### (autoloads (locate-with-filter locate locate-ls-subdir-switches)
- ;;;;;;  "locate" "locate.el" (17771 1419))
+ ;;;;;;  "locate" "locate.el" (17843 45610))
  ;;; Generated autoloads from locate.el
  
  (defvar locate-ls-subdir-switches "-al" "\
@@@ -16851,7 -16947,7 +16887,7 @@@ except that FILTER is not optional
  
  ;;;***
  \f
- ;;;### (autoloads (log-edit) "log-edit" "log-edit.el" (17781 39502))
+ ;;;### (autoloads (log-edit) "log-edit" "log-edit.el" (17843 45610))
  ;;; Generated autoloads from log-edit.el
  
  (autoload (quote log-edit) "log-edit" "\
@@@ -16872,8 -16968,8 +16908,8 @@@ If BUFFER is non-nil `log-edit' will ju
  
  ;;;***
  \f
- ;;;### (autoloads (log-view-mode) "log-view" "log-view.el" (17587
- ;;;;;;  57939))
+ ;;;### (autoloads (log-view-mode) "log-view" "log-view.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from log-view.el
  
  (autoload (quote log-view-mode) "log-view" "\
@@@ -16883,8 -16979,8 +16919,8 @@@ Major mode for browsing CVS log output
  
  ;;;***
  \f
- ;;;### (autoloads (longlines-mode) "longlines" "longlines.el" (17771
- ;;;;;;  1419))
+ ;;;### (autoloads (longlines-mode) "longlines" "longlines.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from longlines.el
  
  (autoload (quote longlines-mode) "longlines" "\
@@@ -16905,8 -17001,8 +16941,8 @@@ are indicated with a symbol
  ;;;***
  \f
  ;;;### (autoloads (print-region lpr-region print-buffer lpr-buffer
- ;;;;;;  lpr-command lpr-switches printer-name) "lpr" "lpr.el" (17682
- ;;;;;;  43101))
+ ;;;;;;  lpr-command lpr-switches printer-name) "lpr" "lpr.el" (17843
+ ;;;;;;  45610))
  ;;; Generated autoloads from lpr.el
  
  (defvar lpr-windows-system (memq system-type (quote (emx win32 w32 mswindows ms-dos windows-nt))))
@@@ -17000,7 -17096,7 +17036,7 @@@ for further customization of the printe
  ;;;***
  \f
  ;;;### (autoloads (ls-lisp-support-shell-wildcards) "ls-lisp" "ls-lisp.el"
- ;;;;;;  (17781 39502))
+ ;;;;;;  (17843 45610))
  ;;; Generated autoloads from ls-lisp.el
  
  (defvar ls-lisp-support-shell-wildcards t "\
@@@ -17011,8 -17107,8 +17047,8 @@@ Otherwise they are treated as Emacs reg
  
  ;;;***
  \f
- ;;;### (autoloads (phases-of-moon) "lunar" "calendar/lunar.el" (17386
- ;;;;;;  33146))
+ ;;;### (autoloads (phases-of-moon) "lunar" "calendar/lunar.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from calendar/lunar.el
  
  (autoload (quote phases-of-moon) "lunar" "\
@@@ -17025,8 -17121,8 +17061,8 @@@ This function is suitable for executio
  
  ;;;***
  \f
- ;;;### (autoloads (m4-mode) "m4-mode" "progmodes/m4-mode.el" (17394
- ;;;;;;  12938))
+ ;;;### (autoloads (m4-mode) "m4-mode" "progmodes/m4-mode.el" (17843
+ ;;;;;;  45628))
  ;;; Generated autoloads from progmodes/m4-mode.el
  
  (autoload (quote m4-mode) "m4-mode" "\
@@@ -17038,7 -17134,7 +17074,7 @@@ A major mode to edit m4 macro files
  ;;;***
  \f
  ;;;### (autoloads (macroexpand-all) "macroexp" "emacs-lisp/macroexp.el"
- ;;;;;;  (17385 8490))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/macroexp.el
  
  (autoload (quote macroexpand-all) "macroexp" "\
@@@ -17052,7 -17148,7 +17088,7 @@@ definitions to shadow the loaded ones f
  ;;;***
  \f
  ;;;### (autoloads (apply-macro-to-region-lines kbd-macro-query insert-kbd-macro
- ;;;;;;  name-last-kbd-macro) "macros" "macros.el" (17781 39502))
+ ;;;;;;  name-last-kbd-macro) "macros" "macros.el" (17843 45611))
  ;;; Generated autoloads from macros.el
  
  (autoload (quote name-last-kbd-macro) "macros" "\
@@@ -17141,7 -17237,7 +17177,7 @@@ and then select the region of un-tablif
  ;;;***
  \f
  ;;;### (autoloads (what-domain mail-extract-address-components) "mail-extr"
- ;;;;;;  "mail/mail-extr.el" (17385 8494))
+ ;;;;;;  "mail/mail-extr.el" (17843 45621))
  ;;; Generated autoloads from mail/mail-extr.el
  
  (autoload (quote mail-extract-address-components) "mail-extr" "\
@@@ -17173,7 -17269,7 +17209,7 @@@ Convert mail domain DOMAIN to the count
  \f
  ;;;### (autoloads (mail-hist-put-headers-into-history mail-hist-keep-history
  ;;;;;;  mail-hist-enable mail-hist-define-keys) "mail-hist" "mail/mail-hist.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45621))
  ;;; Generated autoloads from mail/mail-hist.el
  
  (autoload (quote mail-hist-define-keys) "mail-hist" "\
@@@ -17204,8 -17300,8 +17240,8 @@@ This function normally would be called 
  \f
  ;;;### (autoloads (mail-fetch-field mail-unquote-printable-region
  ;;;;;;  mail-unquote-printable mail-quote-printable mail-file-babyl-p
- ;;;;;;  mail-use-rfc822) "mail-utils" "mail/mail-utils.el" (17385
- ;;;;;;  8494))
+ ;;;;;;  mail-use-rfc822) "mail-utils" "mail/mail-utils.el" (17843
+ ;;;;;;  45621))
  ;;; Generated autoloads from mail/mail-utils.el
  
  (defvar mail-use-rfc822 nil "\
  Otherwise, (the default) use a smaller, somewhat faster, and
  often correct parser.")
  
- (custom-autoload (quote mail-use-rfc822) "mail-utils")
+ (custom-autoload (quote mail-use-rfc822) "mail-utils" t)
  
  (autoload (quote mail-file-babyl-p) "mail-utils" "\
  Not documented
@@@ -17257,7 -17353,7 +17293,7 @@@ If 4th arg LIST is non-nil, return a li
  ;;;***
  \f
  ;;;### (autoloads (define-mail-abbrev build-mail-abbrevs mail-abbrevs-setup)
- ;;;;;;  "mailabbrev" "mail/mailabbrev.el" (17786 56015))
+ ;;;;;;  "mailabbrev" "mail/mailabbrev.el" (17843 45621))
  ;;; Generated autoloads from mail/mailabbrev.el
  
  (autoload (quote mail-abbrevs-setup) "mailabbrev" "\
@@@ -17280,8 -17376,8 +17316,8 @@@ If DEFINITION contains multiple address
  ;;;***
  \f
  ;;;### (autoloads (mail-complete define-mail-alias expand-mail-aliases
- ;;;;;;  mail-complete-style) "mailalias" "mail/mailalias.el" (17786
- ;;;;;;  56015))
+ ;;;;;;  mail-complete-style) "mailalias" "mail/mailalias.el" (17843
+ ;;;;;;  45621))
  ;;; Generated autoloads from mail/mailalias.el
  
  (defvar mail-complete-style (quote angles) "\
@@@ -17327,7 -17423,7 +17363,7 @@@ current header, calls `mail-complete-fu
  ;;;***
  \f
  ;;;### (autoloads (mailclient-send-it) "mailclient" "mail/mailclient.el"
- ;;;;;;  (17385 8494))
+ ;;;;;;  (17843 45621))
  ;;; Generated autoloads from mail/mailclient.el
  
  (autoload (quote mailclient-send-it) "mailclient" "\
@@@ -17341,7 -17437,7 +17377,7 @@@ The mail client is taken to be the hand
  \f
  ;;;### (autoloads (makefile-imake-mode makefile-bsdmake-mode makefile-makepp-mode
  ;;;;;;  makefile-gmake-mode makefile-automake-mode makefile-mode)
- ;;;;;;  "make-mode" "progmodes/make-mode.el" (17692 12587))
+ ;;;;;;  "make-mode" "progmodes/make-mode.el" (17843 45628))
  ;;; Generated autoloads from progmodes/make-mode.el
  
  (autoload (quote makefile-mode) "make-mode" "\
@@@ -17458,8 -17554,8 +17494,8 @@@ An adapted `makefile-mode' that knows a
  
  ;;;***
  \f
- ;;;### (autoloads (make-command-summary) "makesum" "makesum.el" (17781
- ;;;;;;  39502))
+ ;;;### (autoloads (make-command-summary) "makesum" "makesum.el" (17843
+ ;;;;;;  45611))
  ;;; Generated autoloads from makesum.el
  
  (autoload (quote make-command-summary) "makesum" "\
@@@ -17470,7 -17566,7 +17506,7 @@@ Previous contents of that buffer are ki
  
  ;;;***
  \f
- ;;;### (autoloads (man-follow man) "man" "man.el" (17786 62407))
+ ;;;### (autoloads (man-follow man) "man" "man.el" (17843 45611))
  ;;; Generated autoloads from man.el
  
  (defalias (quote manual-entry) (quote man))
@@@ -17497,7 -17593,7 +17533,7 @@@ Get a Un*x manual page of the item unde
  
  ;;;***
  \f
- ;;;### (autoloads (master-mode) "master" "master.el" (17781 39502))
+ ;;;### (autoloads (master-mode) "master" "master.el" (17843 45611))
  ;;; Generated autoloads from master.el
  
  (autoload (quote master-mode) "master" "\
@@@ -17519,8 -17615,8 +17555,8 @@@ yourself the value of `master-of' by ca
  
  ;;;***
  \f
- ;;;### (autoloads (menu-bar-mode) "menu-bar" "menu-bar.el" (17788
- ;;;;;;  29144))
+ ;;;### (autoloads (menu-bar-mode) "menu-bar" "menu-bar.el" (17843
+ ;;;;;;  45611))
  ;;; Generated autoloads from menu-bar.el
  
  (put (quote menu-bar-mode) (quote standard-value) (quote (t)))
@@@ -17555,7 -17651,7 +17591,7 @@@ turn on menu bars; otherwise, turn off 
  ;;;;;;  message-cite-function message-yank-prefix message-citation-line-function
  ;;;;;;  message-send-mail-function message-user-organization-file
  ;;;;;;  message-signature-separator message-from-style) "message"
- ;;;;;;  "gnus/message.el" (17756 33825))
+ ;;;;;;  "gnus/message.el" (17843 45617))
  ;;; Generated autoloads from gnus/message.el
  
  (defvar message-from-style (quote default) "\
@@@ -17809,7 -17905,7 +17845,7 @@@ which specify the range to operate on
  ;;;***
  \f
  ;;;### (autoloads (metapost-mode metafont-mode) "meta-mode" "progmodes/meta-mode.el"
- ;;;;;;  (17394 12938))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/meta-mode.el
  
  (autoload (quote metafont-mode) "meta-mode" "\
@@@ -17836,7 -17932,7 +17872,7 @@@ Turning on MetaPost mode calls the valu
  \f
  ;;;### (autoloads (metamail-region metamail-buffer metamail-interpret-body
  ;;;;;;  metamail-interpret-header) "metamail" "mail/metamail.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45621))
  ;;; Generated autoloads from mail/metamail.el
  
  (autoload (quote metamail-interpret-header) "metamail" "\
@@@ -17881,7 -17977,7 +17917,7 @@@ redisplayed as output is inserted
  \f
  ;;;### (autoloads (mh-fully-kill-draft mh-send-letter mh-user-agent-compose
  ;;;;;;  mh-smail-batch mh-smail-other-window mh-smail) "mh-comp"
- ;;;;;;  "mh-e/mh-comp.el" (17689 24335))
+ ;;;;;;  "mh-e/mh-comp.el" (17843 45622))
  ;;; Generated autoloads from mh-e/mh-comp.el
  
  (autoload (quote mh-smail) "mh-comp" "\
@@@ -17968,7 -18064,7 +18004,7 @@@ delete the draft message
  
  ;;;***
  \f
- ;;;### (autoloads (mh-version) "mh-e" "mh-e/mh-e.el" (17752 39352))
+ ;;;### (autoloads (mh-version) "mh-e" "mh-e/mh-e.el" (17843 45622))
  ;;; Generated autoloads from mh-e/mh-e.el
  
  (put (quote mh-progs) (quote risky-local-variable) t)
@@@ -17985,7 -18081,7 +18021,7 @@@ Display version information about MH-E 
  ;;;***
  \f
  ;;;### (autoloads (mh-folder-mode mh-nmail mh-rmail) "mh-folder"
- ;;;;;;  "mh-e/mh-folder.el" (17485 5461))
+ ;;;;;;  "mh-e/mh-folder.el" (17843 45622))
  ;;; Generated autoloads from mh-e/mh-folder.el
  
  (autoload (quote mh-rmail) "mh-folder" "\
@@@ -18067,7 -18163,7 +18103,7 @@@ perform the operation on all messages i
  ;;;***
  \f
  ;;;### (autoloads (midnight-delay-set clean-buffer-list) "midnight"
- ;;;;;;  "midnight.el" (17781 39502))
+ ;;;;;;  "midnight.el" (17843 45611))
  ;;; Generated autoloads from midnight.el
  
  (autoload (quote clean-buffer-list) "midnight" "\
@@@ -18094,18 -18190,17 +18130,17 @@@ to its second argument TM
  ;;;***
  \f
  ;;;### (autoloads (minibuffer-electric-default-mode) "minibuf-eldef"
- ;;;;;;  "minibuf-eldef.el" (17385 8487))
+ ;;;;;;  "minibuf-eldef.el" (17843 45611))
  ;;; Generated autoloads from minibuf-eldef.el
  
  (defvar minibuffer-electric-default-mode nil "\
  Non-nil if Minibuffer-Electric-Default mode is enabled.
  See the command `minibuffer-electric-default-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `minibuffer-electric-default-mode'.")
- (custom-autoload (quote minibuffer-electric-default-mode) "minibuf-eldef")
+ either customize it (see the info node `Easy Customization')
+ or call the function `minibuffer-electric-default-mode'.")
  
- (put (quote minibuffer-electric-default-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote minibuffer-electric-default-mode) "minibuf-eldef" nil)
  
  (autoload (quote minibuffer-electric-default-mode) "minibuf-eldef" "\
  Toggle Minibuffer Electric Default mode.
@@@ -18123,7 -18218,7 +18158,7 @@@ Returns non-nil if the new state is ena
  ;;;***
  \f
  ;;;### (autoloads (mixal-mode) "mixal-mode" "progmodes/mixal-mode.el"
- ;;;;;;  (17394 12938))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/mixal-mode.el
  
  (autoload (quote mixal-mode) "mixal-mode" "\
@@@ -18138,7 -18233,7 +18173,7 @@@ Major mode for the mixal asm language
  \f
  ;;;### (autoloads (malayalam-composition-function malayalam-post-read-conversion
  ;;;;;;  malayalam-compose-region) "mlm-util" "language/mlm-util.el"
- ;;;;;;  (17788 21816))
+ ;;;;;;  (17843 45620))
  ;;; Generated autoloads from language/mlm-util.el
  
  (autoload (quote malayalam-compose-region) "mlm-util" "\
@@@ -18161,7 -18256,7 +18196,7 @@@ PATTERN regexp
  ;;;***
  \f
  ;;;### (autoloads (mm-inline-external-body mm-extern-cache-contents)
- ;;;;;;  "mm-extern" "gnus/mm-extern.el" (17632 41885))
+ ;;;;;;  "mm-extern" "gnus/mm-extern.el" (17843 45617))
  ;;; Generated autoloads from gnus/mm-extern.el
  
  (autoload (quote mm-extern-cache-contents) "mm-extern" "\
@@@ -18180,7 -18275,7 +18215,7 @@@ If NO-DISPLAY is nil, display it. Other
  ;;;***
  \f
  ;;;### (autoloads (mm-inline-partial) "mm-partial" "gnus/mm-partial.el"
- ;;;;;;  (17385 8493))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/mm-partial.el
  
  (autoload (quote mm-inline-partial) "mm-partial" "\
@@@ -18194,7 -18289,7 +18229,7 @@@ If NO-DISPLAY is nil, display it. Other
  ;;;***
  \f
  ;;;### (autoloads (mm-url-insert-file-contents-external mm-url-insert-file-contents)
- ;;;;;;  "mm-url" "gnus/mm-url.el" (17780 18172))
+ ;;;;;;  "mm-url" "gnus/mm-url.el" (17843 45617))
  ;;; Generated autoloads from gnus/mm-url.el
  
  (autoload (quote mm-url-insert-file-contents) "mm-url" "\
@@@ -18211,7 -18306,7 +18246,7 @@@ Insert file contents of URL using `mm-u
  ;;;***
  \f
  ;;;### (autoloads (mm-uu-dissect-text-parts mm-uu-dissect) "mm-uu"
- ;;;;;;  "gnus/mm-uu.el" (17761 54014))
+ ;;;;;;  "gnus/mm-uu.el" (17843 45617))
  ;;; Generated autoloads from gnus/mm-uu.el
  
  (autoload (quote mm-uu-dissect) "mm-uu" "\
@@@ -18231,7 -18326,7 +18266,7 @@@ Assume text has been decoded if DECODE
  ;;;***
  \f
  ;;;### (autoloads (mml1991-sign mml1991-encrypt) "mml1991" "gnus/mml1991.el"
- ;;;;;;  (17495 43954))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/mml1991.el
  
  (autoload (quote mml1991-encrypt) "mml1991" "\
@@@ -18248,7 -18343,7 +18283,7 @@@ Not documente
  \f
  ;;;### (autoloads (mml2015-self-encrypt mml2015-sign mml2015-encrypt
  ;;;;;;  mml2015-verify-test mml2015-verify mml2015-decrypt-test mml2015-decrypt)
- ;;;;;;  "mml2015" "gnus/mml2015.el" (17776 24487))
+ ;;;;;;  "mml2015" "gnus/mml2015.el" (17843 45617))
  ;;; Generated autoloads from gnus/mml2015.el
  
  (autoload (quote mml2015-decrypt) "mml2015" "\
@@@ -18321,7 -18416,7 +18356,7 @@@ followed by the first character of the 
  ;;;***
  \f
  ;;;### (autoloads (unmorse-region morse-region) "morse" "play/morse.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45626))
  ;;; Generated autoloads from play/morse.el
  
  (autoload (quote morse-region) "morse" "\
@@@ -18336,8 -18431,8 +18371,8 @@@ Convert morse coded text in region to o
  
  ;;;***
  \f
- ;;;### (autoloads (mouse-sel-mode) "mouse-sel" "mouse-sel.el" (17786
- ;;;;;;  62747))
+ ;;;### (autoloads (mouse-sel-mode) "mouse-sel" "mouse-sel.el" (17843
+ ;;;;;;  45611))
  ;;; Generated autoloads from mouse-sel.el
  
  (defvar mouse-sel-mode nil "\
@@@ -18389,7 -18484,7 +18424,7 @@@ primary selection and region
  
  ;;;***
  \f
- ;;;### (autoloads (mpuz) "mpuz" "play/mpuz.el" (17786 56015))
+ ;;;### (autoloads (mpuz) "mpuz" "play/mpuz.el" (17843 45626))
  ;;; Generated autoloads from play/mpuz.el
  
  (autoload (quote mpuz) "mpuz" "\
@@@ -18399,18 -18494,17 +18434,17 @@@ Multiplication puzzle with GNU Emacs
  
  ;;;***
  \f
- ;;;### (autoloads (msb-mode) "msb" "msb.el" (17560 14582))
+ ;;;### (autoloads (msb-mode) "msb" "msb.el" (17843 45611))
  ;;; Generated autoloads from msb.el
  
  (defvar msb-mode nil "\
  Non-nil if Msb mode is enabled.
  See the command `msb-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `msb-mode'.")
- (custom-autoload (quote msb-mode) "msb")
+ either customize it (see the info node `Easy Customization')
+ or call the function `msb-mode'.")
  
- (put (quote msb-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote msb-mode) "msb" nil)
  
  (autoload (quote msb-mode) "msb" "\
  Toggle Msb mode.
@@@ -18427,7 -18521,7 +18461,7 @@@ different buffer menu using the functio
  ;;;;;;  describe-current-coding-system describe-current-coding-system-briefly
  ;;;;;;  describe-coding-system describe-character-set list-charset-chars
  ;;;;;;  read-charset list-character-sets) "mule-diag" "international/mule-diag.el"
- ;;;;;;  (17792 9561))
+ ;;;;;;  (17843 45619))
  ;;; Generated autoloads from international/mule-diag.el
  
  (defvar non-iso-charset-alist (\` ((mac-roman (ascii latin-iso8859-1 mule-unicode-2500-33ff mule-unicode-0100-24ff mule-unicode-e000-ffff) mac-roman-decoder ((0 255))) (viscii (ascii vietnamese-viscii-lower vietnamese-viscii-upper) viet-viscii-nonascii-translation-table ((0 255))) (vietnamese-tcvn (ascii vietnamese-viscii-lower vietnamese-viscii-upper) viet-tcvn-nonascii-translation-table ((0 255))) (koi8-r (ascii cyrillic-iso8859-5) cyrillic-koi8-r-nonascii-translation-table ((32 255))) (alternativnyj (ascii cyrillic-iso8859-5) cyrillic-alternativnyj-nonascii-translation-table ((32 255))) (koi8-u (ascii cyrillic-iso8859-5 mule-unicode-0100-24ff) cyrillic-koi8-u-nonascii-translation-table ((32 255))) (big5 (ascii chinese-big5-1 chinese-big5-2) decode-big5-char ((32 127) ((161 254) 64 126 161 254))) (sjis (ascii katakana-jisx0201 japanese-jisx0208) decode-sjis-char ((32 127 161 223) ((129 159 224 239) 64 126 128 252))))) "\
@@@ -18601,7 -18695,7 +18635,7 @@@ system which uses fontsets)
  ;;;;;;  coding-system-translation-table-for-decode coding-system-pre-write-conversion
  ;;;;;;  coding-system-post-read-conversion lookup-nested-alist set-nested-alist
  ;;;;;;  truncate-string-to-width store-substring string-to-sequence)
- ;;;;;;  "mule-util" "international/mule-util.el" (17792 9561))
+ ;;;;;;  "mule-util" "international/mule-util.el" (17843 45619))
  ;;; Generated autoloads from international/mule-util.el
  
  (autoload (quote string-to-sequence) "mule-util" "\
@@@ -18730,18 -18824,17 +18764,17 @@@ basis, this may not be accurate
  ;;;***
  \f
  ;;;### (autoloads (mwheel-install mouse-wheel-mode) "mwheel" "mwheel.el"
- ;;;;;;  (17515 24181))
+ ;;;;;;  (17843 45611))
  ;;; Generated autoloads from mwheel.el
  
  (defvar mouse-wheel-mode nil "\
  Non-nil if Mouse-Wheel mode is enabled.
  See the command `mouse-wheel-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `mouse-wheel-mode'.")
- (custom-autoload (quote mouse-wheel-mode) "mwheel")
+ either customize it (see the info node `Easy Customization')
+ or call the function `mouse-wheel-mode'.")
  
- (put (quote mouse-wheel-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote mouse-wheel-mode) "mwheel" nil)
  
  (autoload (quote mouse-wheel-mode) "mwheel" "\
  Toggle mouse wheel support.
@@@ -18760,7 -18853,7 +18793,7 @@@ Enable mouse wheel support
  ;;;### (autoloads (network-connection network-connection-to-service
  ;;;;;;  whois-reverse-lookup whois finger ftp run-dig dns-lookup-host
  ;;;;;;  nslookup nslookup-host route arp netstat ipconfig ping traceroute)
- ;;;;;;  "net-utils" "net/net-utils.el" (17385 8495))
+ ;;;;;;  "net-utils" "net/net-utils.el" (17843 45624))
  ;;; Generated autoloads from net/net-utils.el
  
  (autoload (quote traceroute) "net-utils" "\
@@@ -18856,7 -18949,7 +18889,7 @@@ Open a network connection to HOST on PO
  ;;;;;;  uncomment-region comment-kill comment-set-column comment-indent
  ;;;;;;  comment-indent-default comment-normalize-vars comment-multi-line
  ;;;;;;  comment-padding comment-style comment-column) "newcomment"
- ;;;;;;  "newcomment.el" (17781 39502))
+ ;;;;;;  "newcomment.el" (17843 45611))
  ;;; Generated autoloads from newcomment.el
  
  (defalias (quote indent-for-comment) (quote comment-indent))
@@@ -19052,7 -19145,7 +19085,7 @@@ unless optional argument SOFT is non-ni
  \f
  ;;;### (autoloads (newsticker-show-news newsticker-start-ticker newsticker-start
  ;;;;;;  newsticker-ticker-running-p newsticker-running-p) "newsticker"
- ;;;;;;  "net/newsticker.el" (17385 8495))
+ ;;;;;;  "net/newsticker.el" (17843 45624))
  ;;; Generated autoloads from net/newsticker.el
  
  (autoload (quote newsticker-running-p) "newsticker" "\
@@@ -19094,7 -19187,7 +19127,7 @@@ Switch to newsticker buffer.  You may w
  ;;;***
  \f
  ;;;### (autoloads (nndiary-generate-nov-databases) "nndiary" "gnus/nndiary.el"
- ;;;;;;  (17740 981))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/nndiary.el
  
  (autoload (quote nndiary-generate-nov-databases) "nndiary" "\
@@@ -19104,8 -19197,8 +19137,8 @@@ Generate NOV databases in all nndiary d
  
  ;;;***
  \f
- ;;;### (autoloads (nndoc-add-type) "nndoc" "gnus/nndoc.el" (17385
- ;;;;;;  8494))
+ ;;;### (autoloads (nndoc-add-type) "nndoc" "gnus/nndoc.el" (17843
+ ;;;;;;  45617))
  ;;; Generated autoloads from gnus/nndoc.el
  
  (autoload (quote nndoc-add-type) "nndoc" "\
@@@ -19120,7 -19213,7 +19153,7 @@@ symbol in the alist
  ;;;***
  \f
  ;;;### (autoloads (nnfolder-generate-active-file) "nnfolder" "gnus/nnfolder.el"
- ;;;;;;  (17394 12936))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/nnfolder.el
  
  (autoload (quote nnfolder-generate-active-file) "nnfolder" "\
@@@ -19132,7 -19225,7 +19165,7 @@@ This command does not work if you use s
  ;;;***
  \f
  ;;;### (autoloads (nnkiboze-generate-groups) "nnkiboze" "gnus/nnkiboze.el"
- ;;;;;;  (17788 21815))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/nnkiboze.el
  
  (autoload (quote nnkiboze-generate-groups) "nnkiboze" "\
@@@ -19144,7 -19237,7 +19177,7 @@@ Finds out what articles are to be part 
  ;;;***
  \f
  ;;;### (autoloads (nnml-generate-nov-databases) "nnml" "gnus/nnml.el"
- ;;;;;;  (17385 8494))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/nnml.el
  
  (autoload (quote nnml-generate-nov-databases) "nnml" "\
@@@ -19155,7 -19248,7 +19188,7 @@@ Generate NOV databases in all nnml dire
  ;;;***
  \f
  ;;;### (autoloads (nnsoup-revert-variables nnsoup-set-variables nnsoup-pack-replies)
- ;;;;;;  "nnsoup" "gnus/nnsoup.el" (17740 981))
+ ;;;;;;  "nnsoup" "gnus/nnsoup.el" (17843 45617))
  ;;; Generated autoloads from gnus/nnsoup.el
  
  (autoload (quote nnsoup-pack-replies) "nnsoup" "\
@@@ -19176,7 -19269,7 +19209,7 @@@ Revert posting and mailing methods to t
  ;;;***
  \f
  ;;;### (autoloads (disable-command enable-command disabled-command-function)
- ;;;;;;  "novice" "novice.el" (17781 39502))
+ ;;;;;;  "novice" "novice.el" (17843 45611))
  ;;; Generated autoloads from novice.el
  
  (defvar disabled-command-function (quote disabled-command-function) "\
@@@ -19209,7 -19302,7 +19242,7 @@@ to future sessions
  ;;;***
  \f
  ;;;### (autoloads (nroff-mode) "nroff-mode" "textmodes/nroff-mode.el"
- ;;;;;;  (17385 8496))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/nroff-mode.el
  
  (autoload (quote nroff-mode) "nroff-mode" "\
@@@ -19224,7 -19317,7 +19257,7 @@@ closing requests for requests that are 
  ;;;***
  \f
  ;;;### (autoloads (octave-help) "octave-hlp" "progmodes/octave-hlp.el"
- ;;;;;;  (17394 12938))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/octave-hlp.el
  
  (autoload (quote octave-help) "octave-hlp" "\
@@@ -19238,7 -19331,7 +19271,7 @@@ If KEY is not a string, prompt for it w
  ;;;***
  \f
  ;;;### (autoloads (inferior-octave) "octave-inf" "progmodes/octave-inf.el"
- ;;;;;;  (17730 6653))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/octave-inf.el
  
  (autoload (quote inferior-octave) "octave-inf" "\
@@@ -19261,7 -19354,7 +19294,7 @@@ startup file, `~/.emacs-octave'
  ;;;***
  \f
  ;;;### (autoloads (octave-mode) "octave-mod" "progmodes/octave-mod.el"
- ;;;;;;  (17781 39502))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/octave-mod.el
  
  (autoload (quote octave-mode) "octave-mod" "\
@@@ -19360,7 -19453,7 +19393,7 @@@ including a reproducible test case and 
  ;;;***
  \f
  ;;;### (autoloads (edit-options list-options) "options" "obsolete/options.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45625))
  ;;; Generated autoloads from obsolete/options.el
  
  (autoload (quote list-options) "options" "\
@@@ -19387,7 -19480,7 +19420,7 @@@ The Custom feature is intended to make 
  ;;;;;;  org-store-link org-tags-view org-diary org-cycle-agenda-files
  ;;;;;;  org-todo-list org-agenda-list org-batch-agenda org-agenda
  ;;;;;;  org-global-cycle org-cycle org-mode) "org" "textmodes/org.el"
- ;;;;;;  (17798 49643))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/org.el
  
  (autoload (quote org-mode) "org" "\
@@@ -19655,7 -19748,7 +19688,7 @@@ The file is stored under the name `org-
  ;;;***
  \f
  ;;;### (autoloads (outline-minor-mode outline-mode) "outline" "outline.el"
- ;;;;;;  (17797 50970))
+ ;;;;;;  (17843 45611))
  ;;; Generated autoloads from outline.el
  (put 'outline-regexp 'safe-local-variable 'string-or-null-p)
  
@@@ -19711,8 -19804,8 +19744,8 @@@ See the command `outline-mode' for mor
  
  ;;;***
  \f
- ;;;### (autoloads nil "paragraphs" "textmodes/paragraphs.el" (17495
- ;;;;;;  43955))
+ ;;;### (autoloads nil "paragraphs" "textmodes/paragraphs.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from textmodes/paragraphs.el
  (put 'paragraph-start 'safe-local-variable 'stringp)
  (put 'paragraph-separate 'safe-local-variable 'stringp)
  
  ;;;***
  \f
- ;;;### (autoloads (show-paren-mode) "paren" "paren.el" (17779 6042))
+ ;;;### (autoloads (show-paren-mode) "paren" "paren.el" (17843 45611))
  ;;; Generated autoloads from paren.el
  
  (defvar show-paren-mode nil "\
@@@ -19751,7 -19844,7 +19784,7 @@@ in `show-paren-style' after `show-paren
  ;;;***
  \f
  ;;;### (autoloads (parse-time-string) "parse-time" "calendar/parse-time.el"
- ;;;;;;  (17386 33146))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from calendar/parse-time.el
  
  (autoload (quote parse-time-string) "parse-time" "\
@@@ -19763,8 -19856,8 +19796,8 @@@ unknown are returned as nil
  
  ;;;***
  \f
- ;;;### (autoloads (pascal-mode) "pascal" "progmodes/pascal.el" (17394
- ;;;;;;  12938))
+ ;;;### (autoloads (pascal-mode) "pascal" "progmodes/pascal.el" (17843
+ ;;;;;;  45629))
  ;;; Generated autoloads from progmodes/pascal.el
  
  (autoload (quote pascal-mode) "pascal" "\
@@@ -19817,7 -19910,7 +19850,7 @@@ no args, if that value is non-nil
  ;;;***
  \f
  ;;;### (autoloads (pc-bindings-mode) "pc-mode" "emulation/pc-mode.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emulation/pc-mode.el
  
  (autoload (quote pc-bindings-mode) "pc-mode" "\
@@@ -19835,18 -19928,17 +19868,17 @@@ C-Escape does list-buffers
  ;;;***
  \f
  ;;;### (autoloads (pc-selection-mode pc-selection-mode) "pc-select"
- ;;;;;;  "emulation/pc-select.el" (17385 8491))
+ ;;;;;;  "emulation/pc-select.el" (17843 45615))
  ;;; Generated autoloads from emulation/pc-select.el
  
  (defvar pc-selection-mode nil "\
  Non-nil if Pc-Selection mode is enabled.
  See the command `pc-selection-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `pc-selection-mode'.")
- (custom-autoload (quote pc-selection-mode) "pc-select")
+ either customize it (see the info node `Easy Customization')
+ or call the function `pc-selection-mode'.")
  
- (put (quote pc-selection-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote pc-selection-mode) "pc-select" nil)
  
  (autoload (quote pc-selection-mode) "pc-select" "\
  Change mark behavior to emulate Motif, MAC or MS-Windows cut and paste style.
@@@ -19908,12 -20000,12 +19940,12 @@@ This mode enables Delete Selection mod
  Setting this variable directly does not take effect;
  you must modify it using \\[customize] or \\[pc-selection-mode].")
  
- (custom-autoload (quote pc-selection-mode) "pc-select")
+ (custom-autoload (quote pc-selection-mode) "pc-select" nil)
  
  ;;;***
  \f
- ;;;### (autoloads (pcomplete/cvs) "pcmpl-cvs" "pcmpl-cvs.el" (17781
- ;;;;;;  39502))
+ ;;;### (autoloads (pcomplete/cvs) "pcmpl-cvs" "pcmpl-cvs.el" (17843
+ ;;;;;;  45611))
  ;;; Generated autoloads from pcmpl-cvs.el
  
  (autoload (quote pcomplete/cvs) "pcmpl-cvs" "\
@@@ -19924,7 -20016,7 +19956,7 @@@ Completion rules for the `cvs' command
  ;;;***
  \f
  ;;;### (autoloads (pcomplete/tar pcomplete/make pcomplete/bzip2 pcomplete/gzip)
- ;;;;;;  "pcmpl-gnu" "pcmpl-gnu.el" (17781 39502))
+ ;;;;;;  "pcmpl-gnu" "pcmpl-gnu.el" (17843 45611))
  ;;; Generated autoloads from pcmpl-gnu.el
  
  (autoload (quote pcomplete/gzip) "pcmpl-gnu" "\
@@@ -19952,7 -20044,7 +19984,7 @@@ Completion for the GNU tar utility
  ;;;***
  \f
  ;;;### (autoloads (pcomplete/mount pcomplete/umount pcomplete/kill)
- ;;;;;;  "pcmpl-linux" "pcmpl-linux.el" (17781 39502))
+ ;;;;;;  "pcmpl-linux" "pcmpl-linux.el" (17843 45611))
  ;;; Generated autoloads from pcmpl-linux.el
  
  (autoload (quote pcomplete/kill) "pcmpl-linux" "\
@@@ -19972,8 -20064,8 +20004,8 @@@ Completion for GNU/Linux `mount'
  
  ;;;***
  \f
- ;;;### (autoloads (pcomplete/rpm) "pcmpl-rpm" "pcmpl-rpm.el" (17781
- ;;;;;;  39502))
+ ;;;### (autoloads (pcomplete/rpm) "pcmpl-rpm" "pcmpl-rpm.el" (17843
+ ;;;;;;  45611))
  ;;; Generated autoloads from pcmpl-rpm.el
  
  (autoload (quote pcomplete/rpm) "pcmpl-rpm" "\
@@@ -19989,7 -20081,7 +20021,7 @@@ You can use \\[eshell-report-bug] to d
  \f
  ;;;### (autoloads (pcomplete/chgrp pcomplete/chown pcomplete/which
  ;;;;;;  pcomplete/xargs pcomplete/rm pcomplete/rmdir pcomplete/cd)
- ;;;;;;  "pcmpl-unix" "pcmpl-unix.el" (17781 39502))
+ ;;;;;;  "pcmpl-unix" "pcmpl-unix.el" (17843 45611))
  ;;; Generated autoloads from pcmpl-unix.el
  
  (autoload (quote pcomplete/cd) "pcmpl-unix" "\
@@@ -20035,8 -20127,8 +20067,8 @@@ Completion for the `chgrp' command
  \f
  ;;;### (autoloads (pcomplete-shell-setup pcomplete-comint-setup pcomplete-list
  ;;;;;;  pcomplete-help pcomplete-expand pcomplete-continue pcomplete-expand-and-complete
- ;;;;;;  pcomplete-reverse pcomplete) "pcomplete" "pcomplete.el" (17476
- ;;;;;;  4798))
+ ;;;;;;  pcomplete-reverse pcomplete) "pcomplete" "pcomplete.el" (17843
+ ;;;;;;  45611))
  ;;; Generated autoloads from pcomplete.el
  
  (autoload (quote pcomplete) "pcomplete" "\
@@@ -20095,7 -20187,7 +20127,7 @@@ Setup shell-mode to use pcomplete
  \f
  ;;;### (autoloads (cvs-dired-use-hook cvs-dired-action cvs-status
  ;;;;;;  cvs-update cvs-examine cvs-quickdir cvs-checkout) "pcvs"
- ;;;;;;  "pcvs.el" (17781 39502))
+ ;;;;;;  "pcvs.el" (17843 45612))
  ;;; Generated autoloads from pcvs.el
  
  (autoload (quote cvs-checkout) "pcvs" "\
@@@ -20172,7 -20264,7 +20204,7 @@@ The exact behavior is determined also b
  
  ;;;***
  \f
- ;;;### (autoloads nil "pcvs-defs" "pcvs-defs.el" (17781 39502))
+ ;;;### (autoloads nil "pcvs-defs" "pcvs-defs.el" (17843 45611))
  ;;; Generated autoloads from pcvs-defs.el
  
  (defvar cvs-global-menu (let ((m (make-sparse-keymap "PCL-CVS"))) (define-key m [status] (quote (menu-item "Directory Status" cvs-status :help "A more verbose status of a workarea"))) (define-key m [checkout] (quote (menu-item "Checkout Module" cvs-checkout :help "Check out a module from the repository"))) (define-key m [update] (quote (menu-item "Update Directory" cvs-update :help "Fetch updates from the repository"))) (define-key m [examine] (quote (menu-item "Examine Directory" cvs-examine :help "Examine the current state of a workarea"))) (fset (quote cvs-global-menu) m)))
  ;;;***
  \f
  ;;;### (autoloads (perl-mode) "perl-mode" "progmodes/perl-mode.el"
- ;;;;;;  (17515 24182))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/perl-mode.el
  
  (autoload (quote perl-mode) "perl-mode" "\
@@@ -20238,7 -20330,7 +20270,7 @@@ Turning on Perl mode runs the normal ho
  ;;;### (autoloads (pgg-snarf-keys pgg-snarf-keys-region pgg-insert-key
  ;;;;;;  pgg-verify pgg-verify-region pgg-sign pgg-sign-region pgg-decrypt
  ;;;;;;  pgg-decrypt-region pgg-encrypt pgg-encrypt-symmetric pgg-encrypt-symmetric-region
- ;;;;;;  pgg-encrypt-region) "pgg" "pgg.el" (17661 55157))
+ ;;;;;;  pgg-encrypt-region) "pgg" "pgg.el" (17843 45612))
  ;;; Generated autoloads from pgg.el
  
  (autoload (quote pgg-encrypt-region) "pgg" "\
@@@ -20372,7 -20464,7 +20404,7 @@@ Import public keys in the current buffe
  ;;;***
  \f
  ;;;### (autoloads (pgg-gpg-symmetric-key-p) "pgg-gpg" "pgg-gpg.el"
- ;;;;;;  (17797 53312))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from pgg-gpg.el
  
  (autoload (quote pgg-gpg-symmetric-key-p) "pgg-gpg" "\
@@@ -20383,7 -20475,7 +20415,7 @@@ True if decoded armor MESSAGE-KEYS has 
  ;;;***
  \f
  ;;;### (autoloads (picture-mode) "picture" "textmodes/picture.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/picture.el
  
  (autoload (quote picture-mode) "picture" "\
@@@ -20464,7 -20556,7 +20496,7 @@@ they are not defaultly assigned to keys
  ;;;***
  \f
  ;;;### (autoloads (po-find-file-coding-system) "po" "textmodes/po.el"
- ;;;;;;  (17601 9092))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/po.el
  
  (autoload (quote po-find-file-coding-system) "po" "\
@@@ -20475,7 -20567,7 +20507,7 @@@ Called through `file-coding-system-alis
  
  ;;;***
  \f
- ;;;### (autoloads (pong) "pong" "play/pong.el" (17551 7908))
+ ;;;### (autoloads (pong) "pong" "play/pong.el" (17843 45626))
  ;;; Generated autoloads from play/pong.el
  
  (autoload (quote pong) "pong" "\
@@@ -20492,7 -20584,7 +20524,7 @@@ pong-mode keybindings:\\<pong-mode-map
  ;;;***
  \f
  ;;;### (autoloads (pp-eval-last-sexp pp-eval-expression pp pp-buffer
- ;;;;;;  pp-to-string) "pp" "emacs-lisp/pp.el" (17740 981))
+ ;;;;;;  pp-to-string) "pp" "emacs-lisp/pp.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/pp.el
  
  (autoload (quote pp-to-string) "pp" "\
@@@ -20516,15 -20608,10 +20548,10 @@@ Output stream is STREAM, or value of `s
  \(fn OBJECT &optional STREAM)" nil nil)
  
  (autoload (quote pp-eval-expression) "pp" "\
- Evaluate an expression, then pretty-print value EXPVAL into a new buffer.
- If pretty-printed EXPVAL fits on one line, display it in the echo
- area instead.  Also add EXPVAL to the front of the list
- in the variable `values'.
- Non-interactively, the argument is the value, EXPVAL, not the expression
- to evaluate.
+ Evaluate EXPRESSION and pretty-print its value.
+ Also add the value to the front of the list in the variable `values'.
  
- \(fn EXPVAL)" t nil)
+ \(fn EXPRESSION)" t nil)
  
  (autoload (quote pp-eval-last-sexp) "pp" "\
  Run `pp-eval-expression' on sexp before point (which see).
@@@ -20553,7 -20640,7 +20580,7 @@@ Ignores leading comment characters
  ;;;;;;  pr-ps-buffer-print pr-ps-buffer-using-ghostscript pr-ps-buffer-preview
  ;;;;;;  pr-ps-directory-ps-print pr-ps-directory-print pr-ps-directory-using-ghostscript
  ;;;;;;  pr-ps-directory-preview pr-interface) "printing" "printing.el"
- ;;;;;;  (17780 18172))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from printing.el
  
  (autoload (quote pr-interface) "printing" "\
@@@ -21141,7 -21228,7 +21168,7 @@@ are both set to t
  ;;;***
  \f
  ;;;### (autoloads (switch-to-prolog prolog-mode) "prolog" "progmodes/prolog.el"
- ;;;;;;  (17664 20313))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/prolog.el
  
  (autoload (quote prolog-mode) "prolog" "\
@@@ -21164,7 -21251,7 +21191,7 @@@ With prefix argument \\[universal-prefi
  
  ;;;***
  \f
- ;;;### (autoloads nil "ps-bdf" "ps-bdf.el" (17792 9561))
+ ;;;### (autoloads nil "ps-bdf" "ps-bdf.el" (17843 45612))
  ;;; Generated autoloads from ps-bdf.el
  
  (defvar bdf-directory-list (if (memq system-type (quote (ms-dos windows-nt))) (list (expand-file-name "fonts/bdf" installation-directory)) (quote ("/usr/local/share/emacs/fonts/bdf"))) "\
@@@ -21173,8 -21260,8 +21200,8 @@@ The default value is '(\"/usr/local/sha
  
  ;;;***
  \f
- ;;;### (autoloads (ps-mode) "ps-mode" "progmodes/ps-mode.el" (17394
- ;;;;;;  12938))
+ ;;;### (autoloads (ps-mode) "ps-mode" "progmodes/ps-mode.el" (17843
+ ;;;;;;  45629))
  ;;; Generated autoloads from progmodes/ps-mode.el
  
  (autoload (quote ps-mode) "ps-mode" "\
@@@ -21223,7 -21310,7 +21250,7 @@@ Typing \\<ps-run-mode-map>\\[ps-run-got
  ;;;### (autoloads (ps-mule-begin-page ps-mule-begin-job ps-mule-encode-header-string
  ;;;;;;  ps-mule-initialize ps-mule-plot-composition ps-mule-plot-string
  ;;;;;;  ps-mule-set-ascii-font ps-mule-prepare-ascii-font ps-multibyte-buffer)
- ;;;;;;  "ps-mule" "ps-mule.el" (17780 18172))
+ ;;;;;;  "ps-mule" "ps-mule.el" (17843 45612))
  ;;; Generated autoloads from ps-mule.el
  
  (defvar ps-multibyte-buffer nil "\
@@@ -21344,8 -21431,8 +21371,8 @@@ Not documente
  ;;;;;;  ps-spool-region ps-spool-buffer-with-faces ps-spool-buffer
  ;;;;;;  ps-print-region-with-faces ps-print-region ps-print-buffer-with-faces
  ;;;;;;  ps-print-buffer ps-print-customize ps-print-color-p ps-paper-type
- ;;;;;;  ps-page-dimensions-database) "ps-print" "ps-print.el" (17780
- ;;;;;;  18172))
+ ;;;;;;  ps-page-dimensions-database) "ps-print" "ps-print.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from ps-print.el
  
  (defvar ps-page-dimensions-database (list (list (quote a4) (/ (* 72 21.0) 2.54) (/ (* 72 29.7) 2.54) "A4") (list (quote a3) (/ (* 72 29.7) 2.54) (/ (* 72 42.0) 2.54) "A3") (list (quote letter) (* 72 8.5) (* 72 11.0) "Letter") (list (quote legal) (* 72 8.5) (* 72 14.0) "Legal") (list (quote letter-small) (* 72 7.68) (* 72 10.16) "LetterSmall") (list (quote tabloid) (* 72 11.0) (* 72 17.0) "Tabloid") (list (quote ledger) (* 72 17.0) (* 72 11.0) "Ledger") (list (quote statement) (* 72 5.5) (* 72 8.5) "Statement") (list (quote executive) (* 72 7.5) (* 72 10.0) "Executive") (list (quote a4small) (* 72 7.47) (* 72 10.85) "A4Small") (list (quote b4) (* 72 10.125) (* 72 14.33) "B4") (list (quote b5) (* 72 7.16) (* 72 10.125) "B5")) "\
@@@ -21542,7 -21629,7 +21569,7 @@@ If EXTENSION is any other symbol, it i
  ;;;***
  \f
  ;;;### (autoloads (jython-mode python-mode run-python) "python" "progmodes/python.el"
- ;;;;;;  (17780 18172))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/python.el
  
  (add-to-list (quote interpreter-mode-alist) (quote ("jython" . jython-mode)))
@@@ -21617,7 -21704,7 +21644,7 @@@ Runs `jython-mode-hook' after `python-m
  ;;;***
  \f
  ;;;### (autoloads (quoted-printable-decode-region) "qp" "gnus/qp.el"
- ;;;;;;  (17408 40148))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/qp.el
  
  (autoload (quote quoted-printable-decode-region) "qp" "\
@@@ -21640,7 -21727,7 +21667,7 @@@ them into characters should be done sep
  ;;;;;;  quail-defrule quail-install-decode-map quail-install-map
  ;;;;;;  quail-define-rules quail-show-keyboard-layout quail-set-keyboard-layout
  ;;;;;;  quail-define-package quail-use-package quail-title) "quail"
- ;;;;;;  "international/quail.el" (17792 9562))
+ ;;;;;;  "international/quail.el" (17843 45619))
  ;;; Generated autoloads from international/quail.el
  
  (autoload (quote quail-title) "quail" "\
@@@ -21871,8 -21958,8 +21898,8 @@@ of each directory
  \f
  ;;;### (autoloads (quickurl-list quickurl-list-mode quickurl-edit-urls
  ;;;;;;  quickurl-browse-url-ask quickurl-browse-url quickurl-add-url
- ;;;;;;  quickurl-ask quickurl) "quickurl" "net/quickurl.el" (17385
- ;;;;;;  8495))
+ ;;;;;;  quickurl-ask quickurl) "quickurl" "net/quickurl.el" (17843
+ ;;;;;;  45624))
  ;;; Generated autoloads from net/quickurl.el
  
  (defconst quickurl-reread-hook-postfix "\n;; Local Variables:\n;; eval: (progn (require 'quickurl) (add-hook 'local-write-file-hooks (lambda () (quickurl-read) nil)))\n;; End:\n" "\
@@@ -21944,7 -22031,7 +21971,7 @@@ Display `quickurl-list' as a formatted 
  ;;;***
  \f
  ;;;### (autoloads (rcirc-track-minor-mode rcirc-connect rcirc) "rcirc"
- ;;;;;;  "net/rcirc.el" (17767 19634))
+ ;;;;;;  "net/rcirc.el" (17843 45624))
  ;;; Generated autoloads from net/rcirc.el
  
  (autoload (quote rcirc) "rcirc" "\
@@@ -21976,8 -22063,8 +22003,8 @@@ Global minor mode for tracking activit
  
  ;;;***
  \f
- ;;;### (autoloads (remote-compile) "rcompile" "net/rcompile.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (remote-compile) "rcompile" "net/rcompile.el" (17843
+ ;;;;;;  45624))
  ;;; Generated autoloads from net/rcompile.el
  
  (autoload (quote remote-compile) "rcompile" "\
@@@ -21989,7 -22076,7 +22016,7 @@@ See \\[compile]
  ;;;***
  \f
  ;;;### (autoloads (re-builder) "re-builder" "emacs-lisp/re-builder.el"
- ;;;;;;  (17751 22876))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/re-builder.el
  
  (defalias (quote regexp-builder) (quote re-builder))
@@@ -22001,7 -22088,7 +22028,7 @@@ Construct a regexp interactively
  
  ;;;***
  \f
- ;;;### (autoloads (recentf-mode) "recentf" "recentf.el" (17718 28532))
+ ;;;### (autoloads (recentf-mode) "recentf" "recentf.el" (17843 45612))
  ;;; Generated autoloads from recentf.el
  
  (defvar recentf-mode nil "\
@@@ -22028,8 -22115,8 +22055,8 @@@ that were operated on recently
  ;;;### (autoloads (clear-rectangle string-insert-rectangle string-rectangle
  ;;;;;;  delete-whitespace-rectangle open-rectangle insert-rectangle
  ;;;;;;  yank-rectangle kill-rectangle extract-rectangle delete-extract-rectangle
- ;;;;;;  delete-rectangle move-to-column-force) "rect" "rect.el" (17637
- ;;;;;;  59300))
+ ;;;;;;  delete-rectangle move-to-column-force) "rect" "rect.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from rect.el
  
  (autoload (quote move-to-column-force) "rect" "\
@@@ -22157,8 -22244,8 +22184,8 @@@ rectangle which were empty
  
  ;;;***
  \f
- ;;;### (autoloads (refill-mode) "refill" "textmodes/refill.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (refill-mode) "refill" "textmodes/refill.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from textmodes/refill.el
  
  (autoload (quote refill-mode) "refill" "\
@@@ -22174,7 -22261,7 +22201,7 @@@ refilling if they would cause auto-fill
  ;;;***
  \f
  ;;;### (autoloads (reftex-reset-scanning-information reftex-mode
- ;;;;;;  turn-on-reftex) "reftex" "textmodes/reftex.el" (17408 40149))
+ ;;;;;;  turn-on-reftex) "reftex" "textmodes/reftex.el" (17843 45630))
  ;;; Generated autoloads from textmodes/reftex.el
  
  (autoload (quote turn-on-reftex) "reftex" "\
@@@ -22224,7 -22311,7 +22251,7 @@@ This enforces rescanning the buffer on 
  ;;;***
  \f
  ;;;### (autoloads (reftex-citation) "reftex-cite" "textmodes/reftex-cite.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/reftex-cite.el
  
  (autoload (quote reftex-citation) "reftex-cite" "\
@@@ -22254,7 -22341,7 +22281,7 @@@ While entering the regexp, completion o
  ;;;***
  \f
  ;;;### (autoloads (reftex-isearch-minor-mode) "reftex-global" "textmodes/reftex-global.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/reftex-global.el
  
  (autoload (quote reftex-isearch-minor-mode) "reftex-global" "\
@@@ -22271,7 -22358,7 +22298,7 @@@ With no argument, this command toggle
  ;;;***
  \f
  ;;;### (autoloads (reftex-index-phrases-mode) "reftex-index" "textmodes/reftex-index.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/reftex-index.el
  
  (autoload (quote reftex-index-phrases-mode) "reftex-index" "\
@@@ -22304,7 -22391,7 +22331,7 @@@ Here are all local bindings
  ;;;***
  \f
  ;;;### (autoloads (reftex-all-document-files) "reftex-parse" "textmodes/reftex-parse.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/reftex-parse.el
  
  (autoload (quote reftex-all-document-files) "reftex-parse" "\
@@@ -22316,8 -22403,8 +22343,8 @@@ of master file
  
  ;;;***
  \f
- ;;;### (autoloads nil "reftex-vars" "textmodes/reftex-vars.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads nil "reftex-vars" "textmodes/reftex-vars.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from textmodes/reftex-vars.el
  (put 'reftex-vref-is-default 'safe-local-variable (lambda (x) (or (stringp x) (symbolp x))))
  (put 'reftex-fref-is-default 'safe-local-variable (lambda (x) (or (stringp x) (symbolp x))))
  ;;;***
  \f
  ;;;### (autoloads (regexp-opt-depth regexp-opt) "regexp-opt" "emacs-lisp/regexp-opt.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/regexp-opt.el
  
  (autoload (quote regexp-opt) "regexp-opt" "\
@@@ -22354,7 -22441,7 +22381,7 @@@ This means the number of non-shy regex
  
  ;;;***
  \f
- ;;;### (autoloads (repeat) "repeat" "repeat.el" (17781 39502))
+ ;;;### (autoloads (repeat) "repeat" "repeat.el" (17843 45612))
  ;;; Generated autoloads from repeat.el
  
  (autoload (quote repeat) "repeat" "\
@@@ -22372,7 -22459,7 +22399,7 @@@ can be modified by the global variable 
  ;;;***
  \f
  ;;;### (autoloads (reporter-submit-bug-report) "reporter" "mail/reporter.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45622))
  ;;; Generated autoloads from mail/reporter.el
  
  (autoload (quote reporter-submit-bug-report) "reporter" "\
@@@ -22404,7 -22491,7 +22431,7 @@@ mail-sending package is used for editin
  ;;;***
  \f
  ;;;### (autoloads (reposition-window) "reposition" "reposition.el"
- ;;;;;;  (17781 39502))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from reposition.el
  
  (autoload (quote reposition-window) "reposition" "\
@@@ -22431,8 -22518,8 +22458,8 @@@ first comment line visible (if point i
  
  ;;;***
  \f
- ;;;### (autoloads (resume-suspend-hook) "resume" "resume.el" (17781
- ;;;;;;  39502))
+ ;;;### (autoloads (resume-suspend-hook) "resume" "resume.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from resume.el
  
  (autoload (quote resume-suspend-hook) "resume" "\
@@@ -22443,7 -22530,7 +22470,7 @@@ Clear out the file used for transmittin
  ;;;***
  \f
  ;;;### (autoloads (global-reveal-mode reveal-mode) "reveal" "reveal.el"
- ;;;;;;  (17495 43954))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from reveal.el
  
  (autoload (quote reveal-mode) "reveal" "\
@@@ -22460,11 -22547,10 +22487,10 @@@ With zero or negative ARG turn mode off
  Non-nil if Global-Reveal mode is enabled.
  See the command `global-reveal-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `global-reveal-mode'.")
- (custom-autoload (quote global-reveal-mode) "reveal")
+ either customize it (see the info node `Easy Customization')
+ or call the function `global-reveal-mode'.")
  
- (put (quote global-reveal-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote global-reveal-mode) "reveal" nil)
  
  (autoload (quote global-reveal-mode) "reveal" "\
  Toggle Reveal mode in all buffers on or off.
@@@ -22479,7 -22565,7 +22505,7 @@@ With zero or negative ARG turn mode off
  ;;;***
  \f
  ;;;### (autoloads (make-ring ring-p) "ring" "emacs-lisp/ring.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/ring.el
  
  (autoload (quote ring-p) "ring" "\
@@@ -22494,7 -22580,7 +22520,7 @@@ Make a ring that can contain SIZE eleme
  
  ;;;***
  \f
- ;;;### (autoloads (rlogin) "rlogin" "net/rlogin.el" (17786 56015))
+ ;;;### (autoloads (rlogin) "rlogin" "net/rlogin.el" (17843 45624))
  ;;; Generated autoloads from net/rlogin.el
   (add-hook 'same-window-regexps "^\\*rlogin-.*\\*\\(\\|<[0-9]+>\\)")
  
@@@ -22545,8 -22631,8 +22571,8 @@@ variable
  ;;;;;;  rmail-mail-new-frame rmail-primary-inbox-list rmail-delete-after-output
  ;;;;;;  rmail-highlight-face rmail-highlighted-headers rmail-retry-ignored-headers
  ;;;;;;  rmail-displayed-headers rmail-ignored-headers rmail-dont-reply-to-names
- ;;;;;;  rmail-movemail-variant-p) "rmail" "mail/rmail.el" (17742
- ;;;;;;  7456))
+ ;;;;;;  rmail-movemail-variant-p) "rmail" "mail/rmail.el" (17843
+ ;;;;;;  45622))
  ;;; Generated autoloads from mail/rmail.el
  
  (autoload (quote rmail-movemail-variant-p) "rmail" "\
@@@ -22811,7 -22897,7 +22837,7 @@@ Set PASSWORD to be used for retrieving 
  ;;;***
  \f
  ;;;### (autoloads (rmail-edit-current-message) "rmailedit" "mail/rmailedit.el"
- ;;;;;;  (17385 8494))
+ ;;;;;;  (17843 45622))
  ;;; Generated autoloads from mail/rmailedit.el
  
  (autoload (quote rmail-edit-current-message) "rmailedit" "\
@@@ -22823,7 -22909,7 +22849,7 @@@ Edit the contents of this message
  \f
  ;;;### (autoloads (rmail-next-labeled-message rmail-previous-labeled-message
  ;;;;;;  rmail-read-label rmail-kill-label rmail-add-label) "rmailkwd"
- ;;;;;;  "mail/rmailkwd.el" (17385 8494))
+ ;;;;;;  "mail/rmailkwd.el" (17843 45622))
  ;;; Generated autoloads from mail/rmailkwd.el
  
  (autoload (quote rmail-add-label) "rmailkwd" "\
@@@ -22862,7 -22948,7 +22888,7 @@@ With prefix argument N moves forward N 
  ;;;***
  \f
  ;;;### (autoloads (set-rmail-inbox-list) "rmailmsc" "mail/rmailmsc.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45622))
  ;;; Generated autoloads from mail/rmailmsc.el
  
  (autoload (quote set-rmail-inbox-list) "rmailmsc" "\
@@@ -22876,7 -22962,7 +22902,7 @@@ If FILE-NAME is empty, remove any exist
  \f
  ;;;### (autoloads (rmail-output-body-to-file rmail-output rmail-fields-not-to-output
  ;;;;;;  rmail-output-to-rmail-file rmail-output-file-alist) "rmailout"
- ;;;;;;  "mail/rmailout.el" (17752 39352))
+ ;;;;;;  "mail/rmailout.el" (17843 45622))
  ;;; Generated autoloads from mail/rmailout.el
  
  (defvar rmail-output-file-alist nil "\
@@@ -22943,8 -23029,8 +22969,8 @@@ FILE-NAME defaults, interactively, fro
  \f
  ;;;### (autoloads (rmail-sort-by-labels rmail-sort-by-lines rmail-sort-by-correspondent
  ;;;;;;  rmail-sort-by-recipient rmail-sort-by-author rmail-sort-by-subject
- ;;;;;;  rmail-sort-by-date) "rmailsort" "mail/rmailsort.el" (17385
- ;;;;;;  8494))
+ ;;;;;;  rmail-sort-by-date) "rmailsort" "mail/rmailsort.el" (17843
+ ;;;;;;  45622))
  ;;; Generated autoloads from mail/rmailsort.el
  
  (autoload (quote rmail-sort-by-date) "rmailsort" "\
@@@ -22996,18 -23082,18 +23022,18 @@@ KEYWORDS is a comma-separated list of l
  ;;;;;;  rmail-summary-by-senders rmail-summary-by-topic rmail-summary-by-regexp
  ;;;;;;  rmail-summary-by-recipients rmail-summary-by-labels rmail-summary
  ;;;;;;  rmail-summary-line-count-flag rmail-summary-scroll-between-messages)
- ;;;;;;  "rmailsum" "mail/rmailsum.el" (17427 10522))
+ ;;;;;;  "rmailsum" "mail/rmailsum.el" (17843 45622))
  ;;; Generated autoloads from mail/rmailsum.el
  
  (defvar rmail-summary-scroll-between-messages t "\
  *Non-nil means Rmail summary scroll commands move between messages.")
  
- (custom-autoload (quote rmail-summary-scroll-between-messages) "rmailsum")
+ (custom-autoload (quote rmail-summary-scroll-between-messages) "rmailsum" t)
  
  (defvar rmail-summary-line-count-flag t "\
  *Non-nil means Rmail summary should show the number of lines in each message.")
  
- (custom-autoload (quote rmail-summary-line-count-flag) "rmailsum")
+ (custom-autoload (quote rmail-summary-line-count-flag) "rmailsum" t)
  
  (autoload (quote rmail-summary) "rmailsum" "\
  Display a summary of all messages, one line per message.
@@@ -23057,7 -23143,7 +23083,7 @@@ SENDERS is a string of names separated 
  
  By default, `identity' is set.")
  
- (custom-autoload (quote rmail-summary-line-decoder) "rmailsum")
+ (custom-autoload (quote rmail-summary-line-decoder) "rmailsum" t)
  
  (defvar rmail-user-mail-address-regexp nil "\
  *Regexp matching user mail addresses.
@@@ -23073,12 -23159,12 +23099,12 @@@ Then it should be a regexp matching you
  
  Setting this variable has an effect only before reading a mail.")
  
- (custom-autoload (quote rmail-user-mail-address-regexp) "rmailsum")
+ (custom-autoload (quote rmail-user-mail-address-regexp) "rmailsum" t)
  
  ;;;***
  \f
  ;;;### (autoloads (news-post-news) "rnewspost" "obsolete/rnewspost.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45625))
  ;;; Generated autoloads from obsolete/rnewspost.el
  
  (autoload (quote news-post-news) "rnewspost" "\
@@@ -23091,7 -23177,7 +23117,7 @@@ If NOQUERY is non-nil, we do not query 
  ;;;***
  \f
  ;;;### (autoloads (toggle-rot13-mode rot13-other-window rot13-region
- ;;;;;;  rot13-string rot13) "rot13" "rot13.el" (17781 39502))
+ ;;;;;;  rot13-string rot13) "rot13" "rot13.el" (17843 45612))
  ;;; Generated autoloads from rot13.el
  
  (autoload (quote rot13) "rot13" "\
@@@ -23132,7 -23218,7 +23158,7 @@@ Toggle the use of ROT13 encoding for th
  ;;;;;;  resize-minibuffer-frame-max-height resize-minibuffer-frame
  ;;;;;;  resize-minibuffer-window-exactly resize-minibuffer-window-max-height
  ;;;;;;  resize-minibuffer-mode) "rsz-mini" "obsolete/rsz-mini.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45625))
  ;;; Generated autoloads from obsolete/rsz-mini.el
  
  (defvar resize-minibuffer-mode nil "\
@@@ -23172,8 -23258,8 +23198,8 @@@ This function is obsolete
  
  ;;;***
  \f
- ;;;### (autoloads (ruler-mode) "ruler-mode" "ruler-mode.el" (17743
- ;;;;;;  45091))
+ ;;;### (autoloads (ruler-mode) "ruler-mode" "ruler-mode.el" (17838
+ ;;;;;;  18033))
  ;;; Generated autoloads from ruler-mode.el
  
  (autoload (quote ruler-mode) "ruler-mode" "\
@@@ -23183,8 -23269,8 +23209,8 @@@ Display a ruler in the header line if A
  
  ;;;***
  \f
- ;;;### (autoloads (rx rx-to-string) "rx" "emacs-lisp/rx.el" (17420
- ;;;;;;  32030))
+ ;;;### (autoloads (rx rx-to-string) "rx" "emacs-lisp/rx.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emacs-lisp/rx.el
  
  (autoload (quote rx-to-string) "rx" "\
@@@ -23492,7 -23578,7 +23518,7 @@@ enclosed in `(and ...)'
  ;;;***
  \f
  ;;;### (autoloads (savehist-mode savehist-mode) "savehist" "savehist.el"
- ;;;;;;  (17476 4798))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from savehist.el
  
  (defvar savehist-mode nil "\
@@@ -23500,7 -23586,7 +23526,7 @@@ Mode for automatic saving of minibuffe
  Set this by calling the `savehist-mode' function or using the customize
  interface.")
  
- (custom-autoload (quote savehist-mode) "savehist")
+ (custom-autoload (quote savehist-mode) "savehist" nil)
  
  (autoload (quote savehist-mode) "savehist" "\
  Toggle savehist-mode.
@@@ -23518,7 -23604,7 +23544,7 @@@ which is probably undesirable
  ;;;***
  \f
  ;;;### (autoloads (dsssl-mode scheme-mode) "scheme" "progmodes/scheme.el"
- ;;;;;;  (17394 12938))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/scheme.el
  
  (autoload (quote scheme-mode) "scheme" "\
@@@ -23560,7 -23646,7 +23586,7 @@@ that variable's value is a string
  ;;;***
  \f
  ;;;### (autoloads (gnus-score-mode) "score-mode" "gnus/score-mode.el"
- ;;;;;;  (17385 8494))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/score-mode.el
  
  (autoload (quote gnus-score-mode) "score-mode" "\
@@@ -23573,8 -23659,8 +23599,8 @@@ This mode is an extended emacs-lisp mod
  
  ;;;***
  \f
- ;;;### (autoloads (scribe-mode) "scribe" "obsolete/scribe.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (scribe-mode) "scribe" "obsolete/scribe.el" (17843
+ ;;;;;;  45625))
  ;;; Generated autoloads from obsolete/scribe.el
  
  (autoload (quote scribe-mode) "scribe" "\
@@@ -23599,7 -23685,7 +23625,7 @@@ Interesting variables
  ;;;***
  \f
  ;;;### (autoloads (scroll-all-mode) "scroll-all" "scroll-all.el"
- ;;;;;;  (17781 39502))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from scroll-all.el
  
  (defvar scroll-all-mode nil "\
@@@ -23622,7 -23708,7 +23648,7 @@@ apply to all visible windows in the sam
  ;;;***
  \f
  ;;;### (autoloads (scroll-lock-mode) "scroll-lock" "scroll-lock.el"
- ;;;;;;  (17385 8487))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from scroll-lock.el
  
  (autoload (quote scroll-lock-mode) "scroll-lock" "\
@@@ -23644,7 -23730,7 +23670,7 @@@ during scrolling
  ;;;;;;  mail-alias-file mail-default-reply-to mail-archive-file-name
  ;;;;;;  mail-header-separator send-mail-function mail-interactive
  ;;;;;;  mail-self-blind mail-specify-envelope-from mail-from-style)
- ;;;;;;  "sendmail" "mail/sendmail.el" (17660 26729))
+ ;;;;;;  "sendmail" "mail/sendmail.el" (17843 45622))
  ;;; Generated autoloads from mail/sendmail.el
  
  (defvar mail-from-style (quote angles) "\
@@@ -23945,7 -24031,7 +23971,7 @@@ Like `mail' command, but display mail b
  ;;;***
  \f
  ;;;### (autoloads (server-mode server-start) "server" "server.el"
- ;;;;;;  (17771 26718))
+ ;;;;;;  (17838 18033))
  ;;; Generated autoloads from server.el
  
  (autoload (quote server-start) "server" "\
@@@ -23978,7 -24064,7 +24004,7 @@@ Server mode runs a process that accept
  
  ;;;***
  \f
- ;;;### (autoloads (ses-mode) "ses" "ses.el" (17750 12548))
+ ;;;### (autoloads (ses-mode) "ses" "ses.el" (17843 45612))
  ;;; Generated autoloads from ses.el
  
  (autoload (quote ses-mode) "ses" "\
@@@ -23997,7 -24083,7 +24023,7 @@@ These are active only in the minibuffer
  ;;;***
  \f
  ;;;### (autoloads (html-mode sgml-mode) "sgml-mode" "textmodes/sgml-mode.el"
- ;;;;;;  (17780 18172))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/sgml-mode.el
  
  (autoload (quote sgml-mode) "sgml-mode" "\
@@@ -24065,7 -24151,7 +24091,7 @@@ To work around that, do
  ;;;***
  \f
  ;;;### (autoloads (sh-mode) "sh-script" "progmodes/sh-script.el"
- ;;;;;;  (17788 21816))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/sh-script.el
  (put 'sh-shell 'safe-local-variable 'symbolp)
  
@@@ -24129,7 -24215,7 +24155,7 @@@ with your script for an edit-interpret-
  
  ;;;***
  \f
- ;;;### (autoloads (sha1) "sha1" "gnus/sha1.el" (17385 8494))
+ ;;;### (autoloads (sha1) "sha1" "gnus/sha1.el" (17843 45617))
  ;;; Generated autoloads from gnus/sha1.el
  
  (autoload (quote sha1) "sha1" "\
@@@ -24144,7 -24230,7 +24170,7 @@@ If BINARY is non-nil, return a string i
  ;;;***
  \f
  ;;;### (autoloads (list-load-path-shadows) "shadow" "emacs-lisp/shadow.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/shadow.el
  
  (autoload (quote list-load-path-shadows) "shadow" "\
@@@ -24191,8 -24277,8 +24217,8 @@@ buffer called `*Shadows*'.  Shadowings 
  ;;;***
  \f
  ;;;### (autoloads (shadow-initialize shadow-define-regexp-group shadow-define-literal-group
- ;;;;;;  shadow-define-cluster) "shadowfile" "shadowfile.el" (17743
- ;;;;;;  18143))
+ ;;;;;;  shadow-define-cluster) "shadowfile" "shadowfile.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from shadowfile.el
  
  (autoload (quote shadow-define-cluster) "shadowfile" "\
@@@ -24231,7 -24317,7 +24257,7 @@@ Set up file shadowing
  ;;;***
  \f
  ;;;### (autoloads (shell shell-dumb-shell-regexp) "shell" "shell.el"
- ;;;;;;  (17796 10831))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from shell.el
  
  (defvar shell-dumb-shell-regexp "cmd\\(proxy\\)?\\.exe" "\
@@@ -24278,7 -24364,7 +24304,7 @@@ Otherwise, one argument `-i' is passed 
  ;;;***
  \f
  ;;;### (autoloads (sieve-upload-and-bury sieve-upload sieve-manage)
- ;;;;;;  "sieve" "gnus/sieve.el" (17385 8494))
+ ;;;;;;  "sieve" "gnus/sieve.el" (17843 45617))
  ;;; Generated autoloads from gnus/sieve.el
  
  (autoload (quote sieve-manage) "sieve" "\
@@@ -24299,7 -24385,7 +24325,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (sieve-mode) "sieve-mode" "gnus/sieve-mode.el"
- ;;;;;;  (17385 8494))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/sieve-mode.el
  
  (autoload (quote sieve-mode) "sieve-mode" "\
@@@ -24314,14 -24400,14 +24340,14 @@@ Turning on Sieve mode runs `sieve-mode-
  
  ;;;***
  \f
- ;;;### (autoloads nil "simple" "simple.el" (17797 50970))
+ ;;;### (autoloads nil "simple" "simple.el" (17843 45612))
  ;;; Generated autoloads from simple.el
  (put 'fill-prefix 'safe-local-variable 'string-or-null-p)
  
  ;;;***
  \f
- ;;;### (autoloads (simula-mode) "simula" "progmodes/simula.el" (17788
- ;;;;;;  21816))
+ ;;;### (autoloads (simula-mode) "simula" "progmodes/simula.el" (17843
+ ;;;;;;  45629))
  ;;; Generated autoloads from progmodes/simula.el
  
  (autoload (quote simula-mode) "simula" "\
@@@ -24370,7 -24456,7 +24396,7 @@@ with no arguments, if that value is non
  ;;;***
  \f
  ;;;### (autoloads (skeleton-pair-insert-maybe skeleton-insert skeleton-proxy-new
- ;;;;;;  define-skeleton) "skeleton" "skeleton.el" (17781 39502))
+ ;;;;;;  define-skeleton) "skeleton" "skeleton.el" (17843 45612))
  ;;; Generated autoloads from skeleton.el
  
  (defvar skeleton-filter-function (quote identity) "\
@@@ -24480,7 -24566,7 +24506,7 @@@ symmetrical ones, and the same characte
  ;;;***
  \f
  ;;;### (autoloads (smerge-mode smerge-ediff) "smerge-mode" "smerge-mode.el"
- ;;;;;;  (17495 43954))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from smerge-mode.el
  
  (autoload (quote smerge-ediff) "smerge-mode" "\
@@@ -24499,7 -24585,7 +24525,7 @@@ Minor mode to simplify editing output f
  ;;;***
  \f
  ;;;### (autoloads (smiley-buffer smiley-region) "smiley" "gnus/smiley.el"
- ;;;;;;  (17476 4800))
+ ;;;;;;  (17843 45617))
  ;;; Generated autoloads from gnus/smiley.el
  
  (autoload (quote smiley-region) "smiley" "\
@@@ -24517,7 -24603,7 +24543,7 @@@ interactively. If there's no argument, 
  ;;;***
  \f
  ;;;### (autoloads (smtpmail-send-queued-mail smtpmail-send-it) "smtpmail"
- ;;;;;;  "mail/smtpmail.el" (17767 19634))
+ ;;;;;;  "mail/smtpmail.el" (17843 45622))
  ;;; Generated autoloads from mail/smtpmail.el
  
  (autoload (quote smtpmail-send-it) "smtpmail" "\
@@@ -24532,7 -24618,7 +24558,7 @@@ Send mail that was queued as a result o
  
  ;;;***
  \f
- ;;;### (autoloads (snake) "snake" "play/snake.el" (17786 56015))
+ ;;;### (autoloads (snake) "snake" "play/snake.el" (17843 45626))
  ;;; Generated autoloads from play/snake.el
  
  (autoload (quote snake) "snake" "\
@@@ -24556,7 -24642,7 +24582,7 @@@ Snake mode keybindings
  ;;;***
  \f
  ;;;### (autoloads (snmpv2-mode snmp-mode) "snmp-mode" "net/snmp-mode.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45624))
  ;;; Generated autoloads from net/snmp-mode.el
  
  (autoload (quote snmp-mode) "snmp-mode" "\
@@@ -24587,7 -24673,7 +24613,7 @@@ then `snmpv2-mode-hook'
  \f
  ;;;### (autoloads (solar-equinoxes-solstices sunrise-sunset calendar-location-name
  ;;;;;;  calendar-longitude calendar-latitude calendar-time-display-form)
- ;;;;;;  "solar" "calendar/solar.el" (17386 33146))
+ ;;;;;;  "solar" "calendar/solar.el" (17843 45615))
  ;;; Generated autoloads from calendar/solar.el
  
  (defvar calendar-time-display-form (quote (12-hours ":" minutes am-pm (if time-zone " (") time-zone (if time-zone ")"))) "\
@@@ -24604,7 -24690,7 +24630,7 @@@ For example, the for
  
  would give military-style times like `21:07 (UTC)'.")
  
- (custom-autoload (quote calendar-time-display-form) "solar")
+ (custom-autoload (quote calendar-time-display-form) "solar" t)
  
  (defvar calendar-latitude nil "\
  *Latitude of `calendar-location-name' in degrees.
@@@ -24616,7 -24702,7 +24642,7 @@@ York City
  
  This variable should be set in `site-start'.el.")
  
- (custom-autoload (quote calendar-latitude) "solar")
+ (custom-autoload (quote calendar-latitude) "solar" t)
  
  (defvar calendar-longitude nil "\
  *Longitude of `calendar-location-name' in degrees.
@@@ -24628,7 -24714,7 +24654,7 @@@ York City
  
  This variable should be set in `site-start'.el.")
  
- (custom-autoload (quote calendar-longitude) "solar")
+ (custom-autoload (quote calendar-longitude) "solar" t)
  
  (defvar calendar-location-name (quote (let ((float-output-format "%.1f")) (format "%s%s, %s%s" (if (numberp calendar-latitude) (abs calendar-latitude) (+ (aref calendar-latitude 0) (/ (aref calendar-latitude 1) 60.0))) (if (numberp calendar-latitude) (if (> calendar-latitude 0) "N" "S") (if (equal (aref calendar-latitude 2) (quote north)) "N" "S")) (if (numberp calendar-longitude) (abs calendar-longitude) (+ (aref calendar-longitude 0) (/ (aref calendar-longitude 1) 60.0))) (if (numberp calendar-longitude) (if (> calendar-longitude 0) "E" "W") (if (equal (aref calendar-longitude 2) (quote east)) "E" "W"))))) "\
  *Expression evaluating to name of `calendar-longitude', `calendar-latitude'.
@@@ -24637,7 -24723,7 +24663,7 @@@ pair
  
  This variable should be set in `site-start'.el.")
  
- (custom-autoload (quote calendar-location-name) "solar")
+ (custom-autoload (quote calendar-location-name) "solar" t)
  
  (autoload (quote sunrise-sunset) "solar" "\
  Local time of sunrise and sunset for today.  Accurate to a few seconds.
@@@ -24658,8 -24744,8 +24684,8 @@@ Requires floating point
  
  ;;;***
  \f
- ;;;### (autoloads (solitaire) "solitaire" "play/solitaire.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (solitaire) "solitaire" "play/solitaire.el" (17843
+ ;;;;;;  45626))
  ;;; Generated autoloads from play/solitaire.el
  
  (autoload (quote solitaire) "solitaire" "\
@@@ -24736,7 -24822,7 +24762,7 @@@ Pick your favourite shortcuts
  \f
  ;;;### (autoloads (reverse-region sort-columns sort-regexp-fields
  ;;;;;;  sort-fields sort-numeric-fields sort-pages sort-paragraphs
- ;;;;;;  sort-lines sort-subr) "sort" "sort.el" (17781 39502))
+ ;;;;;;  sort-lines sort-subr) "sort" "sort.el" (17843 45612))
  ;;; Generated autoloads from sort.el
  
  (autoload (quote sort-subr) "sort" "\
@@@ -24878,8 -24964,8 +24904,8 @@@ From a program takes two point or marke
  
  ;;;***
  \f
- ;;;### (autoloads (spam-initialize) "spam" "gnus/spam.el" (17476
- ;;;;;;  4800))
+ ;;;### (autoloads (spam-initialize) "spam" "gnus/spam.el" (17843
+ ;;;;;;  45617))
  ;;; Generated autoloads from gnus/spam.el
  
  (autoload (quote spam-initialize) "spam" "\
@@@ -24891,7 -24977,7 +24917,7 @@@ Install the spam.el hooks and do other 
  \f
  ;;;### (autoloads (spam-report-deagentize spam-report-agentize spam-report-url-to-file
  ;;;;;;  spam-report-url-ping-mm-url spam-report-process-queue) "spam-report"
- ;;;;;;  "gnus/spam-report.el" (17386 33146))
+ ;;;;;;  "gnus/spam-report.el" (17843 45617))
  ;;; Generated autoloads from gnus/spam-report.el
  
  (autoload (quote spam-report-process-queue) "spam-report" "\
@@@ -24934,7 -25020,7 +24960,7 @@@ Spam reports will be queued with the me
  ;;;***
  \f
  ;;;### (autoloads (speedbar-get-focus speedbar-frame-mode) "speedbar"
- ;;;;;;  "speedbar.el" (17771 1419))
+ ;;;;;;  "speedbar.el" (17843 45612))
  ;;; Generated autoloads from speedbar.el
  
  (defalias (quote speedbar) (quote speedbar-frame-mode))
@@@ -24959,7 -25045,7 +24985,7 @@@ selected.  If the speedbar frame is act
  ;;;***
  \f
  ;;;### (autoloads (spell-string spell-region spell-word spell-buffer)
- ;;;;;;  "spell" "textmodes/spell.el" (17786 56015))
+ ;;;;;;  "spell" "textmodes/spell.el" (17843 45630))
  ;;; Generated autoloads from textmodes/spell.el
  
  (put (quote spell-filter) (quote risky-local-variable) t)
@@@ -24995,8 -25081,8 +25021,8 @@@ Check spelling of string supplied as ar
  
  ;;;***
  \f
- ;;;### (autoloads (snarf-spooks spook) "spook" "play/spook.el" (17786
- ;;;;;;  56015))
+ ;;;### (autoloads (snarf-spooks spook) "spook" "play/spook.el" (17843
+ ;;;;;;  45626))
  ;;; Generated autoloads from play/spook.el
  
  (autoload (quote spook) "spook" "\
@@@ -25014,8 -25100,8 +25040,8 @@@ Return a vector containing the lines fr
  ;;;### (autoloads (sql-linter sql-db2 sql-interbase sql-postgres
  ;;;;;;  sql-ms sql-ingres sql-solid sql-mysql sql-sqlite sql-informix
  ;;;;;;  sql-sybase sql-oracle sql-product-interactive sql-mode sql-help
- ;;;;;;  sql-add-product-keywords) "sql" "progmodes/sql.el" (17781
- ;;;;;;  39502))
+ ;;;;;;  sql-add-product-keywords) "sql" "progmodes/sql.el" (17843
+ ;;;;;;  45629))
  ;;; Generated autoloads from progmodes/sql.el
  
  (autoload (quote sql-add-product-keywords) "sql" "\
@@@ -25446,8 -25532,8 +25472,8 @@@ input.  See `sql-interactive-mode'
  ;;;;;;  strokes-mode strokes-list-strokes strokes-load-user-strokes
  ;;;;;;  strokes-help strokes-describe-stroke strokes-do-complex-stroke
  ;;;;;;  strokes-do-stroke strokes-read-complex-stroke strokes-read-stroke
- ;;;;;;  strokes-global-set-stroke) "strokes" "strokes.el" (17781
- ;;;;;;  39502))
+ ;;;;;;  strokes-global-set-stroke) "strokes" "strokes.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from strokes.el
  
  (autoload (quote strokes-global-set-stroke) "strokes" "\
@@@ -25577,7 -25663,7 +25603,7 @@@ Studlify-case the current buffer
  
  ;;;***
  \f
- ;;;### (autoloads (locate-library) "subr" "subr.el" (17789 35159))
+ ;;;### (autoloads (locate-library) "subr" "subr.el" (17843 45612))
  ;;; Generated autoloads from subr.el
  
  (autoload (quote locate-library) "subr" "\
@@@ -25599,7 -25685,7 +25625,7 @@@ and the file name is displayed in the e
  ;;;***
  \f
  ;;;### (autoloads (sc-cite-original) "supercite" "mail/supercite.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45622))
  ;;; Generated autoloads from mail/supercite.el
  
  (autoload (quote sc-cite-original) "supercite" "\
@@@ -25631,7 -25717,7 +25657,7 @@@ before, and `sc-post-hook' is run afte
  
  ;;;***
  \f
- ;;;### (autoloads (t-mouse-mode) "t-mouse" "t-mouse.el" (17743 18143))
+ ;;;### (autoloads (t-mouse-mode) "t-mouse" "t-mouse.el" (17842 25773))
  ;;; Generated autoloads from t-mouse.el
  
  (defvar t-mouse-mode nil "\
@@@ -25653,7 -25739,7 +25679,7 @@@ Turn it on to use Emacs mouse commands
  
  ;;;***
  \f
- ;;;### (autoloads (tabify untabify) "tabify" "tabify.el" (17781 39502))
+ ;;;### (autoloads (tabify untabify) "tabify" "tabify.el" (17843 45612))
  ;;; Generated autoloads from tabify.el
  
  (autoload (quote untabify) "tabify" "\
@@@ -25688,7 -25774,7 +25714,7 @@@ The variable `tab-width' controls the s
  ;;;;;;  table-recognize table-insert-row-column table-insert-column
  ;;;;;;  table-insert-row table-insert table-point-left-cell-hook
  ;;;;;;  table-point-entered-cell-hook table-load-hook table-cell-map-hook)
- ;;;;;;  "table" "textmodes/table.el" (17740 982))
+ ;;;;;;  "table" "textmodes/table.el" (17843 45630))
  ;;; Generated autoloads from textmodes/table.el
  
  (defvar table-cell-map-hook nil "\
@@@ -26276,7 -26362,7 +26302,7 @@@ converts a table into plain text withou
  
  ;;;***
  \f
- ;;;### (autoloads (talk-connect) "talk" "talk.el" (17781 39502))
+ ;;;### (autoloads (talk-connect) "talk" "talk.el" (17843 45612))
  ;;; Generated autoloads from talk.el
  
  (autoload (quote talk-connect) "talk" "\
@@@ -26286,7 -26372,7 +26312,7 @@@ Connect to display DISPLAY for the Emac
  
  ;;;***
  \f
- ;;;### (autoloads (tar-mode) "tar-mode" "tar-mode.el" (17771 1419))
+ ;;;### (autoloads (tar-mode) "tar-mode" "tar-mode.el" (17843 45612))
  ;;; Generated autoloads from tar-mode.el
  
  (autoload (quote tar-mode) "tar-mode" "\
@@@ -26310,7 -26396,7 +26336,7 @@@ See also: variables `tar-update-datesta
  ;;;***
  \f
  ;;;### (autoloads (tcl-help-on-word inferior-tcl tcl-mode) "tcl"
- ;;;;;;  "progmodes/tcl.el" (17485 5461))
+ ;;;;;;  "progmodes/tcl.el" (17843 45629))
  ;;; Generated autoloads from progmodes/tcl.el
  
  (autoload (quote tcl-mode) "tcl" "\
@@@ -26361,7 -26447,7 +26387,7 @@@ Prefix argument means invert sense of `
  
  ;;;***
  \f
- ;;;### (autoloads (rsh telnet) "telnet" "net/telnet.el" (17786 56015))
+ ;;;### (autoloads (rsh telnet) "telnet" "net/telnet.el" (17843 45624))
  ;;; Generated autoloads from net/telnet.el
   (add-hook 'same-window-regexps "\\*telnet-.*\\*\\(\\|<[0-9]+>\\)")
  
@@@ -26388,8 -26474,8 +26414,8 @@@ Normally input is edited in Emacs and s
  
  ;;;***
  \f
- ;;;### (autoloads (ansi-term term make-term) "term" "term.el" (17781
- ;;;;;;  39502))
+ ;;;### (autoloads (ansi-term term make-term) "term" "term.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from term.el
  
  (autoload (quote make-term) "term" "\
@@@ -26417,8 -26503,8 +26443,8 @@@ Start a terminal-emulator in a new buff
  
  ;;;***
  \f
- ;;;### (autoloads (terminal-emulator) "terminal" "terminal.el" (17781
- ;;;;;;  39502))
+ ;;;### (autoloads (terminal-emulator) "terminal" "terminal.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from terminal.el
  
  (autoload (quote terminal-emulator) "terminal" "\
@@@ -26455,7 -26541,7 +26481,7 @@@ subprocess started
  ;;;***
  \f
  ;;;### (autoloads (testcover-this-defun) "testcover" "emacs-lisp/testcover.el"
- ;;;;;;  (17385 8490))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/testcover.el
  
  (autoload (quote testcover-this-defun) "testcover" "\
@@@ -26465,7 -26551,7 +26491,7 @@@ Start coverage on function under point
  
  ;;;***
  \f
- ;;;### (autoloads (tetris) "tetris" "play/tetris.el" (17786 56015))
+ ;;;### (autoloads (tetris) "tetris" "play/tetris.el" (17843 45626))
  ;;; Generated autoloads from play/tetris.el
  
  (autoload (quote tetris) "tetris" "\
@@@ -26496,7 -26582,7 +26522,7 @@@ tetris-mode keybindings
  ;;;;;;  tex-start-commands tex-start-options slitex-run-command latex-run-command
  ;;;;;;  tex-run-command tex-offer-save tex-main-file tex-first-line-header-regexp
  ;;;;;;  tex-directory tex-shell-file-name) "tex-mode" "textmodes/tex-mode.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/tex-mode.el
  
  (defvar tex-shell-file-name nil "\
@@@ -26798,7 -26884,7 +26824,7 @@@ Major mode to edit DocTeX files
  ;;;***
  \f
  ;;;### (autoloads (texi2info texinfo-format-region texinfo-format-buffer)
- ;;;;;;  "texinfmt" "textmodes/texinfmt.el" (17743 18144))
+ ;;;;;;  "texinfmt" "textmodes/texinfmt.el" (17843 45630))
  ;;; Generated autoloads from textmodes/texinfmt.el
  
  (autoload (quote texinfo-format-buffer) "texinfmt" "\
@@@ -26838,18 -26924,18 +26864,18 @@@ if large.  You can use Info-split to d
  ;;;***
  \f
  ;;;### (autoloads (texinfo-mode texinfo-close-quote texinfo-open-quote)
- ;;;;;;  "texinfo" "textmodes/texinfo.el" (17385 8496))
+ ;;;;;;  "texinfo" "textmodes/texinfo.el" (17843 45630))
  ;;; Generated autoloads from textmodes/texinfo.el
  
  (defvar texinfo-open-quote "``" "\
  *String inserted by typing \\[texinfo-insert-quote] to open a quotation.")
  
- (custom-autoload (quote texinfo-open-quote) "texinfo")
+ (custom-autoload (quote texinfo-open-quote) "texinfo" t)
  
  (defvar texinfo-close-quote "''" "\
  *String inserted by typing \\[texinfo-insert-quote] to close a quotation.")
  
- (custom-autoload (quote texinfo-close-quote) "texinfo")
+ (custom-autoload (quote texinfo-close-quote) "texinfo" t)
  
  (autoload (quote texinfo-mode) "texinfo" "\
  Major mode for editing Texinfo files.
@@@ -26925,7 -27011,7 +26951,7 @@@ value of `texinfo-mode-hook'
  ;;;### (autoloads (thai-auto-composition-mode thai-composition-function
  ;;;;;;  thai-post-read-conversion thai-compose-buffer thai-compose-string
  ;;;;;;  thai-compose-region) "thai-util" "language/thai-util.el"
- ;;;;;;  (17792 9562))
+ ;;;;;;  (17843 45621))
  ;;; Generated autoloads from language/thai-util.el
  
  (autoload (quote thai-compose-region) "thai-util" "\
@@@ -26969,7 -27055,7 +26995,7 @@@ Minor mode for automatically correct Th
  \f
  ;;;### (autoloads (list-at-point number-at-point symbol-at-point
  ;;;;;;  sexp-at-point thing-at-point bounds-of-thing-at-point forward-thing)
- ;;;;;;  "thingatpt" "thingatpt.el" (17781 39502))
+ ;;;;;;  "thingatpt" "thingatpt.el" (17843 45612))
  ;;; Generated autoloads from thingatpt.el
  
  (autoload (quote forward-thing) "thingatpt" "\
@@@ -27026,7 -27112,7 +27052,7 @@@ Not documente
  \f
  ;;;### (autoloads (thumbs-dired-setroot thumbs-dired-show thumbs-dired-show-marked
  ;;;;;;  thumbs-show-from-dir thumbs-find-thumb) "thumbs" "thumbs.el"
- ;;;;;;  (17601 9091))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from thumbs.el
  
  (autoload (quote thumbs-find-thumb) "thumbs" "\
@@@ -27065,7 -27151,7 +27091,7 @@@ In dired, call the setroot program on t
  ;;;;;;  tibetan-composition-function tibetan-decompose-string tibetan-decompose-region
  ;;;;;;  tibetan-compose-region tibetan-compose-string tibetan-transcription-to-tibetan
  ;;;;;;  tibetan-tibetan-to-transcription tibetan-char-p) "tibet-util"
- ;;;;;;  "language/tibet-util.el" (17792 9562))
+ ;;;;;;  "language/tibet-util.el" (17843 45621))
  ;;; Generated autoloads from language/tibet-util.el
  
  (autoload (quote tibetan-char-p) "tibet-util" "\
@@@ -27144,7 -27230,7 +27170,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (tildify-buffer tildify-region) "tildify" "textmodes/tildify.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from textmodes/tildify.el
  
  (autoload (quote tildify-region) "tildify" "\
@@@ -27168,7 -27254,7 +27194,7 @@@ This function performs no refilling of 
  ;;;***
  \f
  ;;;### (autoloads (display-time-mode display-time display-time-day-and-date)
- ;;;;;;  "time" "time.el" (17674 51268))
+ ;;;;;;  "time" "time.el" (17843 45612))
  ;;; Generated autoloads from time.el
  
  (defvar display-time-day-and-date nil "\
@@@ -27210,8 -27296,8 +27236,8 @@@ This runs the normal hook `display-time
  ;;;### (autoloads (safe-date-to-time time-to-days time-to-day-in-year
  ;;;;;;  date-leap-year-p days-between date-to-day time-add time-subtract
  ;;;;;;  time-since days-to-time time-less-p seconds-to-time time-to-seconds
- ;;;;;;  date-to-time) "time-date" "calendar/time-date.el" (17386
- ;;;;;;  33146))
+ ;;;;;;  date-to-time) "time-date" "calendar/time-date.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from calendar/time-date.el
  
  (autoload (quote date-to-time) "time-date" "\
@@@ -27297,7 -27383,7 +27323,7 @@@ If DATE is malformed, return a time val
  ;;;***
  \f
  ;;;### (autoloads (time-stamp-toggle-active time-stamp) "time-stamp"
- ;;;;;;  "time-stamp.el" (17771 1419))
+ ;;;;;;  "time-stamp.el" (17843 45612))
  ;;; Generated autoloads from time-stamp.el
  (put 'time-stamp-format 'safe-local-variable 'stringp)
  (put 'time-stamp-line-limit 'safe-local-variable 'integerp)
@@@ -27340,7 -27426,7 +27366,7 @@@ With ARG, turn time stamping on if and 
  ;;;;;;  timeclock-workday-remaining-string timeclock-reread-log timeclock-query-out
  ;;;;;;  timeclock-change timeclock-status-string timeclock-out timeclock-in
  ;;;;;;  timeclock-modeline-display) "timeclock" "calendar/timeclock.el"
- ;;;;;;  (17632 41885))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from calendar/timeclock.el
  
  (autoload (quote timeclock-modeline-display) "timeclock" "\
@@@ -27441,7 -27527,7 +27467,7 @@@ relative only to the time worked today
  \f
  ;;;### (autoloads (with-timeout run-with-idle-timer add-timeout run-with-timer
  ;;;;;;  run-at-time cancel-function-timers cancel-timer) "timer"
- ;;;;;;  "emacs-lisp/timer.el" (17785 34467))
+ ;;;;;;  "emacs-lisp/timer.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/timer.el
  
  (defalias (quote disable-timeout) (quote cancel-timer))
@@@ -27517,7 -27603,7 +27543,7 @@@ be detected
  ;;;***
  \f
  ;;;### (autoloads (batch-titdic-convert titdic-convert) "titdic-cnv"
- ;;;;;;  "international/titdic-cnv.el" (17792 9562))
+ ;;;;;;  "international/titdic-cnv.el" (17843 45620))
  ;;; Generated autoloads from international/titdic-cnv.el
  
  (autoload (quote titdic-convert) "titdic-cnv" "\
@@@ -27540,8 -27626,8 +27566,8 @@@ To get complete usage, invoke \"emacs -
  ;;;***
  \f
  ;;;### (autoloads (tamil-composition-function tamil-post-read-conversion
- ;;;;;;  tamil-compose-region) "tml-util" "language/tml-util.el" (17788
- ;;;;;;  21816))
+ ;;;;;;  tamil-compose-region) "tml-util" "language/tml-util.el" (17843
+ ;;;;;;  45621))
  ;;; Generated autoloads from language/tml-util.el
  
  (autoload (quote tamil-compose-region) "tml-util" "\
@@@ -27564,7 -27650,7 +27590,7 @@@ PATTERN regexp
  ;;;***
  \f
  ;;;### (autoloads (tmm-prompt tmm-menubar-mouse tmm-menubar) "tmm"
- ;;;;;;  "tmm.el" (17771 1419))
+ ;;;;;;  "tmm.el" (17843 45612))
  ;;; Generated autoloads from tmm.el
   (define-key global-map "\M-`" 'tmm-menubar)
   (define-key global-map [f10] 'tmm-menubar)
@@@ -27605,7 -27691,7 +27631,7 @@@ Its value should be an event that has 
  \f
  ;;;### (autoloads (todo-show todo-cp todo-mode todo-print todo-top-priorities
  ;;;;;;  todo-insert-item todo-add-item-non-interactively todo-add-category)
- ;;;;;;  "todo-mode" "calendar/todo-mode.el" (17386 33146))
+ ;;;;;;  "todo-mode" "calendar/todo-mode.el" (17843 45615))
  ;;; Generated autoloads from calendar/todo-mode.el
  
  (autoload (quote todo-add-category) "todo-mode" "\
@@@ -27666,7 -27752,7 +27692,7 @@@ Show TODO list
  \f
  ;;;### (autoloads (tool-bar-local-item-from-menu tool-bar-add-item-from-menu
  ;;;;;;  tool-bar-local-item tool-bar-add-item) "tool-bar" "tool-bar.el"
- ;;;;;;  (17495 43954))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from tool-bar.el
  
  (put (quote tool-bar-mode) (quote standard-value) (quote (t)))
@@@ -27733,7 -27819,7 +27759,7 @@@ holds a keymap
  ;;;***
  \f
  ;;;### (autoloads (tpu-edt-on tpu-edt-mode) "tpu-edt" "emulation/tpu-edt.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emulation/tpu-edt.el
  
  (defvar tpu-edt-mode nil "\
@@@ -27760,7 -27846,7 +27786,7 @@@ Turn on TPU/edt emulation
  ;;;***
  \f
  ;;;### (autoloads (tpu-set-cursor-bound tpu-set-cursor-free tpu-set-scroll-margins)
- ;;;;;;  "tpu-extras" "emulation/tpu-extras.el" (17785 34467))
+ ;;;;;;  "tpu-extras" "emulation/tpu-extras.el" (17843 45615))
  ;;; Generated autoloads from emulation/tpu-extras.el
  
  (autoload (quote tpu-set-scroll-margins) "tpu-extras" "\
@@@ -27780,7 -27866,7 +27806,7 @@@ Constrain the cursor to the flow of th
  
  ;;;***
  \f
- ;;;### (autoloads (tq-create) "tq" "emacs-lisp/tq.el" (17785 34467))
+ ;;;### (autoloads (tq-create) "tq" "emacs-lisp/tq.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/tq.el
  
  (autoload (quote tq-create) "tq" "\
@@@ -27794,7 -27880,7 +27820,7 @@@ to a tcp server on another machine
  ;;;***
  \f
  ;;;### (autoloads (trace-function-background trace-function trace-buffer)
- ;;;;;;  "trace" "emacs-lisp/trace.el" (17785 34467))
+ ;;;;;;  "trace" "emacs-lisp/trace.el" (17843 45615))
  ;;; Generated autoloads from emacs-lisp/trace.el
  
  (defvar trace-buffer "*trace-output*" "\
@@@ -27831,7 -27917,7 +27857,7 @@@ BUFFER defaults to `trace-buffer'
  ;;;### (autoloads (tramp-unload-tramp tramp-completion-handle-file-name-completion
  ;;;;;;  tramp-completion-handle-file-name-all-completions tramp-unload-file-name-handlers
  ;;;;;;  tramp-file-name-handler tramp-completion-file-name-regexp
- ;;;;;;  tramp-file-name-regexp) "tramp" "net/tramp.el" (17800 14311))
+ ;;;;;;  tramp-file-name-regexp) "tramp" "net/tramp.el" (17844 62922))
  ;;; Generated autoloads from net/tramp.el
  
  (defvar tramp-unified-filenames (not (featurep (quote xemacs))) "\
@@@ -27934,7 -28020,7 +27960,7 @@@ Like `file-name-all-completions' for pa
  (autoload (quote tramp-completion-handle-file-name-completion) "tramp" "\
  Like `file-name-completion' for tramp files.
  
- \(fn FILENAME DIRECTORY)" nil nil)
+ \(fn FILENAME DIRECTORY &optional PREDICATE)" nil nil)
  
  (autoload (quote tramp-unload-tramp) "tramp" "\
  Discard Tramp from loading remote files.
  ;;;***
  \f
  ;;;### (autoloads (tramp-ftp-enable-ange-ftp) "tramp-ftp" "net/tramp-ftp.el"
- ;;;;;;  (17366 25285))
+ ;;;;;;  (17843 45624))
  ;;; Generated autoloads from net/tramp-ftp.el
  
  (autoload (quote tramp-ftp-enable-ange-ftp) "tramp-ftp" "\
@@@ -27959,8 -28045,8 +27985,8 @@@ Not documente
  ;;;;;;  tumme-display-thumb tumme-display-thumbs-append tumme-setup-dired-keybindings
  ;;;;;;  tumme-jump-thumbnail-buffer tumme-delete-tag tumme-tag-files
  ;;;;;;  tumme-show-all-from-dir tumme-display-thumbs tumme-dired-with-window-configuration
- ;;;;;;  tumme-dired-insert-marked-thumbs) "tumme" "tumme.el" (17645
- ;;;;;;  64048))
+ ;;;;;;  tumme-dired-insert-marked-thumbs) "tumme" "tumme.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from tumme.el
  
  (autoload (quote tumme-dired-insert-marked-thumbs) "tumme" "\
@@@ -28050,7 -28136,7 +28076,7 @@@ Append thumbnails to `tumme-thumbnail-b
  \(fn)" t nil)
  
  (autoload (quote tumme-display-thumb) "tumme" "\
- Shorthard for `tumme-display-thumbs' with prefix argument.
+ Shorthand for `tumme-display-thumbs' with prefix argument.
  
  \(fn)" t nil)
  
@@@ -28090,8 -28176,8 +28116,8 @@@ easy-to-use form
  
  ;;;***
  \f
- ;;;### (autoloads (help-with-tutorial) "tutorial" "tutorial.el" (17763
- ;;;;;;  9424))
+ ;;;### (autoloads (help-with-tutorial) "tutorial" "tutorial.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from tutorial.el
  
  (autoload (quote help-with-tutorial) "tutorial" "\
@@@ -28116,7 -28202,7 +28142,7 @@@ resumed later
  ;;;***
  \f
  ;;;### (autoloads (2C-split 2C-associate-buffer 2C-two-columns) "two-column"
- ;;;;;;  "textmodes/two-column.el" (17786 56015))
+ ;;;;;;  "textmodes/two-column.el" (17843 45630))
  ;;; Generated autoloads from textmodes/two-column.el
   (autoload '2C-command "two-column" () t 'keymap)
   (global-set-key "\C-x6" '2C-command)
@@@ -28167,7 -28253,7 +28193,7 @@@ First column's text    sSs  Second colu
  ;;;;;;  type-break type-break-mode type-break-keystroke-threshold
  ;;;;;;  type-break-good-break-interval type-break-good-rest-interval
  ;;;;;;  type-break-interval type-break-mode) "type-break" "type-break.el"
- ;;;;;;  (17781 39502))
+ ;;;;;;  (17845 22175))
  ;;; Generated autoloads from type-break.el
  
  (defvar type-break-mode nil "\
@@@ -28350,7 -28436,7 +28376,7 @@@ FRAC should be the inverse of the fract
  ;;;***
  \f
  ;;;### (autoloads (ununderline-region underline-region) "underline"
- ;;;;;;  "textmodes/underline.el" (17786 56015))
+ ;;;;;;  "textmodes/underline.el" (17843 45630))
  ;;; Generated autoloads from textmodes/underline.el
  
  (autoload (quote underline-region) "underline" "\
@@@ -28371,7 -28457,7 +28397,7 @@@ which specify the range to operate on
  ;;;***
  \f
  ;;;### (autoloads (unforward-rmail-message undigestify-rmail-message)
- ;;;;;;  "undigest" "mail/undigest.el" (17786 56015))
+ ;;;;;;  "undigest" "mail/undigest.el" (17843 45622))
  ;;; Generated autoloads from mail/undigest.el
  
  (autoload (quote undigestify-rmail-message) "undigest" "\
@@@ -28390,7 -28476,7 +28416,7 @@@ following the containing message
  ;;;***
  \f
  ;;;### (autoloads (unrmail batch-unrmail) "unrmail" "mail/unrmail.el"
- ;;;;;;  (17786 56015))
+ ;;;;;;  (17843 45622))
  ;;; Generated autoloads from mail/unrmail.el
  
  (autoload (quote batch-unrmail) "unrmail" "\
@@@ -28409,8 -28495,8 +28435,8 @@@ Convert Rmail file FILE to system inbo
  
  ;;;***
  \f
- ;;;### (autoloads (unsafep) "unsafep" "emacs-lisp/unsafep.el" (17408
- ;;;;;;  40148))
+ ;;;### (autoloads (unsafep) "unsafep" "emacs-lisp/unsafep.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emacs-lisp/unsafep.el
  
  (autoload (quote unsafep) "unsafep" "\
@@@ -28423,7 -28509,7 +28449,7 @@@ of symbols with local bindings
  ;;;***
  \f
  ;;;### (autoloads (url-retrieve-synchronously url-retrieve) "url"
- ;;;;;;  "url/url.el" (17785 34468))
+ ;;;;;;  "url/url.el" (17843 45630))
  ;;; Generated autoloads from url/url.el
  
  (autoload (quote url-retrieve) "url" "\
@@@ -28463,7 -28549,7 +28489,7 @@@ no further processing).  URL is either 
  ;;;***
  \f
  ;;;### (autoloads (url-register-auth-scheme url-get-authentication)
- ;;;;;;  "url-auth" "url/url-auth.el" (17729 4745))
+ ;;;;;;  "url-auth" "url/url-auth.el" (17843 45630))
  ;;; Generated autoloads from url/url-auth.el
  
  (autoload (quote url-get-authentication) "url-auth" "\
@@@ -28505,8 -28591,8 +28531,8 @@@ RATING   a rating between 1 and 10 of t
  ;;;***
  \f
  ;;;### (autoloads (url-cache-expired url-cache-extract url-is-cached
- ;;;;;;  url-store-in-cache) "url-cache" "url/url-cache.el" (17729
- ;;;;;;  4745))
+ ;;;;;;  url-store-in-cache) "url-cache" "url/url-cache.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from url/url-cache.el
  
  (autoload (quote url-store-in-cache) "url-cache" "\
@@@ -28531,7 -28617,7 +28557,7 @@@ Return t iff a cached file has expired
  
  ;;;***
  \f
- ;;;### (autoloads (url-cid) "url-cid" "url/url-cid.el" (17729 4745))
+ ;;;### (autoloads (url-cid) "url-cid" "url/url-cid.el" (17843 45630))
  ;;; Generated autoloads from url/url-cid.el
  
  (autoload (quote url-cid) "url-cid" "\
@@@ -28542,7 -28628,7 +28568,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (url-dav-vc-registered url-dav-supported-p) "url-dav"
- ;;;;;;  "url/url-dav.el" (17729 4745))
+ ;;;;;;  "url/url-dav.el" (17843 45630))
  ;;; Generated autoloads from url/url-dav.el
  
  (autoload (quote url-dav-supported-p) "url-dav" "\
@@@ -28557,8 -28643,8 +28583,8 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads (url-file) "url-file" "url/url-file.el" (17729
- ;;;;;;  4745))
+ ;;;### (autoloads (url-file) "url-file" "url/url-file.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from url/url-file.el
  
  (autoload (quote url-file) "url-file" "\
@@@ -28569,7 -28655,7 +28595,7 @@@ Handle file: and ftp: URLs
  ;;;***
  \f
  ;;;### (autoloads (url-open-stream url-gateway-nslookup-host) "url-gw"
- ;;;;;;  "url/url-gw.el" (17789 35159))
+ ;;;;;;  "url/url-gw.el" (17843 45630))
  ;;; Generated autoloads from url/url-gw.el
  
  (autoload (quote url-gateway-nslookup-host) "url-gw" "\
@@@ -28588,8 -28674,8 +28614,8 @@@ Might do a non-blocking connection; us
  ;;;***
  \f
  ;;;### (autoloads (url-insert-file-contents url-file-local-copy url-copy-file
- ;;;;;;  url-handler-mode) "url-handlers" "url/url-handlers.el" (17729
- ;;;;;;  4745))
+ ;;;;;;  url-handler-mode) "url-handlers" "url/url-handlers.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from url/url-handlers.el
  
  (defvar url-handler-mode nil "\
@@@ -28633,7 -28719,7 +28659,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (url-http-options url-http-file-attributes url-http-file-exists-p
- ;;;;;;  url-http) "url-http" "url/url-http.el" (17785 34468))
+ ;;;;;;  url-http) "url-http" "url/url-http.el" (17843 45630))
  ;;; Generated autoloads from url/url-http.el
  
  (autoload (quote url-http) "url-http" "\
@@@ -28698,7 -28784,7 +28724,7 @@@ HTTPS retrievals are asynchronous."
  
  ;;;***
  \f
- ;;;### (autoloads (url-irc) "url-irc" "url/url-irc.el" (17729 4745))
+ ;;;### (autoloads (url-irc) "url-irc" "url/url-irc.el" (17843 45630))
  ;;; Generated autoloads from url/url-irc.el
  
  (autoload (quote url-irc) "url-irc" "\
@@@ -28708,8 -28794,8 +28734,8 @@@ Not documente
  
  ;;;***
  \f
- ;;;### (autoloads (url-ldap) "url-ldap" "url/url-ldap.el" (17729
- ;;;;;;  4745))
+ ;;;### (autoloads (url-ldap) "url-ldap" "url/url-ldap.el" (17843
+ ;;;;;;  45630))
  ;;; Generated autoloads from url/url-ldap.el
  
  (autoload (quote url-ldap) "url-ldap" "\
@@@ -28723,7 -28809,7 +28749,7 @@@ URL can be a URL string, or a URL vecto
  ;;;***
  \f
  ;;;### (autoloads (url-mailto url-mail) "url-mailto" "url/url-mailto.el"
- ;;;;;;  (17729 4745))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from url/url-mailto.el
  
  (autoload (quote url-mail) "url-mailto" "\
@@@ -28739,7 -28825,7 +28765,7 @@@ Handle the mailto: URL syntax
  ;;;***
  \f
  ;;;### (autoloads (url-data url-generic-emulator-loader url-info
- ;;;;;;  url-man) "url-misc" "url/url-misc.el" (17729 4745))
+ ;;;;;;  url-man) "url-misc" "url/url-misc.el" (17843 45630))
  ;;; Generated autoloads from url/url-misc.el
  
  (autoload (quote url-man) "url-misc" "\
@@@ -28771,7 -28857,7 +28797,7 @@@ Fetch a data URL (RFC 2397)
  ;;;***
  \f
  ;;;### (autoloads (url-snews url-news) "url-news" "url/url-news.el"
- ;;;;;;  (17729 4745))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from url/url-news.el
  
  (autoload (quote url-news) "url-news" "\
@@@ -28788,7 -28874,7 +28814,7 @@@ Not documente
  \f
  ;;;### (autoloads (url-ns-user-pref url-ns-prefs isInNet isResolvable
  ;;;;;;  dnsResolve dnsDomainIs isPlainHostName) "url-ns" "url/url-ns.el"
- ;;;;;;  (17729 4745))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from url/url-ns.el
  
  (autoload (quote isPlainHostName) "url-ns" "\
@@@ -28829,7 -28915,7 +28855,7 @@@ Not documente
  ;;;***
  \f
  ;;;### (autoloads (url-generic-parse-url url-recreate-url) "url-parse"
- ;;;;;;  "url/url-parse.el" (17756 33825))
+ ;;;;;;  "url/url-parse.el" (17843 45630))
  ;;; Generated autoloads from url/url-parse.el
  
  (autoload (quote url-recreate-url) "url-parse" "\
@@@ -28847,7 -28933,7 +28873,7 @@@ Format is
  ;;;***
  \f
  ;;;### (autoloads (url-setup-privacy-info) "url-privacy" "url/url-privacy.el"
- ;;;;;;  (17729 4745))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from url/url-privacy.el
  
  (autoload (quote url-setup-privacy-info) "url-privacy" "\
@@@ -28863,7 -28949,7 +28889,7 @@@ Setup variables that expose info about 
  ;;;;;;  url-strip-leading-spaces url-eat-trailing-space url-get-normalized-date
  ;;;;;;  url-lazy-message url-normalize-url url-insert-entities-in-string
  ;;;;;;  url-parse-args url-debug url-debug) "url-util" "url/url-util.el"
- ;;;;;;  (17767 19634))
+ ;;;;;;  (17843 45630))
  ;;; Generated autoloads from url/url-util.el
  
  (defvar url-debug nil "\
@@@ -28992,7 -29078,7 +29018,7 @@@ This uses `url-current-object', set loc
  ;;;***
  \f
  ;;;### (autoloads (ask-user-about-supersession-threat ask-user-about-lock)
- ;;;;;;  "userlock" "userlock.el" (17781 39502))
+ ;;;;;;  "userlock" "userlock.el" (17843 45612))
  ;;; Generated autoloads from userlock.el
  
  (autoload (quote ask-user-about-lock) "userlock" "\
@@@ -29018,11 -29104,17 +29044,11 @@@ The buffer in question is current when 
  
  \(fn FN)" nil nil)
  
 -;;;***
 -\f
 -;;;### (autoloads nil "utf-7" "international/utf-7.el" (17843 45620))
 -;;; Generated autoloads from international/utf-7.el
 -(autoload-coding-system 'utf-7 '(require 'utf-7))
 -
  ;;;***
  \f
  ;;;### (autoloads (uudecode-decode-region uudecode-decode-region-internal
  ;;;;;;  uudecode-decode-region-external) "uudecode" "gnus/uudecode.el"
- ;;;;;;  (17551 7908))
+ ;;;;;;  (17843 45618))
  ;;; Generated autoloads from gnus/uudecode.el
  
  (autoload (quote uudecode-decode-region-external) "uudecode" "\
@@@ -29052,7 -29144,7 +29078,7 @@@ If FILE-NAME is non-nil, save the resul
  ;;;;;;  vc-directory vc-merge vc-insert-headers vc-version-other-window
  ;;;;;;  vc-diff vc-register vc-next-action vc-do-command edit-vc-file
  ;;;;;;  with-vc-file vc-branch-part vc-trunk-p vc-before-checkin-hook
- ;;;;;;  vc-checkin-hook vc-checkout-hook) "vc" "vc.el" (17721 20491))
+ ;;;;;;  vc-checkin-hook vc-checkout-hook) "vc" "vc.el" (17843 45612))
  ;;; Generated autoloads from vc.el
  
  (defvar vc-checkout-hook nil "\
@@@ -29340,7 -29432,7 +29366,7 @@@ colors. `vc-annotate-background' specif
  
  ;;;***
  \f
- ;;;### (autoloads nil "vc-arch" "vc-arch.el" (17385 8488))
+ ;;;### (autoloads nil "vc-arch" "vc-arch.el" (17843 45612))
  ;;; Generated autoloads from vc-arch.el
   (defun vc-arch-registered (file)
    (if (vc-find-root file "{arch}/=tagging-method")
  
  ;;;***
  \f
- ;;;### (autoloads nil "vc-cvs" "vc-cvs.el" (17587 57307))
+ ;;;### (autoloads nil "vc-cvs" "vc-cvs.el" (17843 45612))
  ;;; Generated autoloads from vc-cvs.el
   (defun vc-cvs-registered (f)
    (when (file-readable-p (expand-file-name
  
  ;;;***
  \f
- ;;;### (autoloads nil "vc-mcvs" "vc-mcvs.el" (17385 8488))
+ ;;;### (autoloads nil "vc-mcvs" "vc-mcvs.el" (17843 45612))
  ;;; Generated autoloads from vc-mcvs.el
   (defun vc-mcvs-registered (file)
    (if (vc-find-root file "MCVS/CVS")
  ;;;***
  \f
  ;;;### (autoloads (vc-rcs-master-templates) "vc-rcs" "vc-rcs.el"
- ;;;;;;  (17385 8488))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from vc-rcs.el
  
  (defvar vc-rcs-master-templates (quote ("%sRCS/%s,v" "%s%s,v" "%sRCS/%s")) "\
  *Where to look for RCS master files.
  For a description of possible values, see `vc-check-master-templates'.")
  
- (custom-autoload (quote vc-rcs-master-templates) "vc-rcs")
+ (custom-autoload (quote vc-rcs-master-templates) "vc-rcs" t)
   (defun vc-rcs-registered (f) (vc-default-registered 'RCS f))
  
  ;;;***
  \f
  ;;;### (autoloads (vc-sccs-master-templates) "vc-sccs" "vc-sccs.el"
- ;;;;;;  (17385 8488))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from vc-sccs.el
  
  (defvar vc-sccs-master-templates (quote ("%sSCCS/s.%s" "%ss.%s" vc-sccs-search-project-dir)) "\
  *Where to look for SCCS master files.
  For a description of possible values, see `vc-check-master-templates'.")
  
- (custom-autoload (quote vc-sccs-master-templates) "vc-sccs")
+ (custom-autoload (quote vc-sccs-master-templates) "vc-sccs" t)
   (defun vc-sccs-registered(f) (vc-default-registered 'SCCS f))
  
  (defun vc-sccs-search-project-dir (dirname basename) "\
@@@ -29401,7 -29493,7 +29427,7 @@@ find any project directory." (let ((pro
  
  ;;;***
  \f
- ;;;### (autoloads nil "vc-svn" "vc-svn.el" (17747 24147))
+ ;;;### (autoloads nil "vc-svn" "vc-svn.el" (17838 18033))
  ;;; Generated autoloads from vc-svn.el
   (defun vc-svn-registered (f)
    (let ((admin-dir (cond ((and (eq system-type 'windows-nt)
  ;;;***
  \f
  ;;;### (autoloads (vhdl-mode) "vhdl-mode" "progmodes/vhdl-mode.el"
- ;;;;;;  (17781 39502))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/vhdl-mode.el
  
  (autoload (quote vhdl-mode) "vhdl-mode" "\
@@@ -30015,7 -30107,7 +30041,7 @@@ Syntax table and abbrevs while in vi mo
  ;;;### (autoloads (viqr-pre-write-conversion viqr-post-read-conversion
  ;;;;;;  viet-encode-viqr-buffer viet-encode-viqr-region viet-decode-viqr-buffer
  ;;;;;;  viet-decode-viqr-region viet-encode-viscii-char) "viet-util"
- ;;;;;;  "language/viet-util.el" (17792 9562))
+ ;;;;;;  "language/viet-util.el" (17843 45621))
  ;;; Generated autoloads from language/viet-util.el
  
  (autoload (quote viet-encode-viscii-char) "viet-util" "\
@@@ -30061,8 -30153,8 +30087,8 @@@ Not documente
  \f
  ;;;### (autoloads (View-exit-and-edit view-mode-enter view-mode view-buffer-other-frame
  ;;;;;;  view-buffer-other-window view-buffer view-file-other-frame
- ;;;;;;  view-file-other-window view-file) "view" "view.el" (17385
- ;;;;;;  8488))
+ ;;;;;;  view-file-other-window view-file) "view" "view.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from view.el
  
  (defvar view-mode nil "\
@@@ -30271,8 -30363,8 +30297,8 @@@ Exit View mode and make the current buf
  
  ;;;***
  \f
- ;;;### (autoloads (vip-mode vip-setup) "vip" "emulation/vip.el" (17785
- ;;;;;;  34467))
+ ;;;### (autoloads (vip-mode vip-setup) "vip" "emulation/vip.el" (17843
+ ;;;;;;  45615))
  ;;; Generated autoloads from emulation/vip.el
  
  (autoload (quote vip-setup) "vip" "\
@@@ -30288,7 -30380,7 +30314,7 @@@ Turn on VIP emulation of VI
  ;;;***
  \f
  ;;;### (autoloads (viper-mode toggle-viper-mode) "viper" "emulation/viper.el"
- ;;;;;;  (17743 18143))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from emulation/viper.el
  
  (autoload (quote toggle-viper-mode) "viper" "\
@@@ -30305,7 -30397,7 +30331,7 @@@ Turn on Viper emulation of Vi in Emacs
  ;;;***
  \f
  ;;;### (autoloads (warn lwarn display-warning) "warnings" "emacs-lisp/warnings.el"
- ;;;;;;  (17495 43954))
+ ;;;;;;  (17843 45615))
  ;;; Generated autoloads from emacs-lisp/warnings.el
  
  (defvar warning-prefix-function nil "\
@@@ -30394,7 -30486,7 +30420,7 @@@ this is equivalent to `display-warning'
  ;;;***
  \f
  ;;;### (autoloads (wdired-change-to-wdired-mode) "wdired" "wdired.el"
- ;;;;;;  (17786 57515))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from wdired.el
  
  (autoload (quote wdired-change-to-wdired-mode) "wdired" "\
@@@ -30410,7 -30502,7 +30436,7 @@@ See `wdired-mode'
  
  ;;;***
  \f
- ;;;### (autoloads (webjump) "webjump" "net/webjump.el" (17786 56015))
+ ;;;### (autoloads (webjump) "webjump" "net/webjump.el" (17843 45625))
  ;;; Generated autoloads from net/webjump.el
  
  (autoload (quote webjump) "webjump" "\
@@@ -30427,7 -30519,7 +30453,7 @@@ Please submit bug reports and other fee
  ;;;***
  \f
  ;;;### (autoloads (which-function-mode) "which-func" "progmodes/which-func.el"
- ;;;;;;  (17608 57530))
+ ;;;;;;  (17843 45629))
  ;;; Generated autoloads from progmodes/which-func.el
   (put 'which-func-format 'risky-local-variable t)
   (put 'which-func-current 'risky-local-variable t)
  Non-nil if Which-Function mode is enabled.
  See the command `which-function-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `which-function-mode'.")
+ either customize it (see the info node `Easy Customization')
+ or call the function `which-function-mode'.")
  
  (custom-autoload (quote which-function-mode) "which-func" nil)
  
@@@ -30459,7 -30552,7 +30486,7 @@@ and off otherwise
  ;;;;;;  whitespace-buffer whitespace-toggle-ateol-check whitespace-toggle-spacetab-check
  ;;;;;;  whitespace-toggle-indent-check whitespace-toggle-trailing-check
  ;;;;;;  whitespace-toggle-leading-check) "whitespace" "whitespace.el"
- ;;;;;;  (17781 39502))
+ ;;;;;;  (17843 45612))
  ;;; Generated autoloads from whitespace.el
  
  (autoload (quote whitespace-toggle-leading-check) "whitespace" "\
@@@ -30550,7 -30643,7 +30577,7 @@@ This is meant to be added buffer-locall
  ;;;***
  \f
  ;;;### (autoloads (widget-minor-mode widget-browse-other-window widget-browse
- ;;;;;;  widget-browse-at) "wid-browse" "wid-browse.el" (17781 39502))
+ ;;;;;;  widget-browse-at) "wid-browse" "wid-browse.el" (17843 45612))
  ;;; Generated autoloads from wid-browse.el
  
  (autoload (quote widget-browse-at) "wid-browse" "\
@@@ -30577,8 -30670,8 +30604,8 @@@ With arg, turn widget mode on if and on
  ;;;***
  \f
  ;;;### (autoloads (widget-setup widget-insert widget-delete widget-create
- ;;;;;;  widget-prompt-value widgetp) "wid-edit" "wid-edit.el" (17743
- ;;;;;;  45278))
+ ;;;;;;  widget-prompt-value widgetp) "wid-edit" "wid-edit.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from wid-edit.el
  
  (autoload (quote widgetp) "wid-edit" "\
@@@ -30622,8 -30715,8 +30649,8 @@@ Setup current buffer so editing string 
  ;;;***
  \f
  ;;;### (autoloads (windmove-default-keybindings windmove-down windmove-right
- ;;;;;;  windmove-up windmove-left) "windmove" "windmove.el" (17781
- ;;;;;;  39502))
+ ;;;;;;  windmove-up windmove-left) "windmove" "windmove.el" (17843
+ ;;;;;;  45612))
  ;;; Generated autoloads from windmove.el
  
  (autoload (quote windmove-left) "windmove" "\
@@@ -30676,7 -30769,7 +30703,7 @@@ Default MODIFIER is 'shift
  ;;;***
  \f
  ;;;### (autoloads (winner-mode winner-mode) "winner" "winner.el"
- ;;;;;;  (17385 8488))
+ ;;;;;;  (17843 45613))
  ;;; Generated autoloads from winner.el
  
  (defvar winner-mode nil "\
@@@ -30684,7 -30777,7 +30711,7 @@@ Toggle Winner mode
  Setting this variable directly does not take effect;
  use either \\[customize] or the function `winner-mode'.")
  
- (custom-autoload (quote winner-mode) "winner")
+ (custom-autoload (quote winner-mode) "winner" nil)
  
  (autoload (quote winner-mode) "winner" "\
  Toggle Winner mode.
@@@ -30695,7 -30788,7 +30722,7 @@@ With arg, turn Winner mode on if and on
  ;;;***
  \f
  ;;;### (autoloads (woman-find-file woman-dired-find-file woman) "woman"
- ;;;;;;  "woman.el" (17781 39502))
+ ;;;;;;  "woman.el" (17843 45613))
  ;;; Generated autoloads from woman.el
  
  (autoload (quote woman) "woman" "\
@@@ -30731,7 -30824,7 +30758,7 @@@ decompress the file if appropriate.  Se
  ;;;***
  \f
  ;;;### (autoloads (wordstar-mode) "ws-mode" "emulation/ws-mode.el"
- ;;;;;;  (17785 34467))
+ ;;;;;;  (17843 45616))
  ;;; Generated autoloads from emulation/ws-mode.el
  
  (autoload (quote wordstar-mode) "ws-mode" "\
@@@ -30844,7 -30937,7 +30871,7 @@@ The key bindings are
  ;;;***
  \f
  ;;;### (autoloads (xml-parse-region xml-parse-file) "xml" "xml.el"
- ;;;;;;  (17607 45512))
+ ;;;;;;  (17843 45613))
  ;;; Generated autoloads from xml.el
  
  (autoload (quote xml-parse-file) "xml" "\
@@@ -30869,19 -30962,18 +30896,18 @@@ If PARSE-NS is non-nil, then QNAMES ar
  
  ;;;***
  \f
- ;;;### (autoloads (xterm-mouse-mode) "xt-mouse" "xt-mouse.el" (17385
- ;;;;;;  8488))
+ ;;;### (autoloads (xterm-mouse-mode) "xt-mouse" "xt-mouse.el" (17843
+ ;;;;;;  45613))
  ;;; Generated autoloads from xt-mouse.el
  
  (defvar xterm-mouse-mode nil "\
  Non-nil if Xterm-Mouse mode is enabled.
  See the command `xterm-mouse-mode' for a description of this minor-mode.
  Setting this variable directly does not take effect;
- use either \\[customize] or the function `xterm-mouse-mode'.")
- (custom-autoload (quote xterm-mouse-mode) "xt-mouse")
+ either customize it (see the info node `Easy Customization')
+ or call the function `xterm-mouse-mode'.")
  
- (put (quote xterm-mouse-mode) (quote custom-set) (quote custom-set-minor-mode))
+ (custom-autoload (quote xterm-mouse-mode) "xt-mouse" nil)
  
  (autoload (quote xterm-mouse-mode) "xt-mouse" "\
  Toggle XTerm mouse mode.
@@@ -30899,7 -30991,7 +30925,7 @@@ down the SHIFT key while pressing the m
  ;;;***
  \f
  ;;;### (autoloads (yenc-extract-filename yenc-decode-region) "yenc"
- ;;;;;;  "gnus/yenc.el" (17385 8494))
+ ;;;;;;  "gnus/yenc.el" (17843 45618))
  ;;; Generated autoloads from gnus/yenc.el
  
  (autoload (quote yenc-decode-region) "yenc" "\
@@@ -30915,7 -31007,7 +30941,7 @@@ Extract file name from an yenc header
  ;;;***
  \f
  ;;;### (autoloads (psychoanalyze-pinhead apropos-zippy insert-zippyism
- ;;;;;;  yow) "yow" "play/yow.el" (17786 56015))
+ ;;;;;;  yow) "yow" "play/yow.el" (17843 45626))
  ;;; Generated autoloads from play/yow.el
  
  (autoload (quote yow) "yow" "\
@@@ -30941,7 -31033,7 +30967,7 @@@ Zippy goes to the analyst
  
  ;;;***
  \f
- ;;;### (autoloads (zone) "zone" "play/zone.el" (17385 8495))
+ ;;;### (autoloads (zone) "zone" "play/zone.el" (17843 45626))
  ;;; Generated autoloads from play/zone.el
  
  (autoload (quote zone) "zone" "\
@@@ -30988,19 -31080,19 +31014,19 @@@ Zone out, completely
  ;;;;;;  "emulation/viper-cmd.el" "emulation/viper-ex.el" "emulation/viper-init.el"
  ;;;;;;  "emulation/viper-keym.el" "emulation/viper-macs.el" "emulation/viper-mous.el"
  ;;;;;;  "emulation/viper-util.el" "env.el" "erc/erc-backend.el" "erc/erc-goodies.el"
- ;;;;;;  "erc/erc-ibuffer.el" "erc/erc-lang.el" "erc/erc-menu.el"
- ;;;;;;  "erc/erc-nicklist.el" "eshell/em-alias.el" "eshell/em-banner.el"
- ;;;;;;  "eshell/em-basic.el" "eshell/em-cmpl.el" "eshell/em-dirs.el"
- ;;;;;;  "eshell/em-glob.el" "eshell/em-hist.el" "eshell/em-ls.el"
- ;;;;;;  "eshell/em-pred.el" "eshell/em-prompt.el" "eshell/em-rebind.el"
- ;;;;;;  "eshell/em-script.el" "eshell/em-smart.el" "eshell/em-term.el"
- ;;;;;;  "eshell/em-unix.el" "eshell/em-xtra.el" "eshell/esh-arg.el"
- ;;;;;;  "eshell/esh-cmd.el" "eshell/esh-ext.el" "eshell/esh-groups.el"
- ;;;;;;  "eshell/esh-io.el" "eshell/esh-maint.el" "eshell/esh-module.el"
- ;;;;;;  "eshell/esh-opt.el" "eshell/esh-proc.el" "eshell/esh-util.el"
- ;;;;;;  "eshell/esh-var.el" "ezimage.el" "faces.el" "files.el" "finder-inf.el"
- ;;;;;;  "foldout.el" "font-core.el" "font-lock.el" "format.el" "forms-d2.el"
- ;;;;;;  "forms-pass.el" "frame.el" "fringe.el" "generic-x.el" "gnus/compface.el"
+ ;;;;;;  "erc/erc-ibuffer.el" "erc/erc-lang.el" "erc/erc-nicklist.el"
+ ;;;;;;  "eshell/em-alias.el" "eshell/em-banner.el" "eshell/em-basic.el"
+ ;;;;;;  "eshell/em-cmpl.el" "eshell/em-dirs.el" "eshell/em-glob.el"
+ ;;;;;;  "eshell/em-hist.el" "eshell/em-ls.el" "eshell/em-pred.el"
+ ;;;;;;  "eshell/em-prompt.el" "eshell/em-rebind.el" "eshell/em-script.el"
+ ;;;;;;  "eshell/em-smart.el" "eshell/em-term.el" "eshell/em-unix.el"
+ ;;;;;;  "eshell/em-xtra.el" "eshell/esh-arg.el" "eshell/esh-cmd.el"
+ ;;;;;;  "eshell/esh-ext.el" "eshell/esh-groups.el" "eshell/esh-io.el"
+ ;;;;;;  "eshell/esh-maint.el" "eshell/esh-module.el" "eshell/esh-opt.el"
+ ;;;;;;  "eshell/esh-proc.el" "eshell/esh-util.el" "eshell/esh-var.el"
+ ;;;;;;  "ezimage.el" "faces.el" "files.el" "finder-inf.el" "foldout.el"
+ ;;;;;;  "font-core.el" "font-lock.el" "format.el" "forms-d2.el" "forms-pass.el"
+ ;;;;;;  "frame.el" "fringe.el" "generic-x.el" "gnus/compface.el"
  ;;;;;;  "gnus/dig.el" "gnus/dns.el" "gnus/format-spec.el" "gnus/gnus-async.el"
  ;;;;;;  "gnus/gnus-bcklg.el" "gnus/gnus-cite.el" "gnus/gnus-cus.el"
  ;;;;;;  "gnus/gnus-demon.el" "gnus/gnus-dup.el" "gnus/gnus-eform.el"
  ;;;;;;  "net/eudcb-bbdb.el" "net/eudcb-ldap.el" "net/eudcb-mab.el"
  ;;;;;;  "net/eudcb-ph.el" "net/ldap.el" "net/netrc.el" "net/tls.el"
  ;;;;;;  "net/tramp-smb.el" "net/tramp-util.el" "net/tramp-uu.el"
- ;;;;;;  "net/tramp-vc.el" "net/trampver.el" "obsolete/bg-mouse.el"
- ;;;;;;  "obsolete/hilit19.el" "obsolete/sc.el" "obsolete/uncompress.el"
- ;;;;;;  "patcomp.el" "paths.el" "pcvs-info.el" "pcvs-parse.el" "pcvs-util.el"
+ ;;;;;;  "net/tramp-vc.el" "net/trampver.el" "obsolete/sc.el" "patcomp.el"
+ ;;;;;;  "paths.el" "pcvs-info.el" "pcvs-parse.el" "pcvs-util.el"
  ;;;;;;  "pgg-def.el" "pgg-parse.el" "pgg-pgp.el" "pgg-pgp5.el" "play/gamegrid.el"
  ;;;;;;  "play/gametree.el" "play/meese.el" "progmodes/ada-prj.el"
  ;;;;;;  "progmodes/cc-align.el" "progmodes/cc-awk.el" "progmodes/cc-bytecomp.el"
  ;;;;;;  "register.el" "replace.el" "rfn-eshadow.el" "s-region.el"
  ;;;;;;  "saveplace.el" "sb-image.el" "scroll-bar.el" "select.el"
  ;;;;;;  "soundex.el" "startup.el" "subdirs.el" "tempo.el" "term/apollo.el"
- ;;;;;;  "term/bobcat.el" "term/cygwin.el" "term/internal.el" "term/linux.el"
- ;;;;;;  "term/lk201.el" "term/pc-win.el" "term/rxvt.el" "term/sun.el"
- ;;;;;;  "term/tty-colors.el" "term/vt102.el" "term/vt125.el" "term/vt200.el"
- ;;;;;;  "term/vt201.el" "term/vt220.el" "term/vt240.el" "term/vt300.el"
- ;;;;;;  "term/vt320.el" "term/vt400.el" "term/vt420.el" "textmodes/bib-mode.el"
- ;;;;;;  "textmodes/makeinfo.el" "textmodes/page-ext.el" "textmodes/page.el"
- ;;;;;;  "textmodes/refbib.el" "textmodes/refer.el" "textmodes/reftex-auc.el"
- ;;;;;;  "textmodes/reftex-dcr.el" "textmodes/reftex-ref.el" "textmodes/reftex-sel.el"
- ;;;;;;  "textmodes/reftex-toc.el" "textmodes/texnfo-upd.el" "textmodes/text-mode.el"
- ;;;;;;  "timezone.el" "tooltip.el" "tree-widget.el" "uniquify.el"
- ;;;;;;  "url/url-about.el" "url/url-cookie.el" "url/url-dired.el"
- ;;;;;;  "url/url-expand.el" "url/url-ftp.el" "url/url-history.el"
- ;;;;;;  "url/url-imap.el" "url/url-methods.el" "url/url-nfs.el" "url/url-proxy.el"
- ;;;;;;  "url/url-vars.el" "url/vc-dav.el" "vc-hooks.el" "vcursor.el"
- ;;;;;;  "version.el" "vms-patch.el" "vmsproc.el" "vt-control.el"
- ;;;;;;  "vt100-led.el" "w32-fns.el" "w32-vars.el" "widget.el" "window.el"
- ;;;;;;  "x-dnd.el") (17800 15098 489655))
+ ;;;;;;  "term/bobcat.el" "term/cygwin.el" "term/linux.el" "term/lk201.el"
+ ;;;;;;  "term/vt102.el" "term/vt125.el" "term/vt200.el" "term/vt201.el"
+ ;;;;;;  "term/vt220.el" "term/vt240.el" "term/vt300.el" "term/vt320.el"
+ ;;;;;;  "term/vt400.el" "term/vt420.el" "textmodes/bib-mode.el" "textmodes/makeinfo.el"
+ ;;;;;;  "textmodes/page-ext.el" "textmodes/page.el" "textmodes/refbib.el"
+ ;;;;;;  "textmodes/refer.el" "textmodes/reftex-auc.el" "textmodes/reftex-dcr.el"
+ ;;;;;;  "textmodes/reftex-ref.el" "textmodes/reftex-sel.el" "textmodes/reftex-toc.el"
+ ;;;;;;  "textmodes/texnfo-upd.el" "textmodes/text-mode.el" "timezone.el"
+ ;;;;;;  "tooltip.el" "tree-widget.el" "uniquify.el" "url/url-about.el"
+ ;;;;;;  "url/url-cookie.el" "url/url-dired.el" "url/url-expand.el"
+ ;;;;;;  "url/url-ftp.el" "url/url-history.el" "url/url-imap.el" "url/url-methods.el"
+ ;;;;;;  "url/url-nfs.el" "url/url-proxy.el" "url/url-vars.el" "url/vc-dav.el"
+ ;;;;;;  "vc-hooks.el" "vcursor.el" "version.el" "vms-patch.el" "vmsproc.el"
+ ;;;;;;  "vt-control.el" "vt100-led.el" "w32-fns.el" "w32-vars.el"
+ ;;;;;;  "widget.el" "window.el" "x-dnd.el") (17845 23032 619212))
  
  ;;;***
  \f
diff --combined lisp/loadup.el
index 3cba54f7bed17744317443fe6446b9fd0682495d,6a8d5b263eb6d7f086cc458ff9634e794abcd0f1..affaf03b92debc4936b7892345e7fbfde475b222
@@@ -1,7 -1,7 +1,7 @@@
  ;;; loadup.el --- load up standardly loaded Lisp files for Emacs
  
  ;; Copyright (C) 1985, 1986, 1992, 1994, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: internal
@@@ -33,8 -33,6 +33,8 @@@
  ;; get autoloaded when bootstrapping
  (if (or (equal (nth 3 command-line-args) "bootstrap")
        (equal (nth 4 command-line-args) "bootstrap")
 +      (equal (nth 3 command-line-args) "unidata-gen.el")
 +      (equal (nth 4 command-line-args) "unidata-gen-files")
        ;; in case CANNOT_DUMP
        (equal (nth 0 command-line-args) "../src/bootstrap-emacs"))
      (let ((dir (car load-path)))
  ;; multilingual text.
  (load "international/mule-cmds")
  (load "case-table")
 -(load "international/utf-8")
 -(load "international/utf-16")
  (load "international/characters")
 +(load "composite")
 +;; This file doesn't exist when building Emacs from CVS.  It is
 +;; generated just after temacs is build.
 +(load "international/charprop.el" t)
  
 -(let ((set-case-syntax-set-multibyte t))
 -  (load "international/latin-1")
 -  (load "international/latin-2")
 -  (load "international/latin-3")
 -  (load "international/latin-4")
 -  (load "international/latin-5")
 -  (load "international/latin-8")
 -  (load "international/latin-9"))
  ;; Load language-specific files.
  (load "language/chinese")
  (load "language/cyrillic")
  (load "language/utf-8-lang")
  (load "language/georgian")
  
 -(load "international/ucs-tables")
 -
 -(update-coding-systems-internal)
 -
  (load "indent")
  (load "window")
  (load "frame")
        (equal (nth 4 command-line-args) "bootstrap"))
      (setcdr load-path nil))
  
 +(clear-charset-maps)
  (garbage-collect)
  
  ;;; At this point, we're ready to resume undo recording for scratch.
diff --combined lisp/mail/emacsbug.el
index fc46e9f45c25f3100d32b32710a552d67f110b84,cbe14052e19b244bf5bf84f72e7f16b417a7730a..c4592aca66c8118cd02163c4850013790c21fbbc
@@@ -1,7 -1,7 +1,7 @@@
  ;;; emacsbug.el --- command to report Emacs bugs to appropriate mailing list
  
  ;; Copyright (C) 1985, 1994, 1997, 1998, 2000, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: K. Shane Hartman
  ;; Maintainer: FSF
@@@ -151,7 -151,7 +151,7 @@@ usually do not have translators to rea
       '(lambda (var)
        (insert (format "  value of $%s: %s\n" var (getenv var))))
       '("LC_ALL" "LC_COLLATE" "LC_CTYPE" "LC_MESSAGES"
 -       "LC_MONETARY" "LC_NUMERIC" "LC_TIME" "LANG"))
 +       "LC_MONETARY" "LC_NUMERIC" "LC_TIME" "LANG" "XMODIFIERS"))
      (insert (format "  locale-coding-system: %s\n" locale-coding-system))
      (insert (format "  default-enable-multibyte-characters: %s\n"
                    default-enable-multibyte-characters))
diff --combined lisp/mail/rmail.el
index 707f62131cf26e7f6ec08f1f99311624b7fe4e02,5c0412fa2becf1093546ae977c7b21c52b6a8ade..1bc787946a854f81dc45ce973162df3f73288aa4
@@@ -1,7 -1,7 +1,7 @@@
  ;;; rmail.el --- main code of "RMAIL" mail reader for Emacs
  
  ;; Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
- ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: mail
@@@ -934,17 -934,17 +934,17 @@@ Note:    it means the file has no messa
      (unless (and coding-system
                 (coding-system-p coding-system))
        (setq coding-system
 -          ;; Emacs 21.1 and later writes RMAIL files in emacs-mule, but
 -          ;; earlier versions did that with the current buffer's encoding.
 -          ;; So we want to favor detection of emacs-mule (whose normal
 -          ;; priority is quite low), but still allow detection of other
 -          ;; encodings if emacs-mule won't fit.  The call to
 -          ;; detect-coding-with-priority below achieves that.
 -          (car (detect-coding-with-priority
 -                from to
 -                '((coding-category-emacs-mule . emacs-mule))))))
 -    (unless (memq coding-system
 -                '(undecided undecided-unix))
 +          ;; If rmail-file-coding-system is nil, Emacs 21 writes
 +          ;; RMAIL files in emacs-mule, Emacs 22 in utf-8, but
 +          ;; earlier versions did that with the current buffer's
 +          ;; encoding.  So we want to favor detection of emacs-mule
 +          ;; (whose normal priority is quite low) and utf-8, but
 +          ;; still allow detection of other encodings if they won't
 +          ;; fit.  The call to with-coding-priority below achieves
 +          ;; that.
 +          (with-coding-priority '(emacs-mule utf-8)
 +            (detect-coding-region from to 'highest))))
 +    (unless (eq (coding-system-type coding-system) 'undecided)
        (set-buffer-modified-p t)               ; avoid locking when decoding
        (let ((buffer-undo-list t))
        (decode-coding-region from to coding-system))
diff --combined lisp/mail/sendmail.el
index 7e9da94b10086c239848b4cec0b30626b5b59bd5,2bb1a6ed0fa3204866f46d54cc1512d39663a577..b0a8628d089651886278d8df08f08b7f8cd3c93a
@@@ -1,7 -1,7 +1,7 @@@
  ;;; sendmail.el --- mail sending commands for Emacs.  -*- byte-compile-dynamic: t -*-
  
  ;; Copyright (C) 1985, 1986, 1992, 1993, 1994, 1995, 1996, 1998, 2000,
- ;;   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: mail
@@@ -1090,7 -1090,7 +1090,7 @@@ external program defined by `sendmail-p
                          (/= (point) (point-max)))
                   selected-coding
                   (setq charset
 -                       (coding-system-get selected-coding 'mime-charset))
 +                       (coding-system-get selected-coding :mime-charset))
                   (goto-char delimline)
                   (insert "MIME-version: 1.0\n"
                           "Content-type: text/plain; charset="
@@@ -1776,7 -1776,7 +1776,7 @@@ The seventh argument ACTIONS is a list 
        (define-key (current-local-map) "v"
        (lambda ()
          (interactive)
 -        (let ((coding-system-for-read 'emacs-mule-unix))
 +        (let ((coding-system-for-read 'utf-8-emacs-unix))
            (dired-view-file))))
        (define-key (current-local-map) "\C-c\C-c"
        (lambda ()
          (let ((fname (dired-get-filename))
                ;; Auto-saved files are written in the internal
                ;; representation, so they should be read accordingly.
 -              (coding-system-for-read 'emacs-mule-unix))
 +              (coding-system-for-read 'utf-8-emacs-unix))
            (switch-to-buffer-other-window "*mail*")
            (let ((buffer-read-only nil))
              (erase-buffer)
              (insert-file-contents fname nil)
              ;; insert-file-contents will set buffer-file-coding-system
 -            ;; to emacs-mule, which is probably not what they want to
 +            ;; to utf-8-emacs, which is probably not what they want to
              ;; use for sending the message.  But we don't know what
              ;; was its value before the buffer was killed or Emacs
              ;; crashed.  We therefore reset buffer-file-coding-system
@@@ -1841,7 -1841,7 +1841,7 @@@ you can move to one of them and type C-
                     (buffer-coding buffer-file-coding-system)
                     ;; Auto-save files are written in internal
                     ;; representation of non-ASCII characters.
 -                   (coding-system-for-read 'emacs-mule-unix))
 +                   (coding-system-for-read 'utf-8-emacs-unix))
                 (erase-buffer)
                 (insert-file-contents file-name nil)
                 (setq buffer-file-coding-system buffer-coding)))))
diff --combined lisp/makefile.w32-in
index 812ce91d235f0481491d3fa902505b924a33c16b,61e7a358f497dd7ef84c17e212ad55063d3f6203..d8a7371cb13e7a0dee4931f343770a4f107f2f42
@@@ -1,6 -1,6 +1,6 @@@
  #  -*- Makefile -*- for GNU Emacs on the Microsoft W32 API.
  #  Copyright (C) 2000, 2001, 2002, 2003, 2004,
- #                2005, 2006  Free Software Foundation, Inc.
+ #                2005, 2006, 2007  Free Software Foundation, Inc.
  #
  #  This file is part of GNU Emacs.
  #
@@@ -43,9 -43,6 +43,9 @@@ EMACSOPT = -batch --no-init-file --no-s
  # Set EMACSLOADPATH correctly (already defined in environment).
  EMACSLOADPATH=$(lisp)
  
 +# Use C locale
 +LC_ALL = C
 +
  lisptagsfiles1 = $(lisp)/*.el
  lisptagsfiles2 = $(lisp)/*/*.el
  ETAGS = "../lib-src/$(BLD)/etags"
@@@ -327,7 -324,7 +327,7 @@@ $(lisp)/mh-e/mh-loaddefs.el: $(MH_E_SRC
  pre-mh-loaddefs.el-SH:
        echo ";;; mh-loaddefs.el --- automatically extracted autoloads" > $@
        echo ";;" >> $@
-       echo ";; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc." >> $@
+       echo ";; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc." >> $@
        echo ";; Author: Bill Wohler <wohler@newt.com>" >> $@
        echo ";; Keywords: mail" >> $@
        echo ";;; Commentary:" >> $@
  pre-mh-loaddefs.el-CMD:
        echo ;;; mh-loaddefs.el --- automatically extracted autoloads> $@
        echo ;;>> $@
-       echo ;; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.>> $@
+       echo ;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.>> $@
        echo ;; Author: Bill Wohler (wohler@newt.com)>> $@
        echo ;; Keywords: mail>> $@
        echo ;;; Commentary:>> $@
diff --combined lisp/obsolete/swedish.el
index b54b27c1843b1604e6123a42a63619d317c9af7e,06962b09d45a57cf16549d1d5e89b4ac6bf5d159..c2feffa2ccd9c1e0f3eac11091eba9894c5aba49
@@@ -1,6 -1,6 +1,6 @@@
  ;;; swedish.el --- miscellaneous functions for dealing with Swedish
  
- ;; Copyright (C) 1988, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1988, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;;   Free Software Foundation, Inc.
  
  ;; Author: Howard Gayle
  
  ;;; Commentary:
  
 +;; Fixme: Is this actually used?  if so, it should be in language,
 +;; possibly as a feature property of Swedish, probably defining a
 +;; `swascii' coding system.
 +
  ;;; Code:
  
  ;; Written by Howard Gayle.  See case-table.el for details.
  
  ;; See iso-swed.el for a description of the character set.
  
 -(require 'latin-1)
 -
  (defvar mail-send-hook)
  (defvar news-group-hook-alist)
  (defvar news-inews-hook)
index 4d63b07d87c5f0915892c6712ac8643af6b26edf,078e94ffbf47083b293f295480180266424df37f..8b6bc4462d65382cf3cb3f5a12103f0acf9de407
@@@ -1,6 -1,6 +1,6 @@@
  ;;; perl-mode.el --- Perl code editing commands for GNU Emacs
  
- ;; Copyright (C) 1990, 1994, 2001, 2002, 2003, 2004, 2005, 2006
+ ;; Copyright (C) 1990, 1994, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  ;; Free Software Foundation, Inc.
  
  ;; Author: William F. Mann
@@@ -312,7 -312,7 +312,7 @@@ The expansion is entirely correct becau
      (while (< (point) limit)
        (cond
         ((or (null (setq char (nth 3 state)))
 -            (and (char-valid-p char) (eq (char-syntax (nth 3 state)) ?\")))
 +            (and (characterp char) (eq (char-syntax (nth 3 state)) ?\")))
          ;; Normal text, or comment, or docstring, or normal string.
          nil)
         ((eq (nth 3 state) ?\n)
index e7de415fe2ac60ce4c58d4dcab0dd37f3f158a36,2db30ceb4b296a23702ff67099856796dcacff6d..88b5257954f0ba72716988e8f22132ffc2114c84
@@@ -1,7 -1,7 +1,7 @@@
  ;;; sh-script.el --- shell-script editing commands for Emacs
  
  ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2001, 2002,
- ;;  2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ ;;  2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  ;; Author: Daniel Pfeiffer <occitan@esperanto.org>
  ;; Version: 2.0f
@@@ -1101,7 -1101,7 +1101,7 @@@ This is used to flag quote characters i
  (defun sh-font-lock-syntactic-face-function (state)
    (let ((q (nth 3 state)))
      (if q
 -        (if (char-valid-p q)
 +        (if (characterp q)
              (if (eq q ?\`) 'sh-quoted-exec font-lock-string-face)
            sh-heredoc-face)
        font-lock-comment-face)))
diff --combined lisp/ps-print.el
index e50342dac9111f082741bacc113eb4968288f70f,2484bd677cd1e54f1d5d71b372d74488afb7a379..dfdfb2c52b99451b0dbfd5df115db71559d50020
  ;; Maintainer: Kenichi Handa <handa@m17n.org> (multi-byte characters)
  ;;    Vinicius Jose Latorre <viniciusjl@ig.com.br>
  ;; Keywords: wp, print, PostScript
 -;; Version: 6.7.1
 +;; Version: 7.2
  ;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
  
 -(defconst ps-print-version "6.7.1"
 -  "ps-print.el, v 6.7.1 <2007/01/21 vinicius>
 +(defconst ps-print-version "7.2"
 +  "ps-print.el, v 7.2 <2007/01/19 vinicius>
  
  Vinicius's last change version -- this file may have been edited as part of
  Emacs without changes to the version number.  When reporting bugs, please also
@@@ -1331,7 -1331,7 +1331,7 @@@ Please send all bug fixes and enhanceme
  ;;
  ;; Faces are always treated as opaque.
  ;;
 -;; Epoch, Lucid and Emacs 21 not supported.  At all.
 +;; Epoch, Lucid and Emacs 22 not supported.  At all.
  ;;
  ;; Fixed-pitch fonts work better for line folding, but are not required.
  ;;
  
  (require 'lpr)
  
 +
  (or (featurep 'lisp-float-type)
      (error "`ps-print' requires floating point support"))
  
           (error "`ps-print' doesn't support Epoch"))
          (t
           (unless (and (boundp 'emacs-major-version)
 -                      (>= emacs-major-version 22))
 -           (error "`ps-print' only supports Emacs 22 and higher"))
 +                      (> emacs-major-version 22))
 +           (error "`ps-print' only supports Emacs 23 and higher"))
           'emacs))))
  
  
 -;; GNU Emacs
 -(or (fboundp 'line-beginning-position)
 -    (defun line-beginning-position (&optional n)
 -      (save-excursion
 -      (and n (/= n 1) (forward-line (1- n)))
 -      (beginning-of-line)
 -      (point))))
 -
 -
 -;; to avoid compilation gripes
 -
 -;; XEmacs
 -(defalias 'ps-x-color-instance-p              'color-instance-p)
 -(defalias 'ps-x-color-instance-rgb-components 'color-instance-rgb-components)
 -(defalias 'ps-x-color-name                    'color-name)
 -(defalias 'ps-x-color-specifier-p             'color-specifier-p)
 -(defalias 'ps-x-copy-coding-system            'copy-coding-system)
 -(defalias 'ps-x-device-class                  'device-class)
 -(defalias 'ps-x-extent-end-position           'extent-end-position)
 -(defalias 'ps-x-extent-face                   'extent-face)
 -(defalias 'ps-x-extent-priority               'extent-priority)
 -(defalias 'ps-x-extent-start-position         'extent-start-position)
 -(defalias 'ps-x-face-font-instance            'face-font-instance)
 -(defalias 'ps-x-find-coding-system            'find-coding-system)
 -(defalias 'ps-x-font-instance-properties      'font-instance-properties)
 -(defalias 'ps-x-make-color-instance           'make-color-instance)
 -(defalias 'ps-x-map-extents                   'map-extents)
 -(defalias 'ps-x-frame-property                'frame-property)
 -
 -;; GNU Emacs
 -(defalias 'ps-e-face-bold-p         'face-bold-p)
 -(defalias 'ps-e-face-italic-p       'face-italic-p)
 -(defalias 'ps-e-next-overlay-change 'next-overlay-change)
 -(defalias 'ps-e-overlays-at         'overlays-at)
 -(defalias 'ps-e-overlay-get         'overlay-get)
 -(defalias 'ps-e-overlay-end         'overlay-end)
 -(defalias 'ps-e-x-color-values      'x-color-values)
 -(defalias 'ps-e-color-values        'color-values)
 -(defalias 'ps-e-frame-parameter     'frame-parameter)
 -(if (fboundp 'find-composition)
 -    (defalias 'ps-e-find-composition 'find-composition)
 -  (defalias 'ps-e-find-composition 'ignore))
 -
 -
  (defconst ps-windows-system
    (memq system-type '(emx win32 w32 mswindows ms-dos windows-nt)))
  (defconst ps-lp-system
    (memq system-type '(usg-unix-v dgux hpux irix)))
  
  
 -(defun ps-xemacs-color-name (color)
 -  (if (ps-x-color-specifier-p color)
 -      (ps-x-color-name color)
 -    color))
 -
 -
 -(cond ((featurep 'xemacs)             ; xemacs
 -       (defalias 'ps-mark-active-p 'region-active-p)
 -       (defun ps-face-foreground-name (face)
 -       (ps-xemacs-color-name (face-foreground face)))
 -       (defun ps-face-background-name (face)
 -       (ps-xemacs-color-name (face-background face)))
 -       (defun ps-frame-parameter (param)
 -       (ps-x-frame-property nil param))
 -       )
 -      (t                              ; emacs 22 or higher
 -       (defvar mark-active nil)
 -       (defun ps-mark-active-p ()
 -       mark-active)
 -       (defun ps-face-foreground-name (face)
 -       (face-foreground face nil t))
 -       (defun ps-face-background-name (face)
 -       (face-background face nil t))
 -       (defun ps-frame-parameter (param)
 -       (ps-e-frame-parameter nil param))
 -       ))
 +;; Load XEmacs/Emacs definitions
 +(eval-and-compile (require 'ps-def))
  
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@@ -2938,6 -3005,6 +2938,8 @@@ Valid values are
  
     frame-parameter    The foreground-color frame parameter will be used.
  
++   frame-parameter    The foreground-color frame parameter will be used.
++
     NUMBER     It's a real value between 0.0 (black) and 1.0 (white) that
                indicate the gray color.
  
@@@ -2981,6 -3048,6 +2983,8 @@@ Valid values are
  
     frame-parameter    The background-color frame parameter will be used.
  
++   frame-parameter    The background-color frame parameter will be used.
++
     NUMBER     It's a real value between 0.0 (black) and 1.0 (white) that
                indicate the gray color.
  
@@@ -3277,9 -3344,9 +3281,9 @@@ It's like the very first character of b
  (defcustom ps-postscript-code-directory
    (or (if (featurep 'xemacs)
          (cond ((fboundp 'locate-data-directory) ; xemacs
 -               (locate-data-directory "ps-print"))
 +               (funcall 'locate-data-directory "ps-print"))
                ((boundp 'data-directory) ; xemacs
 -               data-directory)
 +               (symbol-value 'data-directory))
                (t                      ; don't know what to do
                 nil))
        data-directory)                 ; emacs
@@@ -3771,6 -3838,107 +3775,6 @@@ It can be retrieved with `(ps-get ALIST
    (format-time-string "%T"))
  
  
 -(and (featurep 'xemacs)
 -     ;; XEmacs change: Need to check for emacs-major-version too.
 -     (or (< emacs-major-version 19)
 -       (and (= emacs-major-version 19) (< emacs-minor-version 12)))
 -     (setq ps-print-color-p nil))
 -
 -
 -;; Return t if the device (which can be changed during an emacs session)
 -;; can handle colors.
 -;; This function is not yet implemented for GNU emacs.
 -(cond ((and (featurep 'xemacs)
 -          ;; XEmacs change: Need to check for emacs-major-version too.
 -          (or (> emacs-major-version 19)
 -              (and (= emacs-major-version 19)
 -                   (>= emacs-minor-version 12)))) ; xemacs >= 19.12
 -       (defun ps-color-device ()
 -       (eq (ps-x-device-class) 'color)))
 -
 -      (t                              ; emacs
 -       (defun ps-color-device ()
 -       (if (fboundp 'color-values)
 -           (ps-e-color-values "Green")
 -         t))))
 -
 -
 -(defun ps-mapper (extent list)
 -  (nconc list
 -       (list (list (ps-x-extent-start-position extent) 'push extent)
 -             (list (ps-x-extent-end-position extent) 'pull extent)))
 -  nil)
 -
 -(defun ps-extent-sorter (a b)
 -  (< (ps-x-extent-priority a) (ps-x-extent-priority b)))
 -
 -(defun ps-xemacs-face-kind-p (face kind kind-regex)
 -  (let* ((frame-font (or (ps-x-face-font-instance face)
 -                       (ps-x-face-font-instance 'default)))
 -       (kind-cons
 -        (and frame-font
 -             (assq kind
 -                   (ps-x-font-instance-properties frame-font))))
 -       (kind-spec (cdr-safe kind-cons))
 -       (case-fold-search t))
 -    (and kind-spec (string-match kind-regex kind-spec))))
 -
 -(cond ((featurep 'xemacs)             ; xemacs
 -
 -       ;; to avoid XEmacs compilation gripes
 -       (defvar coding-system-for-write   nil)
 -       (defvar coding-system-for-read    nil)
 -       (defvar buffer-file-coding-system nil)
 -
 -       (and (fboundp 'find-coding-system)
 -          (or (ps-x-find-coding-system 'raw-text-unix)
 -              (ps-x-copy-coding-system 'no-conversion-unix 'raw-text-unix)))
 -
 -       (defun ps-color-values (x-color)
 -       (let ((color (ps-xemacs-color-name x-color)))
 -         (cond
 -          ((fboundp 'x-color-values)
 -           (ps-e-x-color-values color))
 -          ((and (fboundp 'color-instance-rgb-components)
 -                (ps-color-device))
 -           (ps-x-color-instance-rgb-components
 -            (if (ps-x-color-instance-p x-color)
 -                x-color
 -              (ps-x-make-color-instance color))))
 -          (t
 -           (error "No available function to determine X color values")))))
 -
 -       (defun ps-face-bold-p (face)
 -       (or (ps-xemacs-face-kind-p face 'WEIGHT_NAME "bold\\|demibold")
 -           (memq face ps-bold-faces))) ; Kludge-compatible
 -
 -       (defun ps-face-italic-p (face)
 -       (or (ps-xemacs-face-kind-p face 'ANGLE_NAME "i\\|o")
 -           (ps-xemacs-face-kind-p face 'SLANT "i\\|o")
 -           (memq face ps-italic-faces))) ; Kludge-compatible
 -       )
 -
 -      (t                              ; emacs
 -
 -       (defun ps-color-values (x-color)
 -       (cond
 -        ((fboundp 'color-values)
 -         (ps-e-color-values x-color))
 -        ((fboundp 'x-color-values)
 -         (ps-e-x-color-values x-color))
 -        (t
 -         (error "No available function to determine X color values"))))
 -
 -       (defun ps-face-bold-p (face)
 -       (or (ps-e-face-bold-p face)
 -           (memq face ps-bold-faces)))
 -
 -       (defun ps-face-italic-p (face)
 -       (or (ps-e-face-italic-p face)
 -           (memq face ps-italic-faces)))
 -       ))
 -
 -
  (defvar ps-print-color-scale 1.0)
  
  (defun ps-color-scale (color)
@@@ -3850,6 -4018,15 +3854,6 @@@ Note: No major/minor-mode is activated 
  (defvar ps-razchunk 0)
  
  (defvar ps-color-p nil)
 -(defvar ps-color-format
 -  (if (featurep 'xemacs)
 -      ;; XEmacs will have to make do with %s (princ) for floats.
 -      "%s %s %s"
 -
 -    ;; Emacs understands the %f format; we'll use it to limit color RGB
 -    ;; values to three decimals to cut down some on the size of the
 -    ;; PostScript output.
 -    "%0.3f %0.3f %0.3f"))
  
  ;; These values determine how much print-height to deduct when headers/footers
  ;; are turned on.  This is a pretty clumsy way of handling it, but it'll do for
@@@ -4635,35 -4812,65 +4639,35 @@@ page-height == ((floor print-height ((t
      (goto-char (point-max))
      (insert-file-contents fname)))
  
 -;; These functions are used in `ps-mule' to get charset of header and footer.
 -;; To avoid unnecessary calls to functions in `ps-left-header',
 -;; `ps-right-header', `ps-left-footer' and `ps-right-footer'.
 -
 -(defun ps-generate-string-list (content)
 -  (let (str)
 -    (while content
 -      (setq str (cons (cond
 -                     ;; string
 -                     ((stringp (car content))
 -                      (car content))
 -                     ;; function symbol
 -                     ((functionp (car content))
 -                      (concat "(" (funcall (car content)) ")"))
 -                     ;; variable symbol
 -                     ((and (symbolp (car content)) (boundp (car content)))
 -                      (concat "(" (symbol-value (car content)) ")"))
 -                     ;; otherwise, empty string
 -                     (t
 -                      ""))
 -                    str)
 -          content (cdr content)))
 -    (nreverse str)))
 -
 -(defvar ps-lh-cache nil)
 -(defvar ps-rh-cache nil)
 -(defvar ps-lf-cache nil)
 -(defvar ps-rf-cache nil)
 -
 -(defun ps-header-footer-string ()
 -  (and ps-print-header
 -       (setq ps-lh-cache (ps-generate-string-list ps-left-header)
 -           ps-rh-cache (ps-generate-string-list ps-right-header)))
 -  (and ps-print-footer
 -       (setq ps-lf-cache (ps-generate-string-list ps-left-footer)
 -           ps-rf-cache (ps-generate-string-list ps-right-footer)))
 -  (append ps-lh-cache ps-rh-cache ps-lf-cache ps-rf-cache))
 -
  ;; These functions insert the arrays that define the contents of the headers.
  
 +(defvar ps-encode-header-string-function nil)
 +
  (defun ps-generate-header-line (fonttag &optional content)
    (ps-output " [" fonttag " ")
    (cond
     ;; Literal strings should be output as is -- the string must contain its own
     ;; PS string delimiters, '(' and ')', if necessary.
     ((stringp content)
 -    (ps-output (ps-mule-encode-header-string content fonttag)))
 +    (ps-output content))
  
     ;; Functions are called -- they should return strings; they will be inserted
     ;; as strings and the PS string delimiters added.
 -   ((functionp content)
 -    (ps-output-string (ps-mule-encode-header-string (funcall content)
 -                                                  fonttag)))
 +   ((fboundp content)
 +    (if (fboundp ps-encode-header-string-function)
 +      (dolist (l (funcall ps-encode-header-string-function
 +                          (funcall content) fonttag))
 +        (ps-output-string l))
 +      (ps-output-string (funcall content))))
  
     ;; Variables will have their contents inserted.  They should contain
     ;; strings, and will be inserted as strings.
     ((and (symbolp content) (boundp content))
 -    (ps-output-string (ps-mule-encode-header-string (symbol-value content)
 -                                                  fonttag)))
 +    (if (fboundp ps-encode-header-string-function)
 +      (dolist (l (funcall ps-encode-header-string-function
 +                           (symbol-value content) fonttag))
 +        (ps-output-string l))
 +      (ps-output-string (symbol-value content))))
  
     ;; Anything else will get turned into an empty string.
     (t
        (vector 0 0 0 0)))))
  
  
 -;; Emacs understands the %f format; we'll use it to limit color RGB values
 -;; to three decimals to cut down some on the size of the PostScript output.
 -;; XEmacs will have to make do with %s (princ) for floats.
 -
 -(defvar ps-float-format (if (featurep 'xemacs)
 -                          "%s "       ; xemacs
 -                        "%0.3f "))    ; emacs
 -
 -
  (defun ps-float-format (value &optional default)
    (let ((literal (or value default)))
      (cond ((null literal)
@@@ -5621,7 -5837,6 +5625,7 @@@ XSTART YSTART are the relative positio
        (t (list default default default))
        ))
  
 +(defvar ps-basic-plot-string-function 'ps-basic-plot-string)
  
  (defun ps-begin-job ()
    ;; prologue files
        ps-color-p           (and ps-print-color-p (ps-color-device))
        ps-print-color-scale (if ps-color-p
                                 (float (car (ps-color-values "white")))
 -                             1.0))
 +                             1.0)
 +      ;; Set up default functions.  They may be overridden by
 +      ;; ps-mule-begin-job.
 +      ps-basic-plot-string-function 'ps-basic-plot-string
 +      ps-encode-header-string-function nil)
    ;; initialize page dimensions
    (ps-get-page-dimensions)
    ;; final check
             (format "/PageNumber %d def\n" (ps-page-number)))
  
    (when ps-print-header
 -    (ps-generate-header "HeaderLinesLeft"  "/h0" "/h1"
 -                      (or ps-lh-cache ps-left-header))
 -    (ps-generate-header "HeaderLinesRight" "/h0" "/h1"
 -                      (or ps-rh-cache ps-right-header))
 -    (ps-output (format "%d SetHeaderLines\n" ps-header-lines))
 -    (setq ps-lh-cache nil
 -        ps-rh-cache nil))
 +    (ps-generate-header "HeaderLinesLeft"  "/h0" "/h1" ps-left-header)
 +    (ps-generate-header "HeaderLinesRight" "/h0" "/h1" ps-right-header)
 +    (ps-output (format "%d SetHeaderLines\n" ps-header-lines)))
  
    (when ps-print-footer
 -    (ps-generate-header "FooterLinesLeft"  "/H0" "/H0"
 -                      (or ps-lf-cache ps-left-footer))
 -    (ps-generate-header "FooterLinesRight" "/H0" "/H0"
 -                      (or ps-rf-cache ps-right-footer))
 -    (ps-output (format "%d SetFooterLines\n" ps-footer-lines))
 -    (setq ps-lf-cache nil
 -        ps-rf-cache nil))
 +    (ps-generate-header "FooterLinesLeft"  "/H0" "/H0" ps-left-footer)
 +    (ps-generate-header "FooterLinesRight" "/H0" "/H0" ps-right-footer)
 +    (ps-output (format "%d SetFooterLines\n" ps-footer-lines)))
  
    (ps-output (number-to-string ps-lines-printed) " BeginPage\n")
    (ps-set-font  ps-current-font)
    (ps-set-bg    ps-current-bg)
 -  (ps-set-color ps-current-color)
 -  (ps-mule-begin-page))
 +  (ps-set-color ps-current-color))
  
  (defsubst ps-skip-newline (limit)
    (setq ps-showline-count (1+ ps-showline-count)
                                       (ps-avg-char-width 'ps-font-for-text)))
         (to (car wrappoint))
         (str (substring string from to)))
 -    (ps-mule-prepare-ascii-font str)
      (ps-output-string str)
      (ps-output " S\n")
      wrappoint))
                                       (ps-avg-char-width 'ps-font-for-text)))
         (to (car wrappoint))
         (string (buffer-substring-no-properties from to)))
 -    (ps-mule-prepare-ascii-font string)
      (ps-output-string string)
      (ps-output " S\n")
      wrappoint))
@@@ -5988,16 -6210,26 +5992,16 @@@ to the equivalent Latin-1 characters."
        (if (re-search-forward ps-control-or-escape-regexp to t)
          ;; region with some control characters or some multi-byte characters
          (let* ((match-point (match-beginning 0))
 -               (match       (char-after match-point))
 -               (composition (ps-e-find-composition from (1+ match-point))))
 -          (if composition
 -              (if (and (nth 2 composition)
 -                       (<= (car composition) match-point))
 -                  (progn
 -                    (setq match-point (car composition)
 -                          match 0)
 -                    (goto-char (nth 1 composition)))
 -                (setq composition nil)))
 +               (match       (char-after match-point)))
            (when (< from match-point)
 -            (ps-mule-set-ascii-font)
 -            (ps-plot 'ps-basic-plot-string from match-point bg-color))
 +            (ps-plot ps-basic-plot-string-function
 +                     from match-point bg-color))
            (cond
             ((= match ?\t)             ; tab
              (let ((linestart (line-beginning-position)))
                (forward-char -1)
                (setq from (+ linestart (current-column)))
                (when (re-search-forward "[ \t]+" to t)
 -                (ps-mule-set-ascii-font)
                  (ps-plot 'ps-basic-plot-whitespace
                           from (+ linestart (current-column))
                           bg-color))))
                     (ps-skip-newline to))
                (ps-next-page)))
  
 -           (composition               ; a composite sequence
 -            (ps-plot 'ps-mule-plot-composition match-point (point) bg-color))
 -
 -           ((> match 255)             ; a multi-byte character
 -            (setq match (or (aref ps-print-translation-table match) match))
 -            (let* ((charset (char-charset match))
 -                   (composition (ps-e-find-composition match-point to))
 -                   (stop (if (nth 2 composition) (car composition) to)))
 -              (or (eq charset 'composition)
 -                  (while (and (< (point) stop)
 -                              (let ((ch (following-char)))
 -                                (setq ch
 -                                      (or (aref ps-print-translation-table ch)
 -                                          ch))
 -                                (eq (char-charset ch) charset)))
 -                    (forward-char 1)))
 -              (ps-plot 'ps-mule-plot-string match-point (point) bg-color)))
 -                                      ; characters from ^@ to ^_ and
             (t                         ; characters from 127 to 255
              (ps-control-character match)))
            (setq from (point)))
 -      ;; region without control characters nor multi-byte characters
 -      (ps-mule-set-ascii-font)
 -      (ps-plot 'ps-basic-plot-string from to bg-color)
 +      ;; region without control characters
 +      (ps-plot ps-basic-plot-string-function from to bg-color)
        (setq from to)))))
  
  (defvar ps-string-control-codes
      (if (< (car wrappoint) to)
        (ps-continue-line))
      (setq ps-width-remaining (- ps-width-remaining (* len char-width)))
 -    (ps-mule-prepare-ascii-font str)
      (ps-output-string str)
      (ps-output " S\n")))
  
@@@ -6256,7 -6508,125 +6260,7 @@@ If FACE is not a valid face name, it i
    (save-restriction
      (narrow-to-region from to)
      (ps-print-ensure-fontified from to)
 -    (let ((face 'default)
 -        (position to))
 -      (cond
 -       ((featurep 'xemacs)            ; xemacs
 -      ;; Build the list of extents...
 -      (let ((a (cons 'dummy nil))
 -            record type extent extent-list)
 -        (ps-x-map-extents 'ps-mapper nil from to a)
 -        (setq a (sort (cdr a) 'car-less-than-car)
 -              extent-list nil)
 -
 -        ;; Loop through the extents...
 -        (while a
 -          (setq record (car a)
 -                position (car record)
 -
 -                record (cdr record)
 -                type (car record)
 -
 -                record (cdr record)
 -                extent (car record))
 -
 -          ;; Plot up to this record.
 -          ;; XEmacs 19.12: for some reason, we're getting into a
 -          ;; situation in which some of the records have
 -          ;; positions less than 'from'.  Since we've narrowed
 -          ;; the buffer, this'll generate errors.  This is a hack,
 -          ;; but don't call ps-plot-with-face unless from > point-min.
 -          (and (>= from (point-min))
 -               (ps-plot-with-face from (min position (point-max)) face))
 -
 -          (cond
 -           ((eq type 'push)
 -            (and (ps-x-extent-face extent)
 -                 (setq extent-list (sort (cons extent extent-list)
 -                                         'ps-extent-sorter))))
 -
 -           ((eq type 'pull)
 -            (setq extent-list (sort (delq extent extent-list)
 -                                    'ps-extent-sorter))))
 -
 -          (setq face (if extent-list
 -                         (ps-x-extent-face (car extent-list))
 -                       'default)
 -                from position
 -                a (cdr a)))))
 -
 -       (t                             ; emacs
 -      (let ((property-change from)
 -            (overlay-change from)
 -            (save-buffer-invisibility-spec buffer-invisibility-spec)
 -            (buffer-invisibility-spec nil)
 -            before-string after-string)
 -        (while (< from to)
 -          (and (< property-change to) ; Don't search for property change
 -                                      ; unless previous search succeeded.
 -               (setq property-change (next-property-change from nil to)))
 -          (and (< overlay-change to)  ; Don't search for overlay change
 -                                      ; unless previous search succeeded.
 -               (setq overlay-change (min (ps-e-next-overlay-change from)
 -                                         to)))
 -          (setq position (min property-change overlay-change)
 -                before-string nil
 -                after-string nil)
 -          ;; The code below is not quite correct,
 -          ;; because a non-nil overlay invisible property
 -          ;; which is inactive according to the current value
 -          ;; of buffer-invisibility-spec nonetheless overrides
 -          ;; a face text property.
 -          (setq face
 -                (cond ((let ((prop (get-text-property from 'invisible)))
 -                         ;; Decide whether this invisible property
 -                         ;; really makes the text invisible.
 -                         (if (eq save-buffer-invisibility-spec t)
 -                             (not (null prop))
 -                           (or (memq prop save-buffer-invisibility-spec)
 -                               (assq prop save-buffer-invisibility-spec))))
 -                       'emacs--invisible--face)
 -                      ((get-text-property from 'face))
 -                      (t 'default)))
 -          (let ((overlays (ps-e-overlays-at from))
 -                (face-priority -1))   ; text-property
 -            (while (and overlays
 -                        (not (eq face 'emacs--invisible--face)))
 -              (let* ((overlay (car overlays))
 -                     (overlay-invisible
 -                      (ps-e-overlay-get overlay 'invisible))
 -                     (overlay-priority
 -                      (or (ps-e-overlay-get overlay 'priority) 0)))
 -                (and (> overlay-priority face-priority)
 -                     (setq before-string
 -                           (or (ps-e-overlay-get overlay 'before-string)
 -                               before-string)
 -                           after-string
 -                           (or (and (<= (ps-e-overlay-end overlay) position)
 -                                    (ps-e-overlay-get overlay 'after-string))
 -                               after-string)
 -                           face-priority overlay-priority
 -                           face
 -                           (cond
 -                            ((if (eq save-buffer-invisibility-spec t)
 -                                 (not (null overlay-invisible))
 -                               (or (memq overlay-invisible
 -                                         save-buffer-invisibility-spec)
 -                                   (assq overlay-invisible
 -                                         save-buffer-invisibility-spec)))
 -                             'emacs--invisible--face)
 -                            ((ps-e-overlay-get overlay 'face))
 -                            (t face)
 -                            ))))
 -              (setq overlays (cdr overlays))))
 -          ;; Plot up to this record.
 -          (and before-string
 -               (ps-plot-string before-string))
 -          (ps-plot-with-face from position face)
 -          (and after-string
 -               (ps-plot-string after-string))
 -          (setq from position)))))
 -      (ps-plot-with-face from to face))))
 +    (ps-generate-postscript-with-faces1 from to)))
  
  (defun ps-generate-postscript (from to)
    (ps-plot-region from to 0 nil))
                (ps-begin-page)
                (funcall genfunc from to)
                (ps-end-page)
 +              (ps-mule-end-job)
                (ps-end-job needs-begin-file)
  
                ;; Setting this variable tells the unwind form that the
        (t
         (setq kill-emacs-hook 'ps-kill-emacs-check)))
  
 -\f
 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 -;;; Sample Setup Code:
 -
 -
 -;; This stuff is for anybody that's brave enough to look this far,
 -;; and able to figure out how to use it.  It isn't really part of
 -;; ps-print, but I'll leave it here in hopes it might be useful:
 -
 -;; WARNING!!! The following code is *sample* code only.
 -;; Don't use it unless you understand what it does!
 -
 -(defmacro ps-prsc ()
 -  `(if (featurep 'xemacs) 'f22           [f22]))
 -(defmacro ps-c-prsc ()
 -  `(if (featurep 'xemacs) '(control f22) [C-f22]))
 -(defmacro ps-s-prsc ()
 -  `(if (featurep 'xemacs) '(shift f22)   [S-f22]))
 -
 -;; A hook to bind to `rmail-mode-hook' to locally bind prsc and set the
 -;; `ps-left-headers' specially for mail messages.
 -(defun ps-rmail-mode-hook ()
 -  (local-set-key (ps-prsc) 'ps-rmail-print-message-from-summary)
 -  (setq ps-header-lines 3
 -      ps-left-header
 -      ;; The left headers will display the message's subject, its
 -      ;; author, and the name of the folder it was in.
 -      '(ps-article-subject ps-article-author buffer-name)))
 -
 -;; See `ps-gnus-print-article-from-summary'.  This function does the
 -;; same thing for rmail.
 -(defun ps-rmail-print-message-from-summary ()
 -  (interactive)
 -  (ps-print-message-from-summary 'rmail-summary-buffer "RMAIL"))
 -
 -;; Used in `ps-rmail-print-article-from-summary',
 -;; `ps-gnus-print-article-from-summary' and `ps-vm-print-message-from-summary'.
 -(defun ps-print-message-from-summary (summary-buffer summary-default)
 -  (let ((ps-buf (or (and (boundp summary-buffer)
 -                       (symbol-value summary-buffer))
 -                  summary-default)))
 -    (and (get-buffer ps-buf)
 -       (save-excursion
 -         (set-buffer ps-buf)
 -         (ps-spool-buffer-with-faces)))))
 -
 -;; Look in an article or mail message for the Subject: line.  To be
 -;; placed in `ps-left-headers'.
 -(defun ps-article-subject ()
 -  (save-excursion
 -    (goto-char (point-min))
 -    (if (re-search-forward "^Subject:[ \t]+\\(.*\\)$" nil t)
 -      (buffer-substring (match-beginning 1) (match-end 1))
 -      "Subject ???")))
 -
 -;; Look in an article or mail message for the From: line.  Sorta-kinda
 -;; understands RFC-822 addresses and can pull the real name out where
 -;; it's provided.  To be placed in `ps-left-headers'.
 -(defun ps-article-author ()
 -  (save-excursion
 -    (goto-char (point-min))
 -    (if (re-search-forward "^From:[ \t]+\\(.*\\)$" nil t)
 -      (let ((fromstring (buffer-substring (match-beginning 1) (match-end 1))))
 -        (cond
 -
 -         ;; Try first to match addresses that look like
 -         ;; thompson@wg2.waii.com (Jim Thompson)
 -         ((string-match ".*[ \t]+(\\(.*\\))" fromstring)
 -          (substring fromstring (match-beginning 1) (match-end 1)))
 -
 -         ;; Next try to match addresses that look like
 -         ;; Jim Thompson <thompson@wg2.waii.com> or
 -         ;; "Jim Thompson" <thompson@wg2.waii.com>
 -         ((string-match "\\(\"?\\)\\(.*\\)\\1[ \t]+<.*>" fromstring)
 -          (substring fromstring (match-beginning 2) (match-end 2)))
 -
 -         ;; Couldn't find a real name -- show the address instead.
 -         (t fromstring)))
 -      "From ???")))
 -
 -;; A hook to bind to `gnus-article-prepare-hook'.  This will set the
 -;; `ps-left-headers' specially for gnus articles.  Unfortunately,
 -;; `gnus-article-mode-hook' is called only once, the first time the *Article*
 -;; buffer enters that mode, so it would only work for the first time
 -;; we ran gnus.  The second time, this hook wouldn't get set up.  The
 -;; only alternative is `gnus-article-prepare-hook'.
 -(defun ps-gnus-article-prepare-hook ()
 -  (setq ps-header-lines 3
 -      ps-left-header
 -      ;; The left headers will display the article's subject, its
 -      ;; author, and the newsgroup it was in.
 -      '(ps-article-subject ps-article-author gnus-newsgroup-name)))
 -
 -;; A hook to bind to `vm-mode-hook' to locally bind prsc and set the
 -;; `ps-left-headers' specially for mail messages.
 -(defun ps-vm-mode-hook ()
 -  (local-set-key (ps-prsc) 'ps-vm-print-message-from-summary)
 -  (setq ps-header-lines 3
 -      ps-left-header
 -      ;; The left headers will display the message's subject, its
 -      ;; author, and the name of the folder it was in.
 -      '(ps-article-subject ps-article-author buffer-name)))
 -
 -;; Every now and then I forget to switch from the *Summary* buffer to
 -;; the *Article* before hitting prsc, and a nicely formatted list of
 -;; article subjects shows up at the printer.  This function, bound to
 -;; prsc for the gnus *Summary* buffer means I don't have to switch
 -;; buffers first.
 -;; sb:  Updated for Gnus 5.
 -(defun ps-gnus-print-article-from-summary ()
 -  (interactive)
 -  (ps-print-message-from-summary 'gnus-article-buffer "*Article*"))
 -
 -;; See `ps-gnus-print-article-from-summary'.  This function does the
 -;; same thing for vm.
 -(defun ps-vm-print-message-from-summary ()
 -  (interactive)
 -  (ps-print-message-from-summary 'vm-mail-buffer ""))
 -
 -;; A hook to bind to bind to `gnus-summary-setup-buffer' to locally bind
 -;; prsc.
 -(defun ps-gnus-summary-setup ()
 -  (local-set-key (ps-prsc) 'ps-gnus-print-article-from-summary))
 -
 -;; Look in an article or mail message for the Subject: line.  To be
 -;; placed in `ps-left-headers'.
 -(defun ps-info-file ()
 -  (save-excursion
 -    (goto-char (point-min))
 -    (if (re-search-forward "File:[ \t]+\\([^, \t\n]*\\)" nil t)
 -      (buffer-substring (match-beginning 1) (match-end 1))
 -      "File ???")))
 -
 -;; Look in an article or mail message for the Subject: line.  To be
 -;; placed in `ps-left-headers'.
 -(defun ps-info-node ()
 -  (save-excursion
 -    (goto-char (point-min))
 -    (if (re-search-forward "Node:[ \t]+\\([^,\t\n]*\\)" nil t)
 -      (buffer-substring (match-beginning 1) (match-end 1))
 -      "Node ???")))
 -
 -(defun ps-info-mode-hook ()
 -  (setq ps-left-header
 -      ;; The left headers will display the node name and file name.
 -      '(ps-info-node ps-info-file)))
 -
 -;; WARNING! The following function is a *sample* only, and is *not*
 -;; meant to be used as a whole unless you understand what the effects
 -;; will be!  (In fact, this is a copy of Jim's setup for ps-print --
 -;; I'd be very surprised if it was useful to *anybody*, without
 -;; modification.)
 -
 -(defun ps-jts-ps-setup ()
 -  (global-set-key (ps-prsc) 'ps-spool-buffer-with-faces) ;f22 is prsc
 -  (global-set-key (ps-s-prsc) 'ps-spool-region-with-faces)
 -  (global-set-key (ps-c-prsc) 'ps-despool)
 -  (add-hook 'gnus-article-prepare-hook 'ps-gnus-article-prepare-hook)
 -  (add-hook 'gnus-summary-mode-hook 'ps-gnus-summary-setup)
 -  (add-hook 'vm-mode-hook 'ps-vm-mode-hook)
 -  (add-hook 'vm-mode-hooks 'ps-vm-mode-hook)
 -  (add-hook 'Info-mode-hook 'ps-info-mode-hook)
 -  (setq ps-spool-duplex t
 -      ps-print-color-p nil
 -      ps-lpr-command "lpr"
 -      ps-lpr-switches '("-Jjct,duplex_long"))
 -  'ps-jts-ps-setup)
 -
 -;; WARNING! The following function is a *sample* only, and is *not*
 -;; meant to be used as a whole unless it corresponds to your needs.
 -;; (In fact, this is a copy of Jack's setup for ps-print --
 -;; I would not be that surprised if it was useful to *anybody*,
 -;; without modification.)
 -
 -(defun ps-jack-setup ()
 -  (setq ps-print-color-p  nil
 -      ps-lpr-command    "lpr"
 -      ps-lpr-switches   nil
 -
 -      ps-paper-type        'a4
 -      ps-landscape-mode    t
 -      ps-number-of-columns 2
 -
 -      ps-left-margin   (/ (* 72  1.0) 2.54) ;  1.0 cm
 -      ps-right-margin  (/ (* 72  1.0) 2.54) ;  1.0 cm
 -      ps-inter-column  (/ (* 72  1.0) 2.54) ;  1.0 cm
 -      ps-bottom-margin (/ (* 72  1.5) 2.54) ;  1.5 cm
 -      ps-top-margin    (/ (* 72  1.5) 2.54) ;  1.5 cm
 -      ps-header-offset (/ (* 72  1.0) 2.54) ;  1.0 cm
 -      ps-header-line-pad    .15
 -      ps-print-header       t
 -      ps-print-header-frame t
 -      ps-header-lines       2
 -      ps-show-n-of-n        t
 -      ps-spool-duplex       nil
 -
 -      ps-font-family             'Courier
 -      ps-font-size               5.5
 -      ps-header-font-family      'Helvetica
 -      ps-header-font-size        6
 -      ps-header-title-font-size  8)
 -  'ps-jack-setup)
 -
  \f
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;; To make this file smaller, some commands go in a separate file.
  ;; But autoload them here to make the separation invisible.
  
 -(autoload 'ps-mule-prepare-ascii-font "ps-mule"
 -  "Setup special ASCII font for STRING.
 -STRING should contain only ASCII characters.")
 -
 -(autoload 'ps-mule-set-ascii-font     "ps-mule"
 -  "Adjust current font if current charset is not ASCII.")
 -
 -(autoload 'ps-mule-plot-string        "ps-mule"
 -  "Generate PostScript code for plotting characters in the region FROM and TO.
 -
 -It is assumed that all characters in this region belong to the same charset.
 -
 -Optional argument BG-COLOR specifies background color.
 -
 -Returns the value:
 -
 -      (ENDPOS . RUN-WIDTH)
 -
 -Where ENDPOS is the end position of the sequence and RUN-WIDTH is the width of
 -the sequence.")
 -
  (autoload 'ps-mule-initialize         "ps-mule"
    "Initialize global data for printing multi-byte characters.")
  
@@@ -6465,8 -7058,10 +6469,8 @@@ This checks if all multi-byte character
  (autoload 'ps-mule-begin-page         "ps-mule"
    "Initialize multi-byte charset for printing current page.")
  
 -(autoload 'ps-mule-encode-header-string "ps-mule"
 -  "Generate PostScript code for plotting characters in header STRING.
 -
 -It is assumed that the length of STRING is not zero.")
 +(autoload 'ps-mule-end-job         "ps-mule"
 +  "Finish printing job for multi-byte chars.")
  
  \f
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --combined lisp/ruler-mode.el
index bda7d96662b76bdc850a8e6fa96a73648fae12ce,b2c48349a058d0425a0a967a1fafc943fc05b4ab..037638e8d43bacaf9bd5596ec4f66fc20a390d5d
@@@ -1,7 -1,7 +1,7 @@@
  ;;; ruler-mode.el --- display a ruler in the header line
  
- ;; Copyright (C) 2001, 2002, 2003, 2004, 2005,
- ;;   2006 Free Software Foundation, Inc.
+ ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006,
+ ;;   2007 Free Software Foundation, Inc.
  
  ;; Author: David Ponce <david@dponce.com>
  ;; Maintainer: David Ponce <david@dponce.com>
@@@ -135,7 -135,8 +135,7 @@@ or remove a tab stop.  \\[ruler-mode-to
    "Ensure WIDGET value is a valid character value."
    (save-excursion
      (let ((value (widget-value widget)))
 -      (if (char-valid-p value)
 -          nil
 +      (unless (characterp value)
          (widget-put widget :error
                      (format "Invalid character value: %S" value))
          widget))))
@@@ -630,7 -631,7 +630,7 @@@ Optional argument PROPS specifies othe
    (apply 'propertize " " 'display (list 'space :width width) props))
  \f
  (defun ruler-mode-ruler ()
-   "Compute and return an header line ruler."
+   "Compute and return a header line ruler."
    (let* ((w (window-width))
           (m (window-margins))
           (f (window-fringes))
           ;; Create an "clean" ruler.
           (ruler
            (propertize
 -           (make-string w ruler-mode-basic-graduation-char)
 +           (string-to-multibyte 
 +          (make-string w ruler-mode-basic-graduation-char))
             'face 'ruler-mode-default
             'local-map ruler-mode-map
             'help-echo (cond
diff --combined lisp/simple.el
index 1af1649113dbd1699ec2ade5a1d03174b07b664c,ac97d53d3bf64a5605c1a5353807c66568c6b6c9..09395514e90332262a64eed49f6f5b8768a386d1
@@@ -1,7 -1,7 +1,7 @@@
  ;;; simple.el --- basic editing commands for Emacs
  
  ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: internal
@@@ -948,9 -948,9 +948,9 @@@ in *Help* buffer.  See also the comman
        (if (or (not coding)
                (eq (coding-system-type coding) t))
            (setq coding default-buffer-file-coding-system))
 -      (if (not (char-valid-p char))
 +      (if (eq (char-charset char) 'eight-bit)
            (setq encoding-msg
 -                (format "(%d, #o%o, #x%x, invalid)" char char char))
 +                (format "(%d, #o%o, #x%x, raw-byte)" char char char))
          ;; Check if the character is displayed with some `display'
          ;; text property.  In that case, set under-display to the
          ;; buffer substring covered by that property.
@@@ -4096,7 -4096,7 +4096,7 @@@ With argument, do this that many times.
    (kill-region (point) (progn (forward-word arg) (point))))
  
  (defun backward-kill-word (arg)
-   "Kill characters backward until encountering the end of a word.
+   "Kill characters backward until encountering the beginning of a word.
  With argument, do this that many times."
    (interactive "p")
    (kill-word (- arg)))
diff --combined lisp/startup.el
index 4095a2182588e43eef9e69bc4ef37027fe1ab4f8,138715e68acd710f1cb9b67184576fc089ffa7ff..3fdcf0d856ad0db790914e5bfa63fc4e83e65fb7
@@@ -1,7 -1,7 +1,7 @@@
  ;;; startup.el --- process Emacs shell arguments
  
  ;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- ;;   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: internal
@@@ -781,7 -781,6 +781,7 @@@ or `CVS', and any subdirectory that con
    (custom-reevaluate-setting 'file-name-shadow-mode)
    (custom-reevaluate-setting 'send-mail-function)
    (custom-reevaluate-setting 'focus-follows-mouse)
 +  (custom-reevaluate-setting 'global-auto-composition-mode)
  
    ;; Register default TTY colors for the case the terminal hasn't a
    ;; terminal init file.
@@@ -1266,9 -1265,6 +1266,9 @@@ where FACE is a valid face specificatio
          (insert-image img (propertize "xxx" 'help-echo help-echo
                                        'keymap map)))
        (insert "\n"))))
 +  (fancy-splash-insert
 +   :face '(variable-pitch :background "red")
 +   "\n!! This version is ALPHA status.  It may lose your data!!\n\n")
    (fancy-splash-insert
     :face '(variable-pitch :foreground "red")
     (if (eq system-type 'gnu/linux)
@@@ -1302,7 -1298,7 +1302,7 @@@ using the mouse.\n\n"
                         (emacs-version)
                         "\n"
                         :face '(variable-pitch :height 0.5)
-                        "Copyright (C) 2006 Free Software Foundation, Inc.")
+                        "Copyright (C) 2007 Free Software Foundation, Inc.")
      (and auto-save-list-file-prefix
         ;; Don't signal an error if the
         ;; directory for auto-save-list files
@@@ -1550,7 -1546,7 +1550,7 @@@ More Manuals / Ordering Manuals    How 
  ")
                  (insert "\n\n" (emacs-version)
                          "
- Copyright (C) 2006 Free Software Foundation, Inc."))
+ Copyright (C) 2007 Free Software Foundation, Inc."))
  
              ;; No mouse menus, so give help using kbd commands.
  
@@@ -1598,7 -1594,7 +1598,7 @@@ If you have no Meta key, you may instea
  
              (insert "\n\n" (emacs-version)
                      "
- Copyright (C) 2006 Free Software Foundation, Inc.")
+ Copyright (C) 2007 Free Software Foundation, Inc.")
  
              (if (and (eq (key-binding "\C-h\C-c") 'describe-copying)
                       (eq (key-binding "\C-h\C-d") 'describe-distribution)
diff --combined lisp/subr.el
index 1cb5eb7ff309dd193100988146cdcec1e496a25a,45815a6f0f88d6bae3e27fbd8834b62c45a94feb..3b9407b09e984b8aed0a0b6b56bd16ec1e1bf2d1
@@@ -1,7 -1,7 +1,7 @@@
  ;;; subr.el --- basic lisp subroutines for Emacs
  
  ;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1999, 2000, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: internal
@@@ -694,7 -694,7 +694,7 @@@ The normal global definition of the cha
           ;; Filter out integers too large to be events.
           ;; M is the biggest modifier.
           (zerop (logand obj (lognot (1- (lsh ?\M-\^@ 1)))))
 -         (char-valid-p (event-basic-type obj)))
 +         (characterp (event-basic-type obj)))
        (and (symbolp obj)
           (get obj 'event-symbol-elements))
        (and (consp obj)
@@@ -1887,6 -1887,7 +1887,7 @@@ menu bar menus and the frame title.
  (defun momentary-string-display (string pos &optional exit-char message)
    "Momentarily display STRING in the buffer at POS.
  Display remains until next event is input.
+ If POS is a marker, only its position is used; its buffer is ignored.
  Optional third arg EXIT-CHAR can be a character, event or event
  description list.  EXIT-CHAR defaults to SPC.  If the input is
  EXIT-CHAR it is swallowed; otherwise it is then available as
@@@ -1894,30 -1895,21 +1895,21 @@@ input (as a command if nothing else)
  Display MESSAGE (optional fourth arg) in the echo area.
  If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there."
    (or exit-char (setq exit-char ?\s))
-   (let ((inhibit-read-only t)
-       ;; Don't modify the undo list at all.
-       (buffer-undo-list t)
-       (modified (buffer-modified-p))
-       (name buffer-file-name)
-       insert-end)
+   (let ((momentary-overlay (make-overlay pos pos nil t)))
+     (overlay-put momentary-overlay 'before-string
+                (propertize string 'face 'momentary))
      (unwind-protect
        (progn
+         ;; If the message end is off screen, recenter now.
+         (if (< (window-end nil t) (+ pos (length string)))
+             (recenter (/ (window-height) 2)))
+         ;; If that pushed message start off the screen,
+         ;; scroll to start it at the top of the screen.
          (save-excursion
-           (goto-char pos)
-           ;; defeat file locking... don't try this at home, kids!
-           (setq buffer-file-name nil)
-           (insert-before-markers string)
-           (setq insert-end (point))
-           ;; If the message end is off screen, recenter now.
-           (if (< (window-end nil t) insert-end)
-               (recenter (/ (window-height) 2)))
-           ;; If that pushed message start off the screen,
-           ;; scroll to start it at the top of the screen.
            (move-to-window-line 0)
            (if (> (point) pos)
-               (progn
-                 (goto-char pos)
-                 (recenter 0))))
+               (goto-char pos)
+             (recenter 0)))
          (message (or message "Type %s to continue editing.")
                   (single-key-description exit-char))
          (let (char)
              (or (eq char exit-char)
                  (eq char (event-convert-list exit-char))
                  (setq unread-command-events (list char))))))
-       (if insert-end
-         (save-excursion
-           (delete-region pos insert-end)))
-       (setq buffer-file-name name)
-       (set-buffer-modified-p modified))))
+       (delete-overlay momentary-overlay))))
  
  \f
  ;;;; Overlay operations
@@@ -2690,7 -2678,7 +2678,7 @@@ are effectively trimmed).  If nil, all 
  which correctly parses CSV format, for example.
  
  Note that the effect of `(split-string STRING)' is the same as
- `(split-string STRING split-string-default-separators t)').  In the rare
+ `(split-string STRING split-string-default-separators t)'.  In the rare
  case that you wish to retain zero-length substrings when splitting on
  whitespace, use `(split-string STRING split-string-default-separators)'.
  
diff --combined lisp/tar-mode.el
index f3aa86b48c32cbb6acfdf2a34a09f9b50e06cc4b,cffc8a4ccccbd1dd0c4f799c17afa9ee76464256..1d0c0ec6e0924f9bad442be65c100beac868e79f
@@@ -1,7 -1,7 +1,7 @@@
  ;;; tar-mode.el --- simple editing of tar files from GNU emacs
  
  ;; Copyright (C) 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Jamie Zawinski <jwz@lucid.com>
  ;; Maintainer: FSF
@@@ -129,17 -129,16 +129,17 @@@ This information is useful, but it take
    :group 'tar)
  
  (defvar tar-parse-info nil)
 -;; Be sure that this variable holds byte position, not char position.
  (defvar tar-header-offset nil)
  (defvar tar-superior-buffer nil)
  (defvar tar-superior-descriptor nil)
  (defvar tar-subfile-mode nil)
 +(defvar tar-file-name-coding-system nil)
  
  (put 'tar-parse-info 'permanent-local t)
  (put 'tar-header-offset 'permanent-local t)
  (put 'tar-superior-buffer 'permanent-local t)
  (put 'tar-superior-descriptor 'permanent-local t)
 +(put 'tar-file-name-coding-system 'permanent-local t)
  \f
  (defmacro tar-setf (form val)
    "A mind-numbingly simple implementation of setf."
    "Return a `tar-header' structure.
  This is a list of name, mode, uid, gid, size,
  write-date, checksum, link-type, and link-name."
 +  (setq string (string-as-unibyte string))
    (cond ((< (length string) 512) nil)
        (;(some 'plusp string)           ; <-- oops, massive cycle hog!
         (or (not (= 0 (aref string 0))) ; This will do.
           (setq linkname (substring string tar-link-offset link-end))
           (if default-enable-multibyte-characters
               (setq name
 -                   (decode-coding-string name
 -                                         (or file-name-coding-system
 -                                             default-file-name-coding-system
 -                                             'undecided))
 +                   (decode-coding-string name tar-file-name-coding-system)
                     linkname
                     (decode-coding-string linkname
 -                                         (or file-name-coding-system
 -                                             default-file-name-coding-system
 -                                             'undecided))))
 +                                         tar-file-name-coding-system)))
           (if (and (null link-p) (string-match "/\\'" name)) (setq link-p 5)) ; directory
           (make-tar-header
             name
  
  (defun tar-header-block-checksum (string)
    "Compute and return a tar-acceptable checksum for this block."
 +  (setq string (string-as-unibyte string))
    (let* ((chk-field-start tar-chk-offset)
         (chk-field-end (+ chk-field-start 8))
         (sum 0)
@@@ -397,8 -399,7 +397,8 @@@ MODE should be an integer which is a fi
                (unless (file-directory-p name)
                  (write-region start end name))
                (set-file-modes name (tar-header-mode tokens))))))
 -      (set-buffer-multibyte multibyte))))
 +      (if multibyte
 +        (set-buffer-multibyte 'to)))))
  
  (defun tar-summarize-buffer ()
    "Parse the contents of the tar file in the current buffer.
@@@ -427,11 -428,11 +427,11 @@@ is visible (and the real data of the bu
            (if (< size 0)
                (error "%s has size %s - corrupted"
                       (tar-header-name tokens) size))
 -                                        ;
 -                                        ; This is just too slow.  Don't really need it anyway....
 -                                        ;(tar-header-block-check-checksum
 -                                        ;  hblock (tar-header-block-checksum hblock)
 -                                        ;  (tar-header-name tokens))
 +          ;;
 +          ;; This is just too slow.  Don't really need it anyway....
 +          ;;(tar-header-block-check-checksum
 +          ;;  hblock (tar-header-block-checksum hblock)
 +          ;;  (tar-header-name tokens))
  
            (push (make-tar-desc pos tokens) result)
  
                 (> size 0)
                 (setq pos
                       (+ pos 512 (ash (ash (1- size) -9) 9)) ; this works
 -                                        ;(+ pos (+ size (- 512 (rem (1- size) 512)))) ; this doesn't
 +                     ;;(+ pos (+ size (- 512 (rem (1- size) 512)))) ; this doesn't
                       ))))
        (make-local-variable 'tar-parse-info)
        (setq tar-parse-info (nreverse result))
        (if (eq tokens 'empty-tar-block)
            (progress-reporter-done progress-reporter)
          (message "Warning: premature EOF parsing tar file")))
 -    (set-buffer-multibyte default-enable-multibyte-characters)
 +    ;; Obey the user's preference for the use of uni/multibytes.
 +    (if default-enable-multibyte-characters
 +      (set-buffer-multibyte 'to))
      (goto-char (point-min))
 -    (let ((inhibit-read-only t))
 -      ;; Collect summary lines and insert them all at once since tar files
 -      ;; can be pretty big.
 -      (let ((total-summaries
 -           (mapconcat
 -            (lambda (tar-desc)
 -              (tar-header-block-summarize (tar-desc-tokens tar-desc)))
 -            tar-parse-info
 -            "\n")))
 -      (insert total-summaries "\n"))
 -      (narrow-to-region (point-min) (point))
 -      (set (make-local-variable 'tar-header-offset) (position-bytes (point)))
 -      (goto-char (point-min))
 -      (restore-buffer-modified-p modified))))
 +    (let ((inhibit-read-only t)
 +          ;; Collect summary lines and insert them all at once since tar files
 +          ;; can be pretty big.
 +          (total-summaries
 +           (mapconcat
 +            (lambda (tar-desc)
 +              (tar-header-block-summarize (tar-desc-tokens tar-desc)))
 +            tar-parse-info
 +            "\n")))
 +      (insert total-summaries "\n"))
 +    (narrow-to-region (point-min) (point))
 +    (set (make-local-variable 'tar-header-offset) (position-bytes (point)))
 +    (goto-char (point-min))
 +    (restore-buffer-modified-p modified)))
  \f
  (defvar tar-mode-map
    (let ((map (make-keymap)))
      (define-key map "M" 'tar-chmod-entry)
      (define-key map "G" 'tar-chgrp-entry)
      (define-key map "O" 'tar-chown-entry)
 -
 +\f
      ;; Make menu bar items.
  
      ;; Get rid of the Edit menu bar item to save space.
      (define-key map [menu-bar edit] 'undefined)
  
      (define-key map [menu-bar immediate]
 -      (cons "Immediate" (make-sparse-keymap "Immediate")))
 +  (cons "Immediate" (make-sparse-keymap "Immediate")))
  
      (define-key map [menu-bar immediate view]
 -      '("View This File" . tar-view))
 +  '("View This File" . tar-view))
      (define-key map [menu-bar immediate display]
 -      '("Display in Other Window" . tar-display-other-window))
 +  '("Display in Other Window" . tar-display-other-window))
      (define-key map [menu-bar immediate find-file-other-window]
 -      '("Find in Other Window" . tar-extract-other-window))
 +  '("Find in Other Window" . tar-extract-other-window))
      (define-key map [menu-bar immediate find-file]
 -      '("Find This File" . tar-extract))
 +  '("Find This File" . tar-extract))
  
      (define-key map [menu-bar mark]
 -      (cons "Mark" (make-sparse-keymap "Mark")))
 +  (cons "Mark" (make-sparse-keymap "Mark")))
  
      (define-key map [menu-bar mark unmark-all]
 -      '("Unmark All" . tar-clear-modification-flags))
 +  '("Unmark All" . tar-clear-modification-flags))
      (define-key map [menu-bar mark deletion]
 -      '("Flag" . tar-flag-deleted))
 +  '("Flag" . tar-flag-deleted))
      (define-key map [menu-bar mark unmark]
 -      '("Unflag" . tar-unflag))
 +  '("Unflag" . tar-unflag))
  
      (define-key map [menu-bar operate]
 -      (cons "Operate" (make-sparse-keymap "Operate")))
 +  (cons "Operate" (make-sparse-keymap "Operate")))
  
      (define-key map [menu-bar operate chown]
 -      '("Change Owner..." . tar-chown-entry))
 +  '("Change Owner..." . tar-chown-entry))
      (define-key map [menu-bar operate chgrp]
 -      '("Change Group..." . tar-chgrp-entry))
 +  '("Change Group..." . tar-chgrp-entry))
      (define-key map [menu-bar operate chmod]
 -      '("Change Mode..." . tar-chmod-entry))
 +  '("Change Mode..." . tar-chmod-entry))
      (define-key map [menu-bar operate rename]
 -      '("Rename to..." . tar-rename-entry))
 +  '("Rename to..." . tar-rename-entry))
      (define-key map [menu-bar operate copy]
 -      '("Copy to..." . tar-copy))
 +  '("Copy to..." . tar-copy))
      (define-key map [menu-bar operate expunge]
 -      '("Expunge Marked Files" . tar-expunge))
 -
 +  '("Expunge Marked Files" . tar-expunge))
 +\f
      map)
    "Local keymap for Tar mode listings.")
  
@@@ -575,10 -574,6 +575,10 @@@ See also: variables `tar-update-datesta
    (set (make-local-variable 'revert-buffer-function) 'tar-mode-revert)
    (set (make-local-variable 'local-enable-local-variables) nil)
    (set (make-local-variable 'next-line-add-newlines) nil)
 +  (set (make-local-variable 'tar-file-name-coding-system)
 +       (or file-name-coding-system
 +         default-file-name-coding-system
 +         locale-coding-system))
    ;; Prevent loss of data when saving the file.
    (set (make-local-variable 'file-precious-flag) t)
    (auto-save-mode 0)
    (buffer-disable-undo)
    (widen)
    (if (and (boundp 'tar-header-offset) tar-header-offset)
 -      (narrow-to-region (point-min) (byte-to-position tar-header-offset))
 +      (narrow-to-region (point-min) tar-header-offset)
      (tar-summarize-buffer)
      (tar-next-line 0)))
  
@@@ -698,6 -693,7 +698,6 @@@ appear on disk when you save the tar-fi
                   (- tar-header-offset (point-min))))
         (end (+ start size)))
      (let* ((tar-buffer (current-buffer))
 -         (tar-buffer-multibyte enable-multibyte-characters)
           (tarname (buffer-name))
           (bufname (concat (file-name-nondirectory name)
                            " ("
                                  ;; `:' is not allowed on Windows
                                  (concat tarname "!" name)))
           (buffer (get-file-buffer new-buffer-file-name))
 -         (just-created nil))
 +         (just-created nil)
 +         (pos (point))
 +         undo-list)
        (unless buffer
        (setq buffer (generate-new-buffer bufname))
 +      (save-excursion
 +        (set-buffer buffer)
 +        (setq undo-list buffer-undo-list
 +              buffer-undo-list t))
        (setq bufname (buffer-name buffer))
        (setq just-created t)
        (unwind-protect
 -          (progn
 +          (let (coding)
 +            (narrow-to-region start end)
 +            (goto-char start)
 +            (setq coding (or coding-system-for-read
 +                             (and set-auto-coding-function
 +                                  (funcall set-auto-coding-function
 +                                           name (- end start)))
 +                             (car (find-operation-coding-system
 +                                   'insert-file-contents
 +                                   (cons name (current-buffer)) t))))
 +            (if (or (not coding)
 +                    (eq (coding-system-type coding) 'undecided))
 +                (setq coding (detect-coding-region start end t)))
 +            (if (and default-enable-multibyte-characters
 +                     (coding-system-get coding :for-unibyte))
 +                (save-excursion
 +                  (set-buffer buffer)
 +                  (set-buffer-multibyte nil)))
              (widen)
 -            (set-buffer-multibyte nil)
 +            (decode-coding-region start end coding buffer)
              (save-excursion
                (set-buffer buffer)
 -              (let ((buffer-undo-list t))
 -                (if enable-multibyte-characters
 -                    (progn
 -                      ;; We must avoid unibyte->multibyte conversion.
 -                      (set-buffer-multibyte nil)
 -                      (insert-buffer-substring tar-buffer start end)
 -                      (set-buffer-multibyte t))
 -                  (insert-buffer-substring tar-buffer start end))
 -                (goto-char (point-min))
 -                (setq buffer-file-name new-buffer-file-name)
 -                (setq buffer-file-truename
 -                      (abbreviate-file-name buffer-file-name))
 -                ;; We need to mimic the parts of insert-file-contents
 -                ;; which determine the coding-system and decode the text.
 -                (let ((coding
 -                       (or coding-system-for-read
 -                           (and set-auto-coding-function
 -                                (save-excursion
 -                                  (funcall set-auto-coding-function
 -                                           name (- (point-max) (point)))))
 -                           (car (find-operation-coding-system
 -                                 'insert-file-contents
 -                                 (cons name (current-buffer)) t))))
 -                      (multibyte enable-multibyte-characters)
 -                      (detected (detect-coding-region
 -                                 (point-min)
 -                                 (min (+ (point-min) 16384) (point-max)) t)))
 -                  (if coding
 -                      (or (numberp (coding-system-eol-type coding))
 -                          (vectorp (coding-system-eol-type detected))
 -                          (setq coding (coding-system-change-eol-conversion
 -                                        coding
 -                                        (coding-system-eol-type detected))))
 -                    (setq coding
 -                          (find-new-buffer-file-coding-system detected)))
 -                  (if (or (eq coding 'no-conversion)
 -                          (eq (coding-system-type coding) 5))
 -                      (setq multibyte (set-buffer-multibyte nil)))
 -                  (or multibyte
 -                      (setq coding
 -                            (coding-system-change-text-conversion
 -                             coding 'raw-text)))
 -                  (decode-coding-region (point-min) (point-max) coding)
 -                  (set-buffer-file-coding-system coding))
 -                ;; Set the default-directory to the dir of the
 -                ;; superior buffer.
 -                (setq default-directory
 -                      (save-excursion
 -                        (set-buffer tar-buffer)
 -                        default-directory))
 -                (normal-mode)  ; pick a mode.
 -                (rename-buffer bufname)
 -                (make-local-variable 'tar-superior-buffer)
 -                (make-local-variable 'tar-superior-descriptor)
 -                (setq tar-superior-buffer tar-buffer)
 -                (setq tar-superior-descriptor descriptor)
 -                (setq buffer-read-only read-only-p)
 -                (set-buffer-modified-p nil))
 +              (goto-char (point-min))
 +              (setq buffer-file-name new-buffer-file-name)
 +              (setq buffer-file-truename
 +                    (abbreviate-file-name buffer-file-name))
 +              (set-buffer-file-coding-system coding)
 +              ;; Set the default-directory to the dir of the
 +              ;; superior buffer.
 +              (setq default-directory
 +                    (save-excursion
 +                      (set-buffer tar-buffer)
 +                      default-directory))
 +              (normal-mode)  ; pick a mode.
 +              (rename-buffer bufname)
 +              (make-local-variable 'tar-superior-buffer)
 +              (make-local-variable 'tar-superior-descriptor)
 +              (setq tar-superior-buffer tar-buffer)
 +              (setq tar-superior-descriptor descriptor)
 +              (setq buffer-read-only read-only-p)
 +              (set-buffer-modified-p nil)
 +              (setq buffer-undo-list undo-list)
                (tar-subfile-mode 1))
              (set-buffer tar-buffer))
          (narrow-to-region (point-min) tar-header-offset)
 -        (set-buffer-multibyte tar-buffer-multibyte)))
 +        (goto-char pos)))
        (if view-p
          (view-buffer buffer (and just-created 'kill-buffer))
        (if (eq other-window-p 'display)
@@@ -823,6 -834,7 +823,6 @@@ the current tar-entry.
         (start (+ (tar-desc-data-start descriptor)
                   (- tar-header-offset (point-min))))
         (end (+ start size))
 -       (multibyte enable-multibyte-characters)
         (inhibit-file-name-handlers inhibit-file-name-handlers)
         (inhibit-file-name-operation inhibit-file-name-operation))
      (save-restriction
                      (and (eq inhibit-file-name-operation 'write-region)
                           inhibit-file-name-handlers))
                inhibit-file-name-operation 'write-region))
 -      (unwind-protect
 -        (let ((coding-system-for-write 'no-conversion))
 -          (set-buffer-multibyte nil)
 -          (write-region start end to-file nil nil nil t))
 -      (set-buffer-multibyte multibyte)))
 +      (let ((coding-system-for-write 'no-conversion))
 +      (write-region start end to-file nil nil nil t)))
      (message "Copied tar entry %s to %s" name to-file)))
  
  (defun tar-flag-deleted (p &optional unflag)
@@@ -866,6 -881,7 +866,6 @@@ With a prefix argument, un-mark that ma
    (tar-flag-deleted (- p) t))
  
  
 -;; When this function is called, it is sure that the buffer is unibyte.
  (defun tar-expunge-internal ()
    "Expunge the tar-entry specified by the current line."
    (let* ((descriptor (tar-current-descriptor))
@@@ -915,8 -931,11 +915,8 @@@ for this to be permanent.
    (interactive)
    (if (or noconfirm
          (y-or-n-p "Expunge files marked for deletion? "))
 -      (let ((n 0)
 -          (multibyte enable-multibyte-characters))
 +      (let ((n 0))
        (save-excursion
 -          (widen)
 -          (set-buffer-multibyte nil)
          (goto-char (point-min))
          (while (not (eobp))
            (if (looking-at "D")
                (forward-line 1)))
          ;; after doing the deletions, add any padding that may be necessary.
          (tar-pad-to-blocksize)
 -          (widen)
 -          (set-buffer-multibyte multibyte)
          (narrow-to-region (point-min) tar-header-offset))
        (if (zerop n)
            (message "Nothing to expunge.")
    (interactive)
    (save-excursion
      (goto-char (point-min))
 -    (while (< (position-bytes (point)) tar-header-offset)
 +    (while (< (point) tar-header-offset)
        (if (not (eq (following-char) ?\s))
          (progn (delete-char 1) (insert " ")))
        (forward-line 1))))
@@@ -1006,13 -1027,15 +1006,13 @@@ for this to be permanent.
      (list (read-string "New name: "
            (tar-header-name (tar-desc-tokens (tar-current-descriptor))))))
    (if (string= "" new-name) (error "zero length name"))
 -  (if (> (length new-name) 98) (error "name too long"))
 -  (tar-setf (tar-header-name (tar-desc-tokens (tar-current-descriptor)))
 -          new-name)
 -  (if (multibyte-string-p new-name)
 -      (setq new-name (encode-coding-string new-name
 -                                         (or file-name-coding-system
 -                                             default-file-name-coding-system))))
 -  (tar-alter-one-field 0
 -    (substring (concat new-name (make-string 99 0)) 0 99)))
 +  (let ((encoded-new-name (encode-coding-string new-name
 +                                              tar-file-name-coding-system)))
 +    (if (> (length encoded-new-name) 98) (error "name too long"))
 +    (tar-setf (tar-header-name (tar-desc-tokens (tar-current-descriptor)))
 +            new-name)
 +    (tar-alter-one-field 0
 +     (substring (concat encoded-new-name (make-string 99 0)) 0 99))))
  
  
  (defun tar-chmod-entry (new-mode)
@@@ -1029,7 -1052,8 +1029,7 @@@ for this to be permanent.
  
  (defun tar-alter-one-field (data-position new-data-string)
    (let* ((descriptor (tar-current-descriptor))
 -       (tokens (tar-desc-tokens descriptor))
 -       (multibyte enable-multibyte-characters))
 +       (tokens (tar-desc-tokens descriptor)))
      (unwind-protect
        (save-excursion
          ;;
            (forward-line 1)
            (delete-region p (point))
            (insert (tar-header-block-summarize tokens) "\n")
 -          (setq tar-header-offset (position-bytes (point-max))))
 +          (setq tar-header-offset (point-max)))
  
          (widen)
 -        (set-buffer-multibyte nil)
          (let* ((start (+ (tar-desc-data-start descriptor)
                           (- tar-header-offset (point-min))
                             -512)))
            ;; delete the old field and insert a new one.
            (goto-char (+ start data-position))
            (delete-region (point) (+ (point) (length new-data-string))) ; <--
 -          (insert new-data-string) ; <--
 +
 +          ;; As new-data-string is unibyte, just inserting it will
 +          ;; make eight-bit chars to the corresponding multibyte
 +          ;; chars.  This avoid that conversion, i.e., eight-bit
 +          ;; chars are converted to multibyte form of eight-bit
 +          ;; chars.
 +          (insert (string-to-multibyte new-data-string))
            ;;
            ;; compute a new checksum and insert it.
            (let ((chk (tar-header-block-checksum
                chk (tar-header-name tokens))
              )))
        (narrow-to-region (point-min) tar-header-offset)
 -      (set-buffer-multibyte multibyte)
        (tar-next-line 0))))
  
  
@@@ -1097,9 -1117,14 +1097,9 @@@ to make your changes permanent.
      (error "This buffer doesn't have an index into its superior tar file!"))
    (save-excursion
    (let ((subfile (current-buffer))
 -      (subfile-multibyte enable-multibyte-characters)
        (coding buffer-file-coding-system)
        (descriptor tar-superior-descriptor)
        subfile-size)
 -    ;; We must make the current buffer unibyte temporarily to avoid
 -    ;; multibyte->unibyte conversion in `insert-buffer-substring'.
 -    (set-buffer-multibyte nil)
 -    (setq subfile-size (buffer-size))
      (set-buffer tar-superior-buffer)
      (let* ((tokens (tar-desc-tokens descriptor))
           (start (tar-desc-data-start descriptor))
           (size (tar-header-size tokens))
           (size-pad (ash (ash (+ size 511) -9) 9))
           (head (memq descriptor tar-parse-info))
 -         (following-descs (cdr head))
 -         (tar-buffer-multibyte enable-multibyte-characters))
 +         (following-descs (cdr head)))
        (if (not head)
        (error "Can't find this tar file entry in its parent tar file!"))
        (unwind-protect
         (save-excursion
 -      (widen)
 -      (set-buffer-multibyte nil)
        ;; delete the old data...
        (let* ((data-start (+ start (- tar-header-offset (point-min))))
               (data-end (+ data-start (ash (ash (+ size 511) -9) 9))))
 -        (delete-region data-start data-end)
 +        (narrow-to-region data-start data-end)
 +        (delete-region (point-min) (point-max))
          ;; insert the new data...
          (goto-char data-start)
 -        (insert-buffer-substring subfile)
 -        (setq subfile-size
 -              (encode-coding-region
 -               data-start (+ data-start subfile-size) coding))
 +        (save-excursion
 +          (set-buffer subfile)
 +          (save-restriction
 +            (widen)
 +            (encode-coding-region 1 (point-max) coding tar-superior-buffer)))
 +        (setq subfile-size (- (point-max) (point-min)))
          ;;
          ;; pad the new data out to a multiple of 512...
          (let ((subfile-size-pad (ash (ash (+ subfile-size 511) -9) 9)))
 -          (goto-char (+ data-start subfile-size))
 +          (goto-char (point-max))
            (insert (make-string (- subfile-size-pad subfile-size) 0))
            ;;
            ;; update the data pointer of this and all following files...
                          (+ (tar-desc-data-start desc) difference))))
            ;;
            ;; Update the size field in the header block.
 +          (widen)
            (let ((header-start (- data-start 512)))
              (goto-char (+ header-start tar-size-offset))
              (delete-region (point) (+ (point) 12))
                ;; Insert the new text after the old, before deleting,
                ;; to preserve the window start.
                (let ((line (tar-header-block-summarize tokens t)))
 -                (insert-before-markers (string-as-unibyte line) "\n"))
 +                (insert-before-markers line "\n"))
                (delete-region p after)
                (setq tar-header-offset (marker-position m)))
              )))
        ;; after doing the insertion, add any final padding that may be necessary.
        (tar-pad-to-blocksize))
 -       (narrow-to-region (point-min) tar-header-offset)
 -       (set-buffer-multibyte tar-buffer-multibyte)))
 +       (narrow-to-region (point-min) tar-header-offset)))
      (set-buffer-modified-p t)   ; mark the tar file as modified
      (tar-next-line 0)
      (set-buffer subfile)
 -    ;; Restore the buffer multibyteness.
 -    (set-buffer-multibyte subfile-multibyte)
      (set-buffer-modified-p nil) ; mark the tar subfile as unmodified
      (message "Saved into tar-buffer `%s'.  Be sure to save that buffer!"
             (buffer-name tar-superior-buffer))
@@@ -1235,13 -1262,14 +1235,13 @@@ Leaves the region wide.
        ;; tar-header-offset turns out to be null for files fetched with W3,
        ;; at least.
        (let ((coding-system-for-write 'no-conversion))
 -        (write-region (if tar-header-offset
 -                          (byte-to-position tar-header-offset)
 -                        (point-min))
 +        (write-region (or tar-header-offset
 +                          (point-min))
                        (point-max)
                        buffer-file-name nil t))
        (tar-clear-modification-flags)
        (set-buffer-modified-p nil))
 -    (narrow-to-region (point-min) (byte-to-position tar-header-offset)))
 +    (narrow-to-region (point-min) tar-header-offset))
    ;; Return t because we've written the file.
    t)
  \f
diff --combined lisp/term.el
index f8cf08ef37edf88770c7c132a3cd34ec33083deb,a853c12ec39c91f4168e8ebbb5794976fcaaa572..7bbef6e526e2d3a2e3493ba4f79d568bd59e8ff2
@@@ -1,7 -1,7 +1,7 @@@
  ;;; term.el --- general command interpreter in a window stuff
  
  ;; Copyright (C) 1988, 1990, 1992, 1994, 1995, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Per Bothner <per@bothner.com>
  ;; Maintainer: Dan Nicolaescu <dann@ics.uci.edu>, Per Bothner <per@bothner.com>
@@@ -883,6 -883,8 +883,6 @@@ is buffer-local."
      (unless (or (eq i ?O) (eq i 91))
                (define-key esc-map (make-string 1 i) 'term-send-raw-meta))
      (setq i (1+ i)))
 -  (dolist (elm (generic-character-list))
 -    (define-key map (vector elm) 'term-send-raw))
    (define-key map "\e" esc-map)
    (setq term-raw-map map)
    (setq term-raw-escape-map
diff --combined lisp/term/mac-win.el
index b7a4d3a2f98d7076aab80d5559f2857a5f7879f1,be4c978dd2855317c41ee1d59d85d8ec62ef27a7..09e1c77353b4842fbe8b04d94a8b7f158ea69a83
@@@ -1,7 -1,7 +1,7 @@@
 -;;; mac-win.el --- parse switches controlling interface with Mac window system -*-coding: iso-2022-7bit;-*-
 +;;; mac-win.el --- parse switches controlling interface with Mac window system -*-coding: utf-8
  
  ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Andrew Choi <akochoi@mac.com>
  ;; Keywords: terminals
@@@ -1130,145 -1130,95 +1130,145 @@@ correspoinding TextEncodingBase value.
  (mac-add-charset-info "mac-dingbats" 34)
  (mac-add-charset-info "iso10646-1" 126) ; for ATSUI
  
 -(cp-make-coding-system
 - mac-centraleurroman
 - [?\\e,AD\e(B ?\\e$,1  \e(B ?\\e$,1 !\e(B ?\\e,AI\e(B ?\\e$,1 $\e(B ?\\e,AV\e(B ?\\e,A\\e(B ?\\e,Aa\e(B ?\\e$,1 %\e(B ?\\e$,1 ,\e(B ?\\e,Ad\e(B ?\\e$,1 -\e(B ?\\e$,1 &\e(B ?\\e$,1 '\e(B ?\\e,Ai\e(B ?\\e$,1!9\e(B
 -  ?\\e$,1!:\e(B ?\\e$,1 .\e(B ?\\e,Am\e(B ?\\e$,1 /\e(B ?\\e$,1 2\e(B ?\\e$,1 3\e(B ?\\e$,1 6\e(B ?\\e,As\e(B ?\\e$,1 7\e(B ?\\e,At\e(B ?\\e,Av\e(B ?\\e,Au\e(B ?\\e,Az\e(B ?\\e$,1 :\e(B ?\\e$,1 ;\e(B ?\\e,A|\e(B
 -  ?\\e$,1s \e(B ?\\e,A0\e(B ?\\e$,1 8\e(B ?\\e,A#\e(B ?\\e,A'\e(B ?\\e$,1s"\e(B ?\\e,A6\e(B ?\\e,A_\e(B ?\\e,A.\e(B ?\\e,A)\e(B ?\\e$,1ub\e(B ?\\e$,1 9\e(B ?\\e,A(\e(B ?\\e$,1y \e(B ?\\e$,1 C\e(B ?\\e$,1 N\e(B
 -  ?\\e$,1 O\e(B ?\\e$,1 J\e(B ?\\e$,1y$\e(B ?\\e$,1y%\e(B ?\\e$,1 K\e(B ?\\e$,1 V\e(B ?\\e$,1x"\e(B ?\\e$,1x1\e(B ?\\e$,1 b\e(B ?\\e$,1 [\e(B ?\\e$,1 \\e(B ?\\e$,1 ]\e(B ?\\e$,1 ^\e(B ?\\e$,1 Y\e(B ?\\e$,1 Z\e(B ?\\e$,1 e\e(B
 -  ?\\e$,1 f\e(B ?\\e$,1 c\e(B ?\\e,A,\e(B ?\\e$,1x:\e(B ?\\e$,1 d\e(B ?\\e$,1 g\e(B ?\\e$,1x&\e(B ?\\e,A+\e(B ?\\e,A;\e(B ?\\e$,1s&\e(B ?\\e,A \e(B ?\\e$,1 h\e(B ?\\e$,1 p\e(B ?\\e,AU\e(B ?\\e$,1 q\e(B ?\\e$,1 l\e(B
 -  ?\\e$,1rs\e(B ?\\e$,1rt\e(B ?\\e$,1r|\e(B ?\\e$,1r}\e(B ?\\e$,1rx\e(B ?\\e$,1ry\e(B ?\\e,Aw\e(B ?\\e$,2"*\e(B ?\\e$,1 m\e(B ?\\e$,1 t\e(B ?\\e$,1 u\e(B ?\\e$,1 x\e(B ?\\e$,1s9\e(B ?\\e$,1s:\e(B ?\\e$,1 y\e(B ?\\e$,1 v\e(B
 -  ?\\e$,1 w\e(B ?\\e$,1! \e(B ?\\e$,1rz\e(B ?\\e$,1r~\e(B ?\\e$,1!!\e(B ?\\e$,1 z\e(B ?\\e$,1 {\e(B ?\\e,AA\e(B ?\\e$,1!$\e(B ?\\e$,1!%\e(B ?\\e,AM\e(B ?\\e$,1!=\e(B ?\\e$,1!>\e(B ?\\e$,1!*\e(B ?\\e,AS\e(B ?\\e,AT\e(B
 -  ?\\e$,1!+\e(B ?\\e$,1!.\e(B ?\\e,AZ\e(B ?\\e$,1!/\e(B ?\\e$,1!0\e(B ?\\e$,1!1\e(B ?\\e$,1!2\e(B ?\\e$,1!3\e(B ?\\e,A]\e(B ?\\e,A}\e(B ?\\e$,1 W\e(B ?\\e$,1!;\e(B ?\\e$,1 a\e(B ?\\e$,1!<\e(B ?\\e$,1 B\e(B ?\\e$,1$g\e(B]
 - "Mac Central European Roman Encoding (MIME:x-mac-centraleurroman).")
 -(coding-system-put 'mac-centraleurroman 'mime-charset 'x-mac-centraleurroman)
 -
 -(cp-make-coding-system
 - mac-cyrillic
 - [?\\e$,1(0\e(B ?\\e$,1(1\e(B ?\\e$,1(2\e(B ?\\e$,1(3\e(B ?\\e$,1(4\e(B ?\\e$,1(5\e(B ?\\e$,1(6\e(B ?\\e$,1(7\e(B ?\\e$,1(8\e(B ?\\e$,1(9\e(B ?\\e$,1(:\e(B ?\\e$,1(;\e(B ?\\e$,1(<\e(B ?\\e$,1(=\e(B ?\\e$,1(>\e(B ?\\e$,1(?\e(B
 -  ?\\e$,1(@\e(B ?\\e$,1(A\e(B ?\\e$,1(B\e(B ?\\e$,1(C\e(B ?\\e$,1(D\e(B ?\\e$,1(E\e(B ?\\e$,1(F\e(B ?\\e$,1(G\e(B ?\\e$,1(H\e(B ?\\e$,1(I\e(B ?\\e$,1(J\e(B ?\\e$,1(K\e(B ?\\e$,1(L\e(B ?\\e$,1(M\e(B ?\\e$,1(N\e(B ?\\e$,1(O\e(B
 -  ?\\e$,1s \e(B ?\\e,A0\e(B ?\\e$,1)P\e(B ?\\e,A#\e(B ?\\e,A'\e(B ?\\e$,1s"\e(B ?\\e,A6\e(B ?\\e$,1(&\e(B ?\\e,A.\e(B ?\\e,A)\e(B ?\\e$,1ub\e(B ?\\e$,1("\e(B ?\\e$,1(r\e(B ?\\e$,1y \e(B ?\\e$,1(#\e(B ?\\e$,1(s\e(B
 -  ?\\e$,1x>\e(B ?\\e,A1\e(B ?\\e$,1y$\e(B ?\\e$,1y%\e(B ?\\e$,1(v\e(B ?\\e,A5\e(B ?\\e$,1)Q\e(B ?\\e$,1((\e(B ?\\e$,1($\e(B ?\\e$,1(t\e(B ?\\e$,1('\e(B ?\\e$,1(w\e(B ?\\e$,1()\e(B ?\\e$,1(y\e(B ?\\e$,1(*\e(B ?\\e$,1(z\e(B
 -  ?\\e$,1(x\e(B ?\\e$,1(%\e(B ?\\e,A,\e(B ?\\e$,1x:\e(B ?\\e$,1!R\e(B ?\\e$,1xh\e(B ?\\e$,1x&\e(B ?\\e,A+\e(B ?\\e,A;\e(B ?\\e$,1s&\e(B ?\\e,A \e(B ?\\e$,1(+\e(B ?\\e$,1({\e(B ?\\e$,1(,\e(B ?\\e$,1(|\e(B ?\\e$,1(u\e(B
 -  ?\\e$,1rs\e(B ?\\e$,1rt\e(B ?\\e$,1r|\e(B ?\\e$,1r}\e(B ?\\e$,1rx\e(B ?\\e$,1ry\e(B ?\\e,Aw\e(B ?\\e$,1r~\e(B ?\\e$,1(.\e(B ?\\e$,1(~\e(B ?\\e$,1(/\e(B ?\\e$,1(\7f\e(B ?\\e$,1uV\e(B ?\\e$,1(!\e(B ?\\e$,1(q\e(B ?\\e$,1(o\e(B
 -  ?\\e$,1(P\e(B ?\\e$,1(Q\e(B ?\\e$,1(R\e(B ?\\e$,1(S\e(B ?\\e$,1(T\e(B ?\\e$,1(U\e(B ?\\e$,1(V\e(B ?\\e$,1(W\e(B ?\\e$,1(X\e(B ?\\e$,1(Y\e(B ?\\e$,1(Z\e(B ?\\e$,1([\e(B ?\\e$,1(\\e(B ?\\e$,1(]\e(B ?\\e$,1(^\e(B ?\\e$,1(_\e(B
 -  ?\\e$,1(`\e(B ?\\e$,1(a\e(B ?\\e$,1(b\e(B ?\\e$,1(c\e(B ?\\e$,1(d\e(B ?\\e$,1(e\e(B ?\\e$,1(f\e(B ?\\e$,1(g\e(B ?\\e$,1(h\e(B ?\\e$,1(i\e(B ?\\e$,1(j\e(B ?\\e$,1(k\e(B ?\\e$,1(l\e(B ?\\e$,1(m\e(B ?\\e$,1(n\e(B ?\\e$,1tL\e(B]
 - "Mac Cyrillic Encoding (MIME:x-mac-cyrillic).")
 -(coding-system-put 'mac-cyrillic 'mime-charset 'x-mac-cyrillic)
 -
 -(let
 -    ((encoding-vector
 -      (vconcat
 -       (make-vector 32 nil)
 -       ;; mac-symbol (32..126) -> emacs-mule mapping
 -       [?\  ?\! ?\\e$,1x \e(B ?\# ?\\e$,1x#\e(B ?\% ?\& ?\\e$,1x-\e(B ?\( ?\) ?\\e$,1x7\e(B ?\+ ?\, ?\\e$,1x2\e(B ?\. ?\/
 -      ?\0 ?\1 ?\2 ?\3 ?\4 ?\5 ?\6 ?\7 ?\8 ?\9 ?\: ?\; ?\< ?\= ?\> ?\?
 -      ?\\e$,1xe\e(B ?\\e$,1&q\e(B ?\\e$,1&r\e(B ?\\e$,1''\e(B ?\\e$,1&t\e(B ?\\e$,1&u\e(B ?\\e$,1'&\e(B ?\\e$,1&s\e(B ?\\e$,1&w\e(B ?\\e$,1&y\e(B ?\\e$,1'Q\e(B ?\\e$,1&z\e(B ?\\e$,1&{\e(B ?\\e$,1&|\e(B ?\\e$,1&}\e(B ?\\e$,1&\7f\e(B
 -      ?\\e$,1' \e(B ?\\e$,1&x\e(B ?\\e$,1'!\e(B ?\\e$,1'#\e(B ?\\e$,1'$\e(B ?\\e$,1'%\e(B ?\\e$,1'B\e(B ?\\e$,1')\e(B ?\\e$,1&~\e(B ?\\e$,1'(\e(B ?\\e$,1&v\e(B ?\[ ?\\e$,1xT\e(B ?\] ?\\e$,1ye\e(B ?\_
 -      ?\\e$,3bE\e(B ?\\e$,1'1\e(B ?\\e$,1'2\e(B ?\\e$,1'G\e(B ?\\e$,1'4\e(B ?\\e$,1'5\e(B ?\\e$,1'F\e(B ?\\e$,1'3\e(B ?\\e$,1'7\e(B ?\\e$,1'9\e(B ?\\e$,1'U\e(B ?\\e$,1':\e(B ?\\e$,1';\e(B ?\\e$,1'<\e(B ?\\e$,1'=\e(B ?\\e$,1'?\e(B
 -      ?\\e$,1'@\e(B ?\\e$,1'8\e(B ?\\e$,1'A\e(B ?\\e$,1'C\e(B ?\\e$,1'D\e(B ?\\e$,1'E\e(B ?\\e$,1'V\e(B ?\\e$,1'I\e(B ?\\e$,1'>\e(B ?\\e$,1'H\e(B ?\\e$,1'6\e(B ?\{ ?\| ?\} ?\\e$,1x\\e(B]
 -       (make-vector (- 160 127) nil)
 -       ;; mac-symbol (160..254) -> emacs-mule mapping
 -       ;; Mapping of the following characters are changed from the
 -       ;; original one:
 -       ;; 0xE2        0x00AE+0xF87F -> 0x00AE # REGISTERED SIGN, alternate: sans serif
 -       ;; 0xE3        0x00A9+0xF87F -> 0x00A9 # COPYRIGHT SIGN, alternate: sans serif
 -       ;; 0xE4        0x2122+0xF87F -> 0x2122 # TRADE MARK SIGN, alternate: sans serif
 -       [?\\e$,1tL\e(B ?\\e$,1'R\e(B ?\\e$,1s2\e(B ?\\e$,1y$\e(B ?\\e$,1sD\e(B ?\\e$,1x>\e(B ?\\e$,1!R\e(B ?\\e$,2#c\e(B ?\\e$,2#f\e(B ?\\e$,2#e\e(B ?\\e$,2#`\e(B ?\\e$,1vt\e(B ?\\e$,1vp\e(B ?\\e$,1vq\e(B ?\\e$,1vr\e(B ?\\e$,1vs\e(B
 -      ?\\e,A0\e(B ?\\e,A1\e(B ?\\e$,1s3\e(B ?\\e$,1y%\e(B ?\\e,AW\e(B ?\\e$,1x=\e(B ?\\e$,1x"\e(B ?\\e$,1s"\e(B ?\\e,Aw\e(B ?\\e$,1y \e(B ?\\e$,1y!\e(B ?\\e$,1xh\e(B ?\\e$,1s&\e(B ?\\e$,1|p\e(B ?\\e$,1|O\e(B ?\\e$,1w5\e(B
 -      ?\\e$,1uu\e(B ?\\e$,1uQ\e(B ?\\e$,1u\\e(B ?\\e$,1uX\e(B ?\\e$,1yW\e(B ?\\e$,1yU\e(B ?\\e$,1x%\e(B ?\\e$,1xI\e(B ?\\e$,1xJ\e(B ?\\e$,1yC\e(B ?\\e$,1yG\e(B ?\\e$,1yD\e(B ?\\e$,1yB\e(B ?\\e$,1yF\e(B ?\\e$,1x(\e(B ?\\e$,1x)\e(B
 -      ?\\e$,1x@\e(B ?\\e$,1x'\e(B ?\\e,A.\e(B ?\\e,A)\e(B ?\\e$,1ub\e(B ?\\e$,1x/\e(B ?\\e$,1x:\e(B ?\\e$,1z%\e(B ?\\e,A,\e(B ?\\e$,1xG\e(B ?\\e$,1xH\e(B ?\\e$,1wT\e(B ?\\e$,1wP\e(B ?\\e$,1wQ\e(B ?\\e$,1wR\e(B ?\\e$,1wS\e(B
 -      ?\\e$,2"*\e(B ?\\e$,2=H\e(B ?\\e,A.\e(B ?\\e,A)\e(B ?\\e$,1ub\e(B ?\\e$,1x1\e(B ?\\e$,1|;\e(B ?\\e$,1|<\e(B ?\\e$,1|=\e(B ?\\e$,1|A\e(B ?\\e$,1|B\e(B ?\\e$,1|C\e(B ?\\e$,1|G\e(B ?\\e$,1|H\e(B ?\\e$,1|I\e(B ?\\e$,1|J\e(B
 -      ?\\e$,3b_\e(B ?\\e$,2=I\e(B ?\\e$,1xK\e(B ?\\e$,1{ \e(B ?\\e$,1|N\e(B ?\\e$,1{!\e(B ?\\e$,1|>\e(B ?\\e$,1|?\e(B ?\\e$,1|@\e(B ?\\e$,1|D\e(B ?\\e$,1|E\e(B ?\\e$,1|F\e(B ?\\e$,1|K\e(B ?\\e$,1|L\e(B ?\\e$,1|M\e(B
 -      nil]))
 -     translation-table)
 -  (setq translation-table
 -      (make-translation-table-from-vector encoding-vector))
 -;;  (define-translation-table 'mac-symbol-decoder translation-table)
 -  (define-translation-table 'mac-symbol-encoder
 -    (char-table-extra-slot translation-table 0)))
 -
 -(let
 -    ((encoding-vector
 -      (vconcat
 -       (make-vector 32 nil)
 -       ;; mac-dingbats (32..126) -> emacs-mule mapping
 -       [?\  ?\\e$,2%A\e(B ?\\e$,2%B\e(B ?\\e$,2%C\e(B ?\\e$,2%D\e(B ?\\e$,2"n\e(B ?\\e$,2%F\e(B ?\\e$,2%G\e(B ?\\e$,2%H\e(B ?\\e$,2%I\e(B ?\\e$,2"{\e(B ?\\e$,2"~\e(B ?\\e$,2%L\e(B ?\\e$,2%M\e(B ?\\e$,2%N\e(B ?\\e$,2%O\e(B
 -      ?\\e$,2%P\e(B ?\\e$,2%Q\e(B ?\\e$,2%R\e(B ?\\e$,2%S\e(B ?\\e$,2%T\e(B ?\\e$,2%U\e(B ?\\e$,2%V\e(B ?\\e$,2%W\e(B ?\\e$,2%X\e(B ?\\e$,2%Y\e(B ?\\e$,2%Z\e(B ?\\e$,2%[\e(B ?\\e$,2%\\e(B ?\\e$,2%]\e(B ?\\e$,2%^\e(B ?\\e$,2%_\e(B
 -      ?\\e$,2%`\e(B ?\\e$,2%a\e(B ?\\e$,2%b\e(B ?\\e$,2%c\e(B ?\\e$,2%d\e(B ?\\e$,2%e\e(B ?\\e$,2%f\e(B ?\\e$,2%g\e(B ?\\e$,2"e\e(B ?\\e$,2%i\e(B ?\\e$,2%j\e(B ?\\e$,2%k\e(B ?\\e$,2%l\e(B ?\\e$,2%m\e(B ?\\e$,2%n\e(B ?\\e$,2%o\e(B
 -      ?\\e$,2%p\e(B ?\\e$,2%q\e(B ?\\e$,2%r\e(B ?\\e$,2%s\e(B ?\\e$,2%t\e(B ?\\e$,2%u\e(B ?\\e$,2%v\e(B ?\\e$,2%w\e(B ?\\e$,2%x\e(B ?\\e$,2%y\e(B ?\\e$,2%z\e(B ?\\e$,2%{\e(B ?\\e$,2%|\e(B ?\\e$,2%}\e(B ?\\e$,2%~\e(B ?\\e$,2%\7f\e(B
 -      ?\\e$,2& \e(B ?\\e$,2&!\e(B ?\\e$,2&"\e(B ?\\e$,2&#\e(B ?\\e$,2&$\e(B ?\\e$,2&%\e(B ?\\e$,2&&\e(B ?\\e$,2&'\e(B ?\\e$,2&(\e(B ?\\e$,2&)\e(B ?\\e$,2&*\e(B ?\\e$,2&+\e(B ?\\e$,2"/\e(B ?\\e$,2&-\e(B ?\\e$,2!`\e(B ?\\e$,2&/\e(B
 -      ?\\e$,2&0\e(B ?\\e$,2&1\e(B ?\\e$,2&2\e(B ?\\e$,2!r\e(B ?\\e$,2!|\e(B ?\\e$,2"&\e(B ?\\e$,2&6\e(B ?\\e$,2"7\e(B ?\\e$,2&8\e(B ?\\e$,2&9\e(B ?\\e$,2&:\e(B ?\\e$,2&;\e(B ?\\e$,2&<\e(B ?\\e$,2&=\e(B ?\\e$,2&>\e(B
 -       nil
 -       ;; mac-dingbats (128..141) -> emacs-mule mapping
 -       ?\\e$,2&H\e(B ?\\e$,2&I\e(B ?\\e$,2&J\e(B ?\\e$,2&K\e(B ?\\e$,2&L\e(B ?\\e$,2&M\e(B ?\\e$,2&N\e(B ?\\e$,2&O\e(B ?\\e$,2&P\e(B ?\\e$,2&Q\e(B ?\\e$,2&R\e(B ?\\e$,2&S\e(B ?\\e$,2&T\e(B ?\\e$,2&U\e(B]
 -       (make-vector (- 161 142) nil)
 -       ;; mac-dingbats (161..239) -> emacs-mule mapping
 -       [?\\e$,2&A\e(B ?\\e$,2&B\e(B ?\\e$,2&C\e(B ?\\e$,2&D\e(B ?\\e$,2&E\e(B ?\\e$,2&F\e(B ?\\e$,2&G\e(B ?\\e$,2#c\e(B ?\\e$,2#f\e(B ?\\e$,2#e\e(B ?\\e$,2#`\e(B ?\\e$,1~@\e(B ?\\e$,1~A\e(B ?\\e$,1~B\e(B ?\\e$,1~C\e(B
 -      ?\\e$,1~D\e(B ?\\e$,1~E\e(B ?\\e$,1~F\e(B ?\\e$,1~G\e(B ?\\e$,1~H\e(B ?\\e$,1~I\e(B ?\\e$,2&V\e(B ?\\e$,2&W\e(B ?\\e$,2&X\e(B ?\\e$,2&Y\e(B ?\\e$,2&Z\e(B ?\\e$,2&[\e(B ?\\e$,2&\\e(B ?\\e$,2&]\e(B ?\\e$,2&^\e(B ?\\e$,2&_\e(B
 -      ?\\e$,2&`\e(B ?\\e$,2&a\e(B ?\\e$,2&b\e(B ?\\e$,2&c\e(B ?\\e$,2&d\e(B ?\\e$,2&e\e(B ?\\e$,2&f\e(B ?\\e$,2&g\e(B ?\\e$,2&h\e(B ?\\e$,2&i\e(B ?\\e$,2&j\e(B ?\\e$,2&k\e(B ?\\e$,2&l\e(B ?\\e$,2&m\e(B ?\\e$,2&n\e(B ?\\e$,2&o\e(B
 -      ?\\e$,2&p\e(B ?\\e$,2&q\e(B ?\\e$,2&r\e(B ?\\e$,2&s\e(B ?\\e$,2&t\e(B ?\\e$,1vr\e(B ?\\e$,1vt\e(B ?\\e$,1vu\e(B ?\\e$,2&x\e(B ?\\e$,2&y\e(B ?\\e$,2&z\e(B ?\\e$,2&{\e(B ?\\e$,2&|\e(B ?\\e$,2&}\e(B ?\\e$,2&~\e(B ?\\e$,2&\7f\e(B
 -      ?\\e$,2' \e(B ?\\e$,2'!\e(B ?\\e$,2'"\e(B ?\\e$,2'#\e(B ?\\e$,2'$\e(B ?\\e$,2'%\e(B ?\\e$,2'&\e(B ?\\e$,2''\e(B ?\\e$,2'(\e(B ?\\e$,2')\e(B ?\\e$,2'*\e(B ?\\e$,2'+\e(B ?\\e$,2',\e(B ?\\e$,2'-\e(B ?\\e$,2'.\e(B ?\\e$,2'/\e(B
 -      nil
 -       ;; mac-dingbats (241..254) -> emacs-mule mapping
 -      ?\\e$,2'1\e(B ?\\e$,2'2\e(B ?\\e$,2'3\e(B ?\\e$,2'4\e(B ?\\e$,2'5\e(B ?\\e$,2'6\e(B ?\\e$,2'7\e(B ?\\e$,2'8\e(B ?\\e$,2'9\e(B ?\\e$,2':\e(B ?\\e$,2';\e(B ?\\e$,2'<\e(B ?\\e$,2'=\e(B ?\\e$,2'>\e(B
 -      nil]))
 -     translation-table)
 -  (setq translation-table
 -      (make-translation-table-from-vector encoding-vector))
 -;;  (define-translation-table 'mac-dingbats-decoder translation-table)
 -  (define-translation-table 'mac-dingbats-encoder
 -    (char-table-extra-slot translation-table 0)))
 +(define-charset 'mac-centraleurroman
 +  "Mac Central European Roman"
 +  :short-name "Mac CE"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map
 +  (let ((tbl
 +       [?\Ä ?\Ä€ ?\Ä ?\É ?\Ä„ ?\Ö ?\Ãœ ?\á ?\Ä… ?\ÄŒ ?\ä ?\Ä ?\Ć ?\ć ?\é ?\Ź
 +        ?\ź ?\ÄŽ ?\í ?\Ä ?\Ä’ ?\Ä“ ?\Ä– ?\ó ?\Ä— ?\ô ?\ö ?\õ ?\ú ?\Äš ?\Ä› ?\ü
 +        ?\† ?\° ?\Ę ?\£ ?\§ ?\• ?\¶ ?\ß ?\® ?\© ?\â„¢ ?\Ä™ ?\¨ ?\≠ ?\Ä£ ?\Ä®
 +        ?\į ?\Ī ?\≤ ?\≥ ?\Ä« ?\Ķ ?\∂ ?\∑ ?\Å‚ ?\Ä» ?\ļ ?\Ľ ?\ľ ?\Ĺ ?\ĺ ?\Å…
 +        ?\ņ ?\Ń ?\¬ ?\√ ?\Å„ ?\Ň ?\∆ ?\« ?\» ?\… ?\  ?\ň ?\Å ?\Õ ?\Å‘ ?\ÅŒ
 +        ?\– ?\— ?\“ ?\†?\‘ ?\’ ?\÷ ?\â—Š ?\Å ?\Å” ?\Å• ?\Ř ?\‹ ?\› ?\Å™ ?\Å–
 +        ?\Å— ?\Å  ?\‚ ?\„ ?\Å¡ ?\Åš ?\Å› ?\à?\Ť ?\Å¥ ?\à?\Ž ?\ž ?\Ū ?\Ó ?\Ô
 +        ?\Å« ?\Å® ?\Ú ?\ů ?\Å° ?\ű ?\Ų ?\ų ?\à?\ý ?\Ä· ?\Å» ?\Å ?\ż ?\Ä¢ ?\ˇ])
 +      (map (make-vector 512 nil)))
 +    (or (= (length tbl) 128)
 +      (error "Invalid vector length: %d" (length tbl)))
 +    (dotimes (i 128)
 +      (aset map (* i 2) i)
 +      (aset map (1+ (* i 2)) i))
 +    (dotimes (i 128)
 +      (aset map (+ 256 (* i 2)) (+ 128 i))
 +      (aset map (+ 256 (1+ (* i 2))) (aref tbl i)))
 +    map))
 +
 +(define-coding-system 'mac-centraleurroman
 +  "Mac Central European Roman Encoding (MIME:x-mac-centraleurroman)."
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(mac-centraleurroman)
 +  :mime-charset 'x-mac-centraleurroman)
 +
 +(define-charset 'mac-cyrillic
 +  "Mac Cyrillic"
 +  :short-name "Mac CYRILLIC"
 +  :ascii-compatible-p t
 +  :code-space [0 255]
 +  :map
 +  (let ((tbl
 +       [?\Р?\Б ?\Ð’ ?\Г ?\Д ?\Е ?\Ж ?\З ?\И ?\Й ?\К ?\Л ?\Ðœ ?\Р?\О ?\П
 +        ?\Р ?\С ?\Т ?\У ?\Ф ?\Ð¥ ?\Ц ?\Ч ?\Ш ?\Щ ?\Ъ ?\Ы ?\Ь ?\Э ?\Ю ?\Я
 +        ?\† ?\° ?\Ò ?\£ ?\§ ?\• ?\¶ ?\І ?\® ?\© ?\â„¢ ?\Ђ ?\Ñ’ ?\≠ ?\Ѓ ?\Ñ“
 +        ?\∞ ?\± ?\≤ ?\≥ ?\Ñ– ?\µ ?\Ò‘ ?\Ј ?\Є ?\Ñ” ?\Ї ?\Ñ— ?\Љ ?\Ñ™ ?\Њ ?\Ñš
 +        ?\ј ?\Ð… ?\¬ ?\√ ?\Æ’ ?\≈ ?\∆ ?\« ?\» ?\… ?\  ?\Ћ ?\Ñ› ?\ÐŒ ?\Ñœ ?\Ñ•
 +        ?\– ?\— ?\“ ?\†?\‘ ?\’ ?\÷ ?\„ ?\ÐŽ ?\Ñž ?\Р?\ÑŸ ?\â„– ?\Р?\Ñ‘ ?\Ñ
 +        ?\а ?\б ?\в ?\г ?\д ?\е ?\ж ?\з ?\и ?\й ?\к ?\л ?\м ?\н ?\о ?\п
 +        ?\Ñ€ ?\Ñ ?\Ñ‚ ?\у ?\Ñ„ ?\Ñ… ?\ц ?\ч ?\ш ?\щ ?\ÑŠ ?\Ñ‹ ?\ÑŒ ?\Ñ ?\ÑŽ ?\€])
 +      (map (make-vector 512 nil)))
 +    (or (= (length tbl) 128)
 +      (error "Invalid vector length: %d" (length tbl)))
 +    (dotimes (i 128)
 +      (aset map (* i 2) i)
 +      (aset map (1+ (* i 2)) i))
 +    (dotimes (i 128)
 +      (aset map (+ 256 (* i 2)) (+ 128 i))
 +      (aset map (+ 256 (1+ (* i 2))) (aref tbl i)))
 +    map))
 +
 +(define-coding-system 'mac-cyrillic
 +  "Mac Cyrillic Encoding (MIME:x-mac-cyrillic)."
 +  :coding-type 'charset
 +  :mnemonic ?*
 +  :charset-list '(mac-cyrillic)
 +  :mime-charset 'x-mac-cyrillic)
 +
 +(define-charset 'mac-symbol
 +  "Mac Symbol"
 +  :short-name "Mac SYMBOL"
 +  :code-space [32 254]
 +  :map
 +  (let ((tbl-32-126
 +       [?\  ?\! ?\∀ ?\# ?\∃ ?\% ?\& ?\∠?\( ?\) ?\∗ ?\+ ?\, ?\− ?\. ?\/
 +        ?\0 ?\1 ?\2 ?\3 ?\4 ?\5 ?\6 ?\7 ?\8 ?\9 ?\: ?\; ?\< ?\= ?\> ?\?
 +        ?\≅ ?\Α ?\Î’ ?\Χ ?\Δ ?\Ε ?\Φ ?\Γ ?\Η ?\Ι ?\Ï‘ ?\Κ ?\Λ ?\Îœ ?\Π?\Ο
 +        ?\Π ?\Θ ?\Ρ ?\Σ ?\Τ ?\Î¥ ?\Ï‚ ?\Ω ?\Ξ ?\Ψ ?\Ζ ?\[ ?\∴ ?\] ?\⊥ ?\_
 +        ?\ ?\α ?\β ?\χ ?\δ ?\ε ?\φ ?\γ ?\η ?\ι ?\Ï• ?\κ ?\λ ?\μ ?\ν ?\ο
 +        ?\Ï€ ?\θ ?\Ï ?\σ ?\Ï„ ?\Ï… ?\Ï– ?\ω ?\ξ ?\ψ ?\ζ ?\{ ?\| ?\} ?\∼])
 +      (map-32-126 (make-vector (* (1+ (- 126 32)) 2) nil))
 +      (tbl-160-254
 +       ;; Mapping of the following characters are changed from the
 +       ;; original one:
 +       ;; 0xE2 0x00AE+0xF87F->0x00AE # REGISTERED SIGN, alternate: sans serif
 +       ;; 0xE3 0x00A9+0xF87F->0x00A9 # COPYRIGHT SIGN, alternate: sans serif
 +       ;; 0xE4 0x2122+0xF87F->0x2122 # TRADE MARK SIGN, alternate: sans serif
 +       [?\€ ?\Ï’ ?\′ ?\≤ ?\â„ ?\∞ ?\Æ’ ?\♣ ?\♦ ?\♥ ?\â™  ?\↔ ?\↠?\↑ ?\→ ?\↓
 +        ?\° ?\± ?\″ ?\≥ ?\× ?\∠?\∂ ?\• ?\÷ ?\≠ ?\≡ ?\≈ ?\… ?\â ?\⎯ ?\↵
 +        ?\ℵ ?\â„‘ ?\â„œ ?\℘ ?\⊗ ?\⊕ ?\∅ ?\∩ ?\∪ ?\⊃ ?\⊇ ?\⊄ ?\⊂ ?\⊆ ?\∈ ?\∉
 +        ?\∠ ?\∇ ?\® ?\© ?\â„¢ ?\∠?\√ ?\â‹… ?\¬ ?\∧ ?\∨ ?\⇔ ?\⇠?\⇑ ?\⇒ ?\⇓
 +        ?\â—Š ?\〈 ?\® ?\© ?\â„¢ ?\∑ ?\⎛ ?\⎜ ?\⎠?\⎡ ?\⎢ ?\⎣ ?\⎧ ?\⎨ ?\⎩ ?\⎪
 +        ?\ ?\〉 ?\∫ ?\⌠ ?\⎮ ?\⌡ ?\⎞ ?\⎟ ?\⎠ ?\⎤ ?\⎥ ?\⎦ ?\⎫ ?\⎬ ?\⎭])
 +      (map-160-254 (make-vector (* (1+ (- 254 160)) 2) nil)))
 +    (dotimes (i (1+ (- 126 32)))
 +      (aset map-32-126 (* i 2) (+ 32 i))
 +      (aset map-32-126 (1+ (* i 2)) (aref tbl-32-126 i)))
 +    (dotimes (i (1+ (- 254 160)))
 +      (aset map-160-254 (* i 2) (+ 160 i))
 +      (aset map-160-254 (1+ (* i 2)) (aref tbl-160-254 i)))
 +    (vconcat map-32-126 map-160-254)))
 +
 +(define-charset 'mac-dingbats
 +  "Mac Dingbats"
 +  :short-name "Mac Dingbats"
 +  :code-space [32 254]
 +  :map
 +  (let ((tbl-32-126
 +       [?\  ?\✠?\✂ ?\✃ ?\✄ ?\☎ ?\✆ ?\✇ ?\✈ ?\✉ ?\☛ ?\☞ ?\✌ ?\✠?\✎ ?\âœ
 +        ?\✠?\✑ ?\✒ ?\✓ ?\✔ ?\✕ ?\✖ ?\✗ ?\✘ ?\✙ ?\✚ ?\✛ ?\✜ ?\✠?\✞ ?\✟
 +        ?\✠ ?\✡ ?\✢ ?\✣ ?\✤ ?\✥ ?\✦ ?\✧ ?\★ ?\✩ ?\✪ ?\✫ ?\✬ ?\✭ ?\✮ ?\✯
 +        ?\✰ ?\✱ ?\✲ ?\✳ ?\✴ ?\✵ ?\✶ ?\✷ ?\✸ ?\✹ ?\✺ ?\✻ ?\✼ ?\✽ ?\✾ ?\✿
 +        ?\†?\â ?\â‚ ?\⃠?\â„ ?\â… ?\↠?\⇠?\∠?\≠?\⊠?\â‹ ?\â— ?\â ?\â–  ?\â
 +        ?\â ?\â‘ ?\â’ ?\â–² ?\â–¼ ?\â—† ?\â– ?\â—— ?\☠?\â™ ?\âš ?\â› ?\✠?\â ?\âž])
 +      (map-32-126 (make-vector (* (1+ (- 126 32)) 2) nil))
 +      (tbl-128-141
 +       [?\⨠?\â© ?\⪠?\â« ?\⬠?\â­ ?\â® ?\⯠?\â° ?\â± ?\â² ?\â³ ?\â´ ?\âµ])
 +      (map-128-141 (make-vector (* (1+ (- 141 128)) 2) nil))
 +      (tbl-161-239
 +       [?\â¡ ?\⢠?\⣠?\⤠?\⥠?\⦠?\⧠?\♣ ?\♦ ?\♥ ?\â™  ?\â‘  ?\â‘¡ ?\â‘¢ ?\â‘£
 +        ?\⑤ ?\â‘¥ ?\⑦ ?\⑧ ?\⑨ ?\â‘© ?\ⶠ?\â· ?\⸠?\â¹ ?\⺠?\â» ?\â¼ ?\â½ ?\â¾ ?\â¿
 +        ?\➀ ?\âž ?\âž‚ ?\➃ ?\âž„ ?\âž… ?\➆ ?\➇ ?\➈ ?\➉ ?\➊ ?\âž‹ ?\➌ ?\âž ?\➎ ?\âž
 +        ?\âž ?\âž‘ ?\âž’ ?\âž“ ?\âž” ?\→ ?\↔ ?\↕ ?\➘ ?\âž™ ?\âžš ?\âž› ?\âžœ ?\âž ?\âžž ?\➟
 +        ?\âž  ?\âž¡ ?\➢ ?\➣ ?\➤ ?\➥ ?\➦ ?\➧ ?\➨ ?\âž© ?\➪ ?\âž« ?\➬ ?\âž­ ?\âž® ?\➯])
 +      (map-161-239 (make-vector (* (1+ (- 239 161)) 2) nil))
 +      (tbl-241-254
 +       [?\âž± ?\âž² ?\âž³ ?\âž´ ?\âžµ ?\➶ ?\âž· ?\➸ ?\âž¹ ?\➺ ?\âž» ?\âž¼ ?\âž½ ?\âž¾])
 +      (map-241-254 (make-vector (* (1+ (- 254 241)) 2) nil)))
 +    (dotimes (i (1+ (- 126 32)))
 +      (aset map-32-126 (* i 2) (+ 32 i))
 +      (aset map-32-126 (1+ (* i 2)) (aref tbl-32-126 i)))
 +    (dotimes (i (1+ (- 141 128)))
 +      (aset map-128-141 (* i 2) (+ 128 i))
 +      (aset map-128-141 (1+ (* i 2)) (aref tbl-128-141 i)))
 +    (dotimes (i (1+ (- 239 161)))
 +      (aset map-161-239 (* i 2) (+ 161 i))
 +      (aset map-161-239 (1+ (* i 2)) (aref tbl-161-239 i)))
 +    (dotimes (i (1+ (- 254 241)))
 +      (aset map-241-254 (* i 2) (+ 241 i))
 +      (aset map-241-254 (1+ (* i 2)) (aref tbl-241-254 i)))
 +    (vconcat map-32-126 map-128-141 map-161-239 map-241-254)))
  
  (defconst mac-system-coding-system
    (let ((base (or (cdr (assq mac-system-script-code
              (setq str nil)
            ;; ASCII-only?
            (unless (mac-code-convert-string data nil mac-text-encoding-ascii)
 -            (subst-char-in-string ?\x5c ?\\e(J\\e(B str t)
 +            (subst-char-in-string ?\x5c ?\Â¥ str t)
              (subst-char-in-string ?\x80 ?\\ str t)))))
      (or str
        (decode-coding-string data
                   (eq coding-system 'japanese-shift-jis-mac))
          (setq encoding mac-text-encoding-mac-japanese-basic-variant)
          (setq str (subst-char-in-string ?\\ ?\x80 str))
 -        (subst-char-in-string ?\\e(J\\e(B ?\x5c str t)
 +        (subst-char-in-string ?\Â¥ ?\x5c str t)
          ;; ASCII-only?
          (if (string-match "\\`[\x00-\x7f]*\\'" str)
              (setq str nil)))
    (or coding-system (setq coding-system mac-system-coding-system))
    (prog1 (setq data (decode-coding-string data coding-system))
      (when (eq (coding-system-base coding-system) 'japanese-shift-jis)
 -      ;; (subst-char-in-string ?\x5c ?\\e(J\\e(B data t)
 +      ;; (subst-char-in-string ?\x5c ?\Â¥ data t)
        (subst-char-in-string ?\x80 ?\\ data t))))
  
  (defun mac-string-to-TEXT (string &optional coding-system)
        (coding-system-change-eol-conversion coding-system 'mac))
    (when (eq coding-system 'japanese-shift-jis-mac)
      ;; (setq string (subst-char-in-string ?\\ ?\x80 string))
 -    (setq string (subst-char-in-string ?\\e(J\\e(B ?\x5c string)))
 +    (setq string (subst-char-in-string ?\Â¥ ?\x5c string)))
    (encode-coding-string string coding-system))
  
  (defun mac-furl-to-string (data)
@@@ -1737,6 -1687,26 +1737,26 @@@ in `selection-converter-alist', which s
                                       (+ (* i 10) 12)))))
      result))
  
+ (defconst mac-keyboard-modifier-mask-alist
+   (mapcar
+    (lambda (modifier-bit)
+      (cons (car modifier-bit) (lsh 1 (cdr modifier-bit))))
+    '((command  . 8)                   ; cmdKeyBit
+      (shift    . 9)                   ; shiftKeyBit
+      (option   . 11)                  ; optionKeyBit
+      (control  . 12)                  ; controlKeyBit
+      (function . 17)))                        ; kEventKeyModifierFnBit
+   "Alist of Mac keyboard modifier symbols vs masks.")
+ (defun mac-ae-keyboard-modifiers (ae)
+   (let ((modifiers-value (mac-ae-number ae "kmod"))
+       modifiers)
+     (if modifiers-value
+       (dolist (modifier-mask mac-keyboard-modifier-mask-alist)
+         (if (/= (logand modifiers-value (cdr modifier-mask)) 0)
+             (setq modifiers (cons (car modifier-mask) modifiers)))))
+     modifiers))
  (defun mac-ae-open-documents (event)
    "Open the documents specified by the Apple event EVENT."
    (interactive "e")
              nil t)))))
    (select-frame-set-input-focus (selected-frame)))
  
+ (defun mac-ae-quit-application (event)
+   "Quit the application Emacs with the Apple event EVENT."
+   (interactive "e")
+   (let ((ae (mac-event-ae event)))
+     (unwind-protect
+       (save-buffers-kill-emacs)
+       ;; Reaches here if the user has canceled the quit.
+       (mac-resume-apple-event ae -128)))) ; userCanceledErr
  (defun mac-ae-get-url (event)
    "Open the URL specified by the Apple event EVENT.
  Currently the `mailto' scheme is supported."
    'mac-ae-open-documents)
  (define-key mac-apple-event-map [core-event show-preferences] 'customize)
  (define-key mac-apple-event-map [core-event quit-application]
-   'save-buffers-kill-emacs)
+   'mac-ae-quit-application)
  
  (define-key mac-apple-event-map [internet-event get-url] 'mac-ae-get-url)
  
@@@ -1803,9 -1782,8 +1832,8 @@@ With no keyboard modifiers, it toggles 
  frame where the tool-bar toggle button was pressed.  With some
  modifiers, it changes global tool-bar visibility setting."
    (interactive "e")
-   (let* ((ae (mac-event-ae event))
-        (modifiers (cdr (mac-ae-parameter ae "kmod"))))
-     (if (and modifiers (not (string= modifiers "\000\000\000\000")))
+   (let ((ae (mac-event-ae event)))
+     (if (mac-ae-keyboard-modifiers ae)
        ;; Globally toggle tool-bar-mode if some modifier key is pressed.
        (tool-bar-mode)
        (let ((frame (mac-ae-frame ae)))
@@@ -2227,7 -2205,7 +2255,7 @@@ either in the current buffer or in the 
      ("TIFF" . mac-dnd-insert-TIFF))
    "Which function to call to handle a drop of that type.
  The function takes three arguments, WINDOW, ACTION and DATA.
- WINDOW is where the drop occured, ACTION is always `private' on
+ WINDOW is where the drop occurred, ACTION is always `private' on
  Mac.  DATA is the drop data.  Unlike the x-dnd counterpart, the
  return value of the function is not significant.
  
@@@ -2262,10 -2240,10 +2290,10 @@@ See also `mac-dnd-known-types'.
  (defun mac-dnd-insert-TIFF (window action data)
    (dnd-insert-text window action (mac-TIFF-to-string data)))
  
- (defun mac-dnd-drop-data (event frame window data type)
+ (defun mac-dnd-drop-data (event frame window data type &optional action)
+   (or action (setq action 'private))
    (let* ((type-info (assoc type mac-dnd-types-alist))
         (handler (cdr type-info))
-        (action 'private)
         (w (posn-window (event-start event))))
      (when handler
        (if (and (windowp w) (window-live-p w)
  (defun mac-dnd-handle-drag-n-drop-event (event)
    "Receive drag and drop events."
    (interactive "e")
-   (let ((window (posn-window (event-start event))))
+   (let ((window (posn-window (event-start event)))
+       (ae (mac-event-ae event))
+       action)
      (when (windowp window) (select-window window))
-     (dolist (item (mac-ae-list (mac-event-ae event)))
+     (if (memq 'option (mac-ae-keyboard-modifiers ae))
+       (setq action 'copy))
+     (dolist (item (mac-ae-list ae))
        (if (not (equal (car item) "null"))
          (mac-dnd-drop-data event (selected-frame) window
-                            (cdr item) (car item)))))
+                            (cdr item) (car item) action))))
    (select-frame-set-input-focus (selected-frame)))
  \f
  ;;; Do the actual Windows setup here; the above code just defines
  
  (setq frame-creation-function 'x-create-frame-with-faces)
  
 -(defvar mac-font-encoder-list
 -  '(("mac-roman" mac-roman-encoder
 -     ccl-encode-mac-roman-font "%s")
 -    ("mac-centraleurroman" encode-mac-centraleurroman
 -     ccl-encode-mac-centraleurroman-font "%s ce")
 -    ("mac-cyrillic" encode-mac-cyrillic
 -     ccl-encode-mac-cyrillic-font "%s cy")
 -    ("mac-symbol" mac-symbol-encoder
 -     ccl-encode-mac-symbol-font "symbol")
 -    ("mac-dingbats" mac-dingbats-encoder
 -     ccl-encode-mac-dingbats-font "zapf dingbats")))
 -
 -(let ((encoder-list
 -       (mapcar (lambda (lst) (nth 1 lst)) mac-font-encoder-list))
 -      (charset-list
 -       '(latin-iso8859-2
 -       latin-iso8859-3 latin-iso8859-4
 -       cyrillic-iso8859-5 greek-iso8859-7 hebrew-iso8859-8
 -       latin-iso8859-9 latin-iso8859-14 latin-iso8859-15)))
 -  (dolist (encoder encoder-list)
 -    (let ((table (get encoder 'translation-table)))
 -      (dolist (charset charset-list)
 -      (dotimes (i 96)
 -        (let* ((c (make-char charset (+ i 32)))
 -               (mu (aref ucs-mule-to-mule-unicode c))
 -               (mac-encoded (and mu (aref table mu))))
 -          (if mac-encoded
 -              (aset table c mac-encoded))))))))
 -
 -;; We assume none of official dim2 charsets (0x90..0x99) are encoded
 -;; to these fonts.
 -
 -(define-ccl-program ccl-encode-mac-roman-font
 -  `(0
 -    (if (r0 <= ?\xef)
 -      (translate-character mac-roman-encoder r0 r1)
 -      ((r1 <<= 7)
 -       (r1 |= r2)
 -       (translate-character mac-roman-encoder r0 r1))))
 -  "CCL program for Mac Roman font")
 -
 -(define-ccl-program ccl-encode-mac-centraleurroman-font
 -  `(0
 -    (if (r0 <= ?\xef)
 -      (translate-character encode-mac-centraleurroman r0 r1)
 -      ((r1 <<= 7)
 -       (r1 |= r2)
 -       (translate-character encode-mac-centraleurroman r0 r1))))
 -  "CCL program for Mac Central European Roman font")
 -
 -(define-ccl-program ccl-encode-mac-cyrillic-font
 -  `(0
 -    (if (r0 <= ?\xef)
 -      (translate-character encode-mac-cyrillic r0 r1)
 -      ((r1 <<= 7)
 -       (r1 |= r2)
 -       (translate-character encode-mac-cyrillic r0 r1))))
 -  "CCL program for Mac Cyrillic font")
 -
 -(define-ccl-program ccl-encode-mac-symbol-font
 -  `(0
 -    (if (r0 <= ?\xef)
 -      (translate-character mac-symbol-encoder r0 r1)
 -      ((r1 <<= 7)
 -       (r1 |= r2)
 -       (translate-character mac-symbol-encoder r0 r1))))
 -  "CCL program for Mac Symbol font")
 -
 -(define-ccl-program ccl-encode-mac-dingbats-font
 -  `(0
 -    (if (r0 <= ?\xef)
 -      (translate-character mac-dingbats-encoder r0 r1)
 -      ((r1 <<= 7)
 -       (r1 |= r2)
 -       (translate-character mac-dingbats-encoder r0 r1))))
 -  "CCL program for Mac Dingbats font")
 -
 -
 -(setq font-ccl-encoder-alist
 -      (nconc
 -       (mapcar (lambda (lst) (cons (nth 0 lst) (nth 2 lst)))
 -             mac-font-encoder-list)
 -       font-ccl-encoder-alist))
 -
 -(defconst mac-char-fontspec-list
 -  ;; Directly operate on a char-table instead of a fontset so that it
 -  ;; may not create a dummy fontset.
 -  (let ((template (make-char-table 'fontset)))
 -    (dolist
 -      (font-encoder
 -       (nreverse
 -        (mapcar (lambda (lst)
 -                  (cons (cons (nth 3 lst) (nth 0 lst)) (nth 1 lst)))
 -                mac-font-encoder-list)))
 -      (let ((font (car font-encoder))
 -          (encoder (cdr font-encoder)))
 -      (map-char-table
 -       (lambda (key val)
 -         (or (null val)
 -             (generic-char-p key)
 -             (memq (char-charset key)
 -                   '(ascii eight-bit-control eight-bit-graphic))
 -             (aset template key font)))
 -       (get encoder 'translation-table))))
 -
 -    ;; Like fontset-info, but extend a range only if its "to" part is
 -    ;; the predecessor of the current char.
 -    (let* ((last '((0 nil)))
 -         (accumulator last)
 -         last-char-or-range last-char last-elt)
 -      (map-char-table
 -       (lambda (char elt)
 -       (when elt
 -         (setq last-char-or-range (car (car last))
 -               last-char (if (consp last-char-or-range)
 -                             (cdr last-char-or-range)
 -                           last-char-or-range)
 -               last-elt (cdr (car last)))
 -         (if (and (eq elt last-elt)
 -                  (= char (1+ last-char))
 -                  (eq (char-charset char) (char-charset last-char)))
 -             (if (consp last-char-or-range)
 -                 (setcdr last-char-or-range char)
 -               (setcar (car last) (cons last-char char)))
 -           (setcdr last (list (cons char elt)))
 -           (setq last (cdr last)))))
 -       template)
 -      (cdr accumulator))))
 +(setq font-encoding-alist
 +      (append
 +       '(("mac-roman" . mac-roman)
 +       ("mac-centraleurroman" . mac-centraleurroman)
 +       ("mac-cyrillic" . mac-cyrillic)
 +       ("mac-symbol" . mac-symbol)
 +       ("mac-dingbats" . mac-dingbats))
 +       font-encoding-alist))
  
  (defun fontset-add-mac-fonts (fontset &optional base-family)
 -  "Add font-specs for Mac fonts to FONTSET.
 -The added font-specs are determined by BASE-FAMILY and the value
 -of `mac-char-fontspec-list', which is a list
 -of (CHARACTER-OR-RANGE . (FAMILY-FORMAT . REGISTRY)).  If
 -BASE-FAMILY is nil, the font family in the added font-specs is
 -also nil.  If BASE-FAMILY is a string, `%s' in FAMILY-FORMAT is
 -replaced with the string.  Otherwise, `%s' in FAMILY-FORMAT is
 -replaced with the ASCII font family name in FONTSET."
 -  (if base-family
 -      (if (stringp base-family)
 -        (setq base-family (downcase base-family))
 -      (let ((ascii-font (fontset-font fontset (charset-id 'ascii))))
 -        (if ascii-font
 -            (setq base-family
 -                  (aref (x-decompose-font-name
 -                         (downcase (x-resolve-font-name ascii-font)))
 -                        xlfd-regexp-family-subnum))))))
 -  (let (fontspec-cache fontspec)
 -    (dolist (char-fontspec mac-char-fontspec-list)
 -      (setq fontspec (cdr (assq (cdr char-fontspec) fontspec-cache)))
 -      (when (null fontspec)
 -      (setq fontspec
 -            (cons (and base-family
 -                       (format (car (cdr char-fontspec)) base-family))
 -                  (cdr (cdr char-fontspec))))
 -      (setq fontspec-cache (cons (cons (cdr char-fontspec) fontspec)
 -                                 fontspec-cache)))
 -      (set-fontset-font fontset (car char-fontspec) fontspec))))
 +  (dolist (elt `((latin . (,(or base-family "Monaco") . "mac-roman"))
 +               (mac-roman . (,base-family . "mac-roman"))
 +               (mac-centraleurroman . (,base-family . "mac-centraleurroman"))
 +               (mac-cyrillic . (,base-family . "mac-cyrillic"))
 +               (mac-symbol . (,base-family . "mac-symbol"))
 +               (mac-dingbats . (,base-family . "mac-dingbats"))))
 +    (set-fontset-font fontset (car elt) (cdr elt))))
  
  (defun create-fontset-from-mac-roman-font (font &optional resolved-font
                                                fontset-name)
@@@ -2353,14 -2476,10 +2385,14 @@@ Optional 2nd arg FONTSET-NAME is a stri
  an appropriate name is generated automatically.
  
  It returns a name of the created fontset."
 -  (let ((fontset
 -       (create-fontset-from-ascii-font font resolved-font fontset-name)))
 -    (fontset-add-mac-fonts fontset t)
 -    fontset))
 +  (or resolved-font
 +      (setq resolved-font (x-resolve-font-name font)))
 +  (let ((base-family (aref (x-decompose-font-name resolved-font)
 +                         xlfd-regexp-family-subnum)))
 +    (if (string= base-family "*")
 +      (setq base-family nil))
 +    (new-fontset fontset-name (list (cons 'ascii resolved-font)))
 +    (fontset-add-mac-fonts fontset-name base-family)))
  
  ;; Adjust Courier font specifications in x-fixed-font-alist.
  (let ((courier-fonts (assoc "Courier" x-fixed-font-alist)))
  
  ;; Setup the default fontset.
  (setup-default-fontset)
 -(cond ((x-list-fonts "*-iso10646-1" nil nil 1)
 -       ;; Use ATSUI (if available) for the following charsets.
 -       (dolist
 -         (charset '(latin-iso8859-1
 -                    latin-iso8859-2 latin-iso8859-3 latin-iso8859-4
 -                    thai-tis620 greek-iso8859-7 arabic-iso8859-6
 -                    hebrew-iso8859-8 cyrillic-iso8859-5
 -                    latin-iso8859-9 latin-iso8859-15 latin-iso8859-14
 -                    japanese-jisx0212 chinese-sisheng ipa
 -                    vietnamese-viscii-lower vietnamese-viscii-upper
 -                    lao ethiopic tibetan))
 -       (set-fontset-font nil charset '(nil . "iso10646-1"))))
 -      ((null (x-list-fonts "*-iso8859-1" nil nil 1))
 -       ;; Add Mac-encoding fonts unless ETL fonts are installed.
 -       (fontset-add-mac-fonts "fontset-default")))
  
  ;; Create a fontset that uses mac-roman font.  With this fontset,
 -;; characters decoded from mac-roman encoding (ascii, latin-iso8859-1,
 -;; and mule-unicode-xxxx-yyyy) are displayed by a mac-roman font.
 -(create-fontset-from-fontset-spec
 - "-etl-fixed-medium-r-normal-*-16-*-*-*-*-*-fontset-standard,
 -ascii:-*-Monaco-*-*-*-*-12-*-*-*-*-*-mac-roman")
 -(fontset-add-mac-fonts "fontset-standard" t)
 +;; characters belonging to mac-roman charset (that contains ASCII and
 +;; more Latin characters) are displayed by a mac-roman font.
 +(create-fontset-from-mac-roman-font
 + "-*-Monaco-*-*-*-*-12-*-*-*-*-*-mac-roman" nil
 + "-apple-Monaco-normal-r-*-*-12-*-*-*-*-*-fontset-standard")
  
  ;; Create fontset specified in X resources "Fontset-N" (N is 0, 1, ...).
  (create-fontset-from-x-resource)
  
 -;; Try to create a fontset from a font specification which comes
 -;; from initial-frame-alist, default-frame-alist, or X resource.
 -;; A font specification in command line argument (i.e. -fn XXXX)
 -;; should be already in default-frame-alist as a `font'
 -;; parameter.  However, any font specifications in site-start
 -;; library, user's init file (.emacs), and default.el are not
 -;; yet handled here.
 -
 -(let ((font (or (cdr (assq 'font initial-frame-alist))
 -              (cdr (assq 'font default-frame-alist))
 -              (x-get-resource "font" "Font")))
 -      xlfd-fields resolved-name)
 -  (if (and font
 -         (not (query-fontset font))
 -         (setq resolved-name (x-resolve-font-name font))
 -         (setq xlfd-fields (x-decompose-font-name font)))
 -      (if (string= "fontset" (aref xlfd-fields xlfd-regexp-registry-subnum))
 -        (new-fontset font (x-complement-fontset-spec xlfd-fields nil))
 -      ;; Create a fontset from FONT.  The fontset name is
 -      ;; generated from FONT.
 -      (if (and (string= "mac" (aref xlfd-fields xlfd-regexp-registry-subnum))
 -               (string= "roman" (aref xlfd-fields xlfd-regexp-encoding-subnum)))
 -          (create-fontset-from-mac-roman-font font resolved-name "startup")
 -        (create-fontset-from-ascii-font font resolved-name "startup")))))
 -
  ;; Apply a geometry resource to the initial frame.  Put it at the end
  ;; of the alist, so that anything specified on the command line takes
  ;; precedence.
  ;; Initiate drag and drop
  
  (define-key special-event-map [drag-n-drop] 'mac-dnd-handle-drag-n-drop-event)
- (define-key special-event-map [M-drag-n-drop] 'mac-dnd-handle-drag-n-drop-event)
  
  \f
  ;;;; Non-toolkit Scroll bars
diff --combined lisp/term/w32-win.el
index ba093bc603f87976f043247a1a9a9b65776fd166,56dbf944dfeb1bf1bfba7e5101042b6a7e9c541c..203a41b1d9c8836422d2208ba87d9d13cb7ef650
@@@ -1,7 -1,7 +1,7 @@@
  ;;; w32-win.el --- parse switches controlling interface with W32 window system
  
  ;; Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Kevin Gallo
  ;; Keywords: terminals
@@@ -1200,10 -1200,10 +1200,10 @@@ See the documentation of `create-fontse
      (list face (if (equal value "") nil value))))
  
  ;;; Enable Japanese fonts on Windows to be used by default.
 -(set-fontset-font nil (make-char 'katakana-jisx0201) '("*" . "JISX0208-SJIS"))
 -(set-fontset-font nil (make-char 'latin-jisx0201) '("*" . "JISX0208-SJIS"))
 -(set-fontset-font nil (make-char 'japanese-jisx0208) '("*" . "JISX0208-SJIS"))
 -(set-fontset-font nil (make-char 'japanese-jisx0208-1978) '("*" . "JISX0208-SJIS"))
 +;; (set-fontset-font nil (make-char 'katakana-jisx0201) '("*" . "JISX0208-SJIS"))
 +;; (set-fontset-font nil (make-char 'latin-jisx0201) '("*" . "JISX0208-SJIS"))
 +;; (set-fontset-font nil (make-char 'japanese-jisx0208) '("*" . "JISX0208-SJIS"))
 +;; (set-fontset-font nil (make-char 'japanese-jisx0208-1978) '("*" . "JISX0208-SJIS"))
  
  (defun mouse-set-font (&rest fonts)
    "Select an Emacs font from a list of known good fonts and fontsets.
diff --combined lisp/term/x-win.el
index 6dcaaac0958dcf58ba5f6fbb46f571d1a07a8bcf,d9dc41cdcb86fe06fd16d77eba40d9a9c158fd97..fd95be90bfd4a607ec5434f4b6464d8d02e273e4
@@@ -1,7 -1,7 +1,7 @@@
  ;;; x-win.el --- parse relevant switches and set up for X  -*-coding: iso-2022-7bit;-*-
  
  ;; Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: FSF
  ;; Keywords: terminals, i18n
@@@ -1267,10 -1267,9 +1267,10 @@@ as returned by `x-server-vendor'.
         ;; This is used by DEC's X server.
         '((65280 . remove)))))
  
 +;; Latin-1
  (let ((i 160))
    (while (< i 256)
 -    (puthash i (make-char 'latin-iso8859-1 i) x-keysym-table)
 +    (puthash i i x-keysym-table)
      (setq i (1+ i))))
  
  ;; Table from Kuhn's proposed additions to the `KEYSYM Encoding'
        ;; Kana: Fixme: needs conversion to Japanese charset -- seems
        ;; to require jisx0213, for which the Unicode translation
        ;; isn't clear.
 -      (#x47e . ?\e$,1s>\e(B)
 -      (#x4a1 . ?\e$,2=B\e(B)
 -      (#x4a2 . ?\\e$,2=L\e(B)
 -      (#x4a3 . ?\\e$,2=M\e(B)
 -      (#x4a4 . ?\e$,2=A\e(B)
 -      (#x4a5 . ?\e$,2?{\e(B)
 -      (#x4a6 . ?\e$,2?r\e(B)
 -      (#x4a7 . ?\e$,2?!\e(B)
 -      (#x4a8 . ?\e$,2?#\e(B)
 -      (#x4a9 . ?\e$,2?%\e(B)
 -      (#x4aa . ?\e$,2?'\e(B)
 -      (#x4ab . ?\e$,2?)\e(B)
 -      (#x4ac . ?\e$,2?c\e(B)
 -      (#x4ad . ?\e$,2?e\e(B)
 -      (#x4ae . ?\e$,2?g\e(B)
 -      (#x4af . ?\e$,2?C\e(B)
 -      (#x4b0 . ?\e$,2?|\e(B)
 -      (#x4b1 . ?\e$,2?"\e(B)
 -      (#x4b2 . ?\e$,2?$\e(B)
 -      (#x4b3 . ?\e$,2?&\e(B)
 -      (#x4b4 . ?\e$,2?(\e(B)
 -      (#x4b5 . ?\e$,2?*\e(B)
 -      (#x4b6 . ?\e$,2?+\e(B)
 -      (#x4b7 . ?\e$,2?-\e(B)
 -      (#x4b8 . ?\e$,2?/\e(B)
 -      (#x4b9 . ?\e$,2?1\e(B)
 -      (#x4ba . ?\e$,2?3\e(B)
 -      (#x4bb . ?\e$,2?5\e(B)
 -      (#x4bc . ?\e$,2?7\e(B)
 -      (#x4bd . ?\e$,2?9\e(B)
 -      (#x4be . ?\e$,2?;\e(B)
 -      (#x4bf . ?\e$,2?=\e(B)
 -      (#x4c0 . ?\e$,2??\e(B)
 -      (#x4c1 . ?\e$,2?A\e(B)
 -      (#x4c2 . ?\e$,2?D\e(B)
 -      (#x4c3 . ?\e$,2?F\e(B)
 -      (#x4c4 . ?\e$,2?H\e(B)
 -      (#x4c5 . ?\e$,2?J\e(B)
 -      (#x4c6 . ?\e$,2?K\e(B)
 -      (#x4c7 . ?\e$,2?L\e(B)
 -      (#x4c8 . ?\e$,2?M\e(B)
 -      (#x4c9 . ?\e$,2?N\e(B)
 -      (#x4ca . ?\e$,2?O\e(B)
 -      (#x4cb . ?\e$,2?R\e(B)
 -      (#x4cc . ?\e$,2?U\e(B)
 -      (#x4cd . ?\e$,2?X\e(B)
 -      (#x4ce . ?\e$,2?[\e(B)
 -      (#x4cf . ?\e$,2?^\e(B)
 -      (#x4d0 . ?\e$,2?_\e(B)
 -      (#x4d1 . ?\e$,2?`\e(B)
 -      (#x4d2 . ?\e$,2?a\e(B)
 -      (#x4d3 . ?\e$,2?b\e(B)
 -      (#x4d4 . ?\e$,2?d\e(B)
 -      (#x4d5 . ?\e$,2?f\e(B)
 -      (#x4d6 . ?\e$,2?h\e(B)
 -      (#x4d7 . ?\e$,2?i\e(B)
 -      (#x4d8 . ?\e$,2?j\e(B)
 -      (#x4d9 . ?\e$,2?k\e(B)
 -      (#x4da . ?\e$,2?l\e(B)
 -      (#x4db . ?\e$,2?m\e(B)
 -      (#x4dc . ?\e$,2?o\e(B)
 -      (#x4dd . ?\e$,2?s\e(B)
 -      (#x4de . ?\e$,2>{\e(B)
 -      (#x4df . ?\e$,2>|\e(B)
 +      (#x47e . ?\e(J~\e(B)
 +      (#x4a1 . ?\e$A!#\e(B)
 +      (#x4a2 . ?\\e$A!8\e(B)
 +      (#x4a3 . ?\\e$A!9\e(B)
 +      (#x4a4 . ?\e$A!"\e(B)
 +      (#x4a5 . ?\e$A!$\e(B)
 +      (#x4a6 . ?\e$A%r\e(B)
 +      (#x4a7 . ?\e$A%!\e(B)
 +      (#x4a8 . ?\e$A%#\e(B)
 +      (#x4a9 . ?\e$A%%\e(B)
 +      (#x4aa . ?\e$A%'\e(B)
 +      (#x4ab . ?\e$A%)\e(B)
 +      (#x4ac . ?\e$A%c\e(B)
 +      (#x4ad . ?\e$A%e\e(B)
 +      (#x4ae . ?\e$A%g\e(B)
 +      (#x4af . ?\e$A%C\e(B)
 +      (#x4b0 . ?\e$B!<\e(B)
 +      (#x4b1 . ?\e$A%"\e(B)
 +      (#x4b2 . ?\e$A%$\e(B)
 +      (#x4b3 . ?\e$A%&\e(B)
 +      (#x4b4 . ?\e$A%(\e(B)
 +      (#x4b5 . ?\e$A%*\e(B)
 +      (#x4b6 . ?\e$A%+\e(B)
 +      (#x4b7 . ?\e$A%-\e(B)
 +      (#x4b8 . ?\e$A%/\e(B)
 +      (#x4b9 . ?\e$A%1\e(B)
 +      (#x4ba . ?\e$A%3\e(B)
 +      (#x4bb . ?\e$A%5\e(B)
 +      (#x4bc . ?\e$A%7\e(B)
 +      (#x4bd . ?\e$A%9\e(B)
 +      (#x4be . ?\e$A%;\e(B)
 +      (#x4bf . ?\e$A%=\e(B)
 +      (#x4c0 . ?\e$A%?\e(B)
 +      (#x4c1 . ?\e$A%A\e(B)
 +      (#x4c2 . ?\e$A%D\e(B)
 +      (#x4c3 . ?\e$A%F\e(B)
 +      (#x4c4 . ?\e$A%H\e(B)
 +      (#x4c5 . ?\e$A%J\e(B)
 +      (#x4c6 . ?\e$A%K\e(B)
 +      (#x4c7 . ?\e$A%L\e(B)
 +      (#x4c8 . ?\e$A%M\e(B)
 +      (#x4c9 . ?\e$A%N\e(B)
 +      (#x4ca . ?\e$A%O\e(B)
 +      (#x4cb . ?\e$A%R\e(B)
 +      (#x4cc . ?\e$A%U\e(B)
 +      (#x4cd . ?\e$A%X\e(B)
 +      (#x4ce . ?\e$A%[\e(B)
 +      (#x4cf . ?\e$A%^\e(B)
 +      (#x4d0 . ?\e$A%_\e(B)
 +      (#x4d1 . ?\e$A%`\e(B)
 +      (#x4d2 . ?\e$A%a\e(B)
 +      (#x4d3 . ?\e$A%b\e(B)
 +      (#x4d4 . ?\e$A%d\e(B)
 +      (#x4d5 . ?\e$A%f\e(B)
 +      (#x4d6 . ?\e$A%h\e(B)
 +      (#x4d7 . ?\e$A%i\e(B)
 +      (#x4d8 . ?\e$A%j\e(B)
 +      (#x4d9 . ?\e$A%k\e(B)
 +      (#x4da . ?\e$A%l\e(B)
 +      (#x4db . ?\e$A%m\e(B)
 +      (#x4dc . ?\e$A%o\e(B)
 +      (#x4dd . ?\e$A%s\e(B)
 +      (#x4de . ?\e$B!+\e(B)
 +      (#x4df . ?\e$B!,\e(B)
        ;; Arabic
        (#x5ac . ?\e,G,\e(B)
        (#x5bb . ?\e,G;\e(B)
        (#x7f9 . ?\e,Fy\e(B)
         ;; Technical
        (#x8a1 . ?\e$,1|W\e(B)
 -      (#x8a2 . ?\e$,2 ,\e(B)
 -      (#x8a3 . ?\e$,2  \e(B)
 +      (#x8a2 . ?\e$A)0\e(B)
 +      (#x8a3 . ?\e$A)$\e(B)
        (#x8a4 . ?\e$,1{ \e(B)
        (#x8a5 . ?\e$,1{!\e(B)
 -      (#x8a6 . ?\e$,2 "\e(B)
 +      (#x8a6 . ?\e$A)&\e(B)
        (#x8a7 . ?\e$,1|A\e(B)
        (#x8a8 . ?\e$,1|C\e(B)
        (#x8a9 . ?\e$,1|D\e(B)
        (#x8ae . ?\e$,1|@\e(B)
        (#x8af . ?\e$,1|H\e(B)
        (#x8b0 . ?\e$,1|L\e(B)
 -      (#x8bc . ?\e$,1y$\e(B)
 -      (#x8bd . ?\e$,1y \e(B)
 -      (#x8be . ?\e$,1y%\e(B)
 -      (#x8bf . ?\e$,1xK\e(B)
 -      (#x8c0 . ?\e$,1xT\e(B)
 -      (#x8c1 . ?\e$,1x=\e(B)
 -      (#x8c2 . ?\e$,1x>\e(B)
 -      (#x8c5 . ?\e$,1x'\e(B)
 -      (#x8c8 . ?\e$,1x\\e(B)
 -      (#x8c9 . ?\e$,1xc\e(B)
 -      (#x8cd . ?\e$,1wT\e(B)
 -      (#x8ce . ?\e$,1wR\e(B)
 -      (#x8cf . ?\e$,1y!\e(B)
 -      (#x8d6 . ?\e$,1x:\e(B)
 -      (#x8da . ?\e$,1yB\e(B)
 -      (#x8db . ?\e$,1yC\e(B)
 -      (#x8dc . ?\e$,1xI\e(B)
 -      (#x8dd . ?\e$,1xJ\e(B)
 -      (#x8de . ?\e$,1xG\e(B)
 -      (#x8df . ?\e$,1xH\e(B)
 -      (#x8ef . ?\e$,1x"\e(B)
 +      (#x8bc . ?\e$A!\\e(B)
 +      (#x8bd . ?\e$A!Y\e(B)
 +      (#x8be . ?\e$A!]\e(B)
 +      (#x8bf . ?\e$A!R\e(B)
 +      (#x8c0 . ?\e$A!`\e(B)
 +      (#x8c1 . ?\e$A!X\e(B)
 +      (#x8c2 . ?\e$A!^\e(B)
 +      (#x8c5 . ?\e$B"`\e(B)
 +      (#x8c8 . ?\e$(G"D\e(B)
 +      (#x8c9 . ?\e$(O"l\e(B)
 +      (#x8cd . ?\e$B"N\e(B)
 +      (#x8ce . ?\e$B"M\e(B)
 +      (#x8cf . ?\e$A!T\e(B)
 +      (#x8d6 . ?\e$A!L\e(B)
 +      (#x8da . ?\e$B">\e(B)
 +      (#x8db . ?\e$B"?\e(B)
 +      (#x8dc . ?\e$A!I\e(B)
 +      (#x8dd . ?\e$A!H\e(B)
 +      (#x8de . ?\e$A!D\e(B)
 +      (#x8df . ?\e$A!E\e(B)
 +      (#x8ef . ?\e$B"_\e(B)
        (#x8f6 . ?\e$,1!R\e(B)
 -      (#x8fb . ?\e$,1vp\e(B)
 -      (#x8fc . ?\e$,1vq\e(B)
 -      (#x8fd . ?\e$,1vr\e(B)
 -      (#x8fe . ?\e$,1vs\e(B)
 +      (#x8fb . ?\e$A!{\e(B)
 +      (#x8fc . ?\e$A!|\e(B)
 +      (#x8fd . ?\e$A!z\e(B)
 +      (#x8fe . ?\e$A!}\e(B)
        ;; Special
 -      (#x9e0 . ?\e$,2"&\e(B)
 -      (#x9e1 . ?\e$,2!R\e(B)
 -      (#x9e2 . ?\e$,1}I\e(B)
 -      (#x9e3 . ?\e$,1}L\e(B)
 -      (#x9e4 . ?\e$,1}M\e(B)
 -      (#x9e5 . ?\e$,1}J\e(B)
 +      (#x9e0 . ?\e$A!t\e(B)
 +      (#x9e1 . ?\e$(C"F\e(B)
 +      (#x9e2 . ?\e$(GB*\e(B)
 +      (#x9e3 . ?\e$(GB-\e(B)
 +      (#x9e4 . ?\e$(GB.\e(B)
 +      (#x9e5 . ?\e$(GB+\e(B)
        (#x9e8 . ?\e$,1}d\e(B)
 -      (#x9e9 . ?\e$,1}K\e(B)
 -      (#x9ea . ?\e$,2 8\e(B)
 -      (#x9eb . ?\e$,2 0\e(B)
 -      (#x9ec . ?\e$,2 ,\e(B)
 -      (#x9ed . ?\e$,2 4\e(B)
 -      (#x9ee . ?\e$,2 \\e(B)
 +      (#x9e9 . ?\e$(GB,\e(B)
 +      (#x9ea . ?\e$A)<\e(B)
 +      (#x9eb . ?\e$A)4\e(B)
 +      (#x9ec . ?\e$A)0\e(B)
 +      (#x9ed . ?\e$A)8\e(B)
 +      (#x9ee . ?\e$A)`\e(B)
        (#x9ef . ?\e$,1|Z\e(B)
        (#x9f0 . ?\e$,1|[\e(B)
 -      (#x9f1 . ?\e$,2  \e(B)
 +      (#x9f1 . ?\e$A)$\e(B)
        (#x9f2 . ?\e$,1|\\e(B)
        (#x9f3 . ?\e$,1|]\e(B)
 -      (#x9f4 . ?\e$,2 <\e(B)
 -      (#x9f5 . ?\e$,2 D\e(B)
 -      (#x9f6 . ?\e$,2 T\e(B)
 -      (#x9f7 . ?\e$,2 L\e(B)
 -      (#x9f8 . ?\e$,2 "\e(B)
 +      (#x9f4 . ?\e$A)@\e(B)
 +      (#x9f5 . ?\e$A)H\e(B)
 +      (#x9f6 . ?\e$A)X\e(B)
 +      (#x9f7 . ?\e$A)P\e(B)
 +      (#x9f8 . ?\e$A)&\e(B)
        ;; Publishing
        (#xaa1 . ?\e$,1rc\e(B)
        (#xaa2 . ?\e$,1rb\e(B)
        (#xaa6 . ?\e$,1rh\e(B)
        (#xaa7 . ?\e$,1ri\e(B)
        (#xaa8 . ?\e$,1rj\e(B)
 -      (#xaa9 . ?\e$,1rt\e(B)
 -      (#xaaa . ?\e$,1rs\e(B)
 -      (#xaae . ?\e$,1s&\e(B)
 -      (#xaaf . ?\e$,1s%\e(B)
 -      (#xab0 . ?\e$,1v3\e(B)
 -      (#xab1 . ?\e$,1v4\e(B)
 -      (#xab2 . ?\e$,1v5\e(B)
 +      (#xaa9 . ?\e$(G!7\e(B)
 +      (#xaaa . ?\e$(G!9\e(B)
 +      (#xaae . ?\e$A!-\e(B)
 +      (#xaaf . ?\e$(G!-\e(B)
 +      (#xab0 . ?\e$(O'x\e(B)
 +      (#xab1 . ?\e$(O'y\e(B)
 +      (#xab2 . ?\e$(O'z\e(B)
        (#xab3 . ?\e$,1v6\e(B)
        (#xab4 . ?\e$,1v7\e(B)
        (#xab5 . ?\e$,1v8\e(B)
        (#xab6 . ?\e$,1v9\e(B)
        (#xab7 . ?\e$,1v:\e(B)
 -      (#xab8 . ?\e$,1uE\e(B)
 +      (#xab8 . ?\e$(G""\e(B)
        (#xabb . ?\e$,1rr\e(B)
        (#xabc . ?\e$,1{)\e(B)
        (#xabe . ?\e$,1{*\e(B)
 -      (#xac3 . ?\e$,1v;\e(B)
 -      (#xac4 . ?\e$,1v<\e(B)
 -      (#xac5 . ?\e$,1v=\e(B)
 -      (#xac6 . ?\e$,1v>\e(B)
 -      (#xac9 . ?\e$,1ub\e(B)
 +      (#xac3 . ?\e$(C({\e(B)
 +      (#xac4 . ?\e$(C(|\e(B)
 +      (#xac5 . ?\e$(C(}\e(B)
 +      (#xac6 . ?\e$(C(~\e(B)
 +      (#xac9 . ?\e$(D"o\e(B)
        (#xaca . ?\e$,2"s\e(B)
 -      (#xacc . ?\e$,2"!\e(B)
 -      (#xacd . ?\e$,2!w\e(B)
 -      (#xace . ?\e$,2"+\e(B)
 +      (#xacc . ?\e$(O##\e(B)
 +      (#xacd . ?\e$(O#!\e(B)
 +      (#xace . ?\e$A!p\e(B)
        (#xacf . ?\e$,2!o\e(B)
 -      (#xad0 . ?\e$,1rx\e(B)
 -      (#xad1 . ?\e$,1ry\e(B)
 -      (#xad2 . ?\e$,1r|\e(B)
 -      (#xad3 . ?\e$,1r}\e(B)
 +      (#xad0 . ?\e,F!\e(B)
 +      (#xad1 . ?\e,F"\e(B)
 +      (#xad2 . ?\e,Y4\e(B)
 +      (#xad3 . ?\e,Y!\e(B)
        (#xad4 . ?\e$,1u^\e(B)
 -      (#xad6 . ?\e$,1s2\e(B)
 -      (#xad7 . ?\e$,1s3\e(B)
 +      (#xad6 . ?\e$A!d\e(B)
 +      (#xad7 . ?\e$A!e\e(B)
        (#xad9 . ?\e$,2%]\e(B)
        (#xadb . ?\e$,2!l\e(B)
 -      (#xadc . ?\e$,2" \e(B)
 -      (#xadd . ?\e$,2!v\e(B)
 -      (#xade . ?\e$,2"/\e(B)
 +      (#xadc . ?\e$(O#$\e(B)
 +      (#xadd . ?\e$(O#"\e(B)
 +      (#xade . ?\e$A!q\e(B)
        (#xadf . ?\e$,2!n\e(B)
 -      (#xae0 . ?\e$,2"F\e(B)
 +      (#xae0 . ?\e$(O#?\e(B)
        (#xae1 . ?\e$,2!k\e(B)
        (#xae2 . ?\e$,2!m\e(B)
 -      (#xae3 . ?\e$,2!s\e(B)
 -      (#xae4 . ?\e$,2!}\e(B)
 -      (#xae5 . ?\e$,2"f\e(B)
 -      (#xae6 . ?\e$,1s"\e(B)
 +      (#xae3 . ?\e$A!w\e(B)
 +      (#xae4 . ?\e$(G!}\e(B)
 +      (#xae5 . ?\e$A!n\e(B)
 +      (#xae6 . ?\e$(O#@\e(B)
        (#xae7 . ?\e$,2!j\e(B)
 -      (#xae8 . ?\e$,2!r\e(B)
 -      (#xae9 . ?\e$,2!|\e(B)
 -      (#xaea . ?\e$,2"|\e(B)
 -      (#xaeb . ?\e$,2"~\e(B)
 -      (#xaec . ?\e$,2#c\e(B)
 -      (#xaed . ?\e$,2#f\e(B)
 -      (#xaee . ?\e$,2#e\e(B)
 +      (#xae8 . ?\e$A!x\e(B)
 +      (#xae9 . ?\e$(G!~\e(B)
 +      (#xaea . ?\e$(C"P\e(B)
 +      (#xaeb . ?\e$(O-~\e(B)
 +      (#xaec . ?\e$(O&@\e(B)
 +      (#xaed . ?\e$(O&<\e(B)
 +      (#xaee . ?\e$(O&>\e(B)
        (#xaf0 . ?\e$,2%`\e(B)
 -      (#xaf1 . ?\e$,1s \e(B)
 -      (#xaf2 . ?\e$,1s!\e(B)
 -      (#xaf3 . ?\e$,2%S\e(B)
 +      (#xaf1 . ?\e$B"w\e(B)
 +      (#xaf2 . ?\e$B"x\e(B)
 +      (#xaf3 . ?\e$(O'{\e(B)
        (#xaf4 . ?\e$,2%W\e(B)
 -      (#xaf5 . ?\e$,2#o\e(B)
 -      (#xaf6 . ?\e$,2#m\e(B)
 -      (#xaf7 . ?\e$,2#B\e(B)
 -      (#xaf8 . ?\e$,2#@\e(B)
 -      (#xaf9 . ?\e$,2"n\e(B)
 +      (#xaf5 . ?\e$B"t\e(B)
 +      (#xaf6 . ?\e$B"u\e(B)
 +      (#xaf7 . ?\e$A!a\e(B)
 +      (#xaf8 . ?\e$A!b\e(B)
 +      (#xaf9 . ?\e$(O&g\e(B)
        (#xafa . ?\e$,1zu\e(B)
        (#xafb . ?\e$,1uW\e(B)
        (#xafc . ?\e$,1s8\e(B)
        (#xafd . ?\e$,1rz\e(B)
 -      (#xafe . ?\e$,1r~\e(B)
 +      (#xafe . ?\e,Y%\e(B)
        ;; APL
        (#xba3 . ?<)
        (#xba6 . ?>)
 -      (#xba8 . ?\e$,1xH\e(B)
 -      (#xba9 . ?\e$,1xG\e(B)
 +      (#xba8 . ?\e$A!E\e(B)
 +      (#xba9 . ?\e$A!D\e(B)
        (#xbc0 . ?\e,A/\e(B)
 -      (#xbc2 . ?\e$,1ye\e(B)
 -      (#xbc3 . ?\e$,1xI\e(B)
 +      (#xbc2 . ?\e$A!M\e(B)
 +      (#xbc3 . ?\e$A!I\e(B)
        (#xbc4 . ?\e$,1zj\e(B)
        (#xbc6 . ?_)
        (#xbca . ?\e$,1x8\e(B)
        (#xbcc . ?\e$,1|5\e(B)
        (#xbce . ?\e$,1yd\e(B)
 -      (#xbcf . ?\e$,2"+\e(B)
 +      (#xbcf . ?\e$A!p\e(B)
        (#xbd3 . ?\e$,1zh\e(B)
 -      (#xbd6 . ?\e$,1xJ\e(B)
 -      (#xbd8 . ?\e$,1yC\e(B)
 -      (#xbda . ?\e$,1yB\e(B)
 +      (#xbd6 . ?\e$A!H\e(B)
 +      (#xbd8 . ?\e$B"?\e(B)
 +      (#xbda . ?\e$B">\e(B)
        (#xbdc . ?\e$,1yb\e(B)
        (#xbfc . ?\e$,1yc\e(B)
        ;; Hebrew
        ;; Latin-9
        (#x13bc . ?\e,b<\e(B)
        (#x13bd . ?\e,b=\e(B)
 -      (#x13be . ?\e,b>\e(B)
 +      (#x13be . ?\e,_/\e(B)
        ;; Currency
        (#x20a0 . ?\e$,1t@\e(B)
        (#x20a1 . ?\e$,1tA\e(B)
@@@ -2420,6 -2419,28 +2420,6 @@@ order until succeed."
  ;; Create fontset specified in X resources "Fontset-N" (N is 0, 1, ...).
  (create-fontset-from-x-resource)
  
 -;; Try to create a fontset from a font specification which comes
 -;; from initial-frame-alist, default-frame-alist, or X resource.
 -;; A font specification in command line argument (i.e. -fn XXXX)
 -;; should be already in default-frame-alist as a `font'
 -;; parameter.  However, any font specifications in site-start
 -;; library, user's init file (.emacs), and default.el are not
 -;; yet handled here.
 -
 -(let ((font (or (cdr (assq 'font initial-frame-alist))
 -              (cdr (assq 'font default-frame-alist))
 -              (x-get-resource "font" "Font")))
 -      xlfd-fields resolved-name)
 -  (if (and font
 -         (not (query-fontset font))
 -         (setq resolved-name (x-resolve-font-name font))
 -         (setq xlfd-fields (x-decompose-font-name font)))
 -      (if (string= "fontset" (aref xlfd-fields xlfd-regexp-registry-subnum))
 -        (new-fontset font (x-complement-fontset-spec xlfd-fields nil))
 -      ;; Create a fontset from FONT.  The fontset name is
 -      ;; generated from FONT.
 -      (create-fontset-from-ascii-font font resolved-name "startup"))))
 -
  ;; Apply a geometry resource to the initial frame.  Put it at the end
  ;; of the alist, so that anything specified on the command line takes
  ;; precedence.
diff --combined lisp/textmodes/fill.el
index 4113a884c4c287b24c39a20f10fc8dec6e5131aa,bd157316b4fb7186bc789872884423651c39ff4b..c684a1e2e8f26ce8da7fff0968f8888664c86ef9
@@@ -1,7 -1,7 +1,7 @@@
  ;;; fill.el --- fill commands for Emacs               -*- coding: iso-2022-7bit -*-
  
  ;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1999, 2001, 2002,
- ;;   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: wp
@@@ -368,29 -368,15 +368,29 @@@ and `fill-nobreak-invisible'.
              (looking-at paragraph-start))))
       (run-hook-with-args-until-success 'fill-nobreak-predicate)))))
  
 -;; Put `fill-find-break-point-function' property to charsets which
 -;; require special functions to find line breaking point.
 -(dolist (pair '((katakana-jisx0201 . kinsoku)
 -              (chinese-gb2312 . kinsoku)
 -              (japanese-jisx0208 . kinsoku)
 -              (japanese-jisx0212 . kinsoku)
 -              (chinese-big5-1 . kinsoku)
 -              (chinese-big5-2 . kinsoku)))
 -  (put-charset-property (car pair) 'fill-find-break-point-function (cdr pair)))
 +(defvar fill-find-break-point-function-table (make-char-table nil)
 +  "Char-table of special functions to find line breaking point.")
 +
 +(defvar fill-nospace-between-words-table (make-char-table nil)
 +  "Char-table of characters that don't use space between words.")
 +
 +(progn
 +  ;; Register `kinsoku' for scripts HAN, KANA, BOPOMPFO, and CJK-MISS.
 +  ;; Also tell that they don't use space between words.
 +  (map-char-table
 +   #'(lambda (key val)
 +       (when (memq val '(han kana bopomofo cjk-misc))
 +       (set-char-table-range fill-find-break-point-function-table
 +                             key 'kinsoku)
 +       (set-char-table-range fill-nospace-between-words-table
 +                             key t)))
 +   char-script-table)
 +  ;; Do the same thing also for full width characters and half
 +  ;; width kana variants.
 +  (set-char-table-range fill-find-break-point-function-table
 +                      '(#xFF01 . #xFFE6) 'kinsoku)
 +  (set-char-table-range fill-nospace-between-words-table
 +                      '(#xFF01 . #xFFE6) 'kinsoku))
  
  (defun fill-find-break-point (limit)
    "Move point to a proper line breaking position of the current line.
@@@ -401,9 -387,15 +401,9 @@@ after or before a non-ASCII character
  character has the property `fill-find-break-point-function', this
  function calls the property value as a function with one arg LINEBEG.
  If the charset has no such property, do nothing."
 -  (let* ((ch (following-char))
 -       (charset (char-charset ch))
 -       func)
 -    (if (eq charset 'ascii)
 -      (setq ch (preceding-char)
 -            charset (char-charset ch)))
 -    (if (charsetp charset)
 -      (setq func
 -            (get-charset-property charset 'fill-find-break-point-function)))
 +  (let ((func (or
 +             (aref fill-find-break-point-function-table (following-char))
 +             (aref fill-find-break-point-function-table (preceding-char)))))
      (if (and func (fboundp func))
        (funcall func limit))))
  
@@@ -462,13 -454,14 +462,13 @@@ Point is moved to just past the fill pr
    (goto-char from)
    (if enable-multibyte-characters
        ;; Delete unnecessay newlines surrounded by words.  The
 -      ;; character category `|' means that we can break a line
 -      ;; at the character.  And, charset property
 -      ;; `nospace-between-words' tells how to concatenate
 -      ;; words.  If the value is non-nil, never put spaces
 -      ;; between words, thus delete a newline between them.
 -      ;; If the value is nil, delete a newline only when a
 -      ;; character preceding a newline has text property
 -      ;; `nospace-between-words'.
 +      ;; character category `|' means that we can break a line at the
 +      ;; character.  And, char-table
 +      ;; `fill-nospace-between-words-table' tells how to concatenate
 +      ;; words.  If a character has non-nil value in the table, never
 +      ;; put spaces between words, thus delete a newline between them.
 +      ;; Otherwise, delete a newline only when a character preceding a
 +      ;; newline has non-nil value in that table.
        (while (search-forward "\n" to t)
        (if (get-text-property (match-beginning 0) 'fill-space)
            (replace-match (get-text-property (match-beginning 0) 'fill-space))
                (next (following-char)))
            (if (and (or (aref (char-category-set next) ?|)
                         (aref (char-category-set prev) ?|))
 -                   (or (get-charset-property (char-charset prev)
 -                                             'nospace-between-words)
 -                       (get-text-property (1- (match-beginning 0))
 -                                          'nospace-between-words)))
 +                   (or (aref fill-nospace-between-words-table next)
 +                       (aref fill-nospace-between-words-table prev)))
                (delete-char -1))))))
  
    (goto-char from)
@@@ -748,7 -743,7 +748,7 @@@ space does not end a sentence, so don'
  
  (defun fill-minibuffer-function (arg)
    "Fill a paragraph in the minibuffer, ignoring the prompt."
-   (save-restriction 
+   (save-restriction
      (narrow-to-region (minibuffer-prompt-end) (point-max))
      (fill-paragraph arg)))
  
@@@ -843,18 -838,22 +843,22 @@@ can take care of filling.  JUSTIFY is u
             (commark
              (comment-string-strip (buffer-substring comstart comin) nil t))
             (comment-re
-             ;; `commark' is surrounded with arbitrary text (`\0' and `a')
-             ;;  to make sure it can be used as an optimization of
-             ;; `comment-start-skip' in the middle of a line.  For example,
-             ;; `commark' can't be used with the "@c" in TeXinfo (hence
-             ;; the `a') or with the "C" at BOL in Fortran (hence the `\0').
-             (if (string-match comment-start-skip (concat "\0" commark "a"))
-                 (concat "[ \t]*" (regexp-quote commark)
-                         ;; Make sure we only match comments that use
-                         ;; the exact same comment marker.
-                         "[^" (substring commark -1) "]")
-               (concat "[ \t]*\\(?:" comment-start-skip "\\)")))
-            (comment-fill-prefix       ; Compute a fill prefix.
+               ;; A regexp more specialized than comment-start-skip, that only
+               ;; matches the current commark rather than any valid commark.
+               ;;
+               ;; The specialized regexp only works for "normal" comment
+               ;; syntax, not for Texinfo's "@c" (which can't be immediately
+               ;; followed by word-chars) or Fortran's "C" (which needs to be
+               ;; at bol), so check that comment-start-skip indeed allows the
+               ;; commark to appear in the middle of the line and followed by
+               ;; word chars.  The choice of "\0" and "a" is mostly arbitrary.
+               (if (string-match comment-start-skip (concat "\0" commark "a"))
+                   (concat "[ \t]*" (regexp-quote commark)
+                           ;; Make sure we only match comments that
+                           ;; use the exact same comment marker.
+                           "[^" (substring commark -1) "]")
+                 (concat "[ \t]*\\(?:" comment-start-skip "\\)")))
+              (comment-fill-prefix     ; Compute a fill prefix.
              (save-excursion
                (goto-char comstart)
                (if has-code-and-comment
@@@ -949,13 -948,13 +953,13 @@@ Ordinarily the variable `fill-column' c
  
  Noninteractively, the third argument JUSTIFY specifies which
  kind of justification to do: `full', `left', `right', `center',
- or `none' (equivalent to nil).  t means handle each paragraph
- as specified by its text properties.
+ or `none' (equivalent to nil).  A value of t means handle each
paragraph as specified by its text properties.
  
- The fourth arg NOSQUEEZE non-nil means to leave
- whitespace other than line breaks untouched, and fifth arg TO-EOP
- non-nil means to keep filling to the end of the paragraph (or next
hard newline, if variable `use-hard-newlines' is on).
+ The fourth arg NOSQUEEZE non-nil means to leave whitespace other
+ than line breaks untouched, and fifth arg TO-EOP non-nil means
+ to keep filling to the end of the paragraph (or next hard newline,
+ if variable `use-hard-newlines' is on).
  
  Return the fill-prefix used for filling the last paragraph.
  
diff --combined lisp/textmodes/ispell.el
index a8b7d1bd7dffdd21358633bcf2a9a339f0a6c0fc,fe74bf8f32154a6211c0104f863962dc2b329c0b..ff25f79fcfe5bfc270bc5a49b355eeeabf274f81
@@@ -1,7 -1,7 +1,7 @@@
  ;;; ispell.el --- interface to International Ispell Versions 3.1 and 3.2
  
  ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author:           Ken Stevens <k.stevens@ieee.org>
  ;; Maintainer:       Ken Stevens <k.stevens@ieee.org>
@@@ -574,7 -574,7 +574,7 @@@ re-start Emacs.
      "[A-Za-z^\\]" "[^A-Za-z^\\]"
      "[-'`\"]" t ("-C" "-d" "esperanto") "~tex" iso-8859-3)
     ("francais7"
-     "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil iso-8859-1)
+     "[A-Za-z]" "[^A-Za-z]" "[`'^-]" t nil nil iso-8859-1)
     ("francais"                                ; Francais.aff
      "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]"
      "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]"
     ("polish"                          ; Polish mode
      "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
      "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
-     "." nil nil nil iso-8859-2)
+     "[.]" nil nil nil iso-8859-2)
     ("portugues"                               ; Portuguese mode
      "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
      "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
@@@ -1184,7 -1184,28 +1184,7 @@@ Protects against bogus binding of `enab
        (decode-coding-string str (ispell-get-coding-system))
      str))
  
 -(put 'ispell-unified-chars-table 'char-table-extra-slots 0)
 -
 -;; Char-table that maps an Unicode character (charset:
 -;; latin-iso8859-1, mule-unicode-0100-24ff, mule-unicode-2500-34ff) to
 -;; a string in which all equivalent characters are listed.
 -
 -(defconst ispell-unified-chars-table
 -  (let ((table (make-char-table 'ispell-unified-chars-table)))
 -    (map-char-table
 -     #'(lambda (c v)
 -       (if (and v (/= c v))
 -           (let ((unified (or (aref table v) (string v))))
 -             (aset table v (concat unified (string c))))))
 -     ucs-mule-8859-to-mule-unicode)
 -    table))
 -
 -;; Return a string decoded from Nth element of the current dictionary
 -;; while splicing equivalent characters into the string.  This splicing
 -;; is done only if the string is a regular expression of the form
 -;; "[...]" because, otherwise, splicing will result in incorrect
 -;; regular expression matching.
 -
 +;; Return a string decoded from Nth element of the current dictionary.
  (defun ispell-get-decoded-string (n)
    (let* ((slot (or
                (assoc ispell-current-dictionary ispell-local-dictionary-alist)
      (when (and (> (length str) 0)
               (not (multibyte-string-p str)))
        (setq str (ispell-decode-string str))
 -      (if (and (= (aref str 0) ?\[)
 -             (eq (string-match "\\]" str) (1- (length str))))
 -        (setq str
 -              (string-as-multibyte
 -               (mapconcat
 -                #'(lambda (c)
 -                    (let ((unichar (aref ucs-mule-8859-to-mule-unicode c)))
 -                      (if unichar
 -                          (aref ispell-unified-chars-table unichar)
 -                        (string c))))
 -                str ""))))
 +      (or (multibyte-string-p str)
 +        (setq str (string-to-multibyte str)))
        (setcar (nthcdr n slot) str))
      str))
  
@@@ -2577,6 -2607,7 +2577,7 @@@ By just answering RET you can find out 
               (mapcar 'list (ispell-valid-dictionary-list)))
          nil t)
         current-prefix-arg))
+   (ispell-maybe-find-aspell-dictionaries)
    (unless arg (ispell-buffer-local-dict 'no-reload))
    (if (equal dict "default") (setq dict nil))
    ;; This relies on completing-read's bug of returning "" for no match
index a3341db3ae353528e79ff15b784f3fa9fabcee70,6757eb9be1cff0d8d525112b7f96d3a0ba46d618..b4ecc325e0d76ebe0484795f0a62b40954dc7e3f
@@@ -1,7 -1,7 +1,7 @@@
  ;;; sgml-mode.el --- SGML- and HTML-editing modes -*- coding: iso-2022-7bit -*-
  
  ;; Copyright (C) 1992, 1995, 1996, 1998, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: James Clark <jjc@jclark.com>
  ;; Maintainer: FSF
@@@ -114,6 -114,8 +114,6 @@@ This takes effect when first loading th
          (define-key map "\"" 'sgml-name-self))
        (when (memq ?' sgml-specials)
          (define-key map "'" 'sgml-name-self)))
 -    (define-key map (vector (make-char 'latin-iso8859-1))
 -      'sgml-maybe-name-self)
      (let ((c 127)
          (map (nth 1 map)))
        (while (< (setq c (1+ c)) 256)
    (let ((table (make-char-table 'sgml-table))
        (i 32)
        elt)
 -    (while (< i 256)
 +    (while (< i 128)
        (setq elt (aref sgml-char-names i))
        (if elt (aset table (make-char 'latin-iso8859-1 i) elt))
        (setq i (1+ i)))
diff --combined lisp/time-stamp.el
index 770a86834c8fedd689dd649fcd9cfdb406341577,973ff972af0c09742c3dd9b2c5e98851a024b836..c36b873d7a1588b3d1fe144f6597bafb9d1925b6
@@@ -1,7 -1,7 +1,7 @@@
  ;;; time-stamp.el --- Maintain last change time stamps in files edited by Emacs
  
  ;; Copyright (C) 1989, 1993, 1994, 1995, 1997, 2000, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; This file is part of GNU Emacs.
  
@@@ -710,7 -710,7 +710,7 @@@ around literals.
  ;;; Some functions used in time-stamp-format
  
  ;;; These functions have been obsolete since 1995
 -;;; and will be removed in a future Emacs release.
 +;;; and will be removed in Emacs 23.
  ;;; Meanwhile, discourage other packages from using them.
  (dolist (function '(time-stamp-month-dd-yyyy time-stamp-dd/mm/yyyy
                    time-stamp-mon-dd-yyyy   time-stamp-dd-mon-yy
diff --combined lisp/version.el
index b6654b8a00c88316ae14c3104d842b59d37d3190,f6ab6c4c913034a0499068933ccc64e98e840a24..0d203b3385f38182d699a8d0766ec57aa7877b59
@@@ -1,7 -1,7 +1,7 @@@
  ;;; version.el --- record version number of Emacs -*- no-byte-compile: t -*-
  
  ;; Copyright (C) 1985, 1992, 1994, 1995, 1999, 2000, 2001, 2002,
- ;;   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Maintainer: FSF
  ;; Keywords: internal
@@@ -27,7 -27,7 +27,7 @@@
  
  ;;; Code:
  
 -(defconst emacs-version "22.0.93" "\
 +(defconst emacs-version "23.0.0" "\
  Version numbers of this version of Emacs.")
  
  (defconst emacs-major-version
diff --combined lisp/w32-fns.el
index 85b4be732d130cde384722ed46e33fb40d85a5a2,26aafeb27fc4df4c19aab615fdbb84449e228bba..caf14d48be76a8a37e63f47f6cc43d36d80798e5
@@@ -1,7 -1,7 +1,7 @@@
  ;;; w32-fns.el --- Lisp routines for Windows NT
  
  ;; Copyright (C) 1994, 2001, 2002, 2003, 2004,
- ;;   2005, 2006 Free Software Foundation, Inc.
+ ;;   2005, 2006, 2007 Free Software Foundation, Inc.
  
  ;; Author: Geoff Voelker <voelker@cs.washington.edu>
  ;; Keywords: internal
@@@ -371,11 -371,9 +371,11 @@@ bit output with no translation.
  ;; value from w32-select-font etc, so list the most important charsets last.
  (w32-add-charset-info "iso8859-14" 'w32-charset-ansi  28604)
  (w32-add-charset-info "iso8859-15" 'w32-charset-ansi  28605)
 +;; The following two are included for pattern matching.
 +(w32-add-charset-info "jisx0201" 'w32-charset-shiftjis 932)
 +(w32-add-charset-info "jisx0208" 'w32-charset-shiftjis 932)
  (w32-add-charset-info "jisx0201-latin" 'w32-charset-shiftjis 932)
  (w32-add-charset-info "jisx0201-katakana" 'w32-charset-shiftjis 932)
 -(w32-add-charset-info "jisx0208-sjis" 'w32-charset-shiftjis 932)
  (w32-add-charset-info "ksc5601.1987" 'w32-charset-hangeul 949)
  (w32-add-charset-info "big5" 'w32-charset-chinesebig5 950)
  (w32-add-charset-info "gb2312" 'w32-charset-gb2312 936)
        (w32-add-charset-info "iso8859-5" 'w32-charset-russian 28595)
        (w32-add-charset-info "tis620" 'w32-charset-thai 874)
        (w32-add-charset-info "ksc5601.1992" 'w32-charset-johab 1361)
 -      (w32-add-charset-info "mac" 'w32-charset-mac nil)))
 +      (w32-add-charset-info "mac-roman" 'w32-charset-mac 10000)))
  (if (boundp 'w32-unicode-charset-defined)
      (progn
        (w32-add-charset-info "unicode" 'w32-charset-unicode t)
        (w32-add-charset-info "iso10646-1" 'w32-charset-unicode t))
 -  ;; If unicode windows charset is not defined, use ansi fonts.
 -  (w32-add-charset-info "iso10646-1" 'w32-charset-ansi t))
 +  (w32-add-charset-info "iso10646-1" 'w32-charset-default t))
 +;;   ;; If unicode windows charset is not defined, use ansi fonts.
 +;;   (w32-add-charset-info "iso10646-1" 'w32-charset-ansi t))
 +
 +;; Prefered names
 +(w32-add-charset-info "big5-0" 'w32-charset-chinesebig5 950)
 +(w32-add-charset-info "gb2312.1980-0" 'w32-charset-gb2312 936)
 +(w32-add-charset-info "jisx0208-sjis" 'w32-charset-shiftjis 932)
 +(w32-add-charset-info "ksc5601.1987-0" 'w32-charset-hangeul 949)
 +(w32-add-charset-info "tis620-0" 'w32-charset-thai 874)
  (w32-add-charset-info "iso8859-1" 'w32-charset-ansi 1252)
  
  (make-obsolete-variable 'w32-enable-italics
diff --combined lisp/wid-edit.el
index ee15211f3916c2d37760a116b45b10fbd1ff3085,2e11b6557529407d524c79845f258d7251894787..8be7e158dad1b7677cadd43f4faa34920ee0340d
@@@ -1,7 -1,7 +1,7 @@@
  ;;; wid-edit.el --- Functions for creating and using widgets -*-byte-compile-dynamic: t;-*-
  ;;
  ;; Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003,
- ;;   2004, 2005, 2006 Free Software Foundation, Inc.
+ ;;   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  ;;
  ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
  ;; Maintainer: FSF
@@@ -275,14 -275,15 +275,15 @@@ minibuffer.
                     keys
                     (char 0)
                     (arg 1))
-                (while (not (or (and (>= char ?0) (< char next-digit))
+                (while (not (or (and (integerp char)
+                                     (>= char ?0) (< char next-digit))
                                 (eq value 'keyboard-quit)))
                   ;; Unread a SPC to lead to our new menu.
                   (setq unread-command-events (cons ?\s unread-command-events))
                   (setq keys (read-key-sequence title))
                   (setq value
                         (lookup-key overriding-terminal-local-map keys t)
-                        char (string-to-char (substring keys 1)))
+                        char (aref keys 1))
                   (cond ((eq value 'scroll-other-window)
                          (let ((minibuffer-scroll-window
                                 (get-buffer-window buf)))
@@@ -2997,43 -2998,6 +2998,43 @@@ as the value.
    :complete-function 'ispell-complete-word
    :prompt-history 'widget-string-prompt-value-history)
  
 +(eval-when-compile (defvar widget))
 +
 +(defun widget-string-complete ()
 +  "Complete contents of string field.
 +Completions are taken from the :completion-alist property of the
 +widget.  If that isn't a list, it's evalled and expected to yield a list."
 +  (interactive)
 +  (let* ((prefix (buffer-substring-no-properties (widget-field-start widget)
 +                                               (point)))
 +       (completion-ignore-case (widget-get widget :completion-ignore-case))
 +       (alist (widget-get widget :completion-alist))
 +       (_ (unless (listp alist)
 +            (setq alist (eval alist))))
 +       (completion (try-completion prefix alist)))
 +    (cond ((eq completion t)
 +         (when completion-ignore-case
 +           ;; Replace field with completion in case its case is different.
 +           (delete-region (widget-field-start widget)
 +                          (widget-field-end widget))
 +           (insert-and-inherit (car (assoc-ignore-case prefix alist))))
 +         (message "Only match"))
 +        ((null completion)
 +         (error "No match"))
 +        ((not (eq t (compare-strings prefix nil nil completion nil nil 
 +                                     completion-ignore-case)))
 +         (when completion-ignore-case
 +           ;; Replace field with completion in case its case is different.
 +           (delete-region (widget-field-start widget)
 +                          (widget-field-end widget))
 +           (insert-and-inherit completion)))
 +        (t
 +         (message "Making completion list...")
 +         (with-output-to-temp-buffer "*Completions*"
 +           (display-completion-list
 +            (all-completions prefix alist nil)))
 +         (message "Making completion list...done")))))
 +
  (define-widget 'regexp 'string
    "A regular expression."
    :match 'widget-regexp-match
@@@ -3190,13 -3154,16 +3191,13 @@@ It reads a directory name from an edita
                       (interactive)
                       (lisp-complete-symbol 'boundp))
    :tag "Variable")
 -\f
 -(defvar widget-coding-system-prompt-value-history nil
 -  "History of input to `widget-coding-system-prompt-value'.")
  
  (define-widget 'coding-system 'symbol
    "A MULE coding-system."
    :format "%{%t%}: %v"
    :tag "Coding system"
    :base-only nil
 -  :prompt-history 'widget-coding-system-prompt-value-history
 +  :prompt-history 'coding-system-value-history
    :prompt-value 'widget-coding-system-prompt-value
    :action 'widget-coding-system-action
    :complete-function (lambda ()
@@@ -3436,7 -3403,7 +3437,7 @@@ To use this type, you must define :matc
                           (aref value 0)
                         value))
    :match (lambda (widget value)
 -         (char-valid-p value)))
 +         (characterp value)))
  
  (define-widget 'list 'group
    "A Lisp list."
diff --combined make-dist
index 043faae93b8931c0d54184df292771d3edd4e8c0,1781746f75c1a526d09dba510e82a67bd61f18f6..534015b6ffa7669f5e9d87990d176ec0dae52cdd
+++ b/make-dist
@@@ -7,7 -7,7 +7,7 @@@
  #### you should make sure that this script will include it.
  
  # Copyright (C) 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
- #   2006  Free Software Foundation, Inc.
+ #   2006, 2007  Free Software Foundation, Inc.
  #
  # This file is part of GNU Emacs.
  #
@@@ -317,7 -317,7 +317,7 @@@ for subdir in lisp site-lisp lispref li
              leim/SKK-DIC leim/ja-dic leim/quail \
              src src/m src/s src/bitmaps lib-src oldXMenu lwlib \
              nt nt/inc nt/inc/sys nt/inc/arpa nt/inc/netinet nt/icons \
 -            etc etc/e \
 +            etc etc/charsets etc/e \
              etc/images etc/images/ezimage etc/images/gnus etc/images/gud \
              etc/images/icons etc/images/low-color etc/images/mail \
              etc/images/smilies etc/tree-widget etc/tree-widget/default \
@@@ -572,7 -572,7 +572,7 @@@ echo "Making links to \`etc'
  ### Don't distribute gfdl.1, since no man page references it.
  (cd etc
   files=`ls -d * | grep -v CVS | grep -v RCS | grep -v 'Old' | grep -v '^e$' \
 -        | grep -v '^images$' | grep -v '^tree-widget$'`
 +        | grep -v '^charsets$' | grep -v '^images$' | grep -v '^tree-widget$'`
   ln $files ../${tempdir}/etc
   ## If we ended up with a symlink, or if we did not get anything
   ## due to a cross-device symlink, copy the file.
   rm -f DOC* *~ \#*\# *.dvi *.log *.orig *.rej *,v =* core
   rm -f TAGS)
  
 +echo "Making links to \`etc/charsets'"
 +(cd etc/charsets
 + ln `ls -d * | grep -v CVS | grep -v RCS` ../../${tempdir}/etc/charsets
 + cd ../../${tempdir}/etc/charsets
 + rm -f *~ \#*\# *,v =* core)
 +
  echo "Making links to \`etc/e'"
  (cd etc/e
   ln `ls -d * | grep -v CVS | grep -v RCS` ../../${tempdir}/etc/e
diff --combined src/.gdbinit
index aa6ec1bfe590f66a24d8d052ebbe6adb67889af5,008305ca252d97daf5e0df054e78c72403bf19cb..723f8f6b21c99f2adc9f7d9e81928db67dd69e45
@@@ -1,5 -1,5 +1,5 @@@
  # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001,
- #   2004, 2005, 2006 Free Software Foundation, Inc.
+ #   2002, 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  #
  # This file is part of GNU Emacs.
  #
@@@ -158,7 -158,8 +158,8 @@@ define pp
    printf " SZ=%d\n", $t->gap_size
  end
  document ppt
- Print point, beg, end, narrow, and gap for current buffer.
+ Print current buffer's point and boundaries.
+ Prints values of point, beg, end, narrow, and gap for current buffer.
  end
  
  # Print out iterator given as first arg
@@@ -312,7 -313,7 +313,7 @@@ define pcursor
    printf "y=%d x=%d vpos=%d hpos=%d", $cp->y, $cp->x, $cp->vpos, $cp->hpos
  end
  document pcursorx
- Pretty print a window cursor
+ Pretty print a window cursor.
  end
  
  define pcursor
    printf "\n"
  end
  document pcursor
- Pretty print the output_cursor
+ Pretty print the output_cursor.
  end
  
  define pwinx
  end
  document pwinx
  Pretty print a window structure.
- Takes one argument, a pointer to a window structure
+ Takes one argument, a pointer to a window structure.
  end
  
  define pwin
@@@ -447,7 -448,7 +448,7 @@@ define pg
  end
  document pgx
  Pretty print a glyph structure.
- Takes one argument, a pointer to a glyph structure
+ Takes one argument, a pointer to a glyph structure.
  end
  
  define pg
@@@ -532,7 -533,8 +533,8 @@@ define xvectyp
    echo \n
  end
  document xvectype
- Print the size or vector subtype of $, assuming it is a vector or pseudovector.
+ Print the size or vector subtype of $.
+ This command assumes that $ is a vector or pseudovector.
  end
  
  define xmisctype
    echo \n
  end
  document xmisctype
Print the specific type of $, assuming it is some misc type.
Assume that $ is some misc type and print its specific type.
  end
  
  define xint
    print $int
  end
  document xint
- Print $, assuming it is an Emacs Lisp integer.  This gets the sign right.
+ Print $ as an Emacs Lisp integer.  This gets the sign right.
  end
  
  define xptr
    print (void *) $ptr
  end
  document xptr
- Print the pointer portion of $, assuming it is an Emacs Lisp value.
+ Print the pointer portion of an Emacs Lisp value in $.
  end
  
  define xmarker
    print (struct Lisp_Marker *) $ptr
  end
  document xmarker
- Print $ as a marker pointer, assuming it is an Emacs Lisp marker value.
+ Print $ as a marker pointer.
+ This command assumes that $ is an Emacs Lisp marker value.
  end
  
  define xoverlay
    print (struct Lisp_Overlay *) $ptr
  end
  document xoverlay
- Print $ as a overlay pointer, assuming it is an Emacs Lisp overlay value.
+ Print $ as a overlay pointer.
+ This command assumes that $ is an Emacs Lisp overlay value.
  end
  
  define xmiscfree
    print (struct Lisp_Free *) $ptr
  end
  document xmiscfree
- Print $ as a misc free-cell pointer, assuming it is an Emacs Lisp Misc value.
+ Print $ as a misc free-cell pointer.
+ This command assumes that $ is an Emacs Lisp Misc value.
  end
  
  define xintfwd
    print (struct Lisp_Intfwd *) $ptr
  end
  document xintfwd
- Print $ as an integer forwarding pointer, assuming it is an Emacs Lisp Misc value.
+ Print $ as an integer forwarding pointer.
+ This command assumes that $ is an Emacs Lisp Misc value.
  end
  
  define xboolfwd
    print (struct Lisp_Boolfwd *) $ptr
  end
  document xboolfwd
- Print $ as a boolean forwarding pointer, assuming it is an Emacs Lisp Misc value.
+ Print $ as a boolean forwarding pointer.
+ This command assumes that $ is an Emacs Lisp Misc value.
  end
  
  define xobjfwd
    print (struct Lisp_Objfwd *) $ptr
  end
  document xobjfwd
- Print $ as an object forwarding pointer, assuming it is an Emacs Lisp Misc value.
+ Print $ as an object forwarding pointer.
+ This command assumes that $ is an Emacs Lisp Misc value.
  end
  
  define xbufobjfwd
    print (struct Lisp_Buffer_Objfwd *) $ptr
  end
  document xbufobjfwd
- Print $ as a buffer-local object forwarding pointer, assuming it is an Emacs Lisp Misc value.
+ Print $ as a buffer-local object forwarding pointer.
+ This command assumes that $ is an Emacs Lisp Misc value.
  end
  
  define xkbobjfwd
    print (struct Lisp_Kboard_Objfwd *) $ptr
  end
  document xkbobjfwd
- Print $ as a kboard-local object forwarding pointer, assuming it is an Emacs Lisp Misc value.
+ Print $ as a kboard-local object forwarding pointer.
+ This command assumes that $ is an Emacs Lisp Misc value.
  end
  
  define xbuflocal
    print (struct Lisp_Buffer_Local_Value *) $ptr
  end
  document xbuflocal
- Print $ as a buffer-local-value pointer, assuming it is an Emacs Lisp Misc value.
+ Print $ as a buffer-local-value pointer.
+ This command assumes that $ is an Emacs Lisp Misc value.
  end
  
  define xsymbol
@@@ -673,7 -684,8 +684,8 @@@ define xproces
    echo \n
  end
  document xprocess
- Print the address of the struct Lisp_process which the Lisp_Object $ points to.
+ Print the address of the struct Lisp_process to which $ points.
+ This command assumes that $ is a Lisp_Object.
  end
  
  define xframe
    echo \n
  end
  document xframe
- Print $ as a frame pointer, assuming it is an Emacs Lisp frame value.
+ Print $ as a frame pointer.
+ This command assumes $ is an Emacs Lisp frame value.
  end
  
  define xcompiled
    output ($->contents[0])@($->size & 0xff)
  end
  document xcompiled
- Print $ as a compiled function pointer, assuming it is an Emacs Lisp compiled value.
+ Print $ as a compiled function pointer.
+ This command assumes that $ is an Emacs Lisp compiled value.
  end
  
  define xwindow
@@@ -721,7 -735,8 +735,8 @@@ define xwinconfi
    print (struct save_window_data *) $ptr
  end
  document xwinconfig
- Print $ as a window configuration pointer, assuming it is an Emacs Lisp window configuration value.
+ Print $ as a window configuration pointer.
+ This command assumes that $ is an Emacs Lisp window configuration value.
  end
  
  define xsubr
@@@ -739,7 -754,7 +754,7 @@@ define xchartabl
    print (struct Lisp_Char_Table *) $ptr
    printf "Purpose: "
    xprintsym $->purpose
 -  printf "  %d extra slots", ($->size & 0x1ff) - 388
 +  printf "  %d extra slots", ($->size & 0x1ff) - 68
    echo \n
  end
  document xchartable
@@@ -766,8 -781,8 +781,8 @@@ define xbuffe
    echo \n
  end
  document xbuffer
- Set $ as a buffer pointer, assuming it is an Emacs Lisp buffer value.
Print the name of the buffer.
+ Set $ as a buffer pointer and the name of the buffer.
This command assumes $ is an Emacs Lisp buffer value.
  end
  
  define xhashtable
    print (struct Lisp_Hash_Table *) $ptr
  end
  document xhashtable
- Set $ as a hash table pointer, assuming it is an Emacs Lisp hash table value.
+ Set $ as a hash table pointer.
+ This command assumes that $ is an Emacs Lisp hash table value.
  end
  
  define xcons
    echo \n
  end
  document xcons
- Print the contents of $, assuming it is an Emacs Lisp cons.
+ Print the contents of $ as an Emacs Lisp cons.
  end
  
  define nextcons
  end
  document nextcons
  Print the contents of the next cell in a list.
- This assumes that the last thing you printed was a cons cell contents
+ This command assumes that the last thing you printed was a cons cell contents
  (type struct Lisp_Cons) or a pointer to one.
  end
  define xcar
    print/x ($type == Lisp_Cons ? ((struct Lisp_Cons *) $ptr)->car : 0)
  end
  document xcar
Print the car of $, assuming it is an Emacs Lisp pair.
Assume that $ is an Emacs Lisp pair and print its car.
  end
  
  define xcdr
    print/x ($type == Lisp_Cons ? ((struct Lisp_Cons *) $ptr)->u.cdr : 0)
  end
  document xcdr
Print the cdr of $, assuming it is an Emacs Lisp pair.
Assume that $ is an Emacs Lisp pair and print its cdr.
  end
  
  define xlist
@@@ -976,29 -992,6 +992,29 @@@ document xprintsy
    Print argument as a symbol.
  end
  
 +define xcoding
 +  set $tmp = (struct Lisp_Hash_Table *) ((Vcoding_system_hash_table & $valmask) | gdb_data_seg_bits)
 +  set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & $valmask) | gdb_data_seg_bits)
 +  set $name = $tmp->contents[$arg0 * 2]
 +  print $name
 +  pr
 +  print $tmp->contents[$arg0 * 2 + 1]
 +  pr
 +end
 +document xcoding
 +  Print the name and attributes of coding system that has ID (argument).
 +end
 +
 +define xcharset
 +  set $tmp = (struct Lisp_Hash_Table *) ((Vcharset_hash_table & $valmask) | gdb_data_seg_bits)
 +  set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & $valmask) | gdb_data_seg_bits)
 +  p $tmp->contents[$arg0->hash_index * 2]
 +  pr
 +end
 +document xcharset
 +  Print the name of charset that has ID (argument).
 +end
 +
  define xbacktrace
    set $bt = backtrace_list
    while $bt
@@@ -1030,7 -1023,7 +1046,7 @@@ define whic
    set debug_print (which_symbols ($arg0))
  end
  document which
-   Print symbols which references a given lisp object,
+   Print symbols which references a given lisp object
    either as its symbol value or symbol function.
  end
  
diff --combined src/ChangeLog
index 717e4cdf963d47cad0faca28a09381eadd656128,80d9d85eff766f3f455dd9fc126a918c08a3998f..208084ff12aa9733178d4852462aefc27151b852
+ 2007-01-24  Kim F. Storm  <storm@cua.dk>
+       * keymap.c (describe_map): Don't consider prefix keys to be shadowed.
+ 2007-01-23  Juanma Barranquero  <lekktu@gmail.com>
+       * editfns.c (Finsert_char): Doc fix.
+       (Fget_internal_run_time, Fdecode_time): Fix typos in docstrings.
+ 2007-01-22  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * macselect.c [TARGET_API_MAC_CARBON] (mac_do_receive_drag): Don't
+       pass keyboard modifiers to mac_store_drag_event, but put them as
+       kEventParamKeyModifiers Apple event parameter.
+ 2007-01-21  Chong Yidong  <cyd@stupidchicken.com>
+       * xdisp.c (try_window): Revert previous change.
+       * dispnew.c (update_text_area): Revert 2006-09-17 change.
+       Always redraw non-mode-line rows with mouse-face.
+ 2007-01-20  Chong Yidong  <cyd@stupidchicken.com>
+       * xdisp.c (try_window): Clear mouse-face highlights first.
+       * window.c (set_window_buffer): Revert 2006-11-22 change.
+ 2007-01-20  Eli Zaretskii  <eliz@gnu.org>
+       * .gdbinit (ppt, xtype, xmisctype, xint, xptr, xmarker, xframe)
+       (xbuffer, xcons, xcar, xcdr): Fix doc strings.
+ 2007-01-20  Chong Yidong  <cyd@stupidchicken.com>
+       * keyboard.c (read_key_sequence): Extract local map only if the
+       given position is in an accessible buffer region.
+ 2007-01-19  Nick Roberts  <nickrob@snap.net.nz>
+       * .gdbinit: Reformat documentation so that first sentence
+       displays properly with "help user-defined" (like apropos).
+ 2007-01-18  Bruno Haible  <bruno@clisp.org>  (tiny change)
+       * epaths.in: Move PATH_DOC from local/info to local/share/info.
+ 2007-01-15  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * macmenu.c (create_and_show_dialog) [TARGET_API_MAC_CARBON]:
+       Create movable modal window instead of movable alert window.
+       (create_and_show_dialog) [!MAC_OSX]: Use DeactivateControl instead
+       of DisableControl.
+       * macselect.c (Fmac_resume_apple_event): Set error number when
+       descriptor type of reply is non-null.
+ 2007-01-14  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * macmenu.c (create_and_show_dialog) [TARGET_API_MAC_CARBON]: Use
+       DisableControl for disabled items.  Set default button to first
+       enabled one.  Use icon of application in execution.
+ 2007-01-13  Eli Zaretskii  <eliz@gnu.org>
+       * process.c (Fdelete_process, Fprocess_id, sigchld_handler):
+       Copy PID into EMACS_INT to avoid GCC warnings.
+       * fns.c (maybe_resize_hash_table): Copy new size of hash table
+       into EMACS_INT to avoid GCC warnings.
+       * editfns.c (Fuser_uid, Fuser_real_uid): Copy values returned by
+       geteuid and getuid into EMACS_INT to avoid GCC warnings.
+       * dired.c (Ffile_attributes): Fix last change.
+ 2007-01-12  Eli Zaretskii  <eliz@gnu.org>
+       * dired.c (Ffile_attributes): Copy some members of `struct stat'
+       into int's to avoid GCC warnings about limited range of short in
+       arguments to FIXNUM_OVERFLOW_P.
+ 2007-01-12  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * macmenu.c (HAVE_DIALOGS): Define if TARGET_API_MAC_CARBON.
+       (mac_handle_dialog_event, install_dialog_event_handler)
+       (create_and_show_dialog) [TARGET_API_MAC_CARBON]: New functions.
+       (DIALOG_LEFT_MARGIN, DIALOG_TOP_MARGIN, DIALOG_RIGHT_MARGIN)
+       (DIALOG_BOTTOM_MARGIN, DIALOG_MIN_INNER_WIDTH)
+       (DIALOG_MAX_INNER_WIDTH, DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE)
+       (DIALOG_BUTTON_BUTTON_VERTICAL_SPACE, DIALOG_BUTTON_MIN_WIDTH)
+       (DIALOG_TEXT_MIN_HEIGHT, DIALOG_TEXT_BUTTONS_VERTICAL_SPACE)
+       (DIALOG_ICON_WIDTH, DIALOG_ICON_HEIGHT, DIALOG_ICON_LEFT_MARGIN)
+       (DIALOG_ICON_TOP_MARGIN) [TARGET_API_MAC_CARBON]: New macros.
+       (mac_dialog) [TARGET_API_MAC_CARBON]: Remove function.
+       (mac_dialog_show) [TARGET_API_MAC_CARBON]: Use create_and_show_dialog.
+       * macterm.c (x_free_frame_resources) [USE_CG_DRAWING]: Call
+       mac_prepare_for_quickdraw.
+       (quit_char, make_ctrl_char) [TARGET_API_MAC_CARBON]: Move externs
+       outside #ifdef MAC_OSX.
+       (mac_quit_char_key_p) [TARGET_API_MAC_CARBON]: Move function
+       outside #ifdef MAC_OSX.
+       (mac_check_bundle) [MAC_OSX]: Remove unused function.
+       * macterm.h (mac_quit_char_key_p): Move extern outside #ifdef MAC_OSX.
+       (HOURGLASS_WIDTH, HOURGLASS_HEIGHT): Parenthesize definitions.
+ 2007-01-11  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
+       * alloc.c (BLOCK_INPUT_ALLOC, UNBLOCK_INPUT_ALLOC): Use pthread_equal,
+       block/unblock SIGIO.
+ 2007-01-10  Stefan Monnier  <monnier@iro.umontreal.ca>
+       * editfns.c (Fformat): Allow integer-format to work with floats of size
+       larger than most-positive-fixnum (but still smaller than MAXINT).
+       * dired.c (Ffile_attributes): Use floats for large uids/gids.
+ 2007-01-09  Eli Zaretskii  <eliz@gnu.org>
+       * emacs.c (syms_of_emacs) <path-separator>: Doc fix.
+ 2007-01-09  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * callproc.c (Fcall_process_region) [HAVE_MKSTEMP]: Add BLOCK_INPUT
+       around mkstemp.
+       * image.c (XDrawLine) [MAC_OS]: Remove macro.
+       (XCreateGC_pixmap) [!HAVE_NTGUI]: Likewise.
+       (x_disable_image) [!HAVE_NTGUI]: Use XCreateGC instead of
+       XCreateGC_pixmap.
+       * macgui.h (Display): Typedef to opaque type.
+       * macmenu.c (mac_dialog_modal_filter) [MAC_OSX]: New function.
+       (Fx_popup_dialog) [MAC_OSX]: Use standard alert if called from
+       Fmessage_box, Fyes_or_no_p, or Fy_or_n_p.
+       [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030] (menu_quit_handler):
+       Use mac_quit_char_key_p.
+       * macterm.c (XDrawLine): Rename from mac_draw_line_to_pixmap.
+       (XCreateGC): Change type of 2nd argument to void *.
+       (XFreeGC) [USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+       Fix last change.
+       (mac_to_emacs_modifiers): Change return type to int.
+       [USE_CARBON_EVENTS] (mac_event_to_emacs_modifiers): Likewise.
+       (mac_mapped_modifiers): New function.
+       (XTread_socket): Use it.
+       [USE_TSM] (mac_handle_text_input_event): Likewise.
+       (do_window_update) [USE_CG_DRAWING]: Call mac_prepare_for_quickdraw.
+       (mac_quit_char_modifiers, mac_quit_char_keycode) [MAC_OSX]:
+       Remove variables.
+       (mac_determine_quit_char_modifiers, init_quit_char_handler)
+       [MAC_OSX]: Remove functions.
+       (make_ctrl_char) [MAC_OSX]: Add extern.
+       (mac_quit_char_key_p) [MAC_OSX]: New function.
+       (mac_initialize) [MAC_OSX]: Don't call init_quit_char_handler.
+       * macterm.h (FONT_MAX_WIDTH): Remove unused macro.
+       (XCreateGC): Change type in extern.
+       (XDrawLine): Rename from mac_draw_line_to_pixmap.
+       (mac_quit_char_key_p) [MAC_OSX]: Add extern.
+ 2007-01-08  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
+       * keyboard.c (init_keyboard): Initialize interrupt_input_blocked and
+       interrupt_input_pending.
+       * xterm.h (x_display_info): New: net_supported_atoms,
+       nr_net_supported_atoms and net_supported_window.
+       * xterm.c (last_user_time): New variable.
+       (handle_one_xevent): Set last_user_time from events that have Time.
+       Set net_supported_window to 0 when reparented.
+       (wm_supports): New function.
+       (do_ewmh_fullscreen): Use wm_supports to check for _NET_WM_STATE.
+       (x_term_init): Initialize net_supported_atoms, nr_net_supported_atoms
+       and net_supported_window.
+ 2007-01-05  Kim F. Storm  <storm@cua.dk>
+       * indent.c (Fvertical_motion): Fix it overshoot check for overlay
+       strings without embedded newlines immediately followed by newline.
+ 2007-01-05  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+       * editfns.c (Fformat_time_string, Fdecode_time, Fencode_time)
+       (Fcurrent_time_string, Fcurrent_time_zone): Add BLOCK_INPUT around
+       gmtime/localtime/emacs_memftimeu/mktime.
+       * mac.c (Fmac_set_file_creator): Use MAC_EMACS_CREATOR_CODE
+       instead of 'EMAx'.
+       [!MAC_OSX] (sys_open, sys_creat, sys_fopen): Likewise.
+       * macgui.h (struct _XGC) [USE_CG_DRAWING
+       && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: New members cg_fore_color
+       and cg_back_color.
+       * macmenu.c (Vshow_help_function) [TARGET_API_MAC_CARBON]: Add extern.
+       (restore_show_help_function, menu_target_item_handler)
+       [TARGET_API_MAC_CARBON]: New functions.
+       (install_menu_target_item_handler): New function.
+       (add_menu_item) [TARGET_API_MAC_CARBON]: Set help string as menu
+       item property.
+       * macterm.c (CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR)
+       (CG_SET_FILL_COLOR_WITH_GC_FOREGROUND)
+       (CG_SET_FILL_COLOR_WITH_GC_BACKGROUND)
+       (CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR)
+       (CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND): New macros.
+       (mac_cg_color_space_rgb) [USE_CG_DRAWING]: New variable.
+       (mac_cg_color_black) [USE_CG_DRAWING
+       && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: New variable.
+       (init_cg_color) [USE_CG_DRAWING]: New function.
+       (mac_draw_line, mac_draw_rectangle) [USE_CG_DRAWING]: Use
+       CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND instead of CG_SET_STROKE_COLOR.
+       (mac_erase_rectangle, mac_clear_window, mac_draw_cg_image)
+       (mac_fill_rectangle, mac_draw_image_string_cg) [USE_CG_DRAWING]:
+       Use CG_SET_FILL_COLOR_WITH_GC_FOREGROUND or
+       CG_SET_FILL_COLOR_WITH_GC_BACKGROUND instead of CG_SET_FILL_COLOR.
+       (mac_draw_string_common) [MAC_OSX && USE_ATSUI]: Likewise.
+       (XCreateGC, XFreeGC, XSetForeground, XSetBackground) [USE_CG_DRAWING
+       && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Use gc->cg_fore_color and/or
+       gc->cg_back_color.
+       (install_drag_handler, remove_drag_handler): Make extern.
+       (install_menu_target_item_handler): Add extern.
+       (install_window_handler): Call install_menu_target_item_handler.
+       [MAC_OS8] (main): Use MAC_EMACS_CREATOR_CODE instead of 'EMAx'.
+       (mac_initialize) [USE_CG_DRAWING]: Call init_cg_color.
+       * macterm.h (MAC_EMACS_CREATOR_CODE): New enumerator.
+ 2007-01-04  Juanma Barranquero  <lekktu@gmail.com>
+       * window.c (Fwindow_end): Fix use of >= operator.
+ 2007-01-03  Richard Stallman  <rms@gnu.org>
+       * window.c (Fwindow_end): Check BUF_OVERLAY_MODIFF like BUF_MODIFF.
+ 2007-01-02  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
+       * gtkutil.h (xg_menu_item_cb_data_): Remove highlight_id and
+       unhighlight_id.
+       * gtkutil.c (menuitem_highlight_callback): Invoked widget is the
+       parent of the menu item.  Get menu item widget from event.
+       (xg_create_one_menuitem, xg_update_menu_item): highlight_id and
+       unhighlight_id has been removed.
+       (create_menus): Connect enter/leave-notify-event to the menu instead
+       of individual items.
  2006-12-31  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
  
        * gtkutil.c (update_frame_tool_bar): Connect create-menu-proxy with
  
  2006-12-22  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
  
-       * macfns.c (mac_update_title_bar) [TARGET_API_MAC_CARBON]: Call
-       mac_update_proxy_icon also when buffer modification flag changed.
+       * macfns.c (mac_update_title_bar) [TARGET_API_MAC_CARBON]:
+       Call mac_update_proxy_icon also when buffer modification flag changed.
        [TARGET_API_MAC_CARBON] (mac_update_proxy_icon): Don't update alias,
        but compare FSRef/FSSpec of resolved alias.
  
        (Fmac_atsu_font_face_attributes) [USE_ATSUI]: New function.
        (syms_of_macfns) [USE_ATSUI]: Defsubr it.
  
-       * macselect.c [TARGET_API_MAC_CARBON] (mac_do_receive_drag): Use
-       mac_wakeup_from_rne instead of mac_post_mouse_moved_event.
+       * macselect.c [TARGET_API_MAC_CARBON] (mac_do_receive_drag):
+       Use mac_wakeup_from_rne instead of mac_post_mouse_moved_event.
  
        * macterm.c (mac_query_char_extents) [USE_ATSUI]: Don't call
        ATSUGetGlyphBounds if not necessary.
        (mac_load_query_font) [USE_ATSUI]: Use atsu_find_font_from_family_name.
        Don't get metrics for Latin-1 right half characters.
        (mac_load_query_font): Don't load font if space width is not positive.
-       [TARGET_API_MAC_CARBON] (mac_store_event_ref_as_apple_event): Use
-       mac_wakeup_from_rne instead of mac_post_mouse_moved_event.
+       [TARGET_API_MAC_CARBON] (mac_store_event_ref_as_apple_event):
+       Use mac_wakeup_from_rne instead of mac_post_mouse_moved_event.
        (XTread_socket): Call SelectWindow when unfocused frame is clicked.
  
        * macterm.h (mac_wakeup_from_rne) [TARGET_API_MAC_CARBON]: Add extern.
        * regex.c (re_error_msgid): Add an entry for REG_ERANGEX.
        (regex_compile): Return REG_ERANGEX if appropriate.
  
 -2004-10-22  Kenichi Handa  <handa@m17n.org>
 -
 -      * editfns.c (Ftranslate_region_internal): New function.
 -      (syms_of_editfns): Defsubr it.
 -
  2004-10-22  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
  
        * xfns.c (xic_create_xfontset): Initialize missing_list to NULL.
@@@ -26933,7 -27192,7 +27187,7 @@@ See ChangeLog.9 for earlier changes
  ;; End:
  
      Copyright (C) 2001, 2002, 2003, 2004, 2005,
-       2006 Free Software Foundation, Inc.
+       2006, 2007 Free Software Foundation, Inc.
    Copying and distribution of this file, with or without modification,
    are permitted provided the copyright notice and this notice are preserved.
  
diff --combined src/Makefile.in
index 87352d74830b25c2426ef9a2307099dadd08e69f,49fcbe8508fa81d7cff97cc1897e6aded09710a8..3e6d39246f625b6b8bdaea233ae4781739542c76
@@@ -1,6 -1,6 +1,6 @@@
  # Makefile for GNU Emacs.
  # Copyright (C) 1985, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001, 2002,
- #               2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ #               2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  # This file is part of GNU Emacs.
  
@@@ -51,7 -51,6 +51,7 @@@ LIBOBJS = @LIBOBJS
  dot = .
  dotdot = ${dot}${dot}
  lispsource = ${srcdir}/$(dot)$(dot)/lisp/
 +admindir = $(srcdir)/$(dot)$(dot)/admin/
  libsrc = $(dot)$(dot)/lib-src/
  etc = $(dot)$(dot)/etc/
  oldXMenudir = $(dot)$(dot)/oldXMenu/
@@@ -282,7 -281,7 +282,7 @@@ TOOLKIT_DEFINES 
  
  /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM
     since it may have -I options that should override those two.  */
 -ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${CFLAGS}
 +ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@
  .c.o:
        $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
  
@@@ -403,11 -402,6 +403,11 @@@ LIBXT=$(LIBW
  #endif
  #endif /* not USE_X_TOOLKIT */
  
 +#if HAVE_XFT
 +#undef LIB_X11_LIB
 +#define LIB_X11_LIB @XFT_LIBS@
 +#endif /* HAVE_XFT */
 +
  #if HAVE_XPM
  #ifndef LIBXPM
  #define LIBXPM -lXpm
@@@ -581,27 -575,10 +581,27 @@@ emacsapp = $(PWD)/$(mac)Emacs.app
  emacsappsrc = ${srcdir}/../mac/Emacs.app/
  #endif
  
 +#ifdef HAVE_WINDOW_SYSTEM
 +#ifdef USE_FONT_BACKEND
 +FONTSRC = font.h
 +#ifdef HAVE_X_WINDOWS
 +#if defined (HAVE_XFT)
 +FONTOBJ = font.o xfont.o ftfont.o xftfont.o ftxfont.o
 +#elif defined (HAVE_FREETYPE)
 +FONTOBJ = font.o xfont.o ftfont.o ftxfont.o
 +#else /* ! defined (HAVE_XFT) && ! defined (HAVE_FREETYPE) */
 +FONTOBJ = font.o xfont.o
 +#endif /* ! defined (HAVE_XFT) && ! defined (HAVE_FREETYPE) */
 +#else /* ! HAVE_X_WINDOWS */
 +FONTOBJ = font.o
 +#endif /* ! HAVE_X_WINDOWS */
 +#endif /* USE_FONT_BACKEND */
 +#endif /* HAVE_WINDOW_SYSTEM */
 +
  /* lastfile must follow all files
     whose initialized data areas should be dumped as pure by dump-emacs.  */
  obj=    dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \
 -      charset.o coding.o category.o ccl.o \
 +      charset.o coding.o category.o ccl.o character.o chartab.o \
        cm.o term.o xfaces.o $(XOBJ) $(GTK_OBJ)\
        emacs.o keyboard.o macros.o keymap.o sysdep.o \
        buffer.o filelock.o insdel.o marker.o \
        process.o callproc.o \
        region-cache.o sound.o atimer.o \
        doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \
 -      $(MSDOS_OBJ) $(MAC_OBJ) $(CYGWIN_OBJ)
 +      $(MSDOS_OBJ) $(MAC_OBJ) $(CYGWIN_OBJ) $(FONTOBJ)
  
  /* Object files used on some machine or other.
     These go in the DOC file on all machines
@@@ -622,7 -599,7 +622,7 @@@ SOME_MACHINE_OBJECTS = sunfns.o dosfns.
    xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \
    mac.o macterm.o macfns.o macmenu.o macselect.o fontset.o \
    w32.o w32bdf.o w32console.o w32fns.o w32heap.o w32inevt.o \
 -  w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o
 +  w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o $(FONTOBJ)
  
  
  #ifdef TERMINFO
@@@ -746,7 -723,6 +746,7 @@@ lisp= 
        ${lispsource}buff-menu.elc \
        ${lispsource}button.elc \
        ${lispsource}emacs-lisp/byte-run.elc \
 +      ${lispsource}composite.elc \
        ${lispsource}cus-face.elc \
        ${lispsource}cus-start.elc \
        ${lispsource}custom.elc \
        ${lispsource}international/mule-conf.el \
        ${lispsource}international/mule-cmds.elc \
        ${lispsource}international/characters.elc \
 -      ${lispsource}international/ucs-tables.elc \
 -      ${lispsource}international/utf-8.elc \
 -      ${lispsource}international/utf-16.elc \
 -      ${lispsource}international/latin-1.el \
 -      ${lispsource}international/latin-2.el \
 -      ${lispsource}international/latin-3.el \
 -      ${lispsource}international/latin-4.el \
 -      ${lispsource}international/latin-5.el \
 -      ${lispsource}international/latin-8.el \
 -      ${lispsource}international/latin-9.el \
 +      ${lispsource}international/charprop.el \
        ${lispsource}case-table.elc \
 -      ${lispsource}language/chinese.elc \
 -      ${lispsource}language/cyrillic.elc \
 -      ${lispsource}language/indian.elc \
 +      ${lispsource}language/chinese.el \
 +      ${lispsource}language/cyrillic.el \
 +      ${lispsource}language/indian.el \
        ${lispsource}language/devanagari.el \
        ${lispsource}language/kannada.el \
        ${lispsource}language/malayalam.el \
        ${lispsource}language/lao.el \
        ${lispsource}language/thai.el \
        ${lispsource}language/tibetan.elc \
 -      ${lispsource}language/vietnamese.elc \
 +      ${lispsource}language/vietnamese.el \
        ${lispsource}language/misc-lang.el \
        ${lispsource}language/utf-8-lang.el \
        ${lispsource}language/georgian.el \
@@@ -837,7 -822,6 +837,7 @@@ shortlisp= 
        ../lisp/buff-menu.elc \
        ../lisp/button.elc \
        ../lisp/emacs-lisp/byte-run.elc \
 +      ../lisp/composite.elc \
        ../lisp/cus-face.elc \
        ../lisp/cus-start.elc \
        ../lisp/custom.elc \
        ../lisp/international/mule-conf.el \
        ../lisp/international/mule-cmds.elc \
        ../lisp/international/characters.elc \
 -      ../lisp/international/ucs-tables.elc \
 -      ../lisp/international/utf-8.elc \
 -      ../lisp/international/utf-16.elc \
 -      ../lisp/international/latin-1.el \
 -      ../lisp/international/latin-2.el \
 -      ../lisp/international/latin-3.el \
 -      ../lisp/international/latin-4.el \
 -      ../lisp/international/latin-5.el \
 -      ../lisp/international/latin-8.el \
 -      ../lisp/international/latin-9.el \
        ../lisp/case-table.elc \
 -      ../lisp/language/chinese.elc \
 -      ../lisp/language/cyrillic.elc \
 -      ../lisp/language/indian.elc \
 +      ../lisp/language/chinese.el \
 +      ../lisp/language/cyrillic.el \
 +      ../lisp/language/indian.el \
        ../lisp/language/devanagari.el \
        ../lisp/language/kannada.el \
        ../lisp/language/malayalam.el \
        ../lisp/language/lao.el \
        ../lisp/language/thai.el \
        ../lisp/language/tibetan.elc \
 -      ../lisp/language/vietnamese.elc \
 +      ../lisp/language/vietnamese.el \
        ../lisp/language/misc-lang.el \
        ../lisp/language/utf-8-lang.el \
        ../lisp/language/georgian.el \
@@@ -938,7 -932,7 +938,7 @@@ SOME_MACHINE_LISP = ${dotdot}/lisp/mous
  LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) \
     LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
     LIBS_DEBUG $(GETLOADAVG_LIBS) $(GNULIB_VAR) LIB_MATH LIB_STANDARD \
 -   $(GNULIB_VAR)
 +   $(GNULIB_VAR) @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@
  
  /* Enable recompilation of certain other files depending on system type.  */
  
  #define OBJECTS_MACHINE
  #endif
  
 -RUN_TEMACS = ./temacs
 +#ifdef HAVE_SHM
 +RUN_TEMACS = `/bin/pwd`/temacs -nl
 +#else
 +RUN_TEMACS = `/bin/pwd`/temacs
 +#endif
  
  all: emacs${EXEEXT} OTHER_FILES
  
@@@ -963,7 -953,11 +963,7 @@@ emacs${EXEEXT}: temacs${EXEEXT} ${etc}D
        rm -f emacs${EXEEXT}
        ln temacs${EXEEXT} emacs${EXEEXT}
  #else
 -#ifdef HAVE_SHM
 -      LC_ALL=C $(RUN_TEMACS) -nl -batch -l loadup dump
 -#else /* ! defined (HAVE_SHM) */
        LC_ALL=C $(RUN_TEMACS) -batch -l loadup dump
 -#endif /* ! defined (HAVE_SHM) */
  #endif /* ! defined (CANNOT_DUMP) */
        -./emacs -q -batch -f list-load-path-shadows
  
@@@ -983,16 -977,6 +983,16 @@@ ${etc}DOC: ${libsrc}make-docfile${EXEEX
  ${libsrc}make-docfile${EXEEXT}:
        cd ${libsrc}; ${MAKE} ${MFLAGS} make-docfile${EXEEXT}
  
 +#ifdef HAVE_UNIDATA
 +UNIDATA=${admindir}unidata/UnicodeData.txt
 +#endif
 +
 +${lispsource}international/charprop.el: ${UNIDATA}
 +      RUNEMACS="$(RUN_TEMACS)"; \
 +      cd ${admindir}unidata; \
 +      $(MAKE) $(MFLAGS) \
 +        RUNEMACS="$${RUNEMACS}" DSTDIR=${lispsource}international
 +
  /* Some systems define this to cause parallel Make-ing.  */
  #ifndef MAKE_PARALLEL
  #define MAKE_PARALLEL
@@@ -1099,80 -1083,71 +1099,80 @@@ alloca.o: alloca.c blockinput.h atimer.
     it is so often changed in ways that do not require any recompilation
     and so rarely changed in ways that do require any.  */
  
 -abbrev.o: abbrev.c buffer.h window.h dispextern.h commands.h charset.h \
 +abbrev.o: abbrev.c buffer.h window.h dispextern.h commands.h character.h \
        syntax.h $(config_h)
  buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
 -   dispextern.h $(INTERVAL_SRC) blockinput.h atimer.h systime.h charset.h \
 +   dispextern.h $(INTERVAL_SRC) blockinput.h atimer.h systime.h character.h \
     $(config_h)
  callint.o: callint.c window.h commands.h buffer.h keymap.h \
     keyboard.h dispextern.h $(config_h)
  callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \
 -      process.h systty.h syssignal.h charset.h coding.h ccl.h msdos.h \
 +      process.h systty.h syssignal.h character.h coding.h ccl.h msdos.h \
          composite.h w32.h blockinput.h atimer.h systime.h
 -casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h \
 +casefiddle.o: casefiddle.c syntax.h commands.h buffer.h character.h \
 +   composite.h \
        charset.h keymap.h $(config_h)
  casetab.o: casetab.c buffer.h $(config_h)
 -category.o: category.c category.h buffer.h charset.h keymap.h $(config_h)
 -ccl.o: ccl.c ccl.h charset.h coding.h $(config_h)
 -charset.o: charset.c charset.h buffer.h coding.h composite.h disptab.h \
 -      $(config_h)
 -coding.o: coding.c coding.h ccl.h buffer.h charset.h intervals.h composite.h \
 +category.o: category.c category.h buffer.h charset.h keymap.h \
 +      character.h $(config_h)
 +ccl.o: ccl.c ccl.h charset.h character.h coding.h $(config_h)
 +character.o: character.c character.h buffer.h charset.h composite.h disptab.h \
 +   $(config.h)
 +charset.o: charset.c charset.h character.h buffer.h coding.h composite.h \
 +   disptab.h $(config_h)
 +chartab.o: charset.h character.h $(config.h)
 +coding.o: coding.c coding.h ccl.h buffer.h character.h charset.h intervals.h composite.h \
        window.h dispextern.h $(config_h)
  cm.o: cm.c cm.h termhooks.h $(config_h)
 -cmds.o: cmds.c syntax.h buffer.h charset.h commands.h window.h $(config_h) \
 +cmds.o: cmds.c syntax.h buffer.h character.h commands.h window.h $(config_h) \
        msdos.h dispextern.h keyboard.h keymap.h
  pre-crt0.o: pre-crt0.c
  ecrt0.o: ecrt0.c $(config_h)
        CRT0_COMPILE ${srcdir}/ecrt0.c
 -dired.o: dired.c commands.h buffer.h $(config_h) charset.h coding.h regex.h \
 -   systime.h blockinput.h
 +dired.o: dired.c commands.h buffer.h $(config_h) character.h charset.h \
 +   coding.h regex.h systime.h blockinput.h
  dispnew.o: dispnew.c  systty.h systime.h commands.h process.h frame.h \
     window.h buffer.h dispextern.h termchar.h termopts.h termhooks.h cm.h \
     disptab.h indent.h intervals.h \
 -   xterm.h blockinput.h atimer.h charset.h msdos.h composite.h keyboard.h \
 +   xterm.h blockinput.h atimer.h character.h msdos.h composite.h keyboard.h \
     $(config_h)
 -doc.o: doc.c $(config_h) epaths.h buffer.h keyboard.h keymap.h charset.h
 -doprnt.o: doprnt.c charset.h $(config_h)
 +doc.o: doc.c $(config_h) epaths.h buffer.h keyboard.h keymap.h character.h
 +doprnt.o: doprnt.c character.h $(config_h)
  dosfns.o: buffer.h termchar.h termhooks.h frame.h blockinput.h window.h \
     msdos.h dosfns.h dispextern.h charset.h coding.h $(config_h)
 -editfns.o: editfns.c window.h buffer.h systime.h $(INTERVAL_SRC) charset.h \
 +editfns.o: editfns.c window.h buffer.h systime.h $(INTERVAL_SRC) character.h \
     coding.h dispextern.h frame.h blockinput.h $(config_h)
  emacs.o: emacs.c commands.h systty.h syssignal.h blockinput.h process.h \
     termhooks.h buffer.h atimer.h systime.h $(INTERVAL_SRC) $(config_h) \
     window.h dispextern.h keyboard.h keymap.h
 -fileio.o: fileio.c window.h buffer.h systime.h $(INTERVAL_SRC) charset.h \
 +fileio.o: fileio.c window.h buffer.h systime.h $(INTERVAL_SRC) character.h \
     coding.h msdos.h dispextern.h blockinput.h $(config_h)
 -filelock.o: filelock.c buffer.h charset.h coding.h systime.h epaths.h $(config_h)
 +filelock.o: filelock.c buffer.h character.h charset.h coding.h systime.h \
 +   epaths.h $(config_h)
  filemode.o: filemode.c  $(config_h)
  frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
 -   blockinput.h atimer.h systime.h buffer.h charset.h fontset.h \
 +   blockinput.h atimer.h systime.h buffer.h character.h fontset.h \
     msdos.h dosfns.h dispextern.h w32term.h macterm.h $(config_h)
  fringe.o: fringe.c dispextern.h frame.h window.h buffer.h $(config_h)
 -fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h charset.h frame.h \
 -   keyboard.h $(config_h)
 +font.o: font.c dispextern.h frame.h window.h ccl.h character.h charset.h \
 +   font.h $(config_h)
 +ftfont.o: dispextern.h frame.h character.h charset.h font.h $(config_h)
 +fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h character.h \
 +   charset.h frame.h keyboard.h $(FONTSRC) $(config_h)
  getloadavg.o: getloadavg.c $(config_h)
  image.o: image.c frame.h window.h dispextern.h blockinput.h atimer.h \
     systime.h xterm.h w32term.h w32gui.h macterm.h macgui.h $(config_h)
  indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \
 -   termopts.h disptab.h region-cache.h charset.h composite.h dispextern.h \
 -   keyboard.h
 -insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h charset.h \
 +   termopts.h disptab.h region-cache.h character.h category.h composite.h \
 +   dispextern.h keyboard.h
 +insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h character.h \
     dispextern.h atimer.h systime.h region-cache.h $(config_h)
 -keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h charset.h \
 +keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h character.h \
     commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
     systty.h systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
     atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h $(config_h)
  keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
 -   atimer.h systime.h puresize.h charset.h intervals.h keymap.h window.h \
 +   atimer.h systime.h puresize.h character.h intervals.h keymap.h window.h \
     $(config_h)
  lastfile.o: lastfile.c  $(config_h)
  macros.o: macros.c window.h buffer.h commands.h macros.h keyboard.h \
@@@ -1181,36 -1156,34 +1181,36 @@@ malloc.o: malloc.c $(config_h
  gmalloc.o: gmalloc.c $(config_h)
  ralloc.o: ralloc.c $(config_h)
  vm-limit.o: vm-limit.c mem-limits.h $(config_h)
 -marker.o: marker.c buffer.h charset.h $(config_h)
 +marker.o: marker.c buffer.h character.h $(config_h)
  md5.o: md5.c md5.h $(config_h)
  minibuf.o: minibuf.c syntax.h dispextern.h frame.h window.h keyboard.h \
 -   buffer.h commands.h charset.h msdos.h $(INTERVAL_SRC) keymap.h $(config_h)
 +   buffer.h commands.h character.h msdos.h $(INTERVAL_SRC) keymap.h $(config_h)
  mktime.o: mktime.c $(config_h)
  msdos.o: msdos.c msdos.h dosfns.h systime.h termhooks.h dispextern.h frame.h \
 -   termopts.h termchar.h charset.h coding.h ccl.h disptab.h window.h \
 +   termopts.h termchar.h character.h coding.h ccl.h disptab.h window.h \
     keyboard.h intervals.h buffer.h commands.h blockinput.h $(config_h)
  process.o: process.c process.h buffer.h window.h termhooks.h termopts.h \
     commands.h syssignal.h systime.h systty.h syswait.h frame.h dispextern.h \
     blockinput.h atimer.h charset.h coding.h ccl.h msdos.h composite.h \
     keyboard.h $(config_h)
 -regex.o: regex.c syntax.h buffer.h $(config_h) regex.h category.h charset.h
 +regex.o: regex.c syntax.h buffer.h $(config_h) regex.h category.h character.h \
 +   charset.h
  region-cache.o: region-cache.c buffer.h region-cache.h $(config_h)
  scroll.o: scroll.c termchar.h dispextern.h frame.h msdos.h keyboard.h \
     $(config_h)
  search.o: search.c regex.h commands.h buffer.h region-cache.h syntax.h \
 -   blockinput.h atimer.h systime.h category.h charset.h composite.h \
 -   $(INTERVAL_SRC) $(config_h)
 +   blockinput.h atimer.h systime.h category.h character.h composite.h \
 +   $(INTERVAL_SRC) \
 +   $(config_h)
  strftime.o: strftime.c $(config_h)
 -syntax.o: syntax.c syntax.h buffer.h commands.h category.h charset.h \
 +syntax.o: syntax.c syntax.h buffer.h commands.h category.h character.h \
     composite.h keymap.h regex.h $(INTERVAL_SRC) $(config_h)
  sysdep.o: sysdep.c syssignal.h systty.h systime.h syswait.h blockinput.h \
     process.h dispextern.h termhooks.h termchar.h termopts.h \
     frame.h atimer.h window.h msdos.h dosfns.h keyboard.h  $(config_h)
  term.o: term.c termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \
 -   disptab.h dispextern.h keyboard.h charset.h coding.h ccl.h msdos.h \
 -   window.h keymap.h
 +   disptab.h dispextern.h keyboard.h character.h charset.h coding.h ccl.h \
 +   msdos.h window.h keymap.h
  termcap.o: termcap.c $(config_h)
  terminfo.o: terminfo.c $(config_h)
  tparam.o: tparam.c $(config_h)
@@@ -1226,32 -1199,23 +1226,32 @@@ widget.o: widget.c xterm.h frame.h disp
  window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
     termhooks.h disptab.h keyboard.h dispextern.h msdos.h composite.h \
     keymap.h blockinput.h $(INTERVAL_SRC) xterm.h w32term.h macterm.h $(config_h)
 -xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h coding.h \
 -   termchar.h frame.h window.h disptab.h termhooks.h charset.h $(config_h) \
 -   keyboard.h $(INTERVAL_SRC) region-cache.h xterm.h w32term.h macterm.h \
 -   msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h
 -xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
 -   window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \
 -   keyboard.h fontset.h w32term.h macterm.h $(INTERVAL_SRC) $(config_h)
 +xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h \
 +   coding.h termchar.h frame.h window.h disptab.h termhooks.h character.h     \
 +   charset.h keyboard.h $(INTERVAL_SRC) region-cache.h xterm.h w32term.h      \
 +   macterm.h $(config_h) msdos.h composite.h fontset.h blockinput.h atimer.h  \
 +   systime.h keymap.h $(FONTSRC)
 +xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
 +   window.h character.h charset.h msdos.h dosfns.h composite.h atimer.h       \
 +   systime.h keyboard.h fontset.h w32term.h macterm.h $(INTERVAL_SRC) \
 +   $(FONTSRC) $(config_h)
  xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
     $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
 -   charset.h gtkutil.h $(config_h)
 +   character.h charset.h coding.h gtkutil.h $(config_h) termhooks.h \
 +   fontset.h $(FONTSRC)
 +xfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \
 +   font.h $(config_h)
 +xftfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \
 +   font.h $(config_h)
 +ftxfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \
 +   font.h $(config_h)
  xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \
 -   keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h \
 -   gtkutil.h msdos.h coding.h $(config_h)
 +   charset.h keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h \
 +   systime.h gtkutil.h msdos.h coding.h $(config_h)
  xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \
 -  dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \
 -  keyboard.h gnu.h charset.h ccl.h fontset.h composite.h \
 -  coding.h process.h gtkutil.h $(config_h)
 +   dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \
 +   keyboard.h gnu.h character.h charset.h ccl.h fontset.h composite.h \
 +   coding.h process.h gtkutil.h $(FONTSRC) $(config_h)
  xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \
    buffer.h atimer.h systime.h $(config_h)
  xrdb.o: xrdb.c $(config_h) epaths.h
@@@ -1267,29 -1231,27 +1267,29 @@@ atimer.o: atimer.c atimer.h systime.h $
  /* The files of Lisp proper */
  
  alloc.o: alloc.c process.h frame.h window.h buffer.h  puresize.h syssignal.h keyboard.h \
 - blockinput.h atimer.h systime.h charset.h dispextern.h $(config_h) $(INTERVAL_SRC)
 -bytecode.o: bytecode.c buffer.h syntax.h charset.h window.h dispextern.h \
 + blockinput.h atimer.h systime.h character.h dispextern.h $(config_h) \
 + $(INTERVAL_SRC)
 +bytecode.o: bytecode.c buffer.h syntax.h character.h window.h dispextern.h \
    frame.h xterm.h $(config_h)
 -data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h frame.h $(config_h)
 +data.o: data.c buffer.h puresize.h character.h syssignal.h keyboard.h frame.h \
 + $(config_h)
  eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h \
    dispextern.h $(config_h)
  floatfns.o: floatfns.c $(config_h)
 -fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \
 +fns.o: fns.c commands.h $(config_h) frame.h buffer.h character.h keyboard.h \
   keymap.h frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h \
   blockinput.h xterm.h
 -print.o: print.c process.h frame.h window.h buffer.h keyboard.h charset.h \
 +print.o: print.c process.h frame.h window.h buffer.h keyboard.h character.h \
     $(config_h) dispextern.h termchar.h $(INTERVAL_SRC) msdos.h composite.h
 -lread.o: lread.c commands.h keyboard.h buffer.h epaths.h charset.h \
 - $(config_h) $(INTERVAL_SRC) termhooks.h coding.h msdos.h
 +lread.o: lread.c commands.h keyboard.h buffer.h epaths.h character.h \
 + charset.h $(config_h) $(INTERVAL_SRC) termhooks.h coding.h msdos.h
  
  /* Text properties support */
  textprop.o: textprop.c buffer.h window.h dispextern.h $(INTERVAL_SRC) \
        $(config_h)
  intervals.o: intervals.c buffer.h $(INTERVAL_SRC) keyboard.h puresize.h \
        keymap.h $(config_h)
 -composite.o: composite.c buffer.h  charset.h $(INTERVAL_SRC) $(config_h)
 +composite.o: composite.c buffer.h  character.h $(INTERVAL_SRC) $(config_h)
  
  /* System-specific programs to be made.
     OTHER_FILES and OBJECTS_MACHINE
@@@ -1411,10 -1373,14 +1411,10 @@@ bootstrap: bootstrap-emacs${EXEEXT
  /* Dump an Emacs executable named bootstrap-emacs containing the
     files from loadup.el in source form.  */
  
 -bootstrap-emacs${EXEEXT}: temacs${EXEEXT}
 +bootstrap-emacs${EXEEXT}: temacs${EXEEXT} ${lispsource}international/charprop.el
  #ifdef CANNOT_DUMP
        ln temacs${EXEEXT} bootstrap-emacs${EXEEXT}
  #else
 -#ifdef HAVE_SHM
 -      $(RUN_TEMACS) -nl -batch -l loadup bootstrap
 -#else /* ! defined (HAVE_SHM) */
        $(RUN_TEMACS) --batch --load loadup bootstrap
 -#endif /* ! defined (HAVE_SHM) */
        mv -f emacs${EXEEXT} bootstrap-emacs${EXEEXT}
  #endif /* ! defined (CANNOT_DUMP) */
diff --combined src/abbrev.c
index 2d95b881bc5ce8052579cb08f0852a933d636808,7dea6969f358e972b270ca5cd2789a909a39cbce..8e9bd143089ee7c88e4f2de1c92335e0970385b5
@@@ -1,6 -1,6 +1,6 @@@
  /* Primitives for word-abbrev mode.
     Copyright (C) 1985, 1986, 1993, 1996, 1998, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -27,7 -27,7 +27,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "commands.h"
  #include "buffer.h"
  #include "window.h"
 -#include "charset.h"
 +#include "character.h"
  #include "syntax.h"
  
  /* An abbrev table is an obarray.
@@@ -400,15 -400,9 +400,15 @@@ Returns the abbrev symbol, if expansio
          int pos = wordstart_byte;
  
          /* Find the initial.  */
 -        while (pos < PT_BYTE
 -               && SYNTAX (*BUF_BYTE_ADDRESS (current_buffer, pos)) != Sword)
 -          pos++;
 +        if (multibyte)
 +          while (pos < PT_BYTE
 +                 && SYNTAX (FETCH_MULTIBYTE_CHAR (pos)) != Sword)
 +            INC_POS (pos);
 +        else
 +          while (pos < PT_BYTE
 +                 && (SYNTAX (*BUF_BYTE_ADDRESS (current_buffer, pos))
 +                     != Sword))
 +            pos++;
  
          /* Change just that.  */
          pos = BYTE_TO_CHAR (pos);
diff --combined src/alloc.c
index 8ebaac74c08130597803afa66c380ce4c9aa338c,f24d77f0519b92dff7e46f638fb582942efa91da..b6ad5545f34d8ae91a9119d0900d2931e135d6d0
@@@ -1,6 -1,6 +1,6 @@@
  /* Storage allocation and gc for GNU Emacs Lisp interpreter.
     Copyright (C) 1985, 1986, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
-       2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+       2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -53,7 -53,7 +53,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "keyboard.h"
  #include "frame.h"
  #include "blockinput.h"
 -#include "charset.h"
 +#include "character.h"
  #include "syssignal.h"
  #include <setjmp.h>
  
@@@ -127,21 -127,21 +127,21 @@@ extern __malloc_size_t __malloc_extra_b
  
  static pthread_mutex_t alloc_mutex;
  
- #define BLOCK_INPUT_ALLOC                       \
-   do                                            \
-     {                                           \
-       if (pthread_self () == main_thread)     \
-       BLOCK_INPUT;                            \
-       pthread_mutex_lock (&alloc_mutex);      \
-     }                                           \
+ #define BLOCK_INPUT_ALLOC                               \
+   do                                                    \
+     {                                                   \
+       if (pthread_equal (pthread_self (), main_thread)) \
+         sigblock (sigmask (SIGIO));                     \
+       pthread_mutex_lock (&alloc_mutex);                \
+     }                                                   \
    while (0)
- #define UNBLOCK_INPUT_ALLOC                     \
-   do                                            \
-     {                                           \
-       pthread_mutex_unlock (&alloc_mutex);    \
-       if (pthread_self () == main_thread)     \
-       UNBLOCK_INPUT;                          \
-     }                                           \
+ #define UNBLOCK_INPUT_ALLOC                             \
+   do                                                    \
+     {                                                   \
+       pthread_mutex_unlock (&alloc_mutex);              \
+       if (pthread_equal (pthread_self (), main_thread)) \
+         sigunblock (sigmask (SIGIO));                   \
+     }                                                   \
    while (0)
  
  #else /* SYSTEM_MALLOC || not HAVE_GTK_AND_PTHREAD */
@@@ -502,7 -502,7 +502,7 @@@ struct gcpro *gcprolist
  /* Addresses of staticpro'd variables.  Initialize it to a nonzero
     value; otherwise some compilers put it into BSS.  */
  
 -#define NSTATICS 1280
 +#define NSTATICS 0x600
  Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
  
  /* Index of next unused slot in staticvec.  */
@@@ -2290,7 -2290,7 +2290,7 @@@ INIT must be an integer that represent
    CHECK_NUMBER (init);
  
    c = XINT (init);
 -  if (SINGLE_BYTE_CHAR_P (c))
 +  if (ASCII_CHAR_P (c))
      {
        nbytes = XINT (length);
        val = make_uninit_string (nbytes);
@@@ -3080,6 -3080,49 +3080,6 @@@ See also the function `vector'.  */
  }
  
  
 -DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0,
 -       doc: /* Return a newly created char-table, with purpose PURPOSE.
 -Each element is initialized to INIT, which defaults to nil.
 -PURPOSE should be a symbol which has a `char-table-extra-slots' property.
 -The property's value should be an integer between 0 and 10.  */)
 -     (purpose, init)
 -     register Lisp_Object purpose, init;
 -{
 -  Lisp_Object vector;
 -  Lisp_Object n;
 -  CHECK_SYMBOL (purpose);
 -  n = Fget (purpose, Qchar_table_extra_slots);
 -  CHECK_NUMBER (n);
 -  if (XINT (n) < 0 || XINT (n) > 10)
 -    args_out_of_range (n, Qnil);
 -  /* Add 2 to the size for the defalt and parent slots.  */
 -  vector = Fmake_vector (make_number (CHAR_TABLE_STANDARD_SLOTS + XINT (n)),
 -                       init);
 -  XCHAR_TABLE (vector)->top = Qt;
 -  XCHAR_TABLE (vector)->parent = Qnil;
 -  XCHAR_TABLE (vector)->purpose = purpose;
 -  XSETCHAR_TABLE (vector, XCHAR_TABLE (vector));
 -  return vector;
 -}
 -
 -
 -/* Return a newly created sub char table with slots initialized by INIT.
 -   Since a sub char table does not appear as a top level Emacs Lisp
 -   object, we don't need a Lisp interface to make it.  */
 -
 -Lisp_Object
 -make_sub_char_table (init)
 -     Lisp_Object init;
 -{
 -  Lisp_Object vector
 -    = Fmake_vector (make_number (SUB_CHAR_TABLE_STANDARD_SLOTS), init);
 -  XCHAR_TABLE (vector)->top = Qnil;
 -  XCHAR_TABLE (vector)->defalt = Qnil;
 -  XSETCHAR_TABLE (vector, XCHAR_TABLE (vector));
 -  return vector;
 -}
 -
 -
  DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
         doc: /* Return a newly created vector with specified arguments as elements.
  Any number of arguments, even zero arguments, are allowed.
@@@ -6456,6 -6499,7 +6456,6 @@@ The time is in seconds as a floating po
    defsubr (&Smake_byte_code);
    defsubr (&Smake_list);
    defsubr (&Smake_vector);
 -  defsubr (&Smake_char_table);
    defsubr (&Smake_string);
    defsubr (&Smake_bool_vector);
    defsubr (&Smake_symbol);
diff --combined src/buffer.c
index 6e3b39ad2bb4e2bf9e93fcb4dbb1ace1082bf8c4,493501ef0b981a2c52ce190b0da5e56d142d01ba..2361cce388207f2d1e4ed75ef4b3bae9bd106f88
@@@ -1,7 -1,7 +1,7 @@@
  /* Buffer manipulation primitives for GNU Emacs.
     Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994,
                   1995, 1997, 1998, 1999, 2000, 2001, 2002,
-                  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -42,7 -42,7 +42,7 @@@ extern int errno
  #include "window.h"
  #include "commands.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "region-cache.h"
  #include "indent.h"
  #include "blockinput.h"
@@@ -184,7 -184,6 +184,7 @@@ static struct Lisp_Overlay * copy_overl
  static void modify_overlay P_ ((struct buffer *, EMACS_INT, EMACS_INT));
  static Lisp_Object buffer_lisp_local_variables P_ ((struct buffer *));
  
 +extern char * emacs_strerror P_ ((int));
  
  /* For debugging; temporary.  See set_buffer_internal.  */
  /* Lisp_Object Qlisp_mode, Vcheck_symbol; */
@@@ -2143,10 -2142,8 +2143,10 @@@ DEFUN ("set-buffer-multibyte", Fset_buf
         doc: /* Set the multibyte flag of the current buffer to FLAG.
  If FLAG is t, this makes the buffer a multibyte buffer.
  If FLAG is nil, this makes the buffer a single-byte buffer.
 -The buffer contents remain unchanged as a sequence of bytes
 -but the contents viewed as characters do change.
 +In these cases, the buffer contents remain unchanged as a sequence of
 +bytes but the contents viewed as characters do change.
 +If FLAG is `to', this makes the buffer a multibyte buffer by changing
 +all eight-bit bytes to eight-bit characters.
  If the multibyte flag was really changed, undo information of the
  current buffer is cleared.  */)
       (flag)
              p = GAP_END_ADDR;
              stop = Z;
            }
 -        if (MULTIBYTE_STR_AS_UNIBYTE_P (p, bytes))
 -          p += bytes, pos += bytes;
 -        else
 +        if (ASCII_BYTE_P (*p))
 +          p++, pos++;
 +        else if (CHAR_BYTE8_HEAD_P (*p))
            {
 -            c = STRING_CHAR (p, stop - pos);
 +            c = STRING_CHAR_AND_LENGTH (p, stop - pos, bytes);
              /* Delete all bytes for this 8-bit character but the
                 last one, and change the last one to the charcter
                 code.  */
                zv -= bytes;
              stop = Z;
            }
 +        else
 +          {
 +            bytes = BYTES_BY_CHAR_HEAD (*p);
 +            p += bytes, pos += bytes;
 +          }
        }
        if (narrowed)
        Fnarrow_to_region (make_number (begv), make_number (zv));
      {
        int pt = PT;
        int pos, stop;
 -      unsigned char *p;
 +      unsigned char *p, *pend;
  
        /* Be sure not to have a multibyte sequence striding over the GAP.
 -       Ex: We change this: "...abc\201 _GAP_ \241def..."
 -           to: "...abc _GAP_ \201\241def..."  */
 +       Ex: We change this: "...abc\302 _GAP_ \241def..."
 +           to: "...abc _GAP_ \302\241def..."  */
  
 -      if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
 +      if (EQ (flag, Qt)
 +        && GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
          && ! CHAR_HEAD_P (*(GAP_END_ADDR)))
        {
          unsigned char *p = GPT_ADDR - 1;
        pos = BEG;
        stop = GPT;
        p = BEG_ADDR;
 +      pend = GPT_ADDR;
        while (1)
        {
          int bytes;
              if (pos == Z)
                break;
              p = GAP_END_ADDR;
 +            pend = Z_ADDR;
              stop = Z;
            }
  
 -        if (UNIBYTE_STR_AS_MULTIBYTE_P (p, stop - pos, bytes))
 +        if (ASCII_BYTE_P (*p))
 +          p++, pos++;
 +        else if (EQ (flag, Qt) && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
            p += bytes, pos += bytes;
          else
            {
              unsigned char tmp[MAX_MULTIBYTE_LENGTH];
 +            int c;
  
 -            bytes = CHAR_STRING (*p, tmp);
 +            c = BYTE8_TO_CHAR (*p);
 +            bytes = CHAR_STRING (c, tmp);
              *p = tmp[0];
              TEMP_SET_PT_BOTH (pos + 1, pos + 1);
              bytes--;
                zv += bytes;
              if (pos <= pt)
                pt += bytes;
 +            pend = Z_ADDR;
              stop = Z;
            }
        }
diff --combined src/buffer.h
index 96db95a57e421b852696e2683d9b10f9abb793f1,0652fdb35a86176a119b74b06cfb7545f0261a8f..7ee5d921419bd5e63e138b7857f1ae9898184152
@@@ -1,6 -1,6 +1,6 @@@
  /* Header file for the buffer manipulation primitives.
     Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -325,6 -325,7 +325,6 @@@ els
  
  /* Variables used locally in FETCH_MULTIBYTE_CHAR.  */
  extern unsigned char *_fetch_multibyte_char_p;
 -extern int _fetch_multibyte_char_len;
  
  /* Return character code of multi-byte form at position POS.  If POS
     doesn't point the head of valid multi-byte form, only the byte at
  
  #define FETCH_MULTIBYTE_CHAR(pos)                                     \
    (_fetch_multibyte_char_p = (((pos) >= GPT_BYTE ? GAP_SIZE : 0)      \
 -                             + (pos) + BEG_ADDR - BEG_BYTE),                  \
 -   _fetch_multibyte_char_len                                          \
 -      = ((pos) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE) - (pos),             \
 -   STRING_CHAR (_fetch_multibyte_char_p, _fetch_multibyte_char_len))
 +                             + (pos) + BEG_ADDR - BEG_BYTE),          \
 +   STRING_CHAR (_fetch_multibyte_char_p, 0))
 +
 +/* Return character at position POS.  If the current buffer is unibyte
 +   and the character is not ASCII, make the returning character
 +   multibyte.  */
 +
 +#define FETCH_CHAR_AS_MULTIBYTE(pos)                  \
 +  (!NILP (current_buffer->enable_multibyte_characters)        \
 +   ? FETCH_MULTIBYTE_CHAR ((pos))                     \
 +   : unibyte_char_to_multibyte (FETCH_BYTE ((pos))))
 +
  \f
  /* Macros for accessing a character or byte,
     or converting between byte positions and addresses,
    (_fetch_multibyte_char_p                                            \
       = (((pos) >= BUF_GPT_BYTE (buf) ? BUF_GAP_SIZE (buf) : 0)                \
          + (pos) + BUF_BEG_ADDR (buf) - BEG_BYTE),                     \
 -   _fetch_multibyte_char_len                                          \
 -     = (((pos) >= BUF_GPT_BYTE (buf) ? BUF_ZV_BYTE (buf) : BUF_GPT_BYTE (buf)) \
 -        - (pos)),                                                     \
 -   STRING_CHAR (_fetch_multibyte_char_p, _fetch_multibyte_char_len))
 +   STRING_CHAR (_fetch_multibyte_char_p, 0))
  \f
  /* Define the actual buffer data structures.  */
  
@@@ -870,7 -866,6 +870,7 @@@ extern void mmap_set_vars P_ ((int))
        }                                                                       \
    } while (0)
  
 +EXFUN (Fbuffer_live_p, 1);
  EXFUN (Fbuffer_name, 1);
  EXFUN (Fget_file_buffer, 1);
  EXFUN (Fnext_overlay_change, 1);
diff --combined src/bytecode.c
index 6476070be5da8316b90543b18ee21152894b1e20,4cb9e7428fdfc75068179d69584c3286c117cac6..999addc2f0aa239ed9a02c9d93e364402bed04a2
@@@ -1,6 -1,6 +1,6 @@@
  /* Execution of byte code produced by bytecomp.el.
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -37,7 -37,7 +37,7 @@@ by Hallvard
  #include <config.h>
  #include "lisp.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "syntax.h"
  #include "window.h"
  
@@@ -1394,17 -1394,10 +1394,17 @@@ If the third argument is incorrect, Ema
          break;
  
        case Bchar_syntax:
 -        BEFORE_POTENTIAL_GC ();
 -        CHECK_NUMBER (TOP);
 -        AFTER_POTENTIAL_GC ();
 -        XSETFASTINT (TOP, syntax_code_spec[(int) SYNTAX (XINT (TOP))]);
 +        {
 +          int c;
 +
 +          BEFORE_POTENTIAL_GC ();
 +          CHECK_CHARACTER (TOP);
 +          AFTER_POTENTIAL_GC ();
 +          c = XFASTINT (TOP);
 +          if (NILP (current_buffer->enable_multibyte_characters))
 +            MAKE_CHAR_MULTIBYTE (c);
 +          XSETFASTINT (TOP, syntax_code_spec[(int) SYNTAX (c)]);
 +        }
          break;
  
        case Bbuffer_substring:
diff --combined src/callproc.c
index 819e7ff4a321454c35fbfb7d7f25bad61dd0b94c,f9b71db771853ec30d35177eb76fb12ebacff260..6af47f0ed3e503b98f7b000b52abacdc2e3f0036
@@@ -1,6 -1,6 +1,6 @@@
  /* Synchronous subprocess invocation for GNU Emacs.
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -75,7 -75,7 +75,7 @@@ extern int errno
  #include "lisp.h"
  #include "commands.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "ccl.h"
  #include "coding.h"
  #include "composite.h"
@@@ -273,7 -273,6 +273,7 @@@ usage: (call-process PROGRAM &optional 
      if (nargs >= 5)
        {
        int must_encode = 0;
 +      Lisp_Object coding_attrs;
  
        for (i = 4; i < nargs; i++)
          CHECK_STRING (args[i]);
            else
              val = Qnil;
          }
 +      val = coding_inherit_eol_type (val, Qnil);
        setup_coding_system (Fcheck_coding_system (val), &argument_coding);
 -      if (argument_coding.common_flags & CODING_ASCII_INCOMPATIBLE_MASK)
 -        setup_coding_system (Qraw_text, &argument_coding);
 -      if (argument_coding.eol_type == CODING_EOL_UNDECIDED)
 -        argument_coding.eol_type = system_eol_type;
 +      coding_attrs = CODING_ID_ATTRS (argument_coding.id);
 +      if (NILP (CODING_ATTR_ASCII_COMPAT (coding_attrs)))
 +        {
 +          /* We should not use an ASCII incompatible coding system.  */
 +          val = raw_text_coding_system (val);
 +          setup_coding_system (val, &argument_coding);
 +        }
        }
    }
  
        {
          argument_coding.src_multibyte = STRING_MULTIBYTE (args[i]);
          if (CODING_REQUIRE_ENCODING (&argument_coding))
 -          {
 -            /* We must encode this argument.  */
 -            args[i] = encode_coding_string (args[i], &argument_coding, 1);
 -            if (argument_coding.type == coding_type_ccl)
 -              setup_ccl_program (&(argument_coding.spec.ccl.encoder), Qnil);
 -          }
 +          /* We must encode this argument.  */
 +          args[i] = encode_coding_string (&argument_coding, args[i], 1);
          new_argv[i - 3] = SDATA (args[i]);
        }
        UNGCPRO;
          else
            val = Qnil;
        }
 -      setup_coding_system (Fcheck_coding_system (val), &process_coding);
 +      Fcheck_coding_system (val);
        /* In unibyte mode, character code conversion should not take
         place but EOL conversion should.  So, setup raw-text or one
         of the subsidiary according to the information just setup.  */
        if (NILP (current_buffer->enable_multibyte_characters)
          && !NILP (val))
 -      setup_raw_text_coding_system (&process_coding);
 +      val = raw_text_coding_system (val);
 +      setup_coding_system (val, &process_coding);
      }
 -  process_coding.src_multibyte = 0;
 -  process_coding.dst_multibyte
 -    = (BUFFERP (buffer)
 -       ? ! NILP (XBUFFER (buffer)->enable_multibyte_characters)
 -       : ! NILP (current_buffer->enable_multibyte_characters));
  
    immediate_quit = 1;
    QUIT;
      int carryover = 0;
      int display_on_the_fly = display_p;
      struct coding_system saved_coding;
 -    int pt_orig = PT, pt_byte_orig = PT_BYTE;
 -    int inserted;
  
      saved_coding = process_coding;
 -    if (process_coding.composing != COMPOSITION_DISABLED)
 -      coding_allocate_composition_data (&process_coding, PT);
      while (1)
        {
        /* Repeatedly read until we've filled as much as possible
  
        if (!NILP (buffer))
          {
 -          if (! CODING_MAY_REQUIRE_DECODING (&process_coding))
 +          if (NILP (current_buffer->enable_multibyte_characters)
 +              && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
              insert_1_both (buf, nread, nread, 0, 1, 0);
            else
              {                 /* We have to decode the input.  */
 -              int size;
 -              char *decoding_buf;
 -
 -            repeat_decoding:
 -              size = decoding_buffer_size (&process_coding, nread);
 -              decoding_buf = (char *) xmalloc (size);
 -
 -              /* We can't use the macro CODING_REQUIRE_DETECTION
 -                 because it always returns nonzero if the coding
 -                 system requires EOL detection.  Here, we have to
 -                 check only whether or not the coding system
 -                 requires text-encoding detection.  */
 -              if (process_coding.type == coding_type_undecided)
 -                {
 -                  detect_coding (&process_coding, buf, nread);
 -                  if (process_coding.composing != COMPOSITION_DISABLED)
 -                    /* We have not yet allocated the composition
 -                       data because the coding type was undecided.  */
 -                    coding_allocate_composition_data (&process_coding, PT);
 -                }
 -              if (process_coding.cmp_data)
 -                process_coding.cmp_data->char_offset = PT;
 -
 -              decode_coding (&process_coding, buf, decoding_buf,
 -                             nread, size);
 +              Lisp_Object curbuf;
  
 +              XSETBUFFER (curbuf, current_buffer);
 +              decode_coding_c_string (&process_coding, buf, nread,
 +                                      curbuf);
                if (display_on_the_fly
 -                  && saved_coding.type == coding_type_undecided
 -                  && process_coding.type != coding_type_undecided)
 +                  && CODING_REQUIRE_DETECTION (&saved_coding)
 +                  && ! CODING_REQUIRE_DETECTION (&process_coding))
                  {
                    /* We have detected some coding system.  But,
                       there's a possibility that the detection was
 -                     done by insufficient data.  So, we try the code
 -                     detection again with more data.  */
 -                  xfree (decoding_buf);
 +                     done by insufficient data.  So, we give up
 +                     displaying on the fly.  */
 +                  if (process_coding.produced > 0)
 +                    del_range_2 (process_coding.dst_pos,
 +                                 process_coding.dst_pos_byte,
 +                                 process_coding.dst_pos
 +                                 + process_coding.produced_char,
 +                                 process_coding.dst_pos_byte
 +                                 + process_coding.produced, 0);
                    display_on_the_fly = 0;
                    process_coding = saved_coding;
                    carryover = nread;
                    /* This is to make the above condition always
                       fails in the future.  */
 -                  saved_coding.type = coding_type_no_conversion;
 +                  saved_coding.common_flags
 +                    &= ~CODING_REQUIRE_DETECTION_MASK;
                    continue;
                  }
  
 -              if (process_coding.produced > 0)
 -                insert_1_both (decoding_buf, process_coding.produced_char,
 -                               process_coding.produced, 0, 1, 0);
 -              xfree (decoding_buf);
 -
 -              if (process_coding.result == CODING_FINISH_INCONSISTENT_EOL)
 -                {
 -                  Lisp_Object eol_type, coding;
 -
 -                  if (process_coding.eol_type == CODING_EOL_CR)
 -                    {
 -                      /* CRs have been replaced with LFs.  Undo
 -                         that in the text inserted above.  */
 -                      unsigned char *p;
 -
 -                      move_gap_both (PT, PT_BYTE);
 -
 -                      p = BYTE_POS_ADDR (pt_byte_orig);
 -                      for (; p < GPT_ADDR; ++p)
 -                        if (*p == '\n')
 -                          *p = '\r';
 -                    }
 -                  else if (process_coding.eol_type == CODING_EOL_CRLF)
 -                    {
 -                      /* CR LFs have been replaced with LFs.  Undo
 -                         that by inserting CRs in front of LFs in
 -                         the text inserted above.  */
 -                      EMACS_INT bytepos, old_pt, old_pt_byte, nCR;
 -
 -                      old_pt = PT;
 -                      old_pt_byte = PT_BYTE;
 -                      nCR = 0;
 -
 -                      for (bytepos = PT_BYTE - 1;
 -                           bytepos >= pt_byte_orig;
 -                           --bytepos)
 -                        if (FETCH_BYTE (bytepos) == '\n')
 -                          {
 -                            EMACS_INT charpos = BYTE_TO_CHAR (bytepos);
 -                            TEMP_SET_PT_BOTH (charpos, bytepos);
 -                            insert_1_both ("\r", 1, 1, 0, 1, 0);
 -                            ++nCR;
 -                          }
 -
 -                      TEMP_SET_PT_BOTH (old_pt + nCR, old_pt_byte + nCR);
 -                    }
 -
 -                  /* Set the coding system symbol to that for
 -                     Unix-like EOL.  */
 -                  eol_type = Fget (saved_coding.symbol, Qeol_type);
 -                  if (VECTORP (eol_type)
 -                      && ASIZE (eol_type) == 3
 -                      && SYMBOLP (AREF (eol_type, CODING_EOL_LF)))
 -                    coding = AREF (eol_type, CODING_EOL_LF);
 -                  else
 -                    coding = saved_coding.symbol;
 -
 -                  process_coding.symbol = coding;
 -                  process_coding.eol_type = CODING_EOL_LF;
 -                  process_coding.mode
 -                    &= ~CODING_MODE_INHIBIT_INCONSISTENT_EOL;
 -                }
 -
 -              nread -= process_coding.consumed;
 -              carryover = nread;
 +              TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
 +                                PT_BYTE + process_coding.produced);
 +              carryover = process_coding.carryover_bytes;
                if (carryover > 0)
                  /* As CARRYOVER should not be that large, we had
                     better avoid overhead of bcopy.  */
 -                BCOPY_SHORT (buf + process_coding.consumed, buf,
 -                             carryover);
 -              if (process_coding.result == CODING_FINISH_INSUFFICIENT_CMP)
 -                {
 -                  /* The decoding ended because of insufficient data
 -                     area to record information about composition.
 -                     We must try decoding with additional data area
 -                     before reading more output for the process.  */
 -                  coding_allocate_composition_data (&process_coding, PT);
 -                  goto repeat_decoding;
 -                }
 +                BCOPY_SHORT (process_coding.carryover, buf,
 +                             process_coding.carryover_bytes);
              }
          }
  
        }
    give_up: ;
  
 -    if (!NILP (buffer)
 -      && process_coding.cmp_data)
 -      {
 -      coding_restore_composition (&process_coding, Fcurrent_buffer ());
 -      coding_free_composition_data (&process_coding);
 -      }
 -
 -    {
 -      int post_read_count = SPECPDL_INDEX ();
 -
 -      record_unwind_protect (save_excursion_restore, save_excursion_save ());
 -      inserted = PT - pt_orig;
 -      TEMP_SET_PT_BOTH (pt_orig, pt_byte_orig);
 -      if (SYMBOLP (process_coding.post_read_conversion)
 -        && !NILP (Ffboundp (process_coding.post_read_conversion)))
 -      call1 (process_coding.post_read_conversion, make_number (inserted));
 -
 -      Vlast_coding_system_used = process_coding.symbol;
 -
 -      /* If the caller required, let the buffer inherit the
 -       coding-system used to decode the process output.  */
 -      if (inherit_process_coding_system)
 -      call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
 -             make_number (total_read));
 -
 -      unbind_to (post_read_count, Qnil);
 -    }
 +    Vlast_coding_system_used = CODING_ID_NAME (process_coding.id);
 +    /* If the caller required, let the buffer inherit the
 +       coding-system used to decode the process output.  */
 +    if (inherit_process_coding_system)
 +      call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
 +             make_number (total_read));
    }
  
    /* Wait for it to terminate, unless it already has.  */
@@@ -992,7 -1104,11 +992,11 @@@ usage: (call-process-region START END P
  
  #ifdef HAVE_MKSTEMP
   {
-    int fd = mkstemp (tempfile);
+    int fd;
+    BLOCK_INPUT;
+    fd = mkstemp (tempfile);
+    UNBLOCK_INPUT;
     if (fd == -1)
       report_file_error ("Failed to open temporary file",
                        Fcons (Vtemp_file_name_pattern, Qnil));
diff --combined src/casefiddle.c
index 104f7f97a4186f2b8d4b751fd60270ee09af7f15,57fcefdde3ae69047b00915587970801d29ce24a..56b21e738ceec4e819da7ac0a12bf5c9d2b5f509
@@@ -1,6 -1,6 +1,6 @@@
  /* GNU Emacs case conversion functions.
     Copyright (C) 1985, 1994, 1997, 1998, 1999, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -23,7 -23,7 +23,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <config.h>
  #include "lisp.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "commands.h"
  #include "syntax.h"
  #include "composite.h"
@@@ -38,7 -38,7 +38,7 @@@ casify_object (flag, obj
       enum case_action flag;
       Lisp_Object obj;
  {
 -  register int i, c, len;
 +  register int c, c1;
    register int inword = flag == CASE_DOWN;
  
    /* If the case table is flagged as modified, rescan it.  */
@@@ -50,7 -50,6 +50,7 @@@
        int flagbits = (CHAR_ALT | CHAR_SUPER | CHAR_HYPER
                      | CHAR_SHIFT | CHAR_CTL | CHAR_META);
        int flags = XINT (obj) & flagbits;
 +      int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
  
        /* If the character has higher bits set
         above the flags, return it unchanged.
        if ((unsigned) XFASTINT (obj) > (unsigned) flagbits)
        return obj;
  
 -      c = DOWNCASE (XFASTINT (obj) & ~flagbits);
 +      c1 = XFASTINT (obj) & ~flagbits;
 +      if (! multibyte)
 +      MAKE_CHAR_MULTIBYTE (c1);
 +      c = DOWNCASE (c1);
        if (inword)
        XSETFASTINT (obj, c | flags);
        else if (c == (XFASTINT (obj) & ~flagbits))
        {
 -        c = UPCASE1 ((XFASTINT (obj) & ~flagbits));
 +        if (! inword)
 +          c = UPCASE1 (c1);
 +        if (! multibyte)
 +          MAKE_CHAR_UNIBYTE (c);
          XSETFASTINT (obj, c | flags);
        }
        return obj;
    if (STRINGP (obj))
      {
        int multibyte = STRING_MULTIBYTE (obj);
 -      int n;
 +      int i, i_byte, len;
 +      int size = SCHARS (obj);
  
        obj = Fcopy_sequence (obj);
 -      len = SBYTES (obj);
 -
 -      /* I counts bytes, and N counts chars.  */
 -      for (i = n = 0; i < len; n++)
 +      for (i = i_byte = 0; i < size; i++, i_byte += len)
        {
 -        int from_len = 1, to_len = 1;
 -
 -        c = SREF (obj, i);
 -
 -        if (multibyte && c >= 0x80)
 -          c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i, len -i, from_len);
 +        if (multibyte)
 +          c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, 0, len);
 +        else
 +          {
 +            c = SREF (obj, i_byte);
 +            len = 1;
 +            MAKE_CHAR_MULTIBYTE (c);
 +          }
 +        c1 = c;
          if (inword && flag != CASE_CAPITALIZE_UP)
            c = DOWNCASE (c);
          else if (!UPPERCASEP (c)
                   && (!inword || flag != CASE_CAPITALIZE_UP))
 -          c = UPCASE1 (c);
 -        if ((ASCII_BYTE_P (c) && from_len == 1)
 -            || (! multibyte && SINGLE_BYTE_CHAR_P (c)))
 -          SSET (obj, i, c);
 -        else
 +          c = UPCASE1 (c1);
 +        if ((int) flag >= (int) CASE_CAPITALIZE)
 +          inword = (SYNTAX (c) == Sword);
 +        if (c != c1)
            {
 -            to_len = CHAR_BYTES (c);
 -            if (from_len == to_len)
 -              CHAR_STRING (c, SDATA (obj) + i);
 +            if (! multibyte)
 +              {
 +                MAKE_CHAR_UNIBYTE (c);
 +                SSET (obj, i_byte, c);
 +              }
 +            else if (ASCII_CHAR_P (c1) && ASCII_CHAR_P (c))
 +              SSET (obj, i_byte,  c);
              else
                {
 -                Faset (obj, make_number (n), make_number (c));
 -                len += to_len - from_len;
 +                Faset (obj, make_number (i), make_number (c));
 +                i_byte += CHAR_BYTES (c) - len;
                }
            }
 -        if ((int) flag >= (int) CASE_CAPITALIZE)
 -          inword = SYNTAX (c) == Sword;
 -        i += to_len;
        }
        return obj;
      }
@@@ -176,14 -168,13 +176,14 @@@ casify_region (flag, b, e
       enum case_action flag;
       Lisp_Object b, e;
  {
 -  register int i;
    register int c;
    register int inword = flag == CASE_DOWN;
    register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
    int start, end;
    int start_byte, end_byte;
    int changed = 0;
 +  int opoint = PT;
 +  int opoint_byte = PT_BYTE;
  
    if (EQ (b, e))
      /* Not modifying because nothing marked */
    start_byte = CHAR_TO_BYTE (start);
    end_byte = CHAR_TO_BYTE (end);
  
 -  for (i = start_byte; i < end_byte; i++, start++)
 +  while (start < end)
      {
 -      int c2;
 -      c = c2 = FETCH_BYTE (i);
 -      if (multibyte && c >= 0x80)
 -      /* A multibyte character can't be handled in this simple loop.  */
 -      break;
 +      int c2, len;
 +
 +      if (multibyte)
 +      {
 +        c = FETCH_MULTIBYTE_CHAR (start_byte);
 +        len = CHAR_BYTES (c);
 +      }
 +      else
 +      {
 +        c = FETCH_BYTE (start_byte);
 +        MAKE_CHAR_MULTIBYTE (c);
 +        len = 1;
 +      }
 +      c2 = c;
        if (inword && flag != CASE_CAPITALIZE_UP)
        c = DOWNCASE (c);
        else if (!UPPERCASEP (c)
               && (!inword || flag != CASE_CAPITALIZE_UP))
        c = UPCASE1 (c);
 -      if (multibyte && c >= 0x80)
 -      /* A multibyte result character can't be handled in this
 -         simple loop.  */
 -      break;
 -      FETCH_BYTE (i) = c;
 -      if (c != c2)
 -      changed = 1;
        if ((int) flag >= (int) CASE_CAPITALIZE)
 -      inword = SYNTAX (c) == Sword && (inword || !SYNTAX_PREFIX (c));
 -    }
 -  if (i < end_byte)
 -    {
 -      /* The work is not yet finished because of a multibyte character
 -       just encountered.  */
 -      int opoint = PT;
 -      int opoint_byte = PT_BYTE;
 -      int c2;
 -
 -      while (start < end)
 +      inword = ((SYNTAX (c) == Sword) && (inword || !SYNTAX_PREFIX (c)));
 +      if (c != c2)
        {
 -        if ((c = FETCH_BYTE (i)) >= 0x80)
 -          c = FETCH_MULTIBYTE_CHAR (i);
 -        c2 = c;
 -        if (inword && flag != CASE_CAPITALIZE_UP)
 -          c2 = DOWNCASE (c);
 -        else if (!UPPERCASEP (c)
 -                 && (!inword || flag != CASE_CAPITALIZE_UP))
 -          c2 = UPCASE1 (c);
 -        if (c != c2)
 +        changed = 1;
 +        if (! multibyte)
 +          {
 +            MAKE_CHAR_UNIBYTE (c);
 +            FETCH_BYTE (start_byte) = c;
 +          }
 +        else if (ASCII_CHAR_P (c2) && ASCII_CHAR_P (c))
 +          FETCH_BYTE (start_byte) = c;
 +        else
            {
 -            int fromlen, tolen, j;
 +            int tolen = CHAR_BYTES (c);
 +            int j;
              unsigned char str[MAX_MULTIBYTE_LENGTH];
  
 -            changed = 1;
 -            /* Handle the most likely case */
 -            if (c < 0400 && c2 < 0400)
 -              FETCH_BYTE (i) = c2;
 -            else if (fromlen = CHAR_STRING (c, str),
 -                     tolen = CHAR_STRING (c2, str),
 -                     fromlen == tolen)
 +            CHAR_STRING (c, str);
 +            if (len == tolen)
                {
                  /* Length is unchanged.  */
 -                for (j = 0; j < tolen; ++j)
 -                  FETCH_BYTE (i + j) = str[j];
 +                for (j = 0; j < len; ++j)
 +                  FETCH_BYTE (start_byte + j) = str[j];
                }
              else
                {
                  /* Replace one character with the other,
                     keeping text properties the same.  */
 -                replace_range_2 (start, i,
 -                                 start + 1, i + fromlen,
 +                replace_range_2 (start, start_byte,
 +                                 start + 1, start_byte + len,
                                   str, 1, tolen,
 -                                 1);
 -                if (opoint > start)
 -                  opoint_byte += tolen - fromlen;
 +                                 0);
 +                len = tolen;
                }
            }
 -        if ((int) flag >= (int) CASE_CAPITALIZE)
 -          inword = SYNTAX (c2) == Sword;
 -        INC_BOTH (start, i);
        }
 -      TEMP_SET_PT_BOTH (opoint, opoint_byte);
 +      start++;
 +      start_byte += len;
      }
  
 -  start = XFASTINT (b);
 +  if (PT != opoint)
 +    TEMP_SET_PT_BOTH (opoint, opoint_byte);
 +
    if (changed)
      {
 +      start = XFASTINT (b);
        signal_after_change (start, end - start, end - start);
        update_compositions (start, end, CHECK_ALL);
      }
diff --combined src/casetab.c
index 517f24de0141d5931930f3c43ec15659ec28a748,42c268dd7c60dc8686e1fcf753658307cae2eb3a..2245e8e8b4a40bd328f14ce4e6c1ee368d97cf91
@@@ -1,6 -1,6 +1,6 @@@
  /* GNU Emacs routines to deal with case tables.
-    Copyright (C) 1993, 1994, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004,
+                  2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -24,7 -24,7 +24,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <config.h>
  #include "lisp.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  
  Lisp_Object Qcase_table_p, Qcase_table;
  Lisp_Object Vascii_downcase_table, Vascii_upcase_table;
@@@ -126,6 -126,7 +126,6 @@@ set_case_table (table, standard
       int standard;
  {
    Lisp_Object up, canon, eqv;
 -  Lisp_Object indices[3];
  
    check_case_table (table);
  
    if (NILP (up))
      {
        up = Fmake_char_table (Qcase_table, Qnil);
 -      map_char_table (set_identity, Qnil, table, table, up, 0, indices);
 -      map_char_table (shuffle, Qnil, table, table, up, 0, indices);
 +      map_char_table (set_identity, Qnil, table, up);
 +      map_char_table (shuffle, Qnil, table, up);
        XCHAR_TABLE (table)->extras[0] = up;
      }
  
      {
        canon = Fmake_char_table (Qcase_table, Qnil);
        XCHAR_TABLE (table)->extras[1] = canon;
 -      map_char_table (set_canon, Qnil, table, table, table, 0, indices);
 +      map_char_table (set_canon, Qnil, table, table);
      }
  
    if (NILP (eqv))
      {
        eqv = Fmake_char_table (Qcase_table, Qnil);
 -      map_char_table (set_identity, Qnil, canon, canon, eqv, 0, indices);
 -      map_char_table (shuffle, Qnil, canon, canon, eqv, 0, indices);
 +      map_char_table (set_identity, Qnil, canon, eqv);
 +      map_char_table (shuffle, Qnil, canon, eqv);
        XCHAR_TABLE (table)->extras[2] = eqv;
      }
  
  \f
  /* The following functions are called in map_char_table.  */
  
 -/*  Set CANON char-table element for C to a translated ELT by UP and
 -   DOWN char-tables.  This is done only when ELT is a character.  The
 -   char-tables CANON, UP, and DOWN are in CASE_TABLE.  */
 +/* Set CANON char-table element for characters in RANGE to a
 +   translated ELT by UP and DOWN char-tables.  This is done only when
 +   ELT is a character.  The char-tables CANON, UP, and DOWN are in
 +   CASE_TABLE.  */
  
  static void
 -set_canon (case_table, c, elt)
 -     Lisp_Object case_table, c, elt;
 +set_canon (case_table, range, elt)
 +     Lisp_Object case_table, range, elt;
  {
    Lisp_Object up = XCHAR_TABLE (case_table)->extras[0];
    Lisp_Object canon = XCHAR_TABLE (case_table)->extras[1];
  
    if (NATNUMP (elt))
 -    Faset (canon, c, Faref (case_table, Faref (up, elt)));
 +    Fset_char_table_range (canon, range, Faref (case_table, Faref (up, elt)));
  }
  
 -/* Set elements of char-table TABLE for C to C itself.  This is done
 -   only when ELT is a character.  This is called in map_char_table.  */
 +/* Set elements of char-table TABLE for C to C itself.  C may be a
 +   cons specifying a character range.  In that case, set characters in
 +   that range to themselves.  This is done only when ELT is a
 +   character.  This is called in map_char_table.  */
  
  static void
  set_identity (table, c, elt)
       Lisp_Object table, c, elt;
  {
    if (NATNUMP (elt))
 -    Faset (table, c, c);
 +    {
 +      int from, to;
 +
 +      if (CONSP (c))
 +      {
 +        from = XINT (XCAR (c));
 +        to = XINT (XCDR (c));
 +      }
 +      else
 +      from = to = XINT (c);
 +      for (; from <= to; from++)
 +      CHAR_TABLE_SET (table, from, make_number (from));
 +    }
  }
  
  /* Permute the elements of TABLE (which is initially an identity
@@@ -229,25 -215,11 +229,25 @@@ static voi
  shuffle (table, c, elt)
       Lisp_Object table, c, elt;
  {
 -  if (NATNUMP (elt) && !EQ (c, elt))
 +  if (NATNUMP (elt))
      {
        Lisp_Object tem = Faref (table, elt);
 -      Faset (table, elt, c);
 -      Faset (table, c, tem);
 +      int from, to;
 +
 +      if (CONSP (c))
 +      {
 +        from = XINT (XCAR (c));
 +        to = XINT (XCDR (c));
 +      }
 +      else
 +      from = to = XINT (c);
 +
 +      for (; from <= to; from++)
 +      if (from != XINT (elt))
 +        {
 +          Faset (table, elt, make_number (from));
 +          Faset (table, make_number (from), tem);
 +        }
      }
  }
  \f
@@@ -272,24 -244,22 +272,24 @@@ init_casetab_once (
    Vascii_downcase_table = down;
    XCHAR_TABLE (down)->purpose = Qcase_table;
  
 -  for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
 -    XSETFASTINT (XCHAR_TABLE (down)->contents[i],
 -               (i >= 'A' && i <= 'Z') ? i + ('a' - 'A') : i);
 +  for (i = 0; i < 128; i++)
 +    {
 +      int c = (i >= 'A' && i <= 'Z') ? i + ('a' - 'A') : i;
 +      CHAR_TABLE_SET (down, i, make_number (c));
 +    }
  
    XCHAR_TABLE (down)->extras[1] = Fcopy_sequence (down);
  
    up = Fmake_char_table (Qcase_table, Qnil);
    XCHAR_TABLE (down)->extras[0] = up;
  
 -  for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
 -    XSETFASTINT (XCHAR_TABLE (up)->contents[i],
 -               ((i >= 'A' && i <= 'Z')
 -                ? i + ('a' - 'A')
 -                : ((i >= 'a' && i <= 'z')
 -                   ? i + ('A' - 'a')
 -                   : i)));
 +  for (i = 0; i < 128; i++)
 +    {
 +      int c = ((i >= 'A' && i <= 'Z') ? i + ('a' - 'A')
 +             : ((i >= 'a' && i <= 'z') ? i + ('A' - 'a')
 +                : i));;
 +      CHAR_TABLE_SET (up, i, make_number (c));
 +    }
  
    XCHAR_TABLE (down)->extras[2] = Fcopy_sequence (up);
  
diff --combined src/category.c
index 4d19d4a6ccdbd07a5d759af601e6985985b3742c,809e326cbe997afb4c1b5d81ddbfbb4a765680b4..218d5f7f783196c3f328928b3d9f176ab5e3d918
@@@ -1,12 -1,10 +1,13 @@@
  /* GNU Emacs routines to deal with category tables.
-    Copyright (C) 1998, 2001, 2004, 2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+      Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -33,7 -31,6 +34,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <ctype.h>
  #include "lisp.h"
  #include "buffer.h"
 +#include "character.h"
  #include "charset.h"
  #include "category.h"
  #include "keymap.h"
@@@ -192,18 -189,6 +193,18 @@@ This is the one used for new buffers.  
    return Vstandard_category_table;
  }
  
 +
 +static void
 +copy_category_entry (table, c, val)
 +     Lisp_Object table, c, val;
 +{
 +  val = Fcopy_sequence (val);
 +  if (CONSP (c))
 +    char_table_set_range (table, XINT (XCAR (c)), XINT (XCDR (c)), val);
 +  else
 +    char_table_set (table, XINT (c), val);
 +}
 +
  /* Return a copy of category table TABLE.  We can't simply use the
     function copy-sequence because no contents should be shared between
     the original and the copy.  This function is called recursively by
@@@ -213,14 -198,44 +214,14 @@@ Lisp_Objec
  copy_category_table (table)
       Lisp_Object table;
  {
 -  Lisp_Object tmp;
 -  int i, to;
 +  table = copy_char_table (table);
  
 -  if (!NILP (XCHAR_TABLE (table)->top))
 -    {
 -      /* TABLE is a top level char table.
 -       At first, make a copy of tree structure of the table.  */
 -      table = Fcopy_sequence (table);
 -
 -      /* Then, copy elements for single byte characters one by one.  */
 -      for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
 -      if (!NILP (tmp = XCHAR_TABLE (table)->contents[i]))
 -        XCHAR_TABLE (table)->contents[i] = Fcopy_sequence (tmp);
 -      to = CHAR_TABLE_ORDINARY_SLOTS;
 -
 -      /* Also copy the first (and sole) extra slot.  It is a vector
 -         containing docstring of each category.  */
 -      Fset_char_table_extra_slot
 -      (table, make_number (0),
 -       Fcopy_sequence (Fchar_table_extra_slot (table, make_number (0))));
 -    }
 -  else
 -    {
 -      i  = 32;
 -      to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
 -    }
 -
 -  /* If the table has non-nil default value, copy it.  */
 -  if (!NILP (tmp = XCHAR_TABLE (table)->defalt))
 -    XCHAR_TABLE (table)->defalt = Fcopy_sequence (tmp);
 -
 -  /* At last, copy the remaining elements while paying attention to a
 -     sub char table.  */
 -  for (; i < to; i++)
 -    if (!NILP (tmp = XCHAR_TABLE (table)->contents[i]))
 -      XCHAR_TABLE (table)->contents[i]
 -      = (SUB_CHAR_TABLE_P (tmp)
 -         ? copy_category_table (tmp) : Fcopy_sequence (tmp));
 +  if (! NILP (XCHAR_TABLE (table)->defalt))
 +    XCHAR_TABLE (table)->defalt
 +      = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
 +  XCHAR_TABLE (table)->extras[0]
 +    = Fcopy_sequence (XCHAR_TABLE (table)->extras[0]);
 +  map_char_table (copy_category_entry, Qnil, table, table);
  
    return table;
  }
@@@ -246,12 -261,9 +247,12 @@@ DEFUN ("make-category-table", Fmake_cat
       ()
  {
    Lisp_Object val;
 +  int i;
  
    val = Fmake_char_table (Qcategory_table, Qnil);
    XCHAR_TABLE (val)->defalt = MAKE_CATEGORY_SET;
 +  for (i = 0; i < (1 << CHARTAB_SIZE_BITS_0); i++)
 +    XCHAR_TABLE (val)->contents[i] = MAKE_CATEGORY_SET;
    Fset_char_table_extra_slot (val, make_number (0),
                              Fmake_vector (make_number (95), Qnil));
    return val;
@@@ -273,13 -285,6 +274,13 @@@ Return TABLE.  */
  }
  
  \f
 +Lisp_Object
 +char_category_set (c)
 +     int c;
 +{
 +  return CHAR_TABLE_REF (current_buffer->category_table, c);
 +}
 +
  DEFUN ("char-category-set", Fchar_category_set, Schar_category_set, 1, 1, 0,
         doc: /* Return the category set of CHAR.
  usage: (char-category-set CHAR)  */)
@@@ -313,6 -318,34 +314,6 @@@ The return value is a string containin
    return build_string (str);
  }
  
 -/* Modify all category sets stored under sub char-table TABLE so that
 -   they contain (SET_VALUE is t) or don't contain (SET_VALUE is nil)
 -   CATEGORY.  */
 -
 -void
 -modify_lower_category_set (table, category, set_value)
 -     Lisp_Object table, category, set_value;
 -{
 -  Lisp_Object val;
 -  int i;
 -
 -  val = XCHAR_TABLE (table)->defalt;
 -  if (!CATEGORY_SET_P (val))
 -    val = MAKE_CATEGORY_SET;
 -  SET_CATEGORY_SET (val, category, set_value);
 -  XCHAR_TABLE (table)->defalt = val;
 -
 -  for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
 -    {
 -      val = XCHAR_TABLE (table)->contents[i];
 -
 -      if (CATEGORY_SET_P (val))
 -      SET_CATEGORY_SET (val, category, set_value);
 -      else if (SUB_CHAR_TABLE_P (val))
 -      modify_lower_category_set (val, category, set_value);
 -    }
 -}
 -
  void
  set_category_set (category_set, category, val)
       Lisp_Object category_set, category, val;
@@@ -332,55 -365,113 +333,55 @@@ DEFUN ("modify-category-entry", Fmodify
         Smodify_category_entry, 2, 4, 0,
         doc: /* Modify the category set of CHARACTER by adding CATEGORY to it.
  The category is changed only for table TABLE, which defaults to
 - the current buffer's category table.
 +the current buffer's category table.
 +CHARACTER can be either a single character or a cons representing the
 +lower and upper ends of an inclusive character range to modify.
  If optional fourth argument RESET is non-nil,
  then delete CATEGORY from the category set instead of adding it.  */)
       (character, category, table, reset)
       Lisp_Object character, category, table, reset;
  {
 -  int c, charset, c1, c2;
    Lisp_Object set_value;      /* Actual value to be set in category sets.  */
 -  Lisp_Object val, category_set;
 +  Lisp_Object category_set;
 +  int start, end;
 +  int from, to;
  
 -  CHECK_NUMBER (character);
 -  c = XINT (character);
 -  CHECK_CATEGORY (category);
 -  table = check_category_table (table);
 -
 -  if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
 -    error ("Undefined category: %c", XFASTINT (category));
 -
 -  set_value = NILP (reset) ? Qt : Qnil;
 -
 -  if (c < CHAR_TABLE_SINGLE_BYTE_SLOTS)
 -    {
 -      val = XCHAR_TABLE (table)->contents[c];
 -      if (!CATEGORY_SET_P (val))
 -      XCHAR_TABLE (table)->contents[c] = (val = MAKE_CATEGORY_SET);
 -      SET_CATEGORY_SET (val, category, set_value);
 -      return Qnil;
 -    }
 -
 -  SPLIT_CHAR (c, charset, c1, c2);
 -
 -  /* The top level table.  */
 -  val = XCHAR_TABLE (table)->contents[charset + 128];
 -  if (CATEGORY_SET_P (val))
 -    category_set = val;
 -  else if (!SUB_CHAR_TABLE_P (val))
 -    {
 -      category_set = val = MAKE_CATEGORY_SET;
 -      XCHAR_TABLE (table)->contents[charset + 128] = category_set;
 -    }
 -
 -  if (c1 <= 0)
 +  if (INTEGERP (character))
      {
 -      /* Only a charset is specified.  */
 -      if (SUB_CHAR_TABLE_P (val))
 -      /* All characters in CHARSET should be the same as for having
 -           CATEGORY or not.  */
 -      modify_lower_category_set (val, category, set_value);
 -      else
 -      SET_CATEGORY_SET (category_set, category, set_value);
 -      return Qnil;
 +      CHECK_CHARACTER (character);
 +      start = end = XFASTINT (character);
      }
 -
 -  /* The second level table.  */
 -  if (!SUB_CHAR_TABLE_P (val))
 +  else
      {
 -      val = make_sub_char_table (Qnil);
 -      XCHAR_TABLE (table)->contents[charset + 128] = val;
 -      /* We must set default category set of CHARSET in `defalt' slot.  */
 -      XCHAR_TABLE (val)->defalt = category_set;
 +      CHECK_CONS (character);
 +      CHECK_CHARACTER_CAR (character);
 +      CHECK_CHARACTER_CDR (character);
 +      start = XFASTINT (XCAR (character));
 +      end = XFASTINT (XCDR (character));
      }
 -  table = val;
  
 -  val = XCHAR_TABLE (table)->contents[c1];
 -  if (CATEGORY_SET_P (val))
 -    category_set = val;
 -  else if (!SUB_CHAR_TABLE_P (val))
 -    {
 -      category_set = val = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
 -      XCHAR_TABLE (table)->contents[c1] = category_set;
 -    }
 +  CHECK_CATEGORY (category);
 +  table = check_category_table (table);
  
 -  if (c2 <= 0)
 -    {
 -      if (SUB_CHAR_TABLE_P (val))
 -      /* All characters in C1 group of CHARSET should be the same as
 -           for CATEGORY.  */
 -      modify_lower_category_set (val, category, set_value);
 -      else
 -      SET_CATEGORY_SET (category_set, category, set_value);
 -      return Qnil;
 -    }
 +  if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
 +    error ("Undefined category: %c", XFASTINT (category));
  
 -  /* The third (bottom) level table.  */
 -  if (!SUB_CHAR_TABLE_P (val))
 -    {
 -      val = make_sub_char_table (Qnil);
 -      XCHAR_TABLE (table)->contents[c1] = val;
 -      /* We must set default category set of CHARSET and C1 in
 -         `defalt' slot.  */
 -      XCHAR_TABLE (val)->defalt = category_set;
 -    }
 -  table = val;
 +  set_value = NILP (reset) ? Qt : Qnil;
  
 -  val = XCHAR_TABLE (table)->contents[c2];
 -  if (CATEGORY_SET_P (val))
 -    category_set = val;
 -  else if (!SUB_CHAR_TABLE_P (val))
 +  while (start <= end)
      {
 -      category_set = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
 -      XCHAR_TABLE (table)->contents[c2] = category_set;
 +      category_set = char_table_ref_and_range (table, start, &from, &to);
 +      if (CATEGORY_MEMBER (XFASTINT (category), category_set) != NILP (reset))
 +      {
 +        category_set = Fcopy_sequence (category_set);
 +        SET_CATEGORY_SET (category_set, category, set_value);
 +        if (to > end)
 +          char_table_set_range (table, start, end, category_set);
 +        else
 +          char_table_set_range (table, start, to, category_set);
 +      }
 +      start = to + 1;
      }
 -  else
 -    /* This should never happen.  */
 -    error ("Invalid category table");
 -
 -  SET_CATEGORY_SET (category_set, category, set_value);
  
    return Qnil;
  }
diff --combined src/category.h
index 862576352267c32b2cf41fc90493a8b5deaa5aad,858a94a62242c66bb66fd952a83bc16c2d07bf80..3ce03a83de8370cc63fffcd26b2ebb9c6cd56c5a
@@@ -1,11 -1,8 +1,11 @@@
  /* Declarations having to do with Emacs category tables.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -96,7 -93,21 +96,7 @@@ extern Lisp_Object _temp_category_set
  #define Vstandard_category_table buffer_defaults.category_table
  
  /* Return the category set of character C in the current category table.  */
 -#ifdef __GNUC__
 -#define CATEGORY_SET(c)                                                            \
 -  ({ Lisp_Object table = current_buffer->category_table;                   \
 -     Lisp_Object temp;                                                             \
 -     if ((c) < CHAR_TABLE_SINGLE_BYTE_SLOTS)                               \
 -       while (NILP (temp = XCHAR_TABLE (table)->contents[(unsigned char) c]) \
 -            && NILP (temp = XCHAR_TABLE (table)->defalt))                  \
 -       table = XCHAR_TABLE (table)->parent;                                \
 -     else                                                                  \
 -       temp = Faref (table, make_number (c));                              \
 -     temp; })
 -#else
 -#define CATEGORY_SET(c) \
 -  Faref (current_buffer->category_table, make_number (c))
 -#endif
 +#define CATEGORY_SET(c) char_category_set (c)
  
  /* Return the doc string of CATEGORY in category table TABLE.  */
  #define CATEGORY_DOCSTRING(table, category) \
  
  /* Return 1 if there is a word boundary between two word-constituent
     characters C1 and C2 if they appear in this order, else return 0.
 -   There is no word boundary between two word-constituent ASCII
 -   characters.  */
 +   There is no word boundary between two word-constituent ASCII and
 +   Latin-1 characters.  */
  #define WORD_BOUNDARY_P(c1, c2)                                       \
    (!(SINGLE_BYTE_CHAR_P (c1) && SINGLE_BYTE_CHAR_P (c2))      \
     && word_boundary_p (c1, c2))
diff --combined src/ccl.c
index 017c9ab4feb722e20e7d371050953ee7bc23431d,ded74fb6296905b8edaa275f0f9b75f8667200d0..c13f7c863b1e89a4694bf3182a6feaed0a536b1e
+++ b/src/ccl.c
@@@ -1,13 -1,10 +1,13 @@@
  /* CCL (Code Conversion Language) interpreter.
     Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+                  2006, 2007 Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -31,13 -28,10 +31,13 @@@ Boston, MA 02110-1301, USA.  *
  #include <stdio.h>
  
  #include "lisp.h"
 +#include "character.h"
  #include "charset.h"
  #include "ccl.h"
  #include "coding.h"
  
 +Lisp_Object Qccl, Qcclp;
 +
  /* This contains all code conversion map available to CCL.  */
  Lisp_Object Vcode_conversion_map_vector;
  
@@@ -73,8 -67,6 +73,8 @@@ Lisp_Object Vtranslation_hash_table_vec
  #define GET_HASH_TABLE(id) \
    (XHASH_TABLE (XCDR(XVECTOR(Vtranslation_hash_table_vector)->contents[(id)])))
  
 +extern int charset_unicode;
 +
  /* CCL (Code Conversion Language) is a simple language which has
     operations on one input buffer, one output buffer, and 7 registers.
     The syntax of CCL is described in `ccl.el'.  Emacs Lisp function
  #define CCL_WriteStringJump   0x0A /* Write string and jump:
                                        1:A--D--D--R--E--S--S-000XXXXX
                                        2:LENGTH
 -                                      3:0000STRIN[0]STRIN[1]STRIN[2]
 +                                      3:000MSTRIN[0]STRIN[1]STRIN[2]
                                        ...
                                        ------------------------------
 -                                      write_string (STRING, LENGTH);
 +                                      if (M)
 +                                        write_multibyte_string (STRING, LENGTH);
 +                                      else
 +                                        write_string (STRING, LENGTH);
                                        IC += ADDRESS;
                                        */
  
  
  #define CCL_WriteConstString  0x14 /* Write a constant or a string:
                                        1:CCCCCCCCCCCCCCCCCCCCrrrXXXXX
 -                                      [2:0000STRIN[0]STRIN[1]STRIN[2]]
 +                                      [2:000MSTRIN[0]STRIN[1]STRIN[2]]
                                        [...]
                                        -----------------------------
                                        if (!rrr)
                                          write (CC..C)
                                        else
 -                                        write_string (STRING, CC..C);
 +                                        if (M)
 +                                          write_multibyte_string (STRING, CC..C);
 +                                        else
 +                                          write_string (STRING, CC..C);
                                          IC += (CC..C + 2) / 3;
                                        */
  
@@@ -757,87 -743,136 +757,87 @@@ while(0
  
  /* Encode one character CH to multibyte form and write to the current
     output buffer.  If CH is less than 256, CH is written as is.  */
 -#define CCL_WRITE_CHAR(ch)                                            \
 -  do {                                                                        \
 -    int bytes = SINGLE_BYTE_CHAR_P (ch) ? 1: CHAR_BYTES (ch);         \
 -    if (!dst)                                                         \
 -      CCL_INVALID_CMD;                                                        \
 -    else if (dst + bytes + extra_bytes < (dst_bytes ? dst_end : src)) \
 -      {                                                                       \
 -      if (bytes == 1)                                                 \
 -        {                                                             \
 -          *dst++ = (ch);                                              \
 -          if (extra_bytes && (ch) >= 0x80 && (ch) < 0xA0)             \
 -            /* We may have to convert this eight-bit char to          \
 -               multibyte form later.  */                              \
 -            extra_bytes++;                                            \
 -        }                                                             \
 -      else if (CHAR_VALID_P (ch, 0))                                  \
 -        dst += CHAR_STRING (ch, dst);                                 \
 -      else                                                            \
 -        CCL_INVALID_CMD;                                              \
 -      }                                                                       \
 -    else                                                              \
 -      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);                          \
 -  } while (0)
 -
 -/* Encode one character CH to multibyte form and write to the current
 -   output buffer.  The output bytes always forms a valid multibyte
 -   sequence.  */
 -#define CCL_WRITE_MULTIBYTE_CHAR(ch)                                  \
 -  do {                                                                        \
 -    int bytes = CHAR_BYTES (ch);                                      \
 -    if (!dst)                                                         \
 -      CCL_INVALID_CMD;                                                        \
 -    else if (dst + bytes + extra_bytes < (dst_bytes ? dst_end : src)) \
 -      {                                                                       \
 -      if (CHAR_VALID_P ((ch), 0))                                     \
 -        dst += CHAR_STRING ((ch), dst);                               \
 -      else                                                            \
 -        CCL_INVALID_CMD;                                              \
 -      }                                                                       \
 -    else                                                              \
 -      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);                          \
 +#define CCL_WRITE_CHAR(ch)                    \
 +  do {                                                \
 +    if (! dst)                                        \
 +      CCL_INVALID_CMD;                                \
 +    else if (dst < dst_end)                   \
 +      *dst++ = (ch);                          \
 +    else                                      \
 +      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);  \
    } while (0)
  
  /* Write a string at ccl_prog[IC] of length LEN to the current output
     buffer.  */
 -#define CCL_WRITE_STRING(len)                         \
 -  do {                                                        \
 -    if (!dst)                                         \
 -      CCL_INVALID_CMD;                                        \
 -    else if (dst + len <= (dst_bytes ? dst_end : src))        \
 -      for (i = 0; i < len; i++)                               \
 -      *dst++ = ((XFASTINT (ccl_prog[ic + (i / 3)]))   \
 -                >> ((2 - (i % 3)) * 8)) & 0xFF;       \
 -    else                                              \
 -      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);          \
 -  } while (0)
 -
 -/* Read one byte from the current input buffer into REGth register.  */
 -#define CCL_READ_CHAR(REG)                            \
 -  do {                                                        \
 -    if (!src)                                         \
 -      CCL_INVALID_CMD;                                        \
 -    else if (src < src_end)                           \
 -      {                                                       \
 -      REG = *src++;                                   \
 -      if (REG == '\n'                                 \
 -          && ccl->eol_type != CODING_EOL_LF)          \
 -        {                                             \
 -          /* We are encoding.  */                     \
 -          if (ccl->eol_type == CODING_EOL_CRLF)       \
 -            {                                         \
 -              if (ccl->cr_consumed)                   \
 -                ccl->cr_consumed = 0;                 \
 -              else                                    \
 -                {                                     \
 -                  ccl->cr_consumed = 1;               \
 -                  REG = '\r';                         \
 -                  src--;                              \
 -                }                                     \
 -            }                                         \
 -          else                                        \
 -            REG = '\r';                               \
 -        }                                             \
 -      if (REG == LEADING_CODE_8_BIT_CONTROL           \
 -          && ccl->multibyte)                          \
 -        REG = *src++ - 0x20;                          \
 -      }                                                       \
 -    else if (ccl->last_block)                         \
 -      {                                                       \
 -      REG = -1;                                       \
 -        ic = eof_ic;                                  \
 -        goto ccl_repeat;                              \
 -      }                                                       \
 -    else                                              \
 -      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);          \
 -  } while (0)
 -
 -
 -/* Set C to the character code made from CHARSET and CODE.  This is
 -   like MAKE_CHAR but check the validity of CHARSET and CODE.  If they
 -   are not valid, set C to (CODE & 0xFF) because that is usually the
 -   case that CCL_ReadMultibyteChar2 read an invalid code and it set
 -   CODE to that invalid byte.  */
 -
 -#define CCL_MAKE_CHAR(charset, code, c)                               \
 +#define CCL_WRITE_STRING(len)                                 \
    do {                                                                \
 -    if (charset == CHARSET_ASCII)                             \
 -      c = code & 0xFF;                                                \
 -    else if (CHARSET_DEFINED_P (charset)                      \
 -           && (code & 0x7F) >= 32                             \
 -           && (code < 256 || ((code >> 7) & 0x7F) >= 32))     \
 +    int i;                                                    \
 +    if (!dst)                                                 \
 +      CCL_INVALID_CMD;                                                \
 +    else if (dst + len <= dst_end)                            \
        {                                                               \
 -      int c1 = code & 0x7F, c2 = 0;                           \
 -                                                              \
 -      if (code >= 256)                                        \
 -        c2 = c1, c1 = (code >> 7) & 0x7F;                     \
 -      c = MAKE_CHAR (charset, c1, c2);                        \
 +      if (XFASTINT (ccl_prog[ic]) & 0x1000000)                \
 +        for (i = 0; i < len; i++)                             \
 +          *dst++ = XFASTINT (ccl_prog[ic + i]) & 0xFFFFFF;    \
 +      else                                                    \
 +        for (i = 0; i < len; i++)                             \
 +          *dst++ = ((XFASTINT (ccl_prog[ic + (i / 3)]))       \
 +                    >> ((2 - (i % 3)) * 8)) & 0xFF;           \
        }                                                               \
      else                                                      \
 -      c = code & 0xFF;                                                \
 +      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_DST);                  \
    } while (0)
  
 +/* Read one byte from the current input buffer into Rth register.  */
 +#define CCL_READ_CHAR(r)                      \
 +  do {                                                \
 +    if (! src)                                        \
 +      CCL_INVALID_CMD;                                \
 +    else if (src < src_end)                   \
 +      r = *src++;                             \
 +    else if (ccl->last_block)                 \
 +      {                                               \
 +      r = -1;                                 \
 +      ic = ccl->eof_ic;                       \
 +      goto ccl_repeat;                        \
 +      }                                               \
 +    else                                      \
 +      CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);  \
 +    } while (0)
 +
 +/* Decode CODE by a charset whose id is ID.  If ID is 0, return CODE
 +   as is for backward compatibility.  Assume that we can use the
 +   variable `charset'.  */
 +
 +#define CCL_DECODE_CHAR(id, code)     \
 +  ((id) == 0 ? (code)                 \
 +   : (charset = CHARSET_FROM_ID ((id)), DECODE_CHAR (charset, (code))))
 +
 +/* Encode character C by some of charsets in CHARSET_LIST.  Set ID to
 +   the id of the used charset, ENCODED to the resulf of encoding.
 +   Assume that we can use the variable `charset'.  */
 +
 +#define CCL_ENCODE_CHAR(c, charset_list, id, encoded)         \
 +  do {                                                                \
 +    unsigned code;                                            \
 +                                                              \
 +    charset = char_charset ((c), (charset_list), &code);      \
 +    if (! charset && ! NILP (charset_list))                   \
 +      charset = char_charset ((c), Qnil, &code);              \
 +    if (charset)                                              \
 +      {                                                               \
 +      (id) = CHARSET_ID (charset);                            \
 +      (encoded) = code;                                       \
 +      }                                                               \
 +   } while (0)
  
 -/* Execute CCL code on SRC_BYTES length text at SOURCE.  The resulting
 -   text goes to a place pointed by DESTINATION, the length of which
 -   should not exceed DST_BYTES.  The bytes actually processed is
 -   returned as *CONSUMED.  The return value is the length of the
 -   resulting text.  As a side effect, the contents of CCL registers
 -   are updated.  If SOURCE or DESTINATION is NULL, only operations on
 -   registers are permitted.  */
 +/* Execute CCL code on characters at SOURCE (length SRC_SIZE).  The
 +   resulting text goes to a place pointed by DESTINATION, the length
 +   of which should not exceed DST_SIZE.  As a side effect, how many
 +   characters are consumed and produced are recorded in CCL->consumed
 +   and CCL->produced, and the contents of CCL registers are updated.
 +   If SOURCE or DESTINATION is NULL, only operations on registers are
 +   permitted.  */
  
  #ifdef CCL_DEBUG
  #define CCL_DEBUG_BACKTRACE_LEN 256
@@@ -862,32 -897,36 +862,32 @@@ struct ccl_prog_stac
  /* For the moment, we only support depth 256 of stack.  */
  static struct ccl_prog_stack ccl_prog_stack_struct[256];
  
 -int
 -ccl_driver (ccl, source, destination, src_bytes, dst_bytes, consumed)
 +void
 +ccl_driver (ccl, source, destination, src_size, dst_size, charset_list)
       struct ccl_program *ccl;
 -     unsigned char *source, *destination;
 -     int src_bytes, dst_bytes;
 -     int *consumed;
 +     int *source, *destination;
 +     int src_size, dst_size;
 +     Lisp_Object charset_list;
  {
    register int *reg = ccl->reg;
    register int ic = ccl->ic;
    register int code = 0, field1, field2;
    register Lisp_Object *ccl_prog = ccl->prog;
 -  unsigned char *src = source, *src_end = src + src_bytes;
 -  unsigned char *dst = destination, *dst_end = dst + dst_bytes;
 +  int *src = source, *src_end = src + src_size;
 +  int *dst = destination, *dst_end = dst + dst_size;
    int jump_address;
    int i = 0, j, op;
    int stack_idx = ccl->stack_idx;
    /* Instruction counter of the current CCL code. */
    int this_ic = 0;
 -  /* CCL_WRITE_CHAR will produce 8-bit code of range 0x80..0x9F.  But,
 -     each of them will be converted to multibyte form of 2-byte
 -     sequence.  For that conversion, we remember how many more bytes
 -     we must keep in DESTINATION in this variable.  */
 -  int extra_bytes = ccl->eight_bit_control;
 +  struct charset *charset;
    int eof_ic = ccl->eof_ic;
    int eof_hit = 0;
  
    if (ic >= eof_ic)
      ic = CCL_HEADER_MAIN;
  
 -  if (ccl->buf_magnification == 0) /* We can't produce any bytes.  */
 +  if (ccl->buf_magnification == 0) /* We can't read/produce any bytes.  */
      dst = NULL;
  
    /* Set mapping stack pointer. */
          /* We can't just signal Qquit, instead break the loop as if
               the whole data is processed.  Don't reset Vquit_flag, it
               must be handled later at a safer place.  */
 -        if (consumed)
 -          src = source + src_bytes;
 +        if (src)
 +          src = source + src_size;
          ccl->status = CCL_STAT_QUIT;
          break;
        }
            case CCL_LE: reg[rrr] = i <= j; break;
            case CCL_GE: reg[rrr] = i >= j; break;
            case CCL_NE: reg[rrr] = i != j; break;
 -          case CCL_DECODE_SJIS: DECODE_SJIS (i, j, reg[rrr], reg[7]); break;
 -          case CCL_ENCODE_SJIS: ENCODE_SJIS (i, j, reg[rrr], reg[7]); break;
 +          case CCL_DECODE_SJIS:
 +            {
 +              i = (i << 8) | j;
 +              SJIS_TO_JIS (i);
 +              reg[rrr] = i >> 8;
 +              reg[7] = i & 0xFF;
 +              break;
 +            }
 +          case CCL_ENCODE_SJIS:
 +            {
 +              i = (i << 8) | j;
 +              JIS_TO_SJIS (i);
 +              reg[rrr] = i >> 8;
 +              reg[7] = i & 0xFF;
 +              break;
 +            }
            default: CCL_INVALID_CMD;
            }
          code &= 0x1F;
            case CCL_ReadMultibyteChar2:
              if (!src)
                CCL_INVALID_CMD;
 -
 -            if (src >= src_end)
 -              {
 -                src++;
 -                goto ccl_read_multibyte_character_suspend;
 -              }
 -
 -            if (!ccl->multibyte)
 -              {
 -                int bytes;
 -                if (!UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes))
 -                  {
 -                    reg[RRR] = CHARSET_8_BIT_CONTROL;
 -                    reg[rrr] = *src++;
 -                    break;
 -                  }
 -              }
 -            i = *src++;
 -            if (i == '\n' && ccl->eol_type != CODING_EOL_LF)
 -              {
 -                /* We are encoding.  */
 -                if (ccl->eol_type == CODING_EOL_CRLF)
 -                  {
 -                    if (ccl->cr_consumed)
 -                      ccl->cr_consumed = 0;
 -                    else
 -                      {
 -                        ccl->cr_consumed = 1;
 -                        i = '\r';
 -                        src--;
 -                      }
 -                  }
 -                else
 -                  i = '\r';
 -                reg[rrr] = i;
 -                reg[RRR] = CHARSET_ASCII;
 -              }
 -            else if (i < 0x80)
 -              {
 -                /* ASCII */
 -                reg[rrr] = i;
 -                reg[RRR] = CHARSET_ASCII;
 -              }
 -            else if (i <= MAX_CHARSET_OFFICIAL_DIMENSION2)
 -              {
 -                int dimension = BYTES_BY_CHAR_HEAD (i) - 1;
 -
 -                if (dimension == 0)
 -                  {
 -                    /* `i' is a leading code for an undefined charset.  */
 -                    reg[RRR] = CHARSET_8_BIT_GRAPHIC;
 -                    reg[rrr] = i;
 -                  }
 -                else if (src + dimension > src_end)
 -                  goto ccl_read_multibyte_character_suspend;
 -                else
 -                  {
 -                    reg[RRR] = i;
 -                    i = (*src++ & 0x7F);
 -                    if (dimension == 1)
 -                      reg[rrr] = i;
 -                    else
 -                      reg[rrr] = ((i << 7) | (*src++ & 0x7F));
 -                  }
 -              }
 -            else if ((i == LEADING_CODE_PRIVATE_11)
 -                     || (i == LEADING_CODE_PRIVATE_12))
 -              {
 -                if ((src + 1) >= src_end)
 -                  goto ccl_read_multibyte_character_suspend;
 -                reg[RRR] = *src++;
 -                reg[rrr] = (*src++ & 0x7F);
 -              }
 -            else if ((i == LEADING_CODE_PRIVATE_21)
 -                     || (i == LEADING_CODE_PRIVATE_22))
 -              {
 -                if ((src + 2) >= src_end)
 -                  goto ccl_read_multibyte_character_suspend;
 -                reg[RRR] = *src++;
 -                i = (*src++ & 0x7F);
 -                reg[rrr] = ((i << 7) | (*src & 0x7F));
 -                src++;
 -              }
 -            else if (i == LEADING_CODE_8_BIT_CONTROL)
 -              {
 -                if (src >= src_end)
 -                  goto ccl_read_multibyte_character_suspend;
 -                reg[RRR] = CHARSET_8_BIT_CONTROL;
 -                reg[rrr] = (*src++ - 0x20);
 -              }
 -            else if (i >= 0xA0)
 -              {
 -                reg[RRR] = CHARSET_8_BIT_GRAPHIC;
 -                reg[rrr] = i;
 -              }
 -            else
 -              {
 -                /* INVALID CODE.  Return a single byte character.  */
 -                reg[RRR] = CHARSET_ASCII;
 -                reg[rrr] = i;
 -              }
 -            break;
 -
 -          ccl_read_multibyte_character_suspend:
 -            if (src <= src_end && !ccl->multibyte && ccl->last_block)
 -              {
 -                reg[RRR] = CHARSET_8_BIT_CONTROL;
 -                reg[rrr] = i;
 -                break;
 -              }
 -            src--;
 -            if (ccl->last_block)
 -              {
 -                ic = eof_ic;
 -                eof_hit = 1;
 -                goto ccl_repeat;
 -              }
 -            else
 -              CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);
 -
 +            CCL_READ_CHAR (i);
 +            CCL_ENCODE_CHAR (i, charset_list, reg[RRR], reg[rrr]);
              break;
  
            case CCL_WriteMultibyteChar2:
 -            i = reg[RRR]; /* charset */
 -            if (i == CHARSET_ASCII
 -                || i == CHARSET_8_BIT_CONTROL
 -                || i == CHARSET_8_BIT_GRAPHIC)
 -              i = reg[rrr] & 0xFF;
 -            else if (CHARSET_DIMENSION (i) == 1)
 -              i = ((i - 0x70) << 7) | (reg[rrr] & 0x7F);
 -            else if (i < MIN_CHARSET_PRIVATE_DIMENSION2)
 -              i = ((i - 0x8F) << 14) | reg[rrr];
 -            else
 -              i = ((i - 0xE0) << 14) | reg[rrr];
 -
 -            CCL_WRITE_MULTIBYTE_CHAR (i);
 -
 +            if (! dst)
 +              CCL_INVALID_CMD;
 +            i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
 +            CCL_WRITE_CHAR (i);
              break;
  
            case CCL_TranslateCharacter:
 -            CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);
 -            op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]),
 -                                 i, -1, 0, 0);
 -            SPLIT_CHAR (op, reg[RRR], i, j);
 -            if (j != -1)
 -              i = (i << 7) | j;
 -
 -            reg[rrr] = i;
 +            i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
 +            op = translate_char (GET_TRANSLATION_TABLE (reg[Rrr]), i);
 +            CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]);
              break;
  
            case CCL_TranslateCharacterConstTbl:
              op = XINT (ccl_prog[ic]); /* table */
              ic++;
 -            CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);
 -            op = translate_char (GET_TRANSLATION_TABLE (op), i, -1, 0, 0);
 -            SPLIT_CHAR (op, reg[RRR], i, j);
 -            if (j != -1)
 -              i = (i << 7) | j;
 -
 -            reg[rrr] = i;
 +            i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
 +            op = translate_char (GET_TRANSLATION_TABLE (op), i);
 +            CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]);
              break;
  
            case CCL_LookupIntConstTbl:
                  {
                    Lisp_Object opl;
                    opl = HASH_VALUE (h, op);
 -                  if (!CHAR_VALID_P (XINT (opl), 0))
 +                  if (! CHARACTERP (opl))
                      CCL_INVALID_CMD;
 -                  SPLIT_CHAR (XINT (opl), reg[RRR], i, j);
 -                  if (j != -1)
 -                    i = (i << 7) | j;
 -                  reg[rrr] = i;
 +                  reg[RRR] = charset_unicode;
 +                  reg[rrr] = op;
                    reg[7] = 1; /* r7 true for success */
                  }
                else
            case CCL_LookupCharConstTbl:
              op = XINT (ccl_prog[ic]); /* table */
              ic++;
 -            CCL_MAKE_CHAR (reg[RRR], reg[rrr], i);
 +            i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
              {
                struct Lisp_Hash_Table *h = GET_HASH_TABLE (op);
  
        }
  
        msglen = strlen (msg);
 -      if (dst + msglen <= (dst_bytes ? dst_end : src))
 +      if (dst + msglen <= dst_end)
        {
 -        bcopy (msg, dst, msglen);
 -        dst += msglen;
 +        for (i = 0; i < msglen; i++)
 +          *dst++ = msg[i];
        }
  
        if (ccl->status == CCL_STAT_INVALID_CMD)
    ccl->ic = ic;
    ccl->stack_idx = stack_idx;
    ccl->prog = ccl_prog;
 -  ccl->eight_bit_control = (extra_bytes > 1);
 -  if (consumed)
 -    *consumed = src - source;
 -  return (dst ? dst - destination : 0);
 +  ccl->consumed = src - source;
 +  if (dst != NULL)
 +    ccl->produced = dst - destination;
 +  else
 +    ccl->produced = 0;
  }
  
  /* Resolve symbols in the specified CCL code (Lisp vector).  This
@@@ -1946,6 -2109,7 +1946,6 @@@ setup_ccl_program (ccl, ccl_prog
    ccl->private_state = 0;
    ccl->status = 0;
    ccl->stack_idx = 0;
 -  ccl->eol_type = CODING_EOL_LF;
    ccl->suppress_error = 0;
    ccl->eight_bit_control = 0;
    return 0;
@@@ -2033,7 -2197,7 +2033,7 @@@ programs.  */
                  ? XINT (AREF (reg, i))
                  : 0);
  
 -  ccl_driver (&ccl, (unsigned char *)0, (unsigned char *)0, 0, 0, (int *)0);
 +  ccl_driver (&ccl, NULL, NULL, 0, 0, Qnil);
    QUIT;
    if (ccl.status != CCL_STAT_SUCCESS)
      error ("Error in CCL program at %dth code", ccl.ic);
@@@ -2075,13 -2239,10 +2075,13 @@@ usage: (ccl-execute-on-string CCL-PROGR
  {
    Lisp_Object val;
    struct ccl_program ccl;
 -  int i, produced;
 +  int i;
    int outbufsize;
 -  char *outbuf;
 -  struct gcpro gcpro1, gcpro2;
 +  unsigned char *outbuf, *outp;
 +  int str_chars, str_bytes;
 +#define CCL_EXECUTE_BUF_SIZE 1024
 +  int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE];
 +  int consumed_chars, consumed_bytes, produced_chars;
  
    if (setup_ccl_program (&ccl, ccl_prog) < 0)
      error ("Invalid CCL program");
      error ("Length of vector STATUS is not 9");
    CHECK_STRING (str);
  
 -  GCPRO2 (status, str);
 +  str_chars = SCHARS (str);
 +  str_bytes = SBYTES (str);
  
    for (i = 0; i < 8; i++)
      {
        if (ccl.ic < i && i < ccl.size)
        ccl.ic = i;
      }
 -  outbufsize = SBYTES (str) * ccl.buf_magnification + 256;
 -  outbuf = (char *) xmalloc (outbufsize);
 -  ccl.last_block = NILP (contin);
 -  ccl.multibyte = STRING_MULTIBYTE (str);
 -  produced = ccl_driver (&ccl, SDATA (str), outbuf,
 -                       SBYTES (str), outbufsize, (int *) 0);
 +
 +  outbufsize = (ccl.buf_magnification
 +              ? str_bytes * ccl.buf_magnification + 256
 +              : str_bytes + 256);
 +  outp = outbuf = (unsigned char *) xmalloc (outbufsize);
 +
 +  consumed_chars = consumed_bytes = 0;
 +  produced_chars = 0;
 +  while (1)
 +    {
 +      const unsigned char *p = SDATA (str) + consumed_bytes;
 +      const unsigned char *endp = SDATA (str) + str_bytes;
 +      int i = 0;
 +      int *src, src_size;
 +
 +      if (endp - p == str_chars - consumed_chars)
 +      while (i < CCL_EXECUTE_BUF_SIZE && p < endp)
 +        source[i++] = *p++;
 +      else
 +      while (i < CCL_EXECUTE_BUF_SIZE && p < endp)
 +        source[i++] = STRING_CHAR_ADVANCE (p);
 +      consumed_chars += i;
 +      consumed_bytes = p - SDATA (str);
 +
 +      if (consumed_bytes == str_bytes)
 +      ccl.last_block = NILP (contin);
 +      src = source;
 +      src_size = i;
 +      while (1)
 +      {
 +        ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE,
 +                    Qnil);
 +        produced_chars += ccl.produced;
 +        if (NILP (unibyte_p))
 +          {
 +            if (outp - outbuf + MAX_MULTIBYTE_LENGTH * ccl.produced
 +                > outbufsize)
 +              {
 +                int offset = outp - outbuf;
 +                outbufsize += MAX_MULTIBYTE_LENGTH * ccl.produced;
 +                outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
 +                outp = outbuf + offset;
 +              }
 +            for (i = 0; i < ccl.produced; i++)
 +              CHAR_STRING_ADVANCE (destination[i], outp);
 +          }
 +        else
 +          {
 +            if (outp - outbuf + ccl.produced > outbufsize)
 +              {
 +                int offset = outp - outbuf;
 +                outbufsize += ccl.produced;
 +                outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
 +                outp = outbuf + offset;
 +              }
 +            for (i = 0; i < ccl.produced; i++)
 +              *outp++ = destination[i];
 +          }
 +        src += ccl.consumed;
 +        src_size -= ccl.consumed;
 +        if (ccl.status != CCL_STAT_SUSPEND_BY_DST)
 +          break;
 +      }
 +
 +      if (ccl.status != CCL_STAT_SUSPEND_BY_SRC
 +        || str_chars == consumed_chars)
 +      break;
 +    }
 +
 +  if (ccl.status == CCL_STAT_INVALID_CMD)
 +    error ("Error in CCL program at %dth code", ccl.ic);
 +  if (ccl.status == CCL_STAT_QUIT)
 +    error ("CCL program interrupted at %dth code", ccl.ic);
 +
    for (i = 0; i < 8; i++)
      ASET (status, i, make_number (ccl.reg[i]));
    ASET (status, 8, make_number (ccl.ic));
 -  UNGCPRO;
  
    if (NILP (unibyte_p))
 -    {
 -      int nchars;
 -
 -      produced = str_as_multibyte (outbuf, outbufsize, produced, &nchars);
 -      val = make_multibyte_string (outbuf, nchars, produced);
 -    }
 +    val = make_multibyte_string ((char *) outbuf, produced_chars,
 +                               outp - outbuf);
    else
 -    val = make_unibyte_string (outbuf, produced);
 +    val = make_unibyte_string ((char *) outbuf, produced_chars);
    xfree (outbuf);
 -  QUIT;
 -  if (ccl.status == CCL_STAT_SUSPEND_BY_DST)
 -    error ("Output buffer for the CCL programs overflow");
 -  if (ccl.status != CCL_STAT_SUCCESS
 -      && ccl.status != CCL_STAT_SUSPEND_BY_SRC)
 -    error ("Error in CCL program at %dth code", ccl.ic);
  
    return val;
  }
@@@ -2337,12 -2440,6 +2337,12 @@@ syms_of_ccl (
    staticpro (&Vccl_program_table);
    Vccl_program_table = Fmake_vector (make_number (32), Qnil);
  
 +  Qccl = intern ("ccl");
 +  staticpro (&Qccl);
 +
 +  Qcclp = intern ("cclp");
 +  staticpro (&Qcclp);
 +
    Qccl_program = intern ("ccl-program");
    staticpro (&Qccl_program);
  
diff --combined src/ccl.h
index 01d92b621eb3d04ece085b0c1c4e5d90382c6725,af3a92d3285605106dca31423fa8b852f20d9c39..e1c14e71754d1093dbabce03e6e227b3ac0a2660
+++ b/src/ccl.h
@@@ -1,11 -1,8 +1,11 @@@
  /* Header for CCL (Code Conversion Language) interpreter.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -62,14 -59,16 +62,14 @@@ struct ccl_program 
                                   many times bigger the output buffer
                                   should be than the input buffer.  */
    int stack_idx;              /* How deep the call of CCL_Call is nested.  */
 -  int eol_type;                       /* When the CCL program is used for
 -                                 encoding by a coding system, set to
 -                                 the eol_type of the coding system.
 -                                 In other cases, always
 -                                 CODING_EOL_LF.  */
 -  int multibyte;              /* 1 if the source text is multibyte.  */
 +  int src_multibyte;          /* 1 if the input buffer is multibyte.  */
 +  int dst_multibyte;          /* 1 if the output buffer is multibyte.  */
    int cr_consumed;            /* Flag for encoding DOS-like EOL
                                   format when the CCL program is used
                                   for encoding by a coding
                                   system.  */
 +  int consumed;
 +  int produced;
    int suppress_error;         /* If nonzero, don't insert error
                                   message in the output.  */
    int eight_bit_control;      /* If nonzero, ccl_driver counts all
     coding_system.  */
  
  struct ccl_spec {
 -  struct ccl_program decoder;
 -  struct ccl_program encoder;
 -  unsigned char valid_codes[256];
 +  struct ccl_program ccl;
    int cr_carryover;           /* CR carryover flag.  */
    unsigned char eight_bit_carryover[MAX_MULTIBYTE_LENGTH];
  };
  
 +#define CODING_SPEC_CCL_PROGRAM(coding) ((coding)->spec.ccl.ccl)
 +
  /* Alist of fontname patterns vs corresponding CCL program.  */
  extern Lisp_Object Vfont_ccl_encoder_alist;
  
@@@ -100,8 -99,8 +100,8 @@@ extern int setup_ccl_program P_ ((struc
  /* Check if CCL is updated or not.  If not, re-setup members of CCL.  */
  extern int check_ccl_update P_ ((struct ccl_program *));
  
 -extern int ccl_driver P_ ((struct ccl_program *, unsigned char *,
 -                         unsigned char *, int, int, int *));
 +extern void ccl_driver P_ ((struct ccl_program *, int *, int *, int, int,
 +                          Lisp_Object));
  
  /* Vector of CCL program names vs corresponding program data.  */
  extern Lisp_Object Vccl_program_table;
     is an index for Vccl_protram_table. */
  extern Lisp_Object Qccl_program_idx;
  
 +extern Lisp_Object Qccl, Qcclp;
 +
 +EXFUN (Fccl_program_p, 1);
 +
 +#define CHECK_CCL_PROGRAM(x)                  \
 +  do {                                                \
 +    if (NILP (Fccl_program_p (x)))            \
 +      x = wrong_type_argument (Qcclp, (x));   \
 +  } while (0);
 +
  #endif /* EMACS_CCL_H */
  
  /* arch-tag: 14681df7-876d-43de-bc71-6b78e23a4e3c
diff --combined src/charset.c
index 9fb7f641705b3940bba70a9f31e0484119d64cbe,0d91606da586159b9c0984e8bed8f425d421bd02..d5b15092b7b037d2140254674f6d91a2d8681bb4
@@@ -1,14 -1,11 +1,15 @@@
 -/* Basic multilingual character support.
 +/* Basic character set support.
     Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                2006 Free Software Foundation, Inc.
+                  2006, 2007 Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003, 2004
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
 +
  This file is part of GNU Emacs.
  
  GNU Emacs is free software; you can redistribute it and/or modify
@@@ -26,1403 -23,875 +27,1403 @@@ along with GNU Emacs; see the file COPY
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.  */
  
 -/* At first, see the document in `charset.h' to understand the code in
 -   this file.  */
 -
 -#ifdef emacs
  #include <config.h>
 -#endif
  
  #include <stdio.h>
 -
 -#ifdef emacs
 -
 +#include <unistd.h>
 +#include <ctype.h>
  #include <sys/types.h>
  #include "lisp.h"
 -#include "buffer.h"
 +#include "character.h"
  #include "charset.h"
 -#include "composite.h"
  #include "coding.h"
  #include "disptab.h"
 +#include "buffer.h"
  
 -#else  /* not emacs */
 +/*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) ***
  
 -#include "mulelib.h"
 +  A coded character set ("charset" hereafter) is a meaningful
 +  collection (i.e. language, culture, functionality, etc.) of
 +  characters.  Emacs handles multiple charsets at once.  In Emacs Lisp
 +  code, a charset is represented by a symbol.  In C code, a charset is
 +  represented by its ID number or by a pointer to a struct charset.
  
 -#endif /* emacs */
 +  The actual information about each charset is stored in two places.
 +  Lispy information is stored in the hash table Vcharset_hash_table as
 +  a vector (charset attributes).  The other information is stored in
 +  charset_table as a struct charset.
  
 -Lisp_Object Qcharset, Qascii, Qeight_bit_control, Qeight_bit_graphic;
 -Lisp_Object Qunknown;
 -
 -/* Declaration of special leading-codes.  */
 -EMACS_INT leading_code_private_11; /* for private DIMENSION1 of 1-column */
 -EMACS_INT leading_code_private_12; /* for private DIMENSION1 of 2-column */
 -EMACS_INT leading_code_private_21; /* for private DIMENSION2 of 1-column */
 -EMACS_INT leading_code_private_22; /* for private DIMENSION2 of 2-column */
 -
 -/* Declaration of special charsets.  The values are set by
 -   Fsetup_special_charsets.  */
 -int charset_latin_iso8859_1;  /* ISO8859-1 (Latin-1) */
 -int charset_jisx0208_1978;    /* JISX0208.1978 (Japanese Kanji old set) */
 -int charset_jisx0208;         /* JISX0208.1983 (Japanese Kanji) */
 -int charset_katakana_jisx0201;        /* JISX0201.Kana (Japanese Katakana) */
 -int charset_latin_jisx0201;   /* JISX0201.Roman (Japanese Roman) */
 -int charset_big5_1;           /* Big5 Level 1 (Chinese Traditional) */
 -int charset_big5_2;           /* Big5 Level 2 (Chinese Traditional) */
 -int charset_mule_unicode_0100_24ff;
 -int charset_mule_unicode_2500_33ff;
 -int charset_mule_unicode_e000_ffff;
 -
 -Lisp_Object Qcharset_table;
 -
 -/* A char-table containing information of each character set.  */
 -Lisp_Object Vcharset_table;
 -
 -/* A vector of charset symbol indexed by charset-id.  This is used
 -   only for returning charset symbol from C functions.  */
 -Lisp_Object Vcharset_symbol_table;
 -
 -/* A list of charset symbols ever defined.  */
 +*/
 +
 +/* List of all charsets.  This variable is used only from Emacs
 +   Lisp.  */
  Lisp_Object Vcharset_list;
  
 -/* Vector of translation table ever defined.
 -   ID of a translation table is used to index this vector.  */
 -Lisp_Object Vtranslation_table_vector;
 +/* Hash table that contains attributes of each charset.  Keys are
 +   charset symbols, and values are vectors of charset attributes.  */
 +Lisp_Object Vcharset_hash_table;
  
 -/* A char-table for characters which may invoke auto-filling.  */
 -Lisp_Object Vauto_fill_chars;
 +/* Table of struct charset.  */
 +struct charset *charset_table;
  
 -Lisp_Object Qauto_fill_chars;
 +static int charset_table_size;
 +static int charset_table_used;
  
 -/* Tables used by macros BYTES_BY_CHAR_HEAD and WIDTH_BY_CHAR_HEAD.  */
 -int bytes_by_char_head[256];
 -int width_by_char_head[256];
 +Lisp_Object Qcharsetp;
  
 -/* Mapping table from ISO2022's charset (specified by DIMENSION,
 -   CHARS, and FINAL-CHAR) to Emacs' charset.  */
 -int iso_charset_table[2][2][128];
 +/* Special charset symbols.  */
 +Lisp_Object Qascii;
 +Lisp_Object Qeight_bit;
 +Lisp_Object Qiso_8859_1;
 +Lisp_Object Qunicode;
 +
 +/* The corresponding charsets.  */
 +int charset_ascii;
 +int charset_eight_bit;
 +int charset_iso_8859_1;
 +int charset_unicode;
 +
 +/* The other special charsets.  */
 +int charset_jisx0201_roman;
 +int charset_jisx0208_1978;
 +int charset_jisx0208;
 +
 +/* Value of charset attribute `charset-iso-plane'.  */
 +Lisp_Object Qgl, Qgr;
  
 -/* Variables used locally in the macro FETCH_MULTIBYTE_CHAR.  */
 -unsigned char *_fetch_multibyte_char_p;
 -int _fetch_multibyte_char_len;
 +/* Charset of unibyte characters.  */
 +int charset_unibyte;
  
 -/* Offset to add to a non-ASCII value when inserting it.  */
 -EMACS_INT nonascii_insert_offset;
 +/* List of charsets ordered by the priority.  */
 +Lisp_Object Vcharset_ordered_list;
  
 -/* Translation table for converting non-ASCII unibyte characters
 -   to multibyte codes, or nil.  */
 -Lisp_Object Vnonascii_translation_table;
 +/* Incremented everytime we change Vcharset_ordered_list.  This is
 +   unsigned short so that it fits in Lisp_Int and never matches
 +   -1.  */
 +unsigned short charset_ordered_list_tick;
 +
 +/* List of iso-2022 charsets.  */
 +Lisp_Object Viso_2022_charset_list;
 +
 +/* List of emacs-mule charsets.  */
 +Lisp_Object Vemacs_mule_charset_list;
 +
 +struct charset *emacs_mule_charset[256];
 +
 +/* Mapping table from ISO2022's charset (specified by DIMENSION,
 +   CHARS, and FINAL-CHAR) to Emacs' charset.  */
 +int iso_charset_table[ISO_MAX_DIMENSION][ISO_MAX_CHARS][ISO_MAX_FINAL];
 +
 +Lisp_Object Vcharset_map_path;
 +
 +Lisp_Object Vchar_unified_charset_table;
 +
 +/* Defined in chartab.c */
 +extern void
 +map_char_table_for_charset P_ ((void (*c_function) (Lisp_Object, Lisp_Object),
 +                              Lisp_Object function, Lisp_Object table,
 +                              Lisp_Object arg, struct charset *charset,
 +                              unsigned from, unsigned to));
 +
 +#define CODE_POINT_TO_INDEX(charset, code)                            \
 +  ((charset)->code_linear_p                                           \
 +   ? (code) - (charset)->min_code                                     \
 +   : (((charset)->code_space_mask[(code) >> 24] & 0x8)                        \
 +      && ((charset)->code_space_mask[((code) >> 16) & 0xFF] & 0x4)    \
 +      && ((charset)->code_space_mask[((code) >> 8) & 0xFF] & 0x2)     \
 +      && ((charset)->code_space_mask[(code) & 0xFF] & 0x1))           \
 +   ? (((((code) >> 24) - (charset)->code_space[12])                   \
 +       * (charset)->code_space[11])                                   \
 +      + (((((code) >> 16) & 0xFF) - (charset)->code_space[8])         \
 +       * (charset)->code_space[7])                                    \
 +      + (((((code) >> 8) & 0xFF) - (charset)->code_space[4])          \
 +       * (charset)->code_space[3])                                    \
 +      + (((code) & 0xFF) - (charset)->code_space[0])                  \
 +      - ((charset)->char_index_offset))                                       \
 +   : -1)
 +
 +
 +/* Convert the character index IDX to code-point CODE for CHARSET.
 +   It is assumed that IDX is in a valid range.  */
 +
 +#define INDEX_TO_CODE_POINT(charset, idx)                                  \
 +  ((charset)->code_linear_p                                                \
 +   ? (idx) + (charset)->min_code                                           \
 +   : (idx += (charset)->char_index_offset,                                 \
 +      (((charset)->code_space[0] + (idx) % (charset)->code_space[2])       \
 +       | (((charset)->code_space[4]                                        \
 +         + ((idx) / (charset)->code_space[3] % (charset)->code_space[6]))  \
 +        << 8)                                                              \
 +       | (((charset)->code_space[8]                                        \
 +         + ((idx) / (charset)->code_space[7] % (charset)->code_space[10])) \
 +        << 16)                                                             \
 +       | (((charset)->code_space[12] + ((idx) / (charset)->code_space[11]))  \
 +        << 24))))
  
 -/* List of all possible generic characters.  */
 -Lisp_Object Vgeneric_character_list;
  
  \f
 -void
 -invalid_character (c)
 -     int c;
 -{
 -  error ("Invalid character: %d, #o%o, #x%x", c, c, c);
 -}
  
 -/* Parse string STR of length LENGTH and fetch information of a
 -   character at STR.  Set BYTES to the byte length the character
 -   occupies, CHARSET, C1, C2 to proper values of the character. */
 -
 -#define SPLIT_MULTIBYTE_SEQ(str, length, bytes, charset, c1, c2)           \
 -  do {                                                                             \
 -    (c1) = *(str);                                                         \
 -    (bytes) = BYTES_BY_CHAR_HEAD (c1);                                             \
 -    if ((bytes) == 1)                                                      \
 -      (charset) = ASCII_BYTE_P (c1) ? CHARSET_ASCII : CHARSET_8_BIT_GRAPHIC; \
 -    else if ((bytes) == 2)                                                 \
 -      {                                                                            \
 -      if ((c1) == LEADING_CODE_8_BIT_CONTROL)                              \
 -        (charset) = CHARSET_8_BIT_CONTROL, (c1) = (str)[1] - 0x20;         \
 -      else                                                                 \
 -        (charset) = (c1), (c1) = (str)[1] & 0x7F;                          \
 -      }                                                                            \
 -    else if ((bytes) == 3)                                                 \
 -      {                                                                            \
 -      if ((c1) < LEADING_CODE_PRIVATE_11)                                  \
 -        (charset) = (c1), (c1) = (str)[1] & 0x7F, (c2) = (str)[2] & 0x7F;  \
 -      else                                                                 \
 -        (charset) = (str)[1], (c1) = (str)[2] & 0x7F;                      \
 -      }                                                                            \
 -    else                                                                   \
 -      (charset) = (str)[1], (c1) = (str)[2] & 0x7F, (c2) = (str)[3] & 0x7F;  \
 -  } while (0)
 -
 -/* 1 if CHARSET, C1, and C2 compose a valid character, else 0.
 -   Note that this intentionally allows invalid components, such
 -   as 0xA0 0xA0, because there exist many files that contain
 -   such invalid byte sequences, especially in EUC-GB. */
 -#define CHAR_COMPONENTS_VALID_P(charset, c1, c2)      \
 -  ((charset) == CHARSET_ASCII                         \
 -   ? ((c1) >= 0 && (c1) <= 0x7F)                      \
 -   : ((charset) == CHARSET_8_BIT_CONTROL              \
 -      ? ((c1) >= 0x80 && (c1) <= 0x9F)                        \
 -      : ((charset) == CHARSET_8_BIT_GRAPHIC           \
 -       ? ((c1) >= 0x80 && (c1) <= 0xFF)               \
 -       : (CHARSET_DIMENSION (charset) == 1            \
 -          ? ((c1) >= 0x20 && (c1) <= 0x7F)            \
 -          : ((c1) >= 0x20 && (c1) <= 0x7F             \
 -             && (c2) >= 0x20 && (c2) <= 0x7F)))))
 -
 -/* Store multi-byte form of the character C in STR.  The caller should
 -   allocate at least 4-byte area at STR in advance.  Returns the
 -   length of the multi-byte form.  If C is an invalid character code,
 -   return -1.  */
 +/* Set to 1 to warn that a charset map is loaded and thus a buffer
 +   text and a string data may be relocated.  */
 +int charset_map_loaded;
  
 -int
 -char_to_string_1 (c, str)
 -     int c;
 -     unsigned char *str;
 +struct charset_map_entries
  {
 -  unsigned char *p = str;
 +  struct {
 +    unsigned from, to;
 +    int c;
 +  } entry[0x10000];
 +  struct charset_map_entries *next;
 +};
 +
 +/* Load the mapping information for CHARSET from ENTRIES.
 +
 +   If CONTROL_FLAG is 0, setup CHARSET->min_char and CHARSET->max_char.
 +
 +   If CONTROL_FLAG is 1, setup CHARSET->min_char, CHARSET->max_char,
 +   CHARSET->decoder, and CHARSET->encoder.
 +
 +   If CONTROL_FLAG is 2, setup CHARSET->deunifier and
 +   Vchar_unify_table.  If Vchar_unified_charset_table is non-nil,
 +   setup it too.  */
 +
 +static void
 +load_charset_map (charset, entries, n_entries, control_flag)
 +  struct charset *charset;
 +  struct charset_map_entries *entries;
 +  int n_entries;
 +  int control_flag;
 +{
 +  Lisp_Object vec, table;
 +  unsigned max_code = CHARSET_MAX_CODE (charset);
 +  int ascii_compatible_p = charset->ascii_compatible_p;
 +  int min_char, max_char, nonascii_min_char;
 +  int i;
 +  unsigned char *fast_map = charset->fast_map;
  
 -  if (c & CHAR_MODIFIER_MASK) /* This includes the case C is negative.  */
 +  if (n_entries <= 0)
 +    return;
 +
 +  if (control_flag > 0)
      {
 -      /* Multibyte character can't have a modifier bit.  */
 -      if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
 -      return -1;
 +      int n = CODE_POINT_TO_INDEX (charset, max_code) + 1;
  
 -      /* For Meta, Shift, and Control modifiers, we need special care.  */
 -      if (c & CHAR_META)
 +      table = Fmake_char_table (Qnil, Qnil);
 +      if (control_flag == 1)
 +      vec = Fmake_vector (make_number (n), make_number (-1));
 +      else if (! CHAR_TABLE_P (Vchar_unify_table))
 +      Vchar_unify_table = Fmake_char_table (Qnil, Qnil);
 +
 +      charset_map_loaded = 1;
 +    }
 +
 +  min_char = max_char = entries->entry[0].c;
 +  nonascii_min_char = MAX_CHAR;
 +  for (i = 0; i < n_entries; i++)
 +    {
 +      unsigned from, to;
 +      int from_index, to_index;
 +      int from_c, to_c;
 +      int idx = i % 0x10000;
 +
 +      if (i > 0 && idx == 0)
 +      entries = entries->next;
 +      from = entries->entry[idx].from;
 +      to = entries->entry[idx].to;
 +      from_c = entries->entry[idx].c;
 +      from_index = CODE_POINT_TO_INDEX (charset, from);
 +      if (from == to)
        {
 -        /* Move the meta bit to the right place for a string.  */
 -        c = (c & ~CHAR_META) | 0x80;
 +        to_index = from_index;
 +        to_c = from_c;
        }
 -      if (c & CHAR_SHIFT)
 +      else
        {
 -        /* Shift modifier is valid only with [A-Za-z].  */
 -        if ((c & 0377) >= 'A' && (c & 0377) <= 'Z')
 -          c &= ~CHAR_SHIFT;
 -        else if ((c & 0377) >= 'a' && (c & 0377) <= 'z')
 -          c = (c & ~CHAR_SHIFT) - ('a' - 'A');
 +        to_index = CODE_POINT_TO_INDEX (charset, to);
 +        to_c = from_c + (to_index - from_index);
        }
 -      if (c & CHAR_CTL)
 +      if (from_index < 0 || to_index < 0)
 +      continue;
 +
 +      if (control_flag < 2)
        {
 -        /* Simulate the code in lread.c.  */
 -        /* Allow `\C- ' and `\C-?'.  */
 -        if (c == (CHAR_CTL | ' '))
 -          c = 0;
 -        else if (c == (CHAR_CTL | '?'))
 -          c = 127;
 -        /* ASCII control chars are made from letters (both cases),
 -           as well as the non-letters within 0100...0137.  */
 -        else if ((c & 0137) >= 0101 && (c & 0137) <= 0132)
 -          c &= (037 | (~0177 & ~CHAR_CTL));
 -        else if ((c & 0177) >= 0100 && (c & 0177) <= 0137)
 -          c &= (037 | (~0177 & ~CHAR_CTL));
 -      }
 +        int c;
  
 -      /* If C still has any modifier bits, just ignore it.  */
 -      c &= ~CHAR_MODIFIER_MASK;
 -    }
 +        if (to_c > max_char)
 +          max_char = to_c;
 +        else if (from_c < min_char)
 +          min_char = from_c;
 +        if (ascii_compatible_p)
 +          {
 +            if (! ASCII_BYTE_P (from_c))
 +              {
 +                if (from_c < nonascii_min_char)
 +                  nonascii_min_char = from_c;
 +              }
 +            else if (! ASCII_BYTE_P (to_c))
 +              {
 +                nonascii_min_char = 0x80;
 +              }
 +          }
  
 -  if (SINGLE_BYTE_CHAR_P (c))
 -    {
 -      if (ASCII_BYTE_P (c) || c >= 0xA0)
 -      *p++ = c;
 +        for (c = from_c; c <= to_c; c++)
 +          CHARSET_FAST_MAP_SET (c, fast_map);
 +
 +        if (control_flag == 1)
 +          {
 +            unsigned code = from;
 +
 +            if (CHARSET_COMPACT_CODES_P (charset))
 +              while (1)
 +                {
 +                  ASET (vec, from_index, make_number (from_c));
 +                  if (NILP (CHAR_TABLE_REF (table, from_c)))
 +                    CHAR_TABLE_SET (table, from_c, make_number (code));
 +                  if (from_index == to_index)
 +                    break;
 +                  from_index++, from_c++;
 +                  code = INDEX_TO_CODE_POINT (charset, from_index);
 +                }
 +            else
 +              for (; from_index <= to_index; from_index++, from_c++)
 +                {
 +                  ASET (vec, from_index, make_number (from_c));
 +                  if (NILP (CHAR_TABLE_REF (table, from_c)))
 +                    CHAR_TABLE_SET (table, from_c, make_number (from_index));
 +                }
 +          }
 +      }
        else
        {
 -        *p++ = LEADING_CODE_8_BIT_CONTROL;
 -        *p++ = c + 0x20;
 +        unsigned code = from;
 +
 +        while (1)
 +          {
 +            int c1 = DECODE_CHAR (charset, code);
 +
 +            if (c1 >= 0)
 +              {
 +                CHAR_TABLE_SET (table, from_c, make_number (c1));
 +                CHAR_TABLE_SET (Vchar_unify_table, c1, make_number (from_c));
 +                if (CHAR_TABLE_P (Vchar_unified_charset_table))
 +                  CHAR_TABLE_SET (Vchar_unified_charset_table, c1,
 +                                  CHARSET_NAME (charset));
 +              }
 +            if (from_index == to_index)
 +              break;
 +            from_index++, from_c++;
 +            code = INDEX_TO_CODE_POINT (charset, from_index);
 +          }
        }
      }
 -  else if (CHAR_VALID_P (c, 0))
 -    {
 -      int charset, c1, c2;
  
 -      SPLIT_CHAR (c, charset, c1, c2);
 -
 -      if (charset >= LEADING_CODE_EXT_11)
 -      *p++ = (charset < LEADING_CODE_EXT_12
 -              ? LEADING_CODE_PRIVATE_11
 -              : (charset < LEADING_CODE_EXT_21
 -                 ? LEADING_CODE_PRIVATE_12
 -                 : (charset < LEADING_CODE_EXT_22
 -                    ? LEADING_CODE_PRIVATE_21
 -                    : LEADING_CODE_PRIVATE_22)));
 -      *p++ = charset;
 -      if ((c1 > 0 && c1 < 32) || (c2 > 0 && c2 < 32))
 -      return -1;
 -      if (c1)
 +  if (control_flag < 2)
 +    {
 +      CHARSET_MIN_CHAR (charset) = (ascii_compatible_p
 +                                  ? nonascii_min_char : min_char);
 +      CHARSET_MAX_CHAR (charset) = max_char;
 +      if (control_flag == 1)
        {
 -        *p++ = c1 | 0x80;
 -        if (c2 > 0)
 -          *p++ = c2 | 0x80;
 +        CHARSET_DECODER (charset) = vec;
 +        CHARSET_ENCODER (charset) = table;
        }
      }
    else
 -    return -1;
 -
 -  return (p - str);
 +    CHARSET_DEUNIFIER (charset) = table;
  }
  
  
 -/* Store multi-byte form of the character C in STR.  The caller should
 -   allocate at least 4-byte area at STR in advance.  Returns the
 -   length of the multi-byte form.  If C is an invalid character code,
 -   signal an error.
 -
 -   Use macro `CHAR_STRING (C, STR)' instead of calling this function
 -   directly if C can be an ASCII character.  */
 +/* Read a hexadecimal number (preceded by "0x") from the file FP while
 +   paying attention to comment charcter '#'.  */
  
 -int
 -char_to_string (c, str)
 -     int c;
 -     unsigned char *str;
 +static INLINE unsigned
 +read_hex (fp, eof)
 +     FILE *fp;
 +     int *eof;
  {
 -  int len;
 -  len = char_to_string_1 (c, str);
 -  if (len == -1)
 -    invalid_character (c);
 -  return len;
 -}
 +  int c;
 +  unsigned n;
  
 +  while ((c = getc (fp)) != EOF)
 +    {
 +      if (c == '#')
 +      {
 +        while ((c = getc (fp)) != EOF && c != '\n');
 +      }
 +      else if (c == '0')
 +      {
 +        if ((c = getc (fp)) == EOF || c == 'x')
 +          break;
 +      }
 +    }
 +  if (c == EOF)
 +    {
 +      *eof = 1;
 +      return 0;
 +    }
 +  *eof = 0;
 +  n = 0;
 +  if (c == 'x')
 +    while ((c = getc (fp)) != EOF && isxdigit (c))
 +      n = ((n << 4)
 +         | (c <= '9' ? c - '0' : c <= 'F' ? c - 'A' + 10 : c - 'a' + 10));
 +  else
 +    while ((c = getc (fp)) != EOF && isdigit (c))
 +      n = (n * 10) + c - '0';
 +  if (c != EOF)
 +    ungetc (c, fp);
 +  return n;
 +}
  
 -/* Return the non-ASCII character corresponding to multi-byte form at
 -   STR of length LEN.  If ACTUAL_LEN is not NULL, store the byte
 -   length of the multibyte form in *ACTUAL_LEN.
  
 -   Use macros STRING_CHAR or STRING_CHAR_AND_LENGTH instead of calling
 -   this function directly if you want ot handle ASCII characters as
 -   well.  */
 +/* Return a mapping vector for CHARSET loaded from MAPFILE.
 +   Each line of MAPFILE has this form
 +      0xAAAA 0xCCCC
 +   where 0xAAAA is a code-point and 0xCCCC is the corresponding
 +   character code, or this form
 +      0xAAAA-0xBBBB 0xCCCC
 +   where 0xAAAA and 0xBBBB are code-points specifying a range, and
 +   0xCCCC is the first character code of the range.
  
 -int
 -string_to_char (str, len, actual_len)
 -     const unsigned char *str;
 -     int len, *actual_len;
 -{
 -  int c, bytes, charset, c1, c2;
 +   The returned vector has this form:
 +      [ CODE1 CHAR1 CODE2 CHAR2 .... ]
 +   where CODE1 is a code-point or a cons of code-points specifying a
 +   range.  */
  
 -  SPLIT_MULTIBYTE_SEQ (str, len, bytes, charset, c1, c2);
 -  c = MAKE_CHAR (charset, c1, c2);
 -  if (actual_len)
 -    *actual_len = bytes;
 -  return c;
 -}
 +extern void add_to_log P_ ((char *, Lisp_Object, Lisp_Object));
  
 -/* Return the length of the multi-byte form at string STR of length LEN.
 -   Use the macro MULTIBYTE_FORM_LENGTH instead.  */
 -int
 -multibyte_form_length (str, len)
 -     const unsigned char *str;
 -     int len;
 +static void
 +load_charset_map_from_file (charset, mapfile, control_flag)
 +     struct charset *charset;
 +     Lisp_Object mapfile;
 +     int control_flag;
  {
 -  int bytes;
 -
 -  PARSE_MULTIBYTE_SEQ (str, len, bytes);
 -  return bytes;
 -}
 -
 -/* Check multibyte form at string STR of length LEN and set variables
 -   pointed by CHARSET, C1, and C2 to charset and position codes of the
 -   character at STR, and return 0.  If there's no multibyte character,
 -   return -1.  This should be used only in the macro SPLIT_STRING
 -   which checks range of STR in advance.  */
 +  unsigned min_code = CHARSET_MIN_CODE (charset);
 +  unsigned max_code = CHARSET_MAX_CODE (charset);
 +  int fd;
 +  FILE *fp;
 +  int eof;
 +  Lisp_Object suffixes;
 +  struct charset_map_entries *head, *entries;
 +  int n_entries;
 +
 +  suffixes = Fcons (build_string (".map"),
 +                  Fcons (build_string (".TXT"), Qnil));
 +
 +  fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil);
 +  if (fd < 0
 +      || ! (fp = fdopen (fd, "r")))
 +    {
 +      add_to_log ("Failure in loading charset map: %S", mapfile, Qnil);
 +      return;
 +    }
  
 -int
 -split_string (str, len, charset, c1, c2)
 -     const unsigned char *str;
 -     unsigned char *c1, *c2;
 -     int len, *charset;
 -{
 -  register int bytes, cs, code1, code2 = -1;
 +  head = entries = ((struct charset_map_entries *)
 +                  alloca (sizeof (struct charset_map_entries)));
 +  n_entries = 0;
 +  eof = 0;
 +  while (1)
 +    {
 +      unsigned from, to;
 +      int c;
 +      int idx;
  
 -  SPLIT_MULTIBYTE_SEQ (str, len, bytes, cs, code1, code2);
 -  if (cs == CHARSET_ASCII)
 -    return -1;
 -  *charset = cs;
 -  *c1 = code1;
 -  *c2 = code2;
 -  return 0;
 -}
 +      from = read_hex (fp, &eof);
 +      if (eof)
 +      break;
 +      if (getc (fp) == '-')
 +      to = read_hex (fp, &eof);
 +      else
 +      to = from;
 +      c = (int) read_hex (fp, &eof);
  
 -/* Return 1 iff character C has valid printable glyph.
 -   Use the macro CHAR_PRINTABLE_P instead.  */
 -int
 -char_printable_p (c)
 -     int c;
 -{
 -  int charset, c1, c2;
 +      if (from < min_code || to > max_code || from > to || c > MAX_CHAR)
 +      continue;
  
 -  if (ASCII_BYTE_P (c))
 -    return 1;
 -  else if (SINGLE_BYTE_CHAR_P (c))
 -    return 0;
 -  else if (c >= MAX_CHAR)
 -    return 0;
 +      if (n_entries > 0 && (n_entries % 0x10000) == 0)
 +      {
 +        entries->next = ((struct charset_map_entries *)
 +                         alloca (sizeof (struct charset_map_entries)));
 +        entries = entries->next;
 +      }
 +      idx = n_entries % 0x10000;
 +      entries->entry[idx].from = from;
 +      entries->entry[idx].to = to;
 +      entries->entry[idx].c = c;
 +      n_entries++;
 +    }
 +  fclose (fp);
 +  close (fd);
  
 -  SPLIT_CHAR (c, charset, c1, c2);
 -  if (! CHARSET_DEFINED_P (charset))
 -    return 0;
 -  if (CHARSET_CHARS (charset) == 94
 -      ? c1 <= 32 || c1 >= 127
 -      : c1 < 32)
 -    return 0;
 -  if (CHARSET_DIMENSION (charset) == 2
 -      && (CHARSET_CHARS (charset) == 94
 -        ? c2 <= 32 || c2 >= 127
 -        : c2 < 32))
 -    return 0;
 -  return 1;
 +  load_charset_map (charset, head, n_entries, control_flag);
  }
  
 -/* Translate character C by translation table TABLE.  If C
 -   is negative, translate a character specified by CHARSET, C1, and C2
 -   (C1 and C2 are code points of the character).  If no translation is
 -   found in TABLE, return C.  */
 -int
 -translate_char (table, c, charset, c1, c2)
 -     Lisp_Object table;
 -     int c, charset, c1, c2;
 +static void
 +load_charset_map_from_vector (charset, vec, control_flag)
 +     struct charset *charset;
 +     Lisp_Object vec;
 +     int control_flag;
  {
 -  Lisp_Object ch;
 -  int alt_charset, alt_c1, alt_c2, dimension;
 -
 -  if (c < 0) c = MAKE_CHAR (charset, (c1 & 0x7F) , (c2 & 0x7F));
 -  if (!CHAR_TABLE_P (table)
 -      || (ch = Faref (table, make_number (c)), !NATNUMP (ch)))
 -    return c;
 -
 -  SPLIT_CHAR (XFASTINT (ch), alt_charset, alt_c1, alt_c2);
 -  dimension = CHARSET_DIMENSION (alt_charset);
 -  if ((dimension == 1 && alt_c1 > 0) || (dimension == 2 && alt_c2 > 0))
 -    /* CH is not a generic character, just return it.  */
 -    return XFASTINT (ch);
 -
 -  /* Since CH is a generic character, we must return a specific
 -     charater which has the same position codes as C from CH.  */
 -  if (charset < 0)
 -    SPLIT_CHAR (c, charset, c1, c2);
 -  if (dimension != CHARSET_DIMENSION (charset))
 -    /* We can't make such a character because of dimension mismatch.  */
 -    return c;
 -  return MAKE_CHAR (alt_charset, c1, c2);
 -}
 +  unsigned min_code = CHARSET_MIN_CODE (charset);
 +  unsigned max_code = CHARSET_MAX_CODE (charset);
 +  struct charset_map_entries *head, *entries;
 +  int n_entries;
 +  int len = ASIZE (vec);
 +  int i;
  
 -/* Convert the unibyte character C to multibyte based on
 -   Vnonascii_translation_table or nonascii_insert_offset.  If they can't
 -   convert C to a valid multibyte character, convert it based on
 -   DEFAULT_NONASCII_INSERT_OFFSET which makes C a Latin-1 character.  */
 +  if (len % 2 == 1)
 +    {
 +      add_to_log ("Failure in loading charset map: %V", vec, Qnil);
 +      return;
 +    }
  
 -int
 -unibyte_char_to_multibyte (c)
 -     int c;
 -{
 -  if (c < 0400 && c >= 0200)
 +  head = entries = ((struct charset_map_entries *)
 +                  alloca (sizeof (struct charset_map_entries)));
 +  n_entries = 0;
 +  for (i = 0; i < len; i += 2)
      {
 -      int c_save = c;
 +      Lisp_Object val, val2;
 +      unsigned from, to;
 +      int c;
 +      int idx;
  
 -      if (! NILP (Vnonascii_translation_table))
 +      val = AREF (vec, i);
 +      if (CONSP (val))
        {
 -        c = XINT (Faref (Vnonascii_translation_table, make_number (c)));
 -        if (c >= 0400 && ! char_valid_p (c, 0))
 -          c = c_save + DEFAULT_NONASCII_INSERT_OFFSET;
 +        val2 = XCDR (val);
 +        val = XCAR (val);
 +        CHECK_NATNUM (val);
 +        CHECK_NATNUM (val2);
 +        from = XFASTINT (val);
 +        to = XFASTINT (val2);
        }
 -      else if (c >= 0240 && nonascii_insert_offset > 0)
 +      else
        {
 -        c += nonascii_insert_offset;
 -        if (c < 0400 || ! char_valid_p (c, 0))
 -          c = c_save + DEFAULT_NONASCII_INSERT_OFFSET;
 +        CHECK_NATNUM (val);
 +        from = to = XFASTINT (val);
        }
 -      else if (c >= 0240)
 -      c = c_save + DEFAULT_NONASCII_INSERT_OFFSET;
 -    }
 -  return c;
 -}
 +      val = AREF (vec, i + 1);
 +      CHECK_NATNUM (val);
 +      c = XFASTINT (val);
 +
 +      if (from < min_code || to > max_code || from > to || c > MAX_CHAR)
 +      continue;
  
 +      if (n_entries > 0 && (n_entries % 0x10000) == 0)
 +      {
 +        entries->next = ((struct charset_map_entries *)
 +                         alloca (sizeof (struct charset_map_entries)));
 +        entries = entries->next;
 +      }
 +      idx = n_entries % 0x10000;
 +      entries->entry[idx].from = from;
 +      entries->entry[idx].to = to;
 +      entries->entry[idx].c = c;
 +      n_entries++;
 +    }
  
 -/* Convert the multibyte character C to unibyte 8-bit character based
 -   on Vnonascii_translation_table or nonascii_insert_offset.  If
 -   REV_TBL is non-nil, it should be a reverse table of
 -   Vnonascii_translation_table, i.e. what given by:
 -     Fchar_table_extra_slot (Vnonascii_translation_table, make_number (0))  */
 +  load_charset_map (charset, head, n_entries, control_flag);
 +}
  
 -int
 -multibyte_char_to_unibyte (c, rev_tbl)
 -     int c;
 -     Lisp_Object rev_tbl;
 +static void
 +load_charset (charset)
 +     struct charset *charset;
  {
 -  if (!SINGLE_BYTE_CHAR_P (c))
 +  if (CHARSET_METHOD (charset) == CHARSET_METHOD_MAP_DEFERRED)
      {
 -      int c_save = c;
 +      Lisp_Object map;
  
 -      if (! CHAR_TABLE_P (rev_tbl)
 -        && CHAR_TABLE_P (Vnonascii_translation_table))
 -      rev_tbl = Fchar_table_extra_slot (Vnonascii_translation_table,
 -                                        make_number (0));
 -      if (CHAR_TABLE_P (rev_tbl))
 -      {
 -        Lisp_Object temp;
 -        temp = Faref (rev_tbl, make_number (c));
 -        if (INTEGERP (temp))
 -          c = XINT (temp);
 -        if (c >= 256)
 -          c = (c_save & 0177) + 0200;
 -      }
 +      map = CHARSET_MAP (charset);
 +      if (STRINGP (map))
 +      load_charset_map_from_file (charset, map, 1);
        else
 -      {
 -        if (nonascii_insert_offset > 0)
 -          c -= nonascii_insert_offset;
 -        if (c < 128 || c >= 256)
 -          c = (c_save & 0177) + 0200;
 -      }
 +      load_charset_map_from_vector (charset, map, 1);
 +      CHARSET_METHOD (charset) = CHARSET_METHOD_MAP;
      }
 +}
  
 -  return c;
 +
 +DEFUN ("charsetp", Fcharsetp, Scharsetp, 1, 1, 0,
 +       doc: /* Return non-nil if and only if OBJECT is a charset.*/)
 +     (object)
 +     Lisp_Object object;
 +{
 +  return (CHARSETP (object) ? Qt : Qnil);
  }
  
 -\f
 -/* Update the table Vcharset_table with the given arguments (see the
 -   document of `define-charset' for the meaning of each argument).
 -   Several other table contents are also updated.  The caller should
 -   check the validity of CHARSET-ID and the remaining arguments in
 -   advance.  */
  
  void
 -update_charset_table (charset_id, dimension, chars, width, direction,
 -                    iso_final_char, iso_graphic_plane,
 -                    short_name, long_name, description)
 -     Lisp_Object charset_id, dimension, chars, width, direction;
 -     Lisp_Object iso_final_char, iso_graphic_plane;
 -     Lisp_Object short_name, long_name, description;
 +map_charset_chars (c_function, function, arg,
 +                 charset, from, to)
 +     void (*c_function) P_ ((Lisp_Object, Lisp_Object));
 +     Lisp_Object function, arg;
 +     struct charset *charset;
 +     unsigned from, to;
  {
 -  int charset = XINT (charset_id);
 -  int bytes;
 -  unsigned char leading_code_base, leading_code_ext;
 -
 -  if (NILP (CHARSET_TABLE_ENTRY (charset)))
 -    CHARSET_TABLE_ENTRY (charset)
 -      = Fmake_vector (make_number (CHARSET_MAX_IDX), Qnil);
 -
 -  if (NILP (long_name))
 -    long_name = short_name;
 -  if (NILP (description))
 -    description = long_name;
 -
 -  /* Get byte length of multibyte form, base leading-code, and
 -     extended leading-code of the charset.  See the comment under the
 -     title "GENERAL NOTE on CHARACTER SET (CHARSET)" in charset.h.  */
 -  bytes = XINT (dimension);
 -  if (charset < MIN_CHARSET_PRIVATE_DIMENSION1)
 -    {
 -      /* Official charset, it doesn't have an extended leading-code.  */
 -      if (charset != CHARSET_ASCII && charset != CHARSET_8_BIT_GRAPHIC)
 -      bytes += 1; /* For a base leading-code.  */
 -      leading_code_base = charset;
 -      leading_code_ext = 0;
 -    }
 -  else
 -    {
 -      /* Private charset.  */
 -      bytes += 2; /* For base and extended leading-codes.  */
 -      leading_code_base
 -      = (charset < LEADING_CODE_EXT_12
 -         ? LEADING_CODE_PRIVATE_11
 -         : (charset < LEADING_CODE_EXT_21
 -            ? LEADING_CODE_PRIVATE_12
 -            : (charset < LEADING_CODE_EXT_22
 -               ? LEADING_CODE_PRIVATE_21
 -               : LEADING_CODE_PRIVATE_22)));
 -      leading_code_ext = charset;
 -      if (BYTES_BY_CHAR_HEAD (leading_code_base) != bytes)
 -      error ("Invalid dimension for the charset-ID %d", charset);
 -    }
 -
 -  CHARSET_TABLE_INFO (charset, CHARSET_ID_IDX) = charset_id;
 -  CHARSET_TABLE_INFO (charset, CHARSET_BYTES_IDX) = make_number (bytes);
 -  CHARSET_TABLE_INFO (charset, CHARSET_DIMENSION_IDX) = dimension;
 -  CHARSET_TABLE_INFO (charset, CHARSET_CHARS_IDX) = chars;
 -  CHARSET_TABLE_INFO (charset, CHARSET_WIDTH_IDX) = width;
 -  CHARSET_TABLE_INFO (charset, CHARSET_DIRECTION_IDX) = direction;
 -  CHARSET_TABLE_INFO (charset, CHARSET_LEADING_CODE_BASE_IDX)
 -    = make_number (leading_code_base);
 -  CHARSET_TABLE_INFO (charset, CHARSET_LEADING_CODE_EXT_IDX)
 -    = make_number (leading_code_ext);
 -  CHARSET_TABLE_INFO (charset, CHARSET_ISO_FINAL_CHAR_IDX) = iso_final_char;
 -  CHARSET_TABLE_INFO (charset, CHARSET_ISO_GRAPHIC_PLANE_IDX)
 -    = iso_graphic_plane;
 -  CHARSET_TABLE_INFO (charset, CHARSET_SHORT_NAME_IDX) = short_name;
 -  CHARSET_TABLE_INFO (charset, CHARSET_LONG_NAME_IDX) = long_name;
 -  CHARSET_TABLE_INFO (charset, CHARSET_DESCRIPTION_IDX) = description;
 -  CHARSET_TABLE_INFO (charset, CHARSET_PLIST_IDX) = Qnil;
 +  Lisp_Object range;
 +  int partial;
  
 -  {
 -    /* If we have already defined a charset which has the same
 -       DIMENSION, CHARS and ISO-FINAL-CHAR but the different
 -       DIRECTION, we must update the entry REVERSE-CHARSET of both
 -       charsets.  If there's no such charset, the value of the entry
 -       is set to nil.  */
 -    int i;
 -
 -    for (i = 0; i <= MAX_CHARSET; i++)
 -      if (!NILP (CHARSET_TABLE_ENTRY (i)))
 -      {
 -        if (CHARSET_DIMENSION (i) == XINT (dimension)
 -            && CHARSET_CHARS (i) == XINT (chars)
 -            && CHARSET_ISO_FINAL_CHAR (i) == XINT (iso_final_char)
 -            && CHARSET_DIRECTION (i) != XINT (direction))
 -          {
 -            CHARSET_TABLE_INFO (charset, CHARSET_REVERSE_CHARSET_IDX)
 -              = make_number (i);
 -            CHARSET_TABLE_INFO (i, CHARSET_REVERSE_CHARSET_IDX) = charset_id;
 -            break;
 -          }
 -      }
 -    if (i > MAX_CHARSET)
 -      /* No such a charset.  */
 -      CHARSET_TABLE_INFO (charset, CHARSET_REVERSE_CHARSET_IDX)
 -      = make_number (-1);
 -  }
 +  if (CHARSET_METHOD (charset) == CHARSET_METHOD_MAP_DEFERRED)
 +    load_charset (charset);
  
 -  if (charset != CHARSET_ASCII && charset != CHARSET_8_BIT_GRAPHIC
 -      && charset < MIN_CHARSET_PRIVATE_DIMENSION1)
 +  partial = (from > CHARSET_MIN_CODE (charset)
 +           || to < CHARSET_MAX_CODE (charset));
 +
 +  if (CHARSET_UNIFIED_P (charset)
 +      && CHAR_TABLE_P (CHARSET_DEUNIFIER (charset)))
      {
 -      bytes_by_char_head[leading_code_base] = bytes;
 -      width_by_char_head[leading_code_base] = XINT (width);
 +      map_char_table_for_charset (c_function, function,
 +                                CHARSET_DEUNIFIER (charset), arg,
 +                                partial ? charset : NULL, from, to);
 +    }
  
 -      /* Update table emacs_code_class.  */
 -      emacs_code_class[charset] = (bytes == 2
 -                                 ? EMACS_leading_code_2
 -                                 : (bytes == 3
 -                                    ? EMACS_leading_code_3
 -                                    : EMACS_leading_code_4));
 +  if (CHARSET_METHOD (charset) == CHARSET_METHOD_OFFSET)
 +    {
 +      int from_idx = CODE_POINT_TO_INDEX (charset, from);
 +      int to_idx = CODE_POINT_TO_INDEX (charset, to);
 +      int from_c = from_idx + CHARSET_CODE_OFFSET (charset);
 +      int to_c = to_idx + CHARSET_CODE_OFFSET (charset);
 +
 +      range = Fcons (make_number (from_c), make_number (to_c));
 +      if (NILP (function))
 +      (*c_function) (arg, range);
 +      else
 +      call2 (function, range, arg);
 +    }
 +  else if (CHARSET_METHOD (charset) == CHARSET_METHOD_MAP)
 +    {
 +      if (! CHAR_TABLE_P (CHARSET_ENCODER (charset)))
 +      return;
 +      map_char_table_for_charset (c_function, function,
 +                                CHARSET_ENCODER (charset), arg,
 +                                partial ? charset : NULL, from, to);
      }
 +  else if (CHARSET_METHOD (charset) == CHARSET_METHOD_SUBSET)
 +    {
 +      Lisp_Object subset_info;
 +      int offset;
 +
 +      subset_info = CHARSET_SUBSET (charset);
 +      charset = CHARSET_FROM_ID (XFASTINT (AREF (subset_info, 0)));
 +      offset = XINT (AREF (subset_info, 3));
 +      from -= offset;
 +      if (from < XFASTINT (AREF (subset_info, 1)))
 +      from = XFASTINT (AREF (subset_info, 1));
 +      to -= offset;
 +      if (to > XFASTINT (AREF (subset_info, 2)))
 +      to = XFASTINT (AREF (subset_info, 2));
 +      map_charset_chars (c_function, function, arg, charset, from, to);
 +    }
 +  else                                /* i.e. CHARSET_METHOD_SUPERSET */
 +    {
 +      Lisp_Object parents;
  
 -  /* Update table iso_charset_table.  */
 -  if (XINT (iso_final_char) >= 0
 -      && ISO_CHARSET_TABLE (dimension, chars, iso_final_char) < 0)
 -    ISO_CHARSET_TABLE (dimension, chars, iso_final_char) = charset;
 +      for (parents = CHARSET_SUPERSET (charset); CONSP (parents);
 +         parents = XCDR (parents))
 +      {
 +        int offset;
 +        unsigned this_from, this_to;
 +
 +        charset = CHARSET_FROM_ID (XFASTINT (XCAR (XCAR (parents))));
 +        offset = XINT (XCDR (XCAR (parents)));
 +        this_from = from - offset;
 +        this_to = to - offset;
 +        if (this_from < CHARSET_MIN_CODE (charset))
 +          this_from = CHARSET_MIN_CODE (charset);
 +        if (this_to > CHARSET_MAX_CODE (charset))
 +          this_to = CHARSET_MAX_CODE (charset);
 +        map_charset_chars (c_function, function, arg, charset,
 +                           this_from, this_to);
 +      }
 +    }
  }
  
 -#ifdef emacs
 +DEFUN ("map-charset-chars", Fmap_charset_chars, Smap_charset_chars, 2, 5, 0,
 +       doc: /* Call FUNCTION for all characters in CHARSET.
 +FUNCTION is called with an argument RANGE and the optional 3rd
 +argument ARG.
  
 -/* Return charset id of CHARSET_SYMBOL, or return -1 if CHARSET_SYMBOL
 -   is invalid.  */
 -int
 -get_charset_id (charset_symbol)
 -     Lisp_Object charset_symbol;
 -{
 -  Lisp_Object val;
 -  int charset;
 -
 -  /* This originally used a ?: operator, but reportedly the HP-UX
 -     compiler version HP92453-01 A.10.32.22 miscompiles that.  */
 -  if (SYMBOLP (charset_symbol)
 -      && VECTORP (val = Fget (charset_symbol, Qcharset))
 -      && CHARSET_VALID_P (charset =
 -                        XINT (XVECTOR (val)->contents[CHARSET_ID_IDX])))
 -    return charset;
 -  else
 -    return -1;
 -}
 +RANGE is a cons (FROM .  TO), where FROM and TO indicate a range of
 +characters contained in CHARSET.
  
 -/* Return an identification number for a new private charset of
 -   DIMENSION and WIDTH.  If there's no more room for the new charset,
 -   return 0.  */
 -Lisp_Object
 -get_new_private_charset_id (dimension, width)
 -     int dimension, width;
 +The optional 4th and 5th arguments FROM-CODE and TO-CODE specify the
 +range of code points of target characters.  */)
 +     (function, charset, arg, from_code, to_code)
 +       Lisp_Object function, charset, arg, from_code, to_code;
  {
 -  int charset, from, to;
 +  struct charset *cs;
 +  unsigned from, to;
  
 -  if (dimension == 1)
 +  CHECK_CHARSET_GET_CHARSET (charset, cs);
 +  if (NILP (from_code))
 +    from = CHARSET_MIN_CODE (cs);
 +  else
      {
 -      from = LEADING_CODE_EXT_11;
 -      to = LEADING_CODE_EXT_21;
 +      CHECK_NATNUM (from_code);
 +      from = XINT (from_code);
 +      if (from < CHARSET_MIN_CODE (cs))
 +      from = CHARSET_MIN_CODE (cs);
      }
 +  if (NILP (to_code))
 +    to = CHARSET_MAX_CODE (cs);
    else
      {
 -      from = LEADING_CODE_EXT_21;
 -      to = LEADING_CODE_EXT_MAX + 1;
 +      CHECK_NATNUM (to_code);
 +      to = XINT (to_code);
 +      if (to > CHARSET_MAX_CODE (cs))
 +      to = CHARSET_MAX_CODE (cs);
      }
 -
 -  for (charset = from; charset < to; charset++)
 -    if (!CHARSET_DEFINED_P (charset)) break;
 -
 -  return make_number (charset < to ? charset : 0);
 -}
 -
 -DEFUN ("define-charset", Fdefine_charset, Sdefine_charset, 3, 3, 0,
 -       doc: /* Define CHARSET-ID as the identification number of CHARSET with INFO-VECTOR.
 -If CHARSET-ID is nil, it is decided automatically, which means CHARSET is
 - treated as a private charset.
 -INFO-VECTOR is a vector of the format:
 -   [DIMENSION CHARS WIDTH DIRECTION ISO-FINAL-CHAR ISO-GRAPHIC-PLANE
 -    SHORT-NAME LONG-NAME DESCRIPTION]
 -The meanings of each elements is as follows:
 -DIMENSION (integer) is the number of bytes to represent a character: 1 or 2.
 -CHARS (integer) is the number of characters in a dimension: 94 or 96.
 -WIDTH (integer) is the number of columns a character in the charset
 -occupies on the screen: one of 0, 1, and 2.
 -
 -DIRECTION (integer) is the rendering direction of characters in the
 -charset when rendering.  If 0, render from left to right, else
 -render from right to left.
 -
 -ISO-FINAL-CHAR (character) is the final character of the
 -corresponding ISO 2022 charset.
 -It may be -1 if the charset is internal use only.
 -
 -ISO-GRAPHIC-PLANE (integer) is the graphic plane to be invoked
 -while encoding to variants of ISO 2022 coding system, one of the
 -following: 0/graphic-plane-left(GL), 1/graphic-plane-right(GR).
 -It may be -1 if the charset is internal use only.
 -
 -SHORT-NAME (string) is the short name to refer to the charset.
 -
 -LONG-NAME (string) is the long name to refer to the charset.
 -
 -DESCRIPTION (string) is the description string of the charset.  */)
 -       (charset_id, charset_symbol, info_vector)
 -     Lisp_Object charset_id, charset_symbol, info_vector;
 -{
 -  Lisp_Object *vec;
 -
 -  if (!NILP (charset_id))
 -    CHECK_NUMBER (charset_id);
 -  CHECK_SYMBOL (charset_symbol);
 -  CHECK_VECTOR (info_vector);
 -
 -  if (! NILP (charset_id))
 -    {
 -      if (! CHARSET_VALID_P (XINT (charset_id)))
 -      error ("Invalid CHARSET: %d", XINT (charset_id));
 -      else if (CHARSET_DEFINED_P (XINT (charset_id)))
 -      error ("Already defined charset: %d", XINT (charset_id));
 -    }
 -
 -  vec = XVECTOR (info_vector)->contents;
 -  if (XVECTOR (info_vector)->size != 9
 -      || !INTEGERP (vec[0]) || !(XINT (vec[0]) == 1 || XINT (vec[0]) == 2)
 -      || !INTEGERP (vec[1]) || !(XINT (vec[1]) == 94 || XINT (vec[1]) == 96)
 -      || !INTEGERP (vec[2]) || !(XINT (vec[2]) == 1 || XINT (vec[2]) == 2)
 -      || !INTEGERP (vec[3]) || !(XINT (vec[3]) == 0 || XINT (vec[3]) == 1)
 -      || !INTEGERP (vec[4])
 -      || !(XINT (vec[4]) == -1 || (XINT (vec[4]) >= '0' && XINT (vec[4]) <= '~'))
 -      || !INTEGERP (vec[5])
 -      || !(XINT (vec[5]) == -1 || XINT (vec[5]) == 0 || XINT (vec[5]) == 1)
 -      || !STRINGP (vec[6])
 -      || !STRINGP (vec[7])
 -      || !STRINGP (vec[8]))
 -    error ("Invalid info-vector argument for defining charset %s",
 -         SDATA (SYMBOL_NAME (charset_symbol)));
 -
 -  if (NILP (charset_id))
 -    {
 -      charset_id = get_new_private_charset_id (XINT (vec[0]), XINT (vec[2]));
 -      if (XINT (charset_id) == 0)
 -      error ("There's no room for a new private charset %s",
 -             SDATA (SYMBOL_NAME (charset_symbol)));
 -    }
 -
 -  update_charset_table (charset_id, vec[0], vec[1], vec[2], vec[3],
 -                      vec[4], vec[5], vec[6], vec[7], vec[8]);
 -  Fput (charset_symbol, Qcharset, CHARSET_TABLE_ENTRY (XINT (charset_id)));
 -  CHARSET_SYMBOL (XINT (charset_id)) = charset_symbol;
 -  Vcharset_list = Fcons (charset_symbol, Vcharset_list);
 -  Fupdate_coding_systems_internal ();
 +  map_charset_chars (NULL, function, arg, cs, from, to);
    return Qnil;
  }
  
 -DEFUN ("generic-character-list", Fgeneric_character_list,
 -       Sgeneric_character_list, 0, 0, 0,
 -       doc: /* Return a list of all possible generic characters.
 -It includes a generic character for a charset not yet defined.  */)
 -     ()
 -{
 -  return Vgeneric_character_list;
 -}
  
 -DEFUN ("get-unused-iso-final-char", Fget_unused_iso_final_char,
 -       Sget_unused_iso_final_char, 2, 2, 0,
 -       doc: /* Return an unused ISO's final char for a charset of DIMENSION and CHARS.
 -DIMENSION is the number of bytes to represent a character: 1 or 2.
 -CHARS is the number of characters in a dimension: 94 or 96.
 +/* Define a charset according to the arguments.  The Nth argument is
 +   the Nth attribute of the charset (the last attribute `charset-id'
 +   is not included).  See the docstring of `define-charset' for the
 +   detail.  */
  
 -This final char is for private use, thus the range is `0' (48) .. `?' (63).
 -If there's no unused final char for the specified kind of charset,
 -return nil.  */)
 -     (dimension, chars)
 -     Lisp_Object dimension, chars;
 +DEFUN ("define-charset-internal", Fdefine_charset_internal,
 +       Sdefine_charset_internal, charset_arg_max, MANY, 0,
 +       doc: /* For internal use only.
 +usage: (define-charset-internal ...)  */)
 +     (nargs, args)
 +     int nargs;
 +     Lisp_Object *args;
  {
 -  int final_char;
 +  /* Charset attr vector.  */
 +  Lisp_Object attrs;
 +  Lisp_Object val;
 +  unsigned hash_code;
 +  struct Lisp_Hash_Table *hash_table = XHASH_TABLE (Vcharset_hash_table);
 +  int i, j;
 +  struct charset charset;
 +  int id;
 +  int dimension;
 +  int new_definition_p;
 +  int nchars;
 +
 +  if (nargs != charset_arg_max)
 +    return Fsignal (Qwrong_number_of_arguments,
 +                  Fcons (intern ("define-charset-internal"),
 +                         make_number (nargs)));
 +
 +  attrs = Fmake_vector (make_number (charset_attr_max), Qnil);
 +
 +  CHECK_SYMBOL (args[charset_arg_name]);
 +  ASET (attrs, charset_name, args[charset_arg_name]);
 +
 +  val = args[charset_arg_code_space];
 +  for (i = 0, dimension = 0, nchars = 1; i < 4; i++)
 +    {
 +      int min_byte, max_byte;
 +
 +      min_byte = XINT (Faref (val, make_number (i * 2)));
 +      max_byte = XINT (Faref (val, make_number (i * 2 + 1)));
 +      if (min_byte < 0 || min_byte > max_byte || max_byte >= 256)
 +      error ("Invalid :code-space value");
 +      charset.code_space[i * 4] = min_byte;
 +      charset.code_space[i * 4 + 1] = max_byte;
 +      charset.code_space[i * 4 + 2] = max_byte - min_byte + 1;
 +      nchars *= charset.code_space[i * 4 + 2];
 +      charset.code_space[i * 4 + 3] = nchars;
 +      if (max_byte > 0)
 +      dimension = i + 1;
 +    }
  
 -  CHECK_NUMBER (dimension);
 -  CHECK_NUMBER (chars);
 -  if (XINT (dimension) != 1 && XINT (dimension) != 2)
 -    error ("Invalid charset dimension %d, it should be 1 or 2",
 -         XINT (dimension));
 -  if (XINT (chars) != 94 && XINT (chars) != 96)
 -    error ("Invalid charset chars %d, it should be 94 or 96",
 -         XINT (chars));
 -  for (final_char = '0'; final_char <= '?'; final_char++)
 +  val = args[charset_arg_dimension];
 +  if (NILP (val))
 +    charset.dimension = dimension;
 +  else
      {
 -      if (ISO_CHARSET_TABLE (dimension, chars, make_number (final_char)) < 0)
 -      break;
 +      CHECK_NATNUM (val);
 +      charset.dimension = XINT (val);
 +      if (charset.dimension < 1 || charset.dimension > 4)
 +      args_out_of_range_3 (val, make_number (1), make_number (4));
      }
 -  return (final_char <= '?' ? make_number (final_char) : Qnil);
 -}
  
 -DEFUN ("declare-equiv-charset", Fdeclare_equiv_charset, Sdeclare_equiv_charset,
 -       4, 4, 0,
 -       doc: /* Declare an equivalent charset for ISO-2022 decoding.
 +  charset.code_linear_p
 +    = (charset.dimension == 1
 +       || (charset.code_space[2] == 256
 +         && (charset.dimension == 2
 +             || (charset.code_space[6] == 256
 +                 && (charset.dimension == 3
 +                     || charset.code_space[10] == 256)))));
  
 -On decoding by an ISO-2022 base coding system, when a charset
 -specified by DIMENSION, CHARS, and FINAL-CHAR is designated, behave as
 -if CHARSET is designated instead.  */)
 -     (dimension, chars, final_char, charset)
 -     Lisp_Object dimension, chars, final_char, charset;
 -{
 -  int charset_id;
 +  if (! charset.code_linear_p)
 +    {
 +      charset.code_space_mask = (unsigned char *) xmalloc (256);
 +      bzero (charset.code_space_mask, 256);
 +      for (i = 0; i < 4; i++)
 +      for (j = charset.code_space[i * 4]; j <= charset.code_space[i * 4 + 1];
 +           j++)
 +        charset.code_space_mask[j] |= (1 << i);
 +    }
  
 -  CHECK_NUMBER (dimension);
 -  CHECK_NUMBER (chars);
 -  CHECK_NUMBER (final_char);
 -  CHECK_SYMBOL (charset);
 +  charset.iso_chars_96 = charset.code_space[2] == 96;
  
 -  if (XINT (dimension) != 1 && XINT (dimension) != 2)
 -    error ("Invalid DIMENSION %d, it should be 1 or 2", XINT (dimension));
 -  if (XINT (chars) != 94 && XINT (chars) != 96)
 -    error ("Invalid CHARS %d, it should be 94 or 96", XINT (chars));
 -  if (XINT (final_char) < '0' || XFASTINT (final_char) > '~')
 -    error ("Invalid FINAL-CHAR %c, it should be `0'..`~'", XINT (chars));
 -  if ((charset_id = get_charset_id (charset)) < 0)
 -    error ("Invalid charset %s", SDATA (SYMBOL_NAME (charset)));
 +  charset.min_code = (charset.code_space[0]
 +                    | (charset.code_space[4] << 8)
 +                    | (charset.code_space[8] << 16)
 +                    | (charset.code_space[12] << 24));
 +  charset.max_code = (charset.code_space[1]
 +                    | (charset.code_space[5] << 8)
 +                    | (charset.code_space[9] << 16)
 +                    | (charset.code_space[13] << 24));
 +  charset.char_index_offset = 0;
  
 -  ISO_CHARSET_TABLE (dimension, chars, final_char) = charset_id;
 -  return Qnil;
 -}
 +  val = args[charset_arg_min_code];
 +  if (! NILP (val))
 +    {
 +      unsigned code;
  
 -/* Return information about charsets in the text at PTR of NBYTES
 -   bytes, which are NCHARS characters.  The value is:
 +      if (INTEGERP (val))
 +      code = XINT (val);
 +      else
 +      {
 +        CHECK_CONS (val);
 +        CHECK_NUMBER_CAR (val);
 +        CHECK_NUMBER_CDR (val);
 +        code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val)));
 +      }
 +      if (code < charset.min_code
 +        || code > charset.max_code)
 +      args_out_of_range_3 (make_number (charset.min_code),
 +                           make_number (charset.max_code), val);
 +      charset.char_index_offset = CODE_POINT_TO_INDEX (&charset, code);
 +      charset.min_code = code;
 +    }
  
 -      0: Each character is represented by one byte.  This is always
 -         true for unibyte text.
 -      1: No charsets other than ascii eight-bit-control,
 -         eight-bit-graphic, and latin-1 are found.
 -      2: Otherwise.
 +  val = args[charset_arg_max_code];
 +  if (! NILP (val))
 +    {
 +      unsigned code;
 +
 +      if (INTEGERP (val))
 +      code = XINT (val);
 +      else
 +      {
 +        CHECK_CONS (val);
 +        CHECK_NUMBER_CAR (val);
 +        CHECK_NUMBER_CDR (val);
 +        code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val)));
 +      }
 +      if (code < charset.min_code
 +        || code > charset.max_code)
 +      args_out_of_range_3 (make_number (charset.min_code),
 +                           make_number (charset.max_code), val);
 +      charset.max_code = code;
 +    }
  
 -   In addition, if CHARSETS is nonzero, for each found charset N, set
 -   CHARSETS[N] to 1.  For that, callers should allocate CHARSETS
 -   (MAX_CHARSET + 1 elements) in advance.  It may lookup a translation
 -   table TABLE if supplied.  For invalid charsets, set CHARSETS[1] to
 -   1 (note that there's no charset whose ID is 1).  */
 +  charset.compact_codes_p = charset.max_code < 0x1000000;
  
 -int
 -find_charset_in_text (ptr, nchars, nbytes, charsets, table)
 -     const unsigned char *ptr;
 -     int nchars, nbytes, *charsets;
 -     Lisp_Object table;
 -{
 -  if (nchars == nbytes)
 +  val = args[charset_arg_invalid_code];
 +  if (NILP (val))
      {
 -      if (charsets && nbytes > 0)
 +      if (charset.min_code > 0)
 +      charset.invalid_code = 0;
 +      else
        {
 -        const unsigned char *endp = ptr + nbytes;
 -        int maskbits = 0;
 +        XSETINT (val, charset.max_code + 1);
 +        if (XINT (val) == charset.max_code + 1)
 +          charset.invalid_code = charset.max_code + 1;
 +        else
 +          error ("Attribute :invalid-code must be specified");
 +      }
 +    }
 +  else
 +    {
 +      CHECK_NATNUM (val);
 +      charset.invalid_code = XFASTINT (val);
 +    }
  
 -        while (ptr < endp && maskbits != 7)
 -          {
 -            maskbits |= (*ptr < 0x80 ? 1 : *ptr < 0xA0 ? 2 : 4);
 -            ptr++;
 -          }
 +  val = args[charset_arg_iso_final];
 +  if (NILP (val))
 +    charset.iso_final = -1;
 +  else
 +    {
 +      CHECK_NUMBER (val);
 +      if (XINT (val) < '0' || XINT (val) > 127)
 +      error ("Invalid iso-final-char: %d", XINT (val));
 +      charset.iso_final = XINT (val);
 +    }
  
 -        if (maskbits & 1)
 -          charsets[CHARSET_ASCII] = 1;
 -        if (maskbits & 2)
 -          charsets[CHARSET_8_BIT_CONTROL] = 1;
 -        if (maskbits & 4)
 -          charsets[CHARSET_8_BIT_GRAPHIC] = 1;
 -      }
 -      return 0;
 +  val = args[charset_arg_iso_revision];
 +  if (NILP (val))
 +    charset.iso_revision = -1;
 +  else
 +    {
 +      CHECK_NUMBER (val);
 +      if (XINT (val) > 63)
 +      args_out_of_range (make_number (63), val);
 +      charset.iso_revision = XINT (val);
      }
 +
 +  val = args[charset_arg_emacs_mule_id];
 +  if (NILP (val))
 +    charset.emacs_mule_id = -1;
    else
      {
 -      int return_val = 1;
 -      int bytes, charset, c1, c2;
 +      CHECK_NATNUM (val);
 +      if ((XINT (val) > 0 && XINT (val) <= 128) || XINT (val) >= 256)
 +      error ("Invalid emacs-mule-id: %d", XINT (val));
 +      charset.emacs_mule_id = XINT (val);
 +    }
  
 -      if (! CHAR_TABLE_P (table))
 -      table = Qnil;
 +  charset.ascii_compatible_p = ! NILP (args[charset_arg_ascii_compatible_p]);
  
 -      while (nchars-- > 0)
 -      {
 -        SPLIT_MULTIBYTE_SEQ (ptr, len, bytes, charset, c1, c2);
 -        ptr += bytes;
 +  charset.supplementary_p = ! NILP (args[charset_arg_supplementary_p]);
  
 -        if (!CHARSET_DEFINED_P (charset))
 -          charset = 1;
 -        else if (! NILP (table))
 -          {
 -            int c = translate_char (table, -1, charset, c1, c2);
 -            if (c >= 0)
 -              charset = CHAR_CHARSET (c);
 -          }
 +  charset.unified_p = 0;
  
 -        if (return_val == 1
 -            && charset != CHARSET_ASCII
 -            && charset != CHARSET_8_BIT_CONTROL
 -            && charset != CHARSET_8_BIT_GRAPHIC
 -            && charset != charset_latin_iso8859_1)
 -          return_val = 2;
 +  bzero (charset.fast_map, sizeof (charset.fast_map));
  
 -        if (charsets)
 -          charsets[charset] = 1;
 -        else if (return_val == 2)
 -          break;
 -      }
 -      return return_val;
 +  if (! NILP (args[charset_arg_code_offset]))
 +    {
 +      val = args[charset_arg_code_offset];
 +      CHECK_NUMBER (val);
 +
 +      charset.method = CHARSET_METHOD_OFFSET;
 +      charset.code_offset = XINT (val);
 +
 +      i = CODE_POINT_TO_INDEX (&charset, charset.min_code);
 +      charset.min_char = i + charset.code_offset;
 +      i = CODE_POINT_TO_INDEX (&charset, charset.max_code);
 +      charset.max_char = i + charset.code_offset;
 +      if (charset.max_char > MAX_CHAR)
 +      error ("Unsupported max char: %d", charset.max_char);
 +
 +      i = (charset.min_char >> 7) << 7;
 +      for (; i < 0x10000 && i <= charset.max_char; i += 128)
 +      CHARSET_FAST_MAP_SET (i, charset.fast_map);
 +      i = (i >> 12) << 12;
 +      for (; i <= charset.max_char; i += 0x1000)
 +      CHARSET_FAST_MAP_SET (i, charset.fast_map);
      }
 -}
 -
 -DEFUN ("find-charset-region", Ffind_charset_region, Sfind_charset_region,
 +  else if (! NILP (args[charset_arg_map]))
 +    {
 +      val = args[charset_arg_map];
 +      ASET (attrs, charset_map, val);
 +      if (STRINGP (val))
 +      load_charset_map_from_file (&charset, val, 0);
 +      else
 +      load_charset_map_from_vector (&charset, val, 0);
 +      charset.method = CHARSET_METHOD_MAP_DEFERRED;
 +    }
 +  else if (! NILP (args[charset_arg_subset]))
 +    {
 +      Lisp_Object parent;
 +      Lisp_Object parent_min_code, parent_max_code, parent_code_offset;
 +      struct charset *parent_charset;
 +
 +      val = args[charset_arg_subset];
 +      parent = Fcar (val);
 +      CHECK_CHARSET_GET_CHARSET (parent, parent_charset);
 +      parent_min_code = Fnth (make_number (1), val);
 +      CHECK_NATNUM (parent_min_code);
 +      parent_max_code = Fnth (make_number (2), val);
 +      CHECK_NATNUM (parent_max_code);
 +      parent_code_offset = Fnth (make_number (3), val);
 +      CHECK_NUMBER (parent_code_offset);
 +      val = Fmake_vector (make_number (4), Qnil);
 +      ASET (val, 0, make_number (parent_charset->id));
 +      ASET (val, 1, parent_min_code);
 +      ASET (val, 2, parent_max_code);
 +      ASET (val, 3, parent_code_offset);
 +      ASET (attrs, charset_subset, val);
 +
 +      charset.method = CHARSET_METHOD_SUBSET;
 +      /* Here, we just copy the parent's fast_map.  It's not accurate,
 +       but at least it works for quickly detecting which character
 +       DOESN'T belong to this charset.  */
 +      for (i = 0; i < 190; i++)
 +      charset.fast_map[i] = parent_charset->fast_map[i];
 +
 +      /* We also copy these for parents.  */
 +      charset.min_char = parent_charset->min_char;
 +      charset.max_char = parent_charset->max_char;
 +    }
 +  else if (! NILP (args[charset_arg_superset]))
 +    {
 +      val = args[charset_arg_superset];
 +      charset.method = CHARSET_METHOD_SUPERSET;
 +      val = Fcopy_sequence (val);
 +      ASET (attrs, charset_superset, val);
 +
 +      charset.min_char = MAX_CHAR;
 +      charset.max_char = 0;
 +      for (; ! NILP (val); val = Fcdr (val))
 +      {
 +        Lisp_Object elt, car_part, cdr_part;
 +        int this_id, offset;
 +        struct charset *this_charset;
 +
 +        elt = Fcar (val);
 +        if (CONSP (elt))
 +          {
 +            car_part = XCAR (elt);
 +            cdr_part = XCDR (elt);
 +            CHECK_CHARSET_GET_ID (car_part, this_id);
 +            CHECK_NUMBER (cdr_part);
 +            offset = XINT (cdr_part);
 +          }
 +        else
 +          {
 +            CHECK_CHARSET_GET_ID (elt, this_id);
 +            offset = 0;
 +          }
 +        XSETCAR (val, Fcons (make_number (this_id), make_number (offset)));
 +
 +        this_charset = CHARSET_FROM_ID (this_id);
 +        if (charset.min_char > this_charset->min_char)
 +          charset.min_char = this_charset->min_char;
 +        if (charset.max_char < this_charset->max_char)
 +          charset.max_char = this_charset->max_char;
 +        for (i = 0; i < 190; i++)
 +          charset.fast_map[i] |= this_charset->fast_map[i];
 +      }
 +    }
 +  else
 +    error ("None of :code-offset, :map, :parents are specified");
 +
 +  val = args[charset_arg_unify_map];
 +  if (! NILP (val) && !STRINGP (val))
 +    CHECK_VECTOR (val);
 +  ASET (attrs, charset_unify_map, val);
 +
 +  CHECK_LIST (args[charset_arg_plist]);
 +  ASET (attrs, charset_plist, args[charset_arg_plist]);
 +
 +  charset.hash_index = hash_lookup (hash_table, args[charset_arg_name],
 +                                  &hash_code);
 +  if (charset.hash_index >= 0)
 +    {
 +      new_definition_p = 0;
 +      id = XFASTINT (CHARSET_SYMBOL_ID (args[charset_arg_name]));
 +      HASH_VALUE (hash_table, charset.hash_index) = attrs;
 +    }
 +  else
 +    {
 +      charset.hash_index = hash_put (hash_table, args[charset_arg_name], attrs,
 +                                   hash_code);
 +      if (charset_table_used == charset_table_size)
 +      {
 +        struct charset *new_table
 +          = (struct charset *) xmalloc (sizeof (struct charset)
 +                                        * (charset_table_size + 16));
 +        bcopy (charset_table, new_table,
 +               sizeof (struct charset) * charset_table_size);
 +        charset_table_size += 16;
 +        charset_table = new_table;
 +      }
 +      id = charset_table_used++;
 +      new_definition_p = 1;
 +    }
 +
 +  ASET (attrs, charset_id, make_number (id));
 +  charset.id = id;
 +  charset_table[id] = charset;
 +
 +  if (charset.iso_final >= 0)
 +    {
 +      ISO_CHARSET_TABLE (charset.dimension, charset.iso_chars_96,
 +                       charset.iso_final) = id;
 +      if (new_definition_p)
 +      Viso_2022_charset_list = nconc2 (Viso_2022_charset_list,
 +                                       Fcons (make_number (id), Qnil));
 +      if (ISO_CHARSET_TABLE (1, 0, 'J') == id)
 +      charset_jisx0201_roman = id;
 +      else if (ISO_CHARSET_TABLE (2, 0, '@') == id)
 +      charset_jisx0208_1978 = id;
 +      else if (ISO_CHARSET_TABLE (2, 0, 'B') == id)
 +      charset_jisx0208 = id;
 +    }
 +      
 +  if (charset.emacs_mule_id >= 0)
 +    {
 +      emacs_mule_charset[charset.emacs_mule_id] = CHARSET_FROM_ID (id);
 +      if (charset.emacs_mule_id < 0xA0)
 +      emacs_mule_bytes[charset.emacs_mule_id] = charset.dimension + 1;
 +      else
 +      emacs_mule_bytes[charset.emacs_mule_id] = charset.dimension + 2;
 +      if (new_definition_p)
 +      Vemacs_mule_charset_list = nconc2 (Vemacs_mule_charset_list,
 +                                         Fcons (make_number (id), Qnil));
 +    }
 +
 +  if (new_definition_p)
 +    {
 +      Vcharset_list = Fcons (args[charset_arg_name], Vcharset_list);
 +      Vcharset_ordered_list = nconc2 (Vcharset_ordered_list,
 +                                    Fcons (make_number (id), Qnil));
 +      charset_ordered_list_tick++;
 +    }
 +
 +  return Qnil;
 +}
 +
 +
 +/* Same as Fdefine_charset_internal but arguments are more convenient
 +   to call from C (typically in syms_of_charset).  This can define a
 +   charset of `offset' method only.  Return the ID of the new
 +   charset.  */
 +
 +static int
 +define_charset_internal (name, dimension, code_space, min_code, max_code,
 +                       iso_final, iso_revision, emacs_mule_id,
 +                       ascii_compatible, supplementary,
 +                       code_offset)
 +     Lisp_Object name;
 +     int dimension;
 +     unsigned char *code_space;
 +     unsigned min_code, max_code;
 +     int iso_final, iso_revision, emacs_mule_id;
 +     int ascii_compatible, supplementary;
 +     int code_offset;
 +{
 +  Lisp_Object args[charset_arg_max];
 +  Lisp_Object plist[14];
 +  Lisp_Object val;
 +  int i;
 +
 +  args[charset_arg_name] = name;
 +  args[charset_arg_dimension] = make_number (dimension);
 +  val = Fmake_vector (make_number (8), make_number (0));
 +  for (i = 0; i < 8; i++)
 +    ASET (val, i, make_number (code_space[i]));
 +  args[charset_arg_code_space] = val;
 +  args[charset_arg_min_code] = make_number (min_code);
 +  args[charset_arg_max_code] = make_number (max_code);
 +  args[charset_arg_iso_final]
 +    = (iso_final < 0 ? Qnil : make_number (iso_final));
 +  args[charset_arg_iso_revision] = make_number (iso_revision);
 +  args[charset_arg_emacs_mule_id]
 +    = (emacs_mule_id < 0 ? Qnil : make_number (emacs_mule_id));
 +  args[charset_arg_ascii_compatible_p] = ascii_compatible ? Qt : Qnil;
 +  args[charset_arg_supplementary_p] = supplementary ? Qt : Qnil;
 +  args[charset_arg_invalid_code] = Qnil;
 +  args[charset_arg_code_offset] = make_number (code_offset);
 +  args[charset_arg_map] = Qnil;
 +  args[charset_arg_subset] = Qnil;
 +  args[charset_arg_superset] = Qnil;
 +  args[charset_arg_unify_map] = Qnil;
 +
 +  plist[0] = intern (":name");
 +  plist[1] = args[charset_arg_name];
 +  plist[2] = intern (":dimension");
 +  plist[3] = args[charset_arg_dimension];
 +  plist[4] = intern (":code-space");
 +  plist[5] = args[charset_arg_code_space];
 +  plist[6] = intern (":iso-final-char");
 +  plist[7] = args[charset_arg_iso_final];
 +  plist[8] = intern (":emacs-mule-id");
 +  plist[9] = args[charset_arg_emacs_mule_id];
 +  plist[10] = intern (":ascii-compatible-p");
 +  plist[11] = args[charset_arg_ascii_compatible_p];
 +  plist[12] = intern (":code-offset");
 +  plist[13] = args[charset_arg_code_offset];
 +
 +  args[charset_arg_plist] = Flist (14, plist);
 +  Fdefine_charset_internal (charset_arg_max, args);
 +
 +  return XINT (CHARSET_SYMBOL_ID (name));
 +}
 +
 +
 +DEFUN ("define-charset-alias", Fdefine_charset_alias,
 +       Sdefine_charset_alias, 2, 2, 0,
 +       doc: /* Define ALIAS as an alias for charset CHARSET.  */)
 +     (alias, charset)
 +     Lisp_Object alias, charset;
 +{
 +  Lisp_Object attr;
 +
 +  CHECK_CHARSET_GET_ATTR (charset, attr);
 +  Fputhash (alias, attr, Vcharset_hash_table);
 +  Vcharset_list = Fcons (alias, Vcharset_list);
 +  return Qnil;
 +}
 +
 +
 +DEFUN ("unibyte-charset", Funibyte_charset, Sunibyte_charset, 0, 0, 0,
 +       doc: /* Return the unibyte charset (set by `set-unibyte-charset').  */)
 +     ()
 +{
 +  return CHARSET_NAME (CHARSET_FROM_ID (charset_unibyte));
 +}
 +
 +
 +DEFUN ("set-unibyte-charset", Fset_unibyte_charset, Sset_unibyte_charset,
 +       1, 1, 0,
 +       doc: /* Set the unibyte charset to CHARSET.
 +This determines how unibyte/multibyte conversion is done.  See also
 +function `unibyte-charset'.  */)
 +     (charset)
 +     Lisp_Object charset;
 +{
 +  struct charset *cs;
 +  int i, c;
 +
 +  CHECK_CHARSET_GET_CHARSET (charset, cs);
 +  if (! cs->ascii_compatible_p
 +      || cs->dimension != 1)
 +    error ("Inappropriate unibyte charset: %s", SDATA (SYMBOL_NAME (charset)));
 +  charset_unibyte = cs->id;
 +  memset (unibyte_has_multibyte_table, 1, 128);
 +  for (i = 128; i < 256; i++)
 +    {
 +      c = DECODE_CHAR (cs, i);
 +      unibyte_to_multibyte_table[i] = (c < 0 ? BYTE8_TO_CHAR (i) : c);
 +      unibyte_has_multibyte_table[i] = c >= 0;
 +    }
 +
 +  return Qnil;
 +}
 +
 +
 +DEFUN ("charset-plist", Fcharset_plist, Scharset_plist, 1, 1, 0,
 +       doc: /* Return the property list of CHARSET.  */)
 +     (charset)
 +     Lisp_Object charset;
 +{
 +  Lisp_Object attrs;
 +
 +  CHECK_CHARSET_GET_ATTR (charset, attrs);
 +  return CHARSET_ATTR_PLIST (attrs);
 +}
 +
 +
 +DEFUN ("set-charset-plist", Fset_charset_plist, Sset_charset_plist, 2, 2, 0,
 +       doc: /* Set CHARSET's property list to PLIST.  */)
 +     (charset, plist)
 +     Lisp_Object charset, plist;
 +{
 +  Lisp_Object attrs;
 +
 +  CHECK_CHARSET_GET_ATTR (charset, attrs);
 +  CHARSET_ATTR_PLIST (attrs) = plist;
 +  return plist;
 +}
 +
 +
 +DEFUN ("unify-charset", Funify_charset, Sunify_charset, 1, 3, 0,
 +       doc: /* Unify characters of CHARSET with Unicode.
 +This means reading the relevant file and installing the table defined
 +by CHARSET's `:unify-map' property.
 +
 +Optional second arg UNIFY-MAP is a file name string or a vector.  It has
 +the same meaning as the `:unify-map' attribute in the function
 +`define-charset' (which see).
 +
 +Optional third argument DEUNIFY, if non-nil, means to de-unify CHARSET.  */)
 +     (charset, unify_map, deunify)
 +     Lisp_Object charset, unify_map, deunify;
 +{
 +  int id;
 +  struct charset *cs;
 +
 +  CHECK_CHARSET_GET_ID (charset, id);
 +  cs = CHARSET_FROM_ID (id);
 +  if (CHARSET_METHOD (cs) == CHARSET_METHOD_MAP_DEFERRED)
 +    load_charset (cs);
 +  if (NILP (deunify)
 +      ? CHARSET_UNIFIED_P (cs) && ! NILP (CHARSET_DEUNIFIER (cs))
 +      : ! CHARSET_UNIFIED_P (cs))
 +    return Qnil;
 +
 +  CHARSET_UNIFIED_P (cs) = 0;
 +  if (NILP (deunify))
 +    {
 +      if (CHARSET_METHOD (cs) != CHARSET_METHOD_OFFSET)
 +      error ("Can't unify charset: %s", SDATA (SYMBOL_NAME (charset)));
 +      if (NILP (unify_map))
 +      unify_map = CHARSET_UNIFY_MAP (cs);
 +      if (STRINGP (unify_map))
 +      load_charset_map_from_file (cs, unify_map, 2);
 +      else if (VECTORP (unify_map))
 +      load_charset_map_from_vector (cs, unify_map, 2);
 +      else if (NILP (unify_map))
 +      error ("No unify-map for charset");
 +      else
 +      error ("Bad unify-map arg");
 +      CHARSET_UNIFIED_P (cs) = 1;
 +    }
 +  else if (CHAR_TABLE_P (Vchar_unify_table))
 +    {
 +      int min_code = CHARSET_MIN_CODE (cs);
 +      int max_code = CHARSET_MAX_CODE (cs);
 +      int min_char = DECODE_CHAR (cs, min_code);
 +      int max_char = DECODE_CHAR (cs, max_code);
 +
 +      char_table_set_range (Vchar_unify_table, min_char, max_char, Qnil);
 +    }
 +
 +  return Qnil;
 +}
 +
 +DEFUN ("get-unused-iso-final-char", Fget_unused_iso_final_char,
 +       Sget_unused_iso_final_char, 2, 2, 0,
 +       doc: /*
 +Return an unused ISO final char for a charset of DIMENISION and CHARS.
 +DIMENSION is the number of bytes to represent a character: 1 or 2.
 +CHARS is the number of characters in a dimension: 94 or 96.
 +
 +This final char is for private use, thus the range is `0' (48) .. `?' (63).
 +If there's no unused final char for the specified kind of charset,
 +return nil.  */)
 +     (dimension, chars)
 +     Lisp_Object dimension, chars;
 +{
 +  int final_char;
 +
 +  CHECK_NUMBER (dimension);
 +  CHECK_NUMBER (chars);
 +  if (XINT (dimension) != 1 && XINT (dimension) != 2 && XINT (dimension) != 3)
 +    args_out_of_range_3 (dimension, make_number (1), make_number (3));
 +  if (XINT (chars) != 94 && XINT (chars) != 96)
 +    args_out_of_range_3 (chars, make_number (94), make_number (96));
 +  for (final_char = '0'; final_char <= '?'; final_char++)
 +    if (ISO_CHARSET_TABLE (XINT (dimension), XINT (chars), final_char) < 0)
 +      break;
 +  return (final_char <= '?' ? make_number (final_char) : Qnil);
 +}
 +
 +static void
 +check_iso_charset_parameter (dimension, chars, final_char)
 +     Lisp_Object dimension, chars, final_char;
 +{
 +  CHECK_NATNUM (dimension);
 +  CHECK_NATNUM (chars);
 +  CHECK_NATNUM (final_char);
 +
 +  if (XINT (dimension) > 3)
 +    error ("Invalid DIMENSION %d, it should be 1, 2, or 3", XINT (dimension));
 +  if (XINT (chars) != 94 && XINT (chars) != 96)
 +    error ("Invalid CHARS %d, it should be 94 or 96", XINT (chars));
 +  if (XINT (final_char) < '0' || XINT (final_char) > '~')
 +    error ("Invalid FINAL-CHAR %c, it should be `0'..`~'", XINT (chars));
 +}
 +
 +
 +DEFUN ("declare-equiv-charset", Fdeclare_equiv_charset, Sdeclare_equiv_charset,
 +       4, 4, 0,
 +       doc: /* Declare an equivalent charset for ISO-2022 decoding.
 +
 +On decoding by an ISO-2022 base coding system, when a charset
 +specified by DIMENSION, CHARS, and FINAL-CHAR is designated, behave as
 +if CHARSET is designated instead.  */)
 +     (dimension, chars, final_char, charset)
 +     Lisp_Object dimension, chars, final_char, charset;
 +{
 +  int id;
 +  int chars_flag;
 +
 +  CHECK_CHARSET_GET_ID (charset, id);
 +  check_iso_charset_parameter (dimension, chars, final_char);
 +  chars_flag = XINT (chars) == 96;
 +  ISO_CHARSET_TABLE (XINT (dimension), chars_flag, XINT (final_char)) = id;
 +  return Qnil;
 +}
 +
 +
 +/* Return information about charsets in the text at PTR of NBYTES
 +   bytes, which are NCHARS characters.  The value is:
 +
 +      0: Each character is represented by one byte.  This is always
 +         true for a unibyte string.  For a multibyte string, true if
 +         it contains only ASCII characters.
 +
 +      1: No charsets other than ascii, control-1, and latin-1 are
 +         found.
 +
 +      2: Otherwise.
 +*/
 +
 +int
 +string_xstring_p (string)
 +     Lisp_Object string;
 +{
 +  const unsigned char *p = SDATA (string);
 +  const unsigned char *endp = p + SBYTES (string);
 +
 +  if (SCHARS (string) == SBYTES (string))
 +    return 0;
 +
 +  while (p < endp)
 +    {
 +      int c = STRING_CHAR_ADVANCE (p);
 +
 +      if (c >= 0x100)
 +      return 2;
 +    }
 +  return 1;
 +}
 +
 +
 +/* Find charsets in the string at PTR of NCHARS and NBYTES.
 +
 +   CHARSETS is a vector.  If Nth element is non-nil, it means the
 +   charset whose id is N is already found.
 +
 +   It may lookup a translation table TABLE if supplied.  */
 +
 +static void
 +find_charsets_in_text (ptr, nchars, nbytes, charsets, table, multibyte)
 +     const unsigned char *ptr;
 +     EMACS_INT nchars, nbytes;
 +     Lisp_Object charsets, table;
 +     int multibyte;
 +{
 +  const unsigned char *pend = ptr + nbytes;
 +
 +  if (nchars == nbytes)
 +    {
 +      if (multibyte)
 +      ASET (charsets, charset_ascii, Qt);
 +      else
 +      while (ptr < pend)
 +        {
 +          int c = *ptr++;
 +
 +          if (!NILP (table))
 +            c = translate_char (table, c);
 +          if (ASCII_BYTE_P (c))
 +            ASET (charsets, charset_ascii, Qt);
 +          else
 +            ASET (charsets, charset_eight_bit, Qt);
 +        }
 +    }
 +  else
 +    {
 +      while (ptr < pend)
 +      {
 +        int c = STRING_CHAR_ADVANCE (ptr);
 +        struct charset *charset;
 +
 +        if (!NILP (table))
 +          c = translate_char (table, c);
 +        charset = CHAR_CHARSET (c);
 +        ASET (charsets, CHARSET_ID (charset), Qt);
 +      }
 +    }
 +}
 +
 +DEFUN ("find-charset-region", Ffind_charset_region, Sfind_charset_region,
         2, 3, 0,
         doc: /* Return a list of charsets in the region between BEG and END.
  BEG and END are buffer positions.
  Optional arg TABLE if non-nil is a translation table to look up.
  
 -If the region contains invalid multibyte characters,
 -`unknown' is included in the returned list.
 -
  If the current buffer is unibyte, the returned list may contain
  only `ascii', `eight-bit-control', and `eight-bit-graphic'.  */)
       (beg, end, table)
       Lisp_Object beg, end, table;
  {
 -  int charsets[MAX_CHARSET + 1];
 -  int from, from_byte, to, stop, stop_byte, i;
 +  Lisp_Object charsets;
 +  EMACS_INT from, from_byte, to, stop, stop_byte;
 +  int i;
    Lisp_Object val;
 +  int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
  
    validate_region (&beg, &end);
    from = XFASTINT (beg);
  
    from_byte = CHAR_TO_BYTE (from);
  
 -  bzero (charsets, (MAX_CHARSET + 1) * sizeof (int));
 +  charsets = Fmake_vector (make_number (charset_table_used), Qnil);
    while (1)
      {
 -      find_charset_in_text (BYTE_POS_ADDR (from_byte), stop - from,
 -                          stop_byte - from_byte, charsets, table);
 +      find_charsets_in_text (BYTE_POS_ADDR (from_byte), stop - from,
 +                           stop_byte - from_byte, charsets, table,
 +                           multibyte);
        if (stop < to)
        {
          from = stop, from_byte = stop_byte;
      }
  
    val = Qnil;
 -  if (charsets[1])
 -    val = Fcons (Qunknown, val);
 -  for (i = MAX_CHARSET; i >= MIN_CHARSET_OFFICIAL_DIMENSION1; i--)
 -    if (charsets[i])
 -      val = Fcons (CHARSET_SYMBOL (i), val);
 -  if (charsets[0])
 -    val = Fcons (Qascii, val);
 +  for (i = charset_table_used - 1; i >= 0; i--)
 +    if (!NILP (AREF (charsets, i)))
 +      val = Fcons (CHARSET_NAME (charset_table + i), val);
    return val;
  }
  
@@@ -1465,607 -937,850 +1466,607 @@@ DEFUN ("find-charset-string", Ffind_cha
         doc: /* Return a list of charsets in STR.
  Optional arg TABLE if non-nil is a translation table to look up.
  
 -If the string contains invalid multibyte characters,
 -`unknown' is included in the returned list.
 -
  If STR is unibyte, the returned list may contain
 -only `ascii', `eight-bit-control', and `eight-bit-graphic'.  */)
 +only `ascii', `eight-bit-control', and `eight-bit-graphic'. */)
       (str, table)
       Lisp_Object str, table;
  {
 -  int charsets[MAX_CHARSET + 1];
 +  Lisp_Object charsets;
    int i;
    Lisp_Object val;
  
    CHECK_STRING (str);
  
 -  bzero (charsets, (MAX_CHARSET + 1) * sizeof (int));
 -  find_charset_in_text (SDATA (str), SCHARS (str),
 -                      SBYTES (str), charsets, table);
 -
 +  charsets = Fmake_vector (make_number (charset_table_used), Qnil);
 +  find_charsets_in_text (SDATA (str), SCHARS (str), SBYTES (str),
 +                       charsets, table,
 +                       STRING_MULTIBYTE (str));
    val = Qnil;
 -  if (charsets[1])
 -    val = Fcons (Qunknown, val);
 -  for (i = MAX_CHARSET; i >= MIN_CHARSET_OFFICIAL_DIMENSION1; i--)
 -    if (charsets[i])
 -      val = Fcons (CHARSET_SYMBOL (i), val);
 -  if (charsets[0])
 -    val = Fcons (Qascii, val);
 +  for (i = charset_table_used - 1; i >= 0; i--)
 +    if (!NILP (AREF (charsets, i)))
 +      val = Fcons (CHARSET_NAME (charset_table + i), val);
    return val;
  }
  
  \f
 -DEFUN ("make-char-internal", Fmake_char_internal, Smake_char_internal, 1, 3, 0,
 -       doc: /* Return a character made from arguments.
 -Internal use only.  */)
 -     (charset, code1, code2)
 -     Lisp_Object charset, code1, code2;
 +
 +/* Return a character correponding to the code-point CODE of
 +   CHARSET.  */
 +
 +int
 +decode_char (charset, code)
 +     struct charset *charset;
 +     unsigned code;
  {
 -  int charset_id, c1, c2;
 +  int c, char_index;
 +  enum charset_method method = CHARSET_METHOD (charset);
  
 -  CHECK_NUMBER (charset);
 -  charset_id = XINT (charset);
 -  if (!CHARSET_DEFINED_P (charset_id))
 -    error ("Invalid charset ID: %d", XINT (charset));
 +  if (code < CHARSET_MIN_CODE (charset) || code > CHARSET_MAX_CODE (charset))
 +    return -1;
  
 -  if (NILP (code1))
 -    c1 = 0;
 -  else
 +  if (method == CHARSET_METHOD_MAP_DEFERRED)
      {
 -      CHECK_NUMBER (code1);
 -      c1 = XINT (code1);
 -    }
 -  if (NILP (code2))
 -    c2 = 0;
 -  else
 -    {
 -      CHECK_NUMBER (code2);
 -      c2 = XINT (code2);
 +      load_charset (charset);
 +      method = CHARSET_METHOD (charset);
      }
  
 -  if (charset_id == CHARSET_ASCII)
 -    {
 -      if (c1 < 0 || c1 > 0x7F)
 -      goto invalid_code_posints;
 -      return make_number (c1);
 -    }
 -  else if (charset_id == CHARSET_8_BIT_CONTROL)
 +  if (method == CHARSET_METHOD_SUBSET)
      {
 -      if (NILP (code1))
 -      c1 = 0x80;
 -      else if (c1 < 0x80 || c1 > 0x9F)
 -      goto invalid_code_posints;
 -      return make_number (c1);
 +      Lisp_Object subset_info;
 +
 +      subset_info = CHARSET_SUBSET (charset);
 +      charset = CHARSET_FROM_ID (XFASTINT (AREF (subset_info, 0)));
 +      code -= XINT (AREF (subset_info, 3));
 +      if (code < XFASTINT (AREF (subset_info, 1))
 +        || code > XFASTINT (AREF (subset_info, 2)))
 +      c = -1;
 +      else
 +      c = DECODE_CHAR (charset, code);
      }
 -  else if (charset_id == CHARSET_8_BIT_GRAPHIC)
 +  else if (method == CHARSET_METHOD_SUPERSET)
      {
 -      if (NILP (code1))
 -      c1 = 0xA0;
 -      else if (c1 < 0xA0 || c1 > 0xFF)
 -      goto invalid_code_posints;
 -      return make_number (c1);
 -    }
 -  else if (c1 < 0 || c1 > 0xFF || c2 < 0 || c2 > 0xFF)
 -    goto invalid_code_posints;
 -  c1 &= 0x7F;
 -  c2 &= 0x7F;
 -  if (c1 == 0
 -      ? c2 != 0
 -      : (c2 == 0
 -       ? !CHAR_COMPONENTS_VALID_P (charset_id, c1, 0x20)
 -       : !CHAR_COMPONENTS_VALID_P (charset_id, c1, c2)))
 -    goto invalid_code_posints;
 -  return make_number (MAKE_CHAR (charset_id, c1, c2));
 -
 - invalid_code_posints:
 -  error ("Invalid code points for charset ID %d: %d %d", charset_id, c1, c2);
 -}
 +      Lisp_Object parents;
  
 -DEFUN ("split-char", Fsplit_char, Ssplit_char, 1, 1, 0,
 -       doc: /* Return list of charset and one or two position-codes of CH.
 -If CH is invalid as a character code,
 -return a list of symbol `unknown' and CH.  */)
 -     (ch)
 -     Lisp_Object ch;
 -{
 -  int c, charset, c1, c2;
 +      parents = CHARSET_SUPERSET (charset);
 +      c = -1;
 +      for (; CONSP (parents); parents = XCDR (parents))
 +      {
 +        int id = XINT (XCAR (XCAR (parents)));
 +        int code_offset = XINT (XCDR (XCAR (parents)));
 +        unsigned this_code = code - code_offset;
  
 -  CHECK_NUMBER (ch);
 -  c = XFASTINT (ch);
 -  if (!CHAR_VALID_P (c, 1))
 -    return Fcons (Qunknown, Fcons (ch, Qnil));
 -  SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);
 -  return (c2 >= 0
 -        ? Fcons (CHARSET_SYMBOL (charset),
 -                 Fcons (make_number (c1), Fcons (make_number (c2), Qnil)))
 -        : Fcons (CHARSET_SYMBOL (charset), Fcons (make_number (c1), Qnil)));
 -}
 +        charset = CHARSET_FROM_ID (id);
 +        if ((c = DECODE_CHAR (charset, this_code)) >= 0)
 +          break;
 +      }
 +    }
 +  else
 +    {
 +      char_index = CODE_POINT_TO_INDEX (charset, code);
 +      if (char_index < 0)
 +      return -1;
  
 -DEFUN ("char-charset", Fchar_charset, Schar_charset, 1, 1, 0,
 -       doc: /* Return charset of CH.  */)
 -     (ch)
 -     Lisp_Object ch;
 -{
 -  CHECK_NUMBER (ch);
 +      if (method == CHARSET_METHOD_MAP)
 +      {
 +        Lisp_Object decoder;
  
 -  return CHARSET_SYMBOL (CHAR_CHARSET (XINT (ch)));
 -}
 +        decoder = CHARSET_DECODER (charset);
 +        if (! VECTORP (decoder))
 +          return -1;
 +        c = XINT (AREF (decoder, char_index));
 +      }
 +      else
 +      {
 +        c = char_index + CHARSET_CODE_OFFSET (charset);
 +      }
 +    }
  
 -DEFUN ("charset-after", Fcharset_after, Scharset_after, 0, 1, 0,
 -       doc: /* Return charset of a character in the current buffer at position POS.
 -If POS is nil, it defauls to the current point.
 -If POS is out of range, the value is nil.  */)
 -     (pos)
 -     Lisp_Object pos;
 -{
 -  Lisp_Object ch;
 -  int charset;
 +  if (CHARSET_UNIFIED_P (charset)
 +      && c >= 0)
 +    {
 +      MAYBE_UNIFY_CHAR (c);
 +    }
  
 -  ch = Fchar_after (pos);
 -  if (! INTEGERP (ch))
 -    return ch;
 -  charset = CHAR_CHARSET (XINT (ch));
 -  return CHARSET_SYMBOL (charset);
 +  return c;
  }
  
 -DEFUN ("iso-charset", Fiso_charset, Siso_charset, 3, 3, 0,
 -       doc: /* Return charset of ISO's specification DIMENSION, CHARS, and FINAL-CHAR.
 -
 -ISO 2022's designation sequence (escape sequence) distinguishes charsets
 -by their DIMENSION, CHARS, and FINAL-CHAR,
 -where as Emacs distinguishes them by charset symbol.
 -See the documentation of the function `charset-info' for the meanings of
 -DIMENSION, CHARS, and FINAL-CHAR.  */)
 -     (dimension, chars, final_char)
 -     Lisp_Object dimension, chars, final_char;
 -{
 -  int charset;
 -
 -  CHECK_NUMBER (dimension);
 -  CHECK_NUMBER (chars);
 -  CHECK_NUMBER (final_char);
 +/* Variable used temporarily by the macro ENCODE_CHAR.  */
 +Lisp_Object charset_work;
  
 -  if ((charset = ISO_CHARSET_TABLE (dimension, chars, final_char)) < 0)
 -    return Qnil;
 -  return CHARSET_SYMBOL (charset);
 -}
 +/* Return a code-point of CHAR in CHARSET.  If CHAR doesn't belong to
 +   CHARSET, return CHARSET_INVALID_CODE (CHARSET).  If STRICT is true,
 +   use CHARSET's strict_max_char instead of max_char.  */
  
 -/* If GENERICP is nonzero, return nonzero iff C is a valid normal or
 -   generic character.  If GENERICP is zero, return nonzero iff C is a
 -   valid normal character.  Do not call this function directly,
 -   instead use macro CHAR_VALID_P.  */
 -int
 -char_valid_p (c, genericp)
 -     int c, genericp;
 +unsigned
 +encode_char (charset, c)
 +     struct charset *charset;
 +     int c;
  {
 -  int charset, c1, c2;
 +  unsigned code;
 +  enum charset_method method = CHARSET_METHOD (charset);
  
 -  if (c < 0 || c >= MAX_CHAR)
 -    return 0;
 -  if (SINGLE_BYTE_CHAR_P (c))
 -    return 1;
 -  SPLIT_CHAR (c, charset, c1, c2);
 -  if (genericp)
 +  if (CHARSET_UNIFIED_P (charset))
      {
 -      if (c1)
 -      {
 -        if (c2 <= 0) c2 = 0x20;
 -      }
 -      else
 +      Lisp_Object deunifier, deunified;
 +
 +      deunifier = CHARSET_DEUNIFIER (charset);
 +      if (! CHAR_TABLE_P (deunifier))
        {
 -        if (c2 <= 0) c1 = c2 = 0x20;
 +        Funify_charset (CHARSET_NAME (charset), Qnil, Qnil);
 +        deunifier = CHARSET_DEUNIFIER (charset);
        }
 +      deunified = CHAR_TABLE_REF (deunifier, c);
 +      if (! NILP (deunified))
 +      c = XINT (deunified);
      }
 -  return (CHARSET_DEFINED_P (charset)
 -        && CHAR_COMPONENTS_VALID_P (charset, c1, c2));
 -}
  
 -DEFUN ("char-valid-p", Fchar_valid_p, Schar_valid_p, 1, 2, 0,
 -       doc: /* Return t if OBJECT is a valid normal character.
 -If optional arg GENERICP is non-nil, also return t if OBJECT is
 -a valid generic character.  */)
 -     (object, genericp)
 -     Lisp_Object object, genericp;
 -{
 -  if (! NATNUMP (object))
 -    return Qnil;
 -  return (CHAR_VALID_P (XFASTINT (object), !NILP (genericp)) ? Qt : Qnil);
 -}
 +  if (method == CHARSET_METHOD_SUBSET)
 +    {
 +      Lisp_Object subset_info;
 +      struct charset *this_charset;
 +
 +      subset_info = CHARSET_SUBSET (charset);
 +      this_charset = CHARSET_FROM_ID (XFASTINT (AREF (subset_info, 0)));
 +      code = ENCODE_CHAR (this_charset, c);
 +      if (code == CHARSET_INVALID_CODE (this_charset)
 +        || code < XFASTINT (AREF (subset_info, 1))
 +        || code > XFASTINT (AREF (subset_info, 2)))
 +      return CHARSET_INVALID_CODE (charset);
 +      code += XINT (AREF (subset_info, 3));
 +      return code;
 +    }
  
 -DEFUN ("unibyte-char-to-multibyte", Funibyte_char_to_multibyte,
 -       Sunibyte_char_to_multibyte, 1, 1, 0,
 -       doc: /* Convert the unibyte character CH to multibyte character.
 -The conversion is done based on `nonascii-translation-table' (which see)
 - or `nonascii-insert-offset' (which see).  */)
 -     (ch)
 -     Lisp_Object ch;
 -{
 -  int c;
 +  if (method == CHARSET_METHOD_SUPERSET)
 +    {
 +      Lisp_Object parents;
  
 -  CHECK_NUMBER (ch);
 -  c = XINT (ch);
 -  if (c < 0 || c >= 0400)
 -    error ("Invalid unibyte character: %d", c);
 -  c = unibyte_char_to_multibyte (c);
 -  if (c < 0)
 -    error ("Can't convert to multibyte character: %d", XINT (ch));
 -  return make_number (c);
 -}
 +      parents = CHARSET_SUPERSET (charset);
 +      for (; CONSP (parents); parents = XCDR (parents))
 +      {
 +        int id = XINT (XCAR (XCAR (parents)));
 +        int code_offset = XINT (XCDR (XCAR (parents)));
 +        struct charset *this_charset = CHARSET_FROM_ID (id);
  
 -DEFUN ("multibyte-char-to-unibyte", Fmultibyte_char_to_unibyte,
 -       Smultibyte_char_to_unibyte, 1, 1, 0,
 -       doc: /* Convert the multibyte character CH to unibyte character.
 -The conversion is done based on `nonascii-translation-table' (which see)
 - or `nonascii-insert-offset' (which see).  */)
 -     (ch)
 -     Lisp_Object ch;
 -{
 -  int c;
 +        code = ENCODE_CHAR (this_charset, c);
 +        if (code != CHARSET_INVALID_CODE (this_charset))
 +          return code + code_offset;
 +      }
 +      return CHARSET_INVALID_CODE (charset);
 +    }
  
 -  CHECK_NUMBER (ch);
 -  c = XINT (ch);
 -  if (! CHAR_VALID_P (c, 0))
 -    error ("Invalid multibyte character: %d", c);
 -  c = multibyte_char_to_unibyte (c, Qnil);
 -  if (c < 0)
 -    error ("Can't convert to unibyte character: %d", XINT (ch));
 -  return make_number (c);
 -}
 +  if (! CHARSET_FAST_MAP_REF ((c), charset->fast_map)
 +      || c < CHARSET_MIN_CHAR (charset) || c > CHARSET_MAX_CHAR (charset))
 +    return CHARSET_INVALID_CODE (charset);
  
 -DEFUN ("char-bytes", Fchar_bytes, Schar_bytes, 1, 1, 0,
 -       doc: /* Return 1 regardless of the argument CH.  */)
 -     (ch)
 -     Lisp_Object ch;
 -{
 -  CHECK_NUMBER (ch);
 -  return make_number (1);
 -}
 +  if (method == CHARSET_METHOD_MAP_DEFERRED)
 +    {
 +      load_charset (charset);
 +      method = CHARSET_METHOD (charset);
 +    }
  
 -/* Return how many bytes C will occupy in a multibyte buffer.
 -   Don't call this function directly, instead use macro CHAR_BYTES.  */
 -int
 -char_bytes (c)
 -     int c;
 -{
 -  int charset;
 +  if (method == CHARSET_METHOD_MAP)
 +    {
 +      Lisp_Object encoder;
 +      Lisp_Object val;
  
 -  if (ASCII_BYTE_P (c) || (c & ~((1 << CHARACTERBITS) -1)))
 -    return 1;
 -  if (SINGLE_BYTE_CHAR_P (c) && c >= 0xA0)
 -    return 1;
 +      encoder = CHARSET_ENCODER (charset);
 +      if (! CHAR_TABLE_P (CHARSET_ENCODER (charset)))
 +      return CHARSET_INVALID_CODE (charset);
 +      val = CHAR_TABLE_REF (encoder, c);
 +      if (NILP (val))
 +      return CHARSET_INVALID_CODE (charset);
 +      code = XINT (val);
 +      if (! CHARSET_COMPACT_CODES_P (charset))
 +      code = INDEX_TO_CODE_POINT (charset, code);
 +    }
 +  else                                /* method == CHARSET_METHOD_OFFSET */
 +    {
 +      code = c - CHARSET_CODE_OFFSET (charset);
 +      code = INDEX_TO_CODE_POINT (charset, code);
 +    }
  
 -  charset = CHAR_CHARSET (c);
 -  return (CHARSET_DEFINED_P (charset) ? CHARSET_BYTES (charset) : 1);
 +  return code;
  }
  
 -/* Return the width of character of which multi-byte form starts with
 -   C.  The width is measured by how many columns occupied on the
 -   screen when displayed in the current buffer.  */
 -
 -#define ONE_BYTE_CHAR_WIDTH(c)                                                \
 -  (c < 0x20                                                           \
 -   ? (c == '\t'                                                               \
 -      ? XFASTINT (current_buffer->tab_width)                          \
 -      : (c == '\n' ? 0 : (NILP (current_buffer->ctl_arrow) ? 4 : 2))) \
 -   : (c < 0x7f                                                                \
 -      ? 1                                                             \
 -      : (c == 0x7F                                                    \
 -       ? (NILP (current_buffer->ctl_arrow) ? 4 : 2)                   \
 -       : ((! NILP (current_buffer->enable_multibyte_characters)       \
 -           && BASE_LEADING_CODE_P (c))                                \
 -          ? WIDTH_BY_CHAR_HEAD (c)                                    \
 -          : 4))))
 -
 -DEFUN ("char-width", Fchar_width, Schar_width, 1, 1, 0,
 -       doc: /* Return width of CH when displayed in the current buffer.
 -The width is measured by how many columns it occupies on the screen.
 -Tab is taken to occupy `tab-width' columns.  */)
 -     (ch)
 -     Lisp_Object ch;
 -{
 -  Lisp_Object val, disp;
 -  int c;
 -  struct Lisp_Char_Table *dp = buffer_display_table ();
  
 -  CHECK_NUMBER (ch);
 +DEFUN ("decode-char", Fdecode_char, Sdecode_char, 2, 3, 0,
 +       doc: /* Decode the pair of CHARSET and CODE-POINT into a character.
 +Return nil if CODE-POINT is not valid in CHARSET.
  
 -  c = XINT (ch);
 +CODE-POINT may be a cons (HIGHER-16-BIT-VALUE . LOWER-16-BIT-VALUE).
  
 -  /* Get the way the display table would display it.  */
 -  disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil;
 +Optional argument RESTRICTION specifies a way to map the pair of CCS
 +and CODE-POINT to a chracter.   Currently not supported and just ignored.  */)
 +  (charset, code_point, restriction)
 +     Lisp_Object charset, code_point, restriction;
 +{
 +  int c, id;
 +  unsigned code;
 +  struct charset *charsetp;
  
 -  if (VECTORP (disp))
 -    XSETINT (val, XVECTOR (disp)->size);
 -  else if (SINGLE_BYTE_CHAR_P (c))
 -    XSETINT (val, ONE_BYTE_CHAR_WIDTH (c));
 +  CHECK_CHARSET_GET_ID (charset, id);
 +  if (CONSP (code_point))
 +    {
 +      CHECK_NATNUM_CAR (code_point);
 +      CHECK_NATNUM_CDR (code_point);
 +      code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point)));
 +    }
    else
      {
 -      int charset = CHAR_CHARSET (c);
 -
 -      XSETFASTINT (val, CHARSET_WIDTH (charset));
 +      CHECK_NATNUM (code_point);
 +      code = XINT (code_point);
      }
 -  return val;
 +  charsetp = CHARSET_FROM_ID (id);
 +  c = DECODE_CHAR (charsetp, code);
 +  return (c >= 0 ? make_number (c) : Qnil);
  }
  
 -/* Return width of string STR of length LEN when displayed in the
 -   current buffer.  The width is measured by how many columns it
 -   occupies on the screen.  */
  
 -int
 -strwidth (str, len)
 -     unsigned char *str;
 -     int len;
 +DEFUN ("encode-char", Fencode_char, Sencode_char, 2, 3, 0,
 +       doc: /* Encode the character CH into a code-point of CHARSET.
 +Return nil if CHARSET doesn't include CH.
 +
 +Optional argument RESTRICTION specifies a way to map CHAR to a
 +code-point in CCS.  Currently not supported and just ignored.  */)
 +     (ch, charset, restriction)
 +     Lisp_Object ch, charset, restriction;
  {
 -  return c_string_width (str, len, -1, NULL, NULL);
 +  int id;
 +  unsigned code;
 +  struct charset *charsetp;
 +
 +  CHECK_CHARSET_GET_ID (charset, id);
 +  CHECK_NATNUM (ch);
 +  charsetp = CHARSET_FROM_ID (id);
 +  code = ENCODE_CHAR (charsetp, XINT (ch));
 +  if (code == CHARSET_INVALID_CODE (charsetp))
 +    return Qnil;
 +  if (code > 0x7FFFFFF)
 +    return Fcons (make_number (code >> 16), make_number (code & 0xFFFF));
 +  return make_number (code);
  }
  
 -/* Return width of string STR of length LEN when displayed in the
 -   current buffer.  The width is measured by how many columns it
 -   occupies on the screen.  If PRECISION > 0, return the width of
 -   longest substring that doesn't exceed PRECISION, and set number of
 -   characters and bytes of the substring in *NCHARS and *NBYTES
 -   respectively.  */
  
 -int
 -c_string_width (str, len, precision, nchars, nbytes)
 -     const unsigned char *str;
 -     int len, precision, *nchars, *nbytes;
 +DEFUN ("make-char", Fmake_char, Smake_char, 1, 5, 0,
 +       doc:
 +       /* Return a character of CHARSET whose position codes are CODEn.
 +
 +CODE1 through CODE4 are optional, but if you don't supply sufficient
 +position codes, it is assumed that the minimum code in each dimension
 +is specified.  */)
 +     (charset, code1, code2, code3, code4)
 +     Lisp_Object charset, code1, code2, code3, code4;
  {
 -  int i = 0, i_byte = 0;
 -  int width = 0;
 -  int chars;
 -  struct Lisp_Char_Table *dp = buffer_display_table ();
 +  int id, dimension;
 +  struct charset *charsetp;
 +  unsigned code;
 +  int c;
  
 -  while (i_byte < len)
 +  CHECK_CHARSET_GET_ID (charset, id);
 +  charsetp = CHARSET_FROM_ID (id);
 +
 +  dimension = CHARSET_DIMENSION (charsetp);
 +  if (NILP (code1))
 +    code = (CHARSET_ASCII_COMPATIBLE_P (charsetp)
 +          ? 0 : CHARSET_MIN_CODE (charsetp));
 +  else
      {
 -      int bytes, thiswidth;
 -      Lisp_Object val;
 +      CHECK_NATNUM (code1);
 +      if (XFASTINT (code1) >= 0x100)
 +      args_out_of_range (make_number (0xFF), code1);
 +      code = XFASTINT (code1);
  
 -      if (dp)
 +      if (dimension > 1)
        {
 -        int c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes);
 -
 -        chars = 1;
 -        val = DISP_CHAR_VECTOR (dp, c);
 -        if (VECTORP (val))
 -          thiswidth = XVECTOR (val)->size;
 +        code <<= 8;
 +        if (NILP (code2))
 +          code |= charsetp->code_space[(dimension - 2) * 4];
          else
 -          thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]);
 -      }
 -      else
 -      {
 -        chars = 1;
 -        PARSE_MULTIBYTE_SEQ (str + i_byte, len - i_byte, bytes);
 -        thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]);
 -      }
 +          {
 +            CHECK_NATNUM (code2);
 +            if (XFASTINT (code2) >= 0x100)
 +              args_out_of_range (make_number (0xFF), code2);
 +            code |= XFASTINT (code2);
 +          }
  
 -      if (precision > 0
 -        && (width + thiswidth > precision))
 -      {
 -        *nchars = i;
 -        *nbytes = i_byte;
 -        return width;
 +        if (dimension > 2)
 +          {
 +            code <<= 8;
 +            if (NILP (code3))
 +              code |= charsetp->code_space[(dimension - 3) * 4];
 +            else
 +              {
 +                CHECK_NATNUM (code3);
 +                if (XFASTINT (code3) >= 0x100)
 +                  args_out_of_range (make_number (0xFF), code3);
 +                code |= XFASTINT (code3);
 +              }
 +
 +            if (dimension > 3)
 +              {
 +                code <<= 8;
 +                if (NILP (code4))
 +                  code |= charsetp->code_space[0];
 +                else
 +                  {
 +                    CHECK_NATNUM (code4);
 +                    if (XFASTINT (code4) >= 0x100)
 +                      args_out_of_range (make_number (0xFF), code4);
 +                    code |= XFASTINT (code4);
 +                  }
 +              }
 +          }
        }
 -      i++;
 -      i_byte += bytes;
 -      width += thiswidth;
 -  }
 -
 -  if (precision > 0)
 -    {
 -      *nchars = i;
 -      *nbytes = i_byte;
      }
  
 -  return width;
 +  if (CHARSET_ISO_FINAL (charsetp) >= 0)
 +    code &= 0x7F7F7F7F;
 +  c = DECODE_CHAR (charsetp, code);
 +  if (c < 0)
 +    error ("Invalid code(s)");
 +  return make_number (c);
  }
  
 -/* Return width of Lisp string STRING when displayed in the current
 -   buffer.  The width is measured by how many columns it occupies on
 -   the screen while paying attention to compositions.  If PRECISION >
 -   0, return the width of longest substring that doesn't exceed
 -   PRECISION, and set number of characters and bytes of the substring
 -   in *NCHARS and *NBYTES respectively.  */
  
 -int
 -lisp_string_width (string, precision, nchars, nbytes)
 -     Lisp_Object string;
 -     int precision, *nchars, *nbytes;
 -{
 -  int len = SCHARS (string);
 -  int len_byte = SBYTES (string);
 -  /* This set multibyte to 0 even if STRING is multibyte when it
 -     contains only ascii and eight-bit-graphic, but that's
 -     intentional.  */
 -  int multibyte = len < len_byte;
 -  const unsigned char *str = SDATA (string);
 -  int i = 0, i_byte = 0;
 -  int width = 0;
 -  struct Lisp_Char_Table *dp = buffer_display_table ();
 -
 -  while (i < len)
 -    {
 -      int chars, bytes, thiswidth;
 -      Lisp_Object val;
 -      int cmp_id;
 -      int ignore, end;
 +/* Return the first charset in CHARSET_LIST that contains C.
 +   CHARSET_LIST is a list of charset IDs.  If it is nil, use
 +   Vcharset_ordered_list.  */
  
 -      if (find_composition (i, -1, &ignore, &end, &val, string)
 -        && ((cmp_id = get_composition_id (i, i_byte, end - i, val, string))
 -            >= 0))
 -      {
 -        thiswidth = composition_table[cmp_id]->width;
 -        chars = end - i;
 -        bytes = string_char_to_byte (string, end) - i_byte;
 -      }
 -      else if (dp)
 -      {
 -        int c;
 +struct charset *
 +char_charset (c, charset_list, code_return)
 +     int c;
 +     Lisp_Object charset_list;
 +     unsigned *code_return;
 +{
 +  if (NILP (charset_list))
 +    charset_list = Vcharset_ordered_list;
  
 -        if (multibyte)
 -          c = STRING_CHAR_AND_LENGTH (str + i_byte, len - i_byte, bytes);
 -        else
 -          c = str[i_byte], bytes = 1;
 -        chars = 1;
 -        val = DISP_CHAR_VECTOR (dp, c);
 -        if (VECTORP (val))
 -          thiswidth = XVECTOR (val)->size;
 -        else
 -          thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]);
 -      }
 -      else
 -      {
 -        chars = 1;
 -        if (multibyte)
 -          PARSE_MULTIBYTE_SEQ (str + i_byte, len_byte - i_byte, bytes);
 -        else
 -          bytes = 1;
 -        thiswidth = ONE_BYTE_CHAR_WIDTH (str[i_byte]);
 -      }
 +  while (CONSP (charset_list))
 +    {
 +      struct charset *charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
 +      unsigned code = ENCODE_CHAR (charset, c);
  
 -      if (precision > 0
 -        && (width + thiswidth > precision))
 +      if (code != CHARSET_INVALID_CODE (charset))
        {
 -        *nchars = i;
 -        *nbytes = i_byte;
 -        return width;
 +        if (code_return)
 +          *code_return = code;
 +        return charset;
        }
 -      i += chars;
 -      i_byte += bytes;
 -      width += thiswidth;
 -  }
 -
 -  if (precision > 0)
 -    {
 -      *nchars = i;
 -      *nbytes = i_byte;
 +      charset_list = XCDR (charset_list);
      }
 -
 -  return width;
 +  return NULL;
  }
  
 -DEFUN ("string-width", Fstring_width, Sstring_width, 1, 1, 0,
 -       doc: /* Return width of STRING when displayed in the current buffer.
 -Width is measured by how many columns it occupies on the screen.
 -When calculating width of a multibyte character in STRING,
 -only the base leading-code is considered; the validity of
 -the following bytes is not checked.  Tabs in STRING are always
 -taken to occupy `tab-width' columns.  */)
 -     (string)
 -     Lisp_Object string;
 -{
 -  Lisp_Object val;
 -
 -  CHECK_STRING (string);
 -  XSETFASTINT (val, lisp_string_width (string, -1, NULL, NULL));
 -  return val;
 -}
  
 -DEFUN ("char-direction", Fchar_direction, Schar_direction, 1, 1, 0,
 -       doc: /* Return the direction of CH.
 -The returned value is 0 for left-to-right and 1 for right-to-left.  */)
 +DEFUN ("split-char", Fsplit_char, Ssplit_char, 1, 1, 0,
 +       doc:
 +       /*Return list of charset and one to four position-codes of CHAR.
 +The charset is decided by the current priority order of charsets.
 +A position-code is a byte value of each dimension of the code-point of
 +CHAR in the charset.  */)
       (ch)
       Lisp_Object ch;
  {
 -  int charset;
 +  struct charset *charset;
 +  int c, dimension;
 +  unsigned code;
 +  Lisp_Object val;
  
 -  CHECK_NUMBER (ch);
 -  charset = CHAR_CHARSET (XFASTINT (ch));
 -  if (!CHARSET_DEFINED_P (charset))
 -    invalid_character (XINT (ch));
 -  return CHARSET_TABLE_INFO (charset, CHARSET_DIRECTION_IDX);
 +  CHECK_CHARACTER (ch);
 +  c = XFASTINT (ch);
 +  charset = CHAR_CHARSET (c);
 +  if (! charset)
 +    abort ();
 +  code = ENCODE_CHAR (charset, c);
 +  if (code == CHARSET_INVALID_CODE (charset))
 +    abort ();
 +  dimension = CHARSET_DIMENSION (charset);
 +  for (val = Qnil; dimension > 0; dimension--)
 +    {
 +      val = Fcons (make_number (code & 0xFF), val);
 +      code >>= 8;
 +    }
 +  return Fcons (CHARSET_NAME (charset), val);
  }
  
 -/* Return the number of characters in the NBYTES bytes at PTR.
 -   This works by looking at the contents and checking for multibyte sequences.
 -   However, if the current buffer has enable-multibyte-characters = nil,
 -   we treat each byte as a character.  */
  
 -int
 -chars_in_text (ptr, nbytes)
 -     const unsigned char *ptr;
 -     int nbytes;
 +DEFUN ("char-charset", Fchar_charset, Schar_charset, 1, 1, 0,
 +       doc: /* Return the charset of highest priority that contains CH.  */)
 +     (ch)
 +     Lisp_Object ch;
  {
 -  /* current_buffer is null at early stages of Emacs initialization.  */
 -  if (current_buffer == 0
 -      || NILP (current_buffer->enable_multibyte_characters))
 -    return nbytes;
 +  struct charset *charset;
  
 -  return multibyte_chars_in_text (ptr, nbytes);
 +  CHECK_CHARACTER (ch);
 +  charset = CHAR_CHARSET (XINT (ch));
 +  return (CHARSET_NAME (charset));
  }
  
 -/* Return the number of characters in the NBYTES bytes at PTR.
 -   This works by looking at the contents and checking for multibyte sequences.
 -   It ignores enable-multibyte-characters.  */
  
 -int
 -multibyte_chars_in_text (ptr, nbytes)
 -     const unsigned char *ptr;
 -     int nbytes;
 +DEFUN ("charset-after", Fcharset_after, Scharset_after, 0, 1, 0,
 +       doc: /*
 +Return charset of a character in the current buffer at position POS.
 +If POS is nil, it defauls to the current point.
 +If POS is out of range, the value is nil.  */)
 +     (pos)
 +     Lisp_Object pos;
  {
 -  const unsigned char *endp;
 -  int chars, bytes;
 +  Lisp_Object ch;
 +  struct charset *charset;
  
 -  endp = ptr + nbytes;
 -  chars = 0;
 +  ch = Fchar_after (pos);
 +  if (! INTEGERP (ch))
 +    return ch;
 +  charset = CHAR_CHARSET (XINT (ch));
 +  return (CHARSET_NAME (charset));
 +}
  
 -  while (ptr < endp)
 -    {
 -      PARSE_MULTIBYTE_SEQ (ptr, endp - ptr, bytes);
 -      ptr += bytes;
 -      chars++;
 -    }
  
 -  return chars;
 -}
 +DEFUN ("iso-charset", Fiso_charset, Siso_charset, 3, 3, 0,
 +       doc: /*
 +Return charset of ISO's specification DIMENSION, CHARS, and FINAL-CHAR.
  
 -/* Parse unibyte text at STR of LEN bytes as multibyte text, and
 -   count the numbers of characters and bytes in it.  On counting
 -   bytes, pay attention to the fact that 8-bit characters in the range
 -   0x80..0x9F are represented by 2 bytes in multibyte text.  */
 -void
 -parse_str_as_multibyte (str, len, nchars, nbytes)
 -     const unsigned char *str;
 -     int len, *nchars, *nbytes;
 +ISO 2022's designation sequence (escape sequence) distinguishes charsets
 +by their DIMENSION, CHARS, and FINAL-CHAR,
 +where as Emacs distinguishes them by charset symbol.
 +See the documentation of the function `charset-info' for the meanings of
 +DIMENSION, CHARS, and FINAL-CHAR.  */)
 +     (dimension, chars, final_char)
 +     Lisp_Object dimension, chars, final_char;
  {
 -  const unsigned char *endp = str + len;
 -  int n, chars = 0, bytes = 0;
 -
 -  while (str < endp)
 -    {
 -      if (UNIBYTE_STR_AS_MULTIBYTE_P (str, endp - str, n))
 -      str += n, bytes += n;
 -      else
 -      str++, bytes += 2;
 -      chars++;
 -    }
 -  *nchars = chars;
 -  *nbytes = bytes;
 -  return;
 +  int id;
 +  int chars_flag;
 +
 +  check_iso_charset_parameter (dimension, chars, final_char);
 +  chars_flag = XFASTINT (chars) == 96;
 +  id = ISO_CHARSET_TABLE (XFASTINT (dimension), chars_flag,
 +                        XFASTINT (final_char));
 +  return (id >= 0 ? CHARSET_NAME (CHARSET_FROM_ID (id)) : Qnil);
  }
  
 -/* Arrange unibyte text at STR of NBYTES bytes as multibyte text.
 -   It actually converts only 8-bit characters in the range 0x80..0x9F
 -   that don't contruct multibyte characters to multibyte forms.  If
 -   NCHARS is nonzero, set *NCHARS to the number of characters in the
 -   text.  It is assured that we can use LEN bytes at STR as a work
 -   area and that is enough.  Return the number of bytes of the
 -   resulting text.  */
  
 -int
 -str_as_multibyte (str, len, nbytes, nchars)
 -     unsigned char *str;
 -     int len, nbytes, *nchars;
 +DEFUN ("clear-charset-maps", Fclear_charset_maps, Sclear_charset_maps,
 +       0, 0, 0,
 +       doc: /*
 +Clear encoder and decoder of charsets that are loaded from mapfiles.  */)
 +     ()
  {
 -  unsigned char *p = str, *endp = str + nbytes;
 -  unsigned char *to;
 -  int chars = 0;
 -  int n;
 -
 -  while (p < endp && UNIBYTE_STR_AS_MULTIBYTE_P (p, endp - p, n))
 -    p += n, chars++;
 -  if (nchars)
 -    *nchars = chars;
 -  if (p == endp)
 -    return nbytes;
 -
 -  to = p;
 -  nbytes = endp - p;
 -  endp = str + len;
 -  safe_bcopy (p, endp - nbytes, nbytes);
 -  p = endp - nbytes;
 -  while (p < endp)
 +  int i;
 +  struct charset *charset;
 +  Lisp_Object attrs;
 +
 +  for (i = 0; i < charset_table_used; i++)
      {
 -      if (UNIBYTE_STR_AS_MULTIBYTE_P (p, endp - p, n))
 -      {
 -        while (n--)
 -          *to++ = *p++;
 -      }
 -      else
 +      charset = CHARSET_FROM_ID (i);
 +      attrs = CHARSET_ATTRIBUTES (charset);
 +
 +      if (CHARSET_METHOD (charset) == CHARSET_METHOD_MAP)
        {
 -        *to++ = LEADING_CODE_8_BIT_CONTROL;
 -        *to++ = *p++ + 0x20;
 +        CHARSET_ATTR_DECODER (attrs) = Qnil;
 +        CHARSET_ATTR_ENCODER (attrs) = Qnil;
 +        CHARSET_METHOD (charset) = CHARSET_METHOD_MAP_DEFERRED;
        }
 -      chars++;
 -    }
 -  if (nchars)
 -    *nchars = chars;
 -  return (to - str);
 -}
 -
 -/* Parse unibyte string at STR of LEN bytes, and return the number of
 -   bytes it may ocupy when converted to multibyte string by
 -   `str_to_multibyte'.  */
 -
 -int
 -parse_str_to_multibyte (str, len)
 -     unsigned char *str;
 -     int len;
 -{
 -  unsigned char *endp = str + len;
 -  int bytes;
 -
 -  for (bytes = 0; str < endp; str++)
 -    bytes += (*str < 0x80 || *str >= 0xA0) ? 1 : 2;
 -  return bytes;
 -}
  
 -/* Convert unibyte text at STR of NBYTES bytes to multibyte text
 -   that contains the same single-byte characters.  It actually
 -   converts all 8-bit characters to multibyte forms.  It is assured
 -   that we can use LEN bytes at STR as a work area and that is
 -   enough.  */
 +      if (CHARSET_UNIFIED_P (charset))
 +      CHARSET_ATTR_DEUNIFIER (attrs) = Qnil;
 +    }
  
 -int
 -str_to_multibyte (str, len, bytes)
 -     unsigned char *str;
 -     int len, bytes;
 -{
 -  unsigned char *p = str, *endp = str + bytes;
 -  unsigned char *to;
 -
 -  while (p < endp && (*p < 0x80 || *p >= 0xA0)) p++;
 -  if (p == endp)
 -    return bytes;
 -  to = p;
 -  bytes = endp - p;
 -  endp = str + len;
 -  safe_bcopy (p, endp - bytes, bytes);
 -  p = endp - bytes;
 -  while (p < endp)
 +  if (CHAR_TABLE_P (Vchar_unified_charset_table))
      {
 -      if (*p < 0x80 || *p >= 0xA0)
 -      *to++ = *p++;
 -      else
 -      *to++ = LEADING_CODE_8_BIT_CONTROL, *to++ = *p++ + 0x20;
 +      Foptimize_char_table (Vchar_unified_charset_table);
 +      Vchar_unify_table = Vchar_unified_charset_table;
 +      Vchar_unified_charset_table = Qnil;
      }
 -  return (to - str);
 -}
  
 -/* Arrange multibyte text at STR of LEN bytes as a unibyte text.  It
 -   actually converts only 8-bit characters in the range 0x80..0x9F to
 -   unibyte forms.  */
 +  return Qnil;
 +}
  
 -int
 -str_as_unibyte (str, bytes)
 -     unsigned char *str;
 -     int bytes;
 +DEFUN ("charset-priority-list", Fcharset_priority_list,
 +       Scharset_priority_list, 0, 1, 0,
 +       doc: /* Return the list of charsets ordered by priority.
 +HIGHESTP non-nil means just return the highest priority one.  */)
 +     (highestp)
 +     Lisp_Object highestp;
  {
 -  unsigned char *p = str, *endp = str + bytes;
 -  unsigned char *to = str;
 +  Lisp_Object val = Qnil, list = Vcharset_ordered_list;
  
 -  while (p < endp && *p != LEADING_CODE_8_BIT_CONTROL) p++;
 -  to = p;
 -  while (p < endp)
 +  if (!NILP (highestp))
 +    return CHARSET_NAME (CHARSET_FROM_ID (XINT (Fcar (list))));
 +
 +  while (!NILP (list))
      {
 -      if (*p == LEADING_CODE_8_BIT_CONTROL)
 -      *to++ = *(p + 1) - 0x20, p += 2;
 -      else
 -      *to++ = *p++;
 +      val = Fcons (CHARSET_NAME (CHARSET_FROM_ID (XINT (XCAR (list)))), val);
 +      list = XCDR (list);
      }
 -  return (to - str);
 +  return Fnreverse (val);
  }
  
 -\f
 -DEFUN ("string", Fstring, Sstring, 0, MANY, 0,
 -  doc: /* Concatenate all the argument characters and make the result a string.
 -usage: (string &rest CHARACTERS)  */)
 -     (n, args)
 -     int n;
 +DEFUN ("set-charset-priority", Fset_charset_priority, Sset_charset_priority,
 +       1, MANY, 0,
 +       doc: /* Assign higher priority to the charsets given as arguments.
 +usage: (set-charset-priority &rest charsets)  */)
 +       (nargs, args)
 +     int nargs;
       Lisp_Object *args;
  {
 -  int i, bufsize;
 -  unsigned char *buf, *p;
 -  int c;
 -  int multibyte = 0;
 -  Lisp_Object ret;
 -  USE_SAFE_ALLOCA;
 -
 -  bufsize = MAX_MULTIBYTE_LENGTH * n;
 -  SAFE_ALLOCA (buf, unsigned char *, bufsize);
 -  p = buf;
 +  Lisp_Object new_head, old_list, arglist[2];
 +  Lisp_Object list_2022, list_emacs_mule;
 +  int i, id;
  
 -  for (i = 0; i < n; i++)
 +  old_list = Fcopy_sequence (Vcharset_ordered_list);
 +  new_head = Qnil;
 +  for (i = 0; i < nargs; i++)
      {
 -      CHECK_NUMBER (args[i]);
 -      if (!multibyte && !SINGLE_BYTE_CHAR_P (XFASTINT (args[i])))
 -      multibyte = 1;
 +      CHECK_CHARSET_GET_ID (args[i], id);
 +      if (! NILP (Fmemq (make_number (id), old_list)))
 +      {
 +        old_list = Fdelq (make_number (id), old_list);
 +        new_head = Fcons (make_number (id), new_head);
 +      }
      }
 +  arglist[0] = Fnreverse (new_head);
 +  arglist[1] = old_list;
 +  Vcharset_ordered_list = Fnconc (2, arglist);
 +  charset_ordered_list_tick++;
  
 -  for (i = 0; i < n; i++)
 +  for (old_list = Vcharset_ordered_list, list_2022 = list_emacs_mule = Qnil;
 +       CONSP (old_list); old_list = XCDR (old_list))
      {
 -      c = XINT (args[i]);
 -      if (multibyte)
 -      p += CHAR_STRING (c, p);
 -      else
 -      *p++ = c;
 +      if (! NILP (Fmemq (XCAR (old_list), Viso_2022_charset_list)))
 +      list_2022 = Fcons (XCAR (old_list), list_2022);
 +      if (! NILP (Fmemq (XCAR (old_list), Vemacs_mule_charset_list)))
 +      list_emacs_mule = Fcons (XCAR (old_list), list_emacs_mule);
      }
 +  Viso_2022_charset_list = Fnreverse (list_2022);
 +  Vemacs_mule_charset_list = Fnreverse (list_emacs_mule);
  
 -  ret = make_string_from_bytes (buf, n, p - buf);
 -  SAFE_FREE ();
 -
 -  return ret;
 +  return Qnil;
  }
  
 -#endif /* emacs */
 -\f
 -int
 -charset_id_internal (charset_name)
 -     char *charset_name;
 +DEFUN ("charset-id-internal", Fcharset_id_internal, Scharset_id_internal,
 +       0, 1, 0,
 +       doc: /* Internal use only.
 +Return charset identification number of CHARSET.  */)
 +     (charset)
 +     Lisp_Object charset;
  {
 -  Lisp_Object val;
 -
 -  val= Fget (intern (charset_name), Qcharset);
 -  if (!VECTORP (val))
 -    error ("Charset %s is not defined", charset_name);
 +  int id;
  
 -  return (XINT (XVECTOR (val)->contents[0]));
 +  CHECK_CHARSET_GET_ID (charset, id);
 +  return make_number (id);
  }
  
 -DEFUN ("setup-special-charsets", Fsetup_special_charsets,
 -       Ssetup_special_charsets, 0, 0, 0, doc: /* Internal use only.  */)
 -     ()
 +\f
 +void
 +init_charset ()
  {
 -  charset_latin_iso8859_1 = charset_id_internal ("latin-iso8859-1");
 -  charset_jisx0208_1978 = charset_id_internal ("japanese-jisx0208-1978");
 -  charset_jisx0208 = charset_id_internal ("japanese-jisx0208");
 -  charset_katakana_jisx0201 = charset_id_internal ("katakana-jisx0201");
 -  charset_latin_jisx0201 = charset_id_internal ("latin-jisx0201");
 -  charset_big5_1 = charset_id_internal ("chinese-big5-1");
 -  charset_big5_2 = charset_id_internal ("chinese-big5-2");
 -  charset_mule_unicode_0100_24ff
 -    = charset_id_internal ("mule-unicode-0100-24ff");
 -  charset_mule_unicode_2500_33ff
 -    = charset_id_internal ("mule-unicode-2500-33ff");
 -  charset_mule_unicode_e000_ffff
 -    = charset_id_internal ("mule-unicode-e000-ffff");
 -  return Qnil;
 +  Vcharset_map_path
 +    = Fcons (Fexpand_file_name (build_string ("charsets"), Vdata_directory),
 +           Qnil);
  }
  
 +
  void
  init_charset_once ()
  {
    int i, j, k;
  
 -  staticpro (&Vcharset_table);
 -  staticpro (&Vcharset_symbol_table);
 -  staticpro (&Vgeneric_character_list);
 -
 -  /* This has to be done here, before we call Fmake_char_table.  */
 -  Qcharset_table = intern ("charset-table");
 -  staticpro (&Qcharset_table);
 -
 -  /* Intern this now in case it isn't already done.
 -     Setting this variable twice is harmless.
 -     But don't staticpro it here--that is done in alloc.c.  */
 -  Qchar_table_extra_slots = intern ("char-table-extra-slots");
 -
 -  /* Now we are ready to set up this property, so we can
 -     create the charset table.  */
 -  Fput (Qcharset_table, Qchar_table_extra_slots, make_number (0));
 -  Vcharset_table = Fmake_char_table (Qcharset_table, Qnil);
 -
 -  Qunknown = intern ("unknown");
 -  staticpro (&Qunknown);
 -  Vcharset_symbol_table = Fmake_vector (make_number (MAX_CHARSET + 1),
 -                                      Qunknown);
 -
 -  /* Setup tables.  */
 -  for (i = 0; i < 2; i++)
 -    for (j = 0; j < 2; j++)
 -      for (k = 0; k < 128; k++)
 -      iso_charset_table [i][j][k] = -1;
 +  for (i = 0; i < ISO_MAX_DIMENSION; i++)
 +    for (j = 0; j < ISO_MAX_CHARS; j++)
 +      for (k = 0; k < ISO_MAX_FINAL; k++)
 +      iso_charset_table[i][j][k] = -1;
  
    for (i = 0; i < 256; i++)
 -    bytes_by_char_head[i] = 1;
 -  bytes_by_char_head[LEADING_CODE_PRIVATE_11] = 3;
 -  bytes_by_char_head[LEADING_CODE_PRIVATE_12] = 3;
 -  bytes_by_char_head[LEADING_CODE_PRIVATE_21] = 4;
 -  bytes_by_char_head[LEADING_CODE_PRIVATE_22] = 4;
 +    emacs_mule_charset[i] = NULL;
 +
 +  charset_jisx0201_roman = -1;
 +  charset_jisx0208_1978 = -1;
 +  charset_jisx0208 = -1;
  
    for (i = 0; i < 128; i++)
 -    width_by_char_head[i] = 1;
 +    unibyte_to_multibyte_table[i] = i;
    for (; i < 256; i++)
 -    width_by_char_head[i] = 4;
 -  width_by_char_head[LEADING_CODE_PRIVATE_11] = 1;
 -  width_by_char_head[LEADING_CODE_PRIVATE_12] = 2;
 -  width_by_char_head[LEADING_CODE_PRIVATE_21] = 1;
 -  width_by_char_head[LEADING_CODE_PRIVATE_22] = 2;
 -
 -  {
 -    Lisp_Object val;
 -
 -    val = Qnil;
 -    for (i = 0x81; i < 0x90; i++)
 -      val = Fcons (make_number ((i - 0x70) << 7), val);
 -    for (; i < 0x9A; i++)
 -      val = Fcons (make_number ((i - 0x8F) << 14), val);
 -    for (i = 0xA0; i < 0xF0; i++)
 -      val = Fcons (make_number ((i - 0x70) << 7), val);
 -    for (; i < 0xFF; i++)
 -      val = Fcons (make_number ((i - 0xE0) << 14), val);
 -    Vgeneric_character_list = Fnreverse (val);
 -  }
 -
 -  nonascii_insert_offset = 0;
 -  Vnonascii_translation_table = Qnil;
 +    unibyte_to_multibyte_table[i] = BYTE8_TO_CHAR (i);
  }
  
  #ifdef emacs
  void
  syms_of_charset ()
  {
 -  Qcharset = intern ("charset");
 -  staticpro (&Qcharset);
 -
 -  Qascii = intern ("ascii");
 -  staticpro (&Qascii);
 -
 -  Qeight_bit_control = intern ("eight-bit-control");
 -  staticpro (&Qeight_bit_control);
 -
 -  Qeight_bit_graphic = intern ("eight-bit-graphic");
 -  staticpro (&Qeight_bit_graphic);
 -
 -  /* Define special charsets ascii, eight-bit-control, and
 -     eight-bit-graphic.  */
 -  update_charset_table (make_number (CHARSET_ASCII),
 -                      make_number (1), make_number (94),
 -                      make_number (1),
 -                      make_number (0),
 -                      make_number ('B'),
 -                      make_number (0),
 -                      build_string ("ASCII"),
 -                      Qnil,   /* same as above */
 -                      build_string ("ASCII (ISO646 IRV)"));
 -  CHARSET_SYMBOL (CHARSET_ASCII) = Qascii;
 -  Fput (Qascii, Qcharset, CHARSET_TABLE_ENTRY (CHARSET_ASCII));
 -
 -  update_charset_table (make_number (CHARSET_8_BIT_CONTROL),
 -                      make_number (1), make_number (96),
 -                      make_number (4),
 -                      make_number (0),
 -                      make_number (-1),
 -                      make_number (-1),
 -                      build_string ("8-bit control code (0x80..0x9F)"),
 -                      Qnil,   /* same as above */
 -                      Qnil);  /* same as above */
 -  CHARSET_SYMBOL (CHARSET_8_BIT_CONTROL) = Qeight_bit_control;
 -  Fput (Qeight_bit_control, Qcharset,
 -      CHARSET_TABLE_ENTRY (CHARSET_8_BIT_CONTROL));
 -
 -  update_charset_table (make_number (CHARSET_8_BIT_GRAPHIC),
 -                      make_number (1), make_number (96),
 -                      make_number (4),
 -                      make_number (0),
 -                      make_number (-1),
 -                      make_number (-1),
 -                      build_string ("8-bit graphic char (0xA0..0xFF)"),
 -                      Qnil,   /* same as above */
 -                      Qnil);  /* same as above */
 -  CHARSET_SYMBOL (CHARSET_8_BIT_GRAPHIC) = Qeight_bit_graphic;
 -  Fput (Qeight_bit_graphic, Qcharset,
 -      CHARSET_TABLE_ENTRY (CHARSET_8_BIT_GRAPHIC));
 -
 -  Qauto_fill_chars = intern ("auto-fill-chars");
 -  staticpro (&Qauto_fill_chars);
 -  Fput (Qauto_fill_chars, Qchar_table_extra_slots, make_number (0));
 -
 -  defsubr (&Sdefine_charset);
 -  defsubr (&Sgeneric_character_list);
 +  DEFSYM (Qcharsetp, "charsetp");
 +
 +  DEFSYM (Qascii, "ascii");
 +  DEFSYM (Qunicode, "unicode");
 +  DEFSYM (Qeight_bit, "eight-bit");
 +  DEFSYM (Qiso_8859_1, "iso-8859-1");
 +
 +  DEFSYM (Qgl, "gl");
 +  DEFSYM (Qgr, "gr");
 +
 +  staticpro (&Vcharset_ordered_list);
 +  Vcharset_ordered_list = Qnil;
 +
 +  staticpro (&Viso_2022_charset_list);
 +  Viso_2022_charset_list = Qnil;
 +
 +  staticpro (&Vemacs_mule_charset_list);
 +  Vemacs_mule_charset_list = Qnil;
 +
 +  staticpro (&Vcharset_hash_table);
 +  {
 +    Lisp_Object args[2];
 +    args[0] = QCtest;
 +    args[1] = Qeq;
 +    Vcharset_hash_table = Fmake_hash_table (2, args);
 +  }
 +
 +  charset_table_size = 128;
 +  charset_table = ((struct charset *)
 +                 xmalloc (sizeof (struct charset) * charset_table_size));
 +  charset_table_used = 0;
 +
 +  staticpro (&Vchar_unified_charset_table);
 +  Vchar_unified_charset_table = Fmake_char_table (Qnil, make_number (-1));
 +
 +  defsubr (&Scharsetp);
 +  defsubr (&Smap_charset_chars);
 +  defsubr (&Sdefine_charset_internal);
 +  defsubr (&Sdefine_charset_alias);
 +  defsubr (&Sunibyte_charset);
 +  defsubr (&Sset_unibyte_charset);
 +  defsubr (&Scharset_plist);
 +  defsubr (&Sset_charset_plist);
 +  defsubr (&Sunify_charset);
    defsubr (&Sget_unused_iso_final_char);
    defsubr (&Sdeclare_equiv_charset);
    defsubr (&Sfind_charset_region);
    defsubr (&Sfind_charset_string);
 -  defsubr (&Smake_char_internal);
 +  defsubr (&Sdecode_char);
 +  defsubr (&Sencode_char);
    defsubr (&Ssplit_char);
 +  defsubr (&Smake_char);
    defsubr (&Schar_charset);
    defsubr (&Scharset_after);
    defsubr (&Siso_charset);
 -  defsubr (&Schar_valid_p);
 -  defsubr (&Sunibyte_char_to_multibyte);
 -  defsubr (&Smultibyte_char_to_unibyte);
 -  defsubr (&Schar_bytes);
 -  defsubr (&Schar_width);
 -  defsubr (&Sstring_width);
 -  defsubr (&Schar_direction);
 -  defsubr (&Sstring);
 -  defsubr (&Ssetup_special_charsets);
 +  defsubr (&Sclear_charset_maps);
 +  defsubr (&Scharset_priority_list);
 +  defsubr (&Sset_charset_priority);
 +  defsubr (&Scharset_id_internal);
 +
 +  DEFVAR_LISP ("charset-map-path", &Vcharset_map_path,
 +             doc: /* *Lisp of directories to search for charset map files.  */);
 +  Vcharset_map_path = Qnil;
  
    DEFVAR_LISP ("charset-list", &Vcharset_list,
 -             doc: /* List of charsets ever defined.  */);
 -  Vcharset_list = Fcons (Qascii, Fcons (Qeight_bit_control,
 -                                      Fcons (Qeight_bit_graphic, Qnil)));
 -
 -  DEFVAR_LISP ("translation-table-vector",  &Vtranslation_table_vector,
 -             doc: /* Vector of cons cell of a symbol and translation table ever defined.
 -An ID of a translation table is an index of this vector.  */);
 -  Vtranslation_table_vector = Fmake_vector (make_number (16), Qnil);
 -
 -  DEFVAR_INT ("leading-code-private-11", &leading_code_private_11,
 -            doc: /* Leading-code of private TYPE9N charset of column-width 1.  */);
 -  leading_code_private_11 = LEADING_CODE_PRIVATE_11;
 -
 -  DEFVAR_INT ("leading-code-private-12", &leading_code_private_12,
 -            doc: /* Leading-code of private TYPE9N charset of column-width 2.  */);
 -  leading_code_private_12 = LEADING_CODE_PRIVATE_12;
 -
 -  DEFVAR_INT ("leading-code-private-21", &leading_code_private_21,
 -            doc: /* Leading-code of private TYPE9Nx9N charset of column-width 1.  */);
 -  leading_code_private_21 = LEADING_CODE_PRIVATE_21;
 -
 -  DEFVAR_INT ("leading-code-private-22", &leading_code_private_22,
 -            doc: /* Leading-code of private TYPE9Nx9N charset of column-width 2.  */);
 -  leading_code_private_22 = LEADING_CODE_PRIVATE_22;
 -
 -  DEFVAR_INT ("nonascii-insert-offset", &nonascii_insert_offset,
 -            doc: /* Offset for converting non-ASCII unibyte codes 0240...0377 to multibyte.
 -This is used for converting unibyte text to multibyte,
 -and for inserting character codes specified by number.
 -
 -This serves to convert a Latin-1 or similar 8-bit character code
 -to the corresponding Emacs multibyte character code.
 -Typically the value should be (- (make-char CHARSET 0) 128),
 -for your choice of character set.
 -If `nonascii-translation-table' is non-nil, it overrides this variable.  */);
 -  nonascii_insert_offset = 0;
 -
 -  DEFVAR_LISP ("nonascii-translation-table", &Vnonascii_translation_table,
 -             doc: /* Translation table to convert non-ASCII unibyte codes to multibyte.
 -This is used for converting unibyte text to multibyte,
 -and for inserting character codes specified by number.
 -
 -Conversion is performed only when multibyte characters are enabled,
 -and it serves to convert a Latin-1 or similar 8-bit character code
 -to the corresponding Emacs character code.
 -
 -If this is nil, `nonascii-insert-offset' is used instead.
 -See also the docstring of `make-translation-table'.  */);
 -  Vnonascii_translation_table = Qnil;
 -
 -  DEFVAR_LISP ("auto-fill-chars", &Vauto_fill_chars,
 -             doc: /* A char-table for characters which invoke auto-filling.
 -Such characters have value t in this table.  */);
 -  Vauto_fill_chars = Fmake_char_table (Qauto_fill_chars, Qnil);
 -  CHAR_TABLE_SET (Vauto_fill_chars, make_number (' '), Qt);
 -  CHAR_TABLE_SET (Vauto_fill_chars, make_number ('\n'), Qt);
 +             doc: /* List of all charsets ever defined.  */);
 +  Vcharset_list = Qnil;
 +
 +  charset_ascii
 +    = define_charset_internal (Qascii, 1, "\x00\x7F\x00\x00\x00\x00",
 +                             0, 127, 'B', -1, 0, 1, 0, 0);
 +  charset_iso_8859_1
 +    = define_charset_internal (Qiso_8859_1, 1, "\x00\xFF\x00\x00\x00\x00",
 +                             0, 255, -1, -1, -1, 1, 0, 0);
 +  charset_unicode
 +    = define_charset_internal (Qunicode, 3, "\x00\xFF\x00\xFF\x00\x10",
 +                             0, MAX_UNICODE_CHAR, -1, 0, -1, 1, 0, 0);
 +  charset_eight_bit
 +    = define_charset_internal (Qeight_bit, 1, "\x80\xFF\x00\x00\x00\x00",
 +                             128, 255, -1, 0, -1, 0, 0,
 +                             MAX_5_BYTE_CHAR + 1);
  }
  
  #endif /* emacs */
diff --combined src/charset.h
index e7aaf9d6194c76cea654e44870591145cf6bdbb9,2d0116d263ee54d8ad32175cc3023e0b1d1408c2..8c76aa0607112d01e3e63043344dbc564d7a6058
@@@ -1,14 -1,11 +1,15 @@@
 -/* Header for multibyte character handler.
 +/* Header for charset handler.
     Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                2006 Free Software Foundation, Inc.
+                  2006, 2007 Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
 +
  This file is part of GNU Emacs.
  
  GNU Emacs is free software; you can redistribute it and/or modify
@@@ -29,523 -26,866 +30,523 @@@ Boston, MA 02110-1301, USA.  *
  #ifndef EMACS_CHARSET_H
  #define EMACS_CHARSET_H
  
 -/* #define BYTE_COMBINING_DEBUG */
 -
 -/*** GENERAL NOTE on CHARACTER SET (CHARSET) ***
 -
 -  A character set ("charset" hereafter) is a meaningful collection
 -  (i.e. language, culture, functionality, etc) of characters.  Emacs
 -  handles multiple charsets at once.  Each charset corresponds to one
 -  of the ISO charsets.  Emacs identifies a charset by a unique
 -  identification number, whereas ISO identifies a charset by a triplet
 -  of DIMENSION, CHARS and FINAL-CHAR.  So, hereafter, just saying
 -  "charset" means an identification number (integer value).
 -
 -  The value range of charsets is 0x00, 0x81..0xFE.  There are four
 -  kinds of charset depending on DIMENSION (1 or 2) and CHARS (94 or
 -  96).  For instance, a charset of DIMENSION2_CHARS94 contains 94x94
 -  characters.
 -
 -  Within Emacs Lisp, a charset is treated as a symbol which has a
 -  property `charset'.  The property value is a vector containing
 -  various information about the charset.  For readability of C code,
 -  we use the following convention for C variable names:
 -      charset_symbol: Emacs Lisp symbol of a charset
 -      charset_id: Emacs Lisp integer of an identification number of a charset
 -      charset: C integer of an identification number of a charset
 -
 -  Each charset (except for ascii) is assigned a base leading-code
 -  (range 0x80..0x9E).  In addition, a charset of greater than 0xA0
 -  (whose base leading-code is 0x9A..0x9D) is assigned an extended
 -  leading-code (range 0xA0..0xFE).  In this case, each base
 -  leading-code specifies the allowable range of extended leading-code
 -  as shown in the table below.  A leading-code is used to represent a
 -  character in Emacs' buffer and string.
 -
 -  We call a charset which has extended leading-code a "private
 -  charset" because those are mainly for a charset which is not yet
 -  registered by ISO.  On the contrary, we call a charset which does
 -  not have extended leading-code an "official charset".
 -
 -  ---------------------------------------------------------------------------
 -  charset     dimension        base leading-code      extended leading-code
 -  ---------------------------------------------------------------------------
 -  0x00                official dim1    -- none --             -- none --
 -              (ASCII)
 -  0x01..0x7F  --never used--
 -  0x80                official dim1    -- none --             -- none --
 -              (eight-bit-graphic)
 -  0x81..0x8F  official dim1    same as charset        -- none --
 -  0x90..0x99  official dim2    same as charset        -- none --
 -  0x9A..0x9D  --never used--
 -  0x9E                official dim1    same as charset        -- none --
 -              (eight-bit-control)
 -  0x9F                --never used--
 -  0xA0..0xDF  private dim1        0x9A                same as charset
 -              of 1-column width
 -  0xE0..0xEF  private dim1        0x9B                same as charset
 -              of 2-column width
 -  0xF0..0xF4  private dim2        0x9C                same as charset
 -              of 1-column width
 -  0xF5..0xFE  private dim2        0x9D                same as charset
 -              of 2-column width
 -  0xFF                --never used--
 -  ---------------------------------------------------------------------------
 -
 -*/
 -
 -/* Definition of special leading-codes.  */
 -/* Leading-code followed by extended leading-code.  */
 -#define LEADING_CODE_PRIVATE_11       0x9A /* for private DIMENSION1 of 1-column */
 -#define LEADING_CODE_PRIVATE_12       0x9B /* for private DIMENSION1 of 2-column */
 -#define LEADING_CODE_PRIVATE_21       0x9C /* for private DIMENSION2 of 1-column */
 -#define LEADING_CODE_PRIVATE_22       0x9D /* for private DIMENSION2 of 2-column */
 -
 -#define LEADING_CODE_8_BIT_CONTROL 0x9E /* for `eight-bit-control' */
 -
 -/* Extended leading-code.  */
 -/* Start of each extended leading-codes.  */
 -#define LEADING_CODE_EXT_11 0xA0 /* follows LEADING_CODE_PRIVATE_11 */
 -#define LEADING_CODE_EXT_12 0xE0 /* follows LEADING_CODE_PRIVATE_12 */
 -#define LEADING_CODE_EXT_21 0xF0 /* follows LEADING_CODE_PRIVATE_21 */
 -#define LEADING_CODE_EXT_22 0xF5 /* follows LEADING_CODE_PRIVATE_22 */
 -/* Maximum value of extended leading-codes.  */
 -#define LEADING_CODE_EXT_MAX 0xFE
 -
 -/* Definition of minimum/maximum charset of each DIMENSION.  */
 -#define MIN_CHARSET_OFFICIAL_DIMENSION1       0x80
 -#define MAX_CHARSET_OFFICIAL_DIMENSION1       0x8F
 -#define MIN_CHARSET_OFFICIAL_DIMENSION2       0x90
 -#define MAX_CHARSET_OFFICIAL_DIMENSION2 0x99
 -#define MIN_CHARSET_PRIVATE_DIMENSION1        LEADING_CODE_EXT_11
 -#define MIN_CHARSET_PRIVATE_DIMENSION2        LEADING_CODE_EXT_21
 -
 -/* Maximum value of overall charset identification number.  */
 -#define MAX_CHARSET 0xFE
 -
 -/* Definition of special charsets.  */
 -#define CHARSET_ASCII         0       /* 0x00..0x7F */
 -#define CHARSET_8_BIT_CONTROL 0x9E    /* 0x80..0x9F */
 -#define CHARSET_8_BIT_GRAPHIC 0x80    /* 0xA0..0xFF */
 -
 -extern int charset_latin_iso8859_1; /* ISO8859-1 (Latin-1) */
 -extern int charset_jisx0208_1978; /* JISX0208.1978 (Japanese Kanji old set) */
 -extern int charset_jisx0208;  /* JISX0208.1983 (Japanese Kanji) */
 -extern int charset_katakana_jisx0201; /* JISX0201.Kana (Japanese Katakana) */
 -extern int charset_latin_jisx0201; /* JISX0201.Roman (Japanese Roman) */
 -extern int charset_big5_1;    /* Big5 Level 1 (Chinese Traditional) */
 -extern int charset_big5_2;    /* Big5 Level 2 (Chinese Traditional) */
 -extern int charset_mule_unicode_0100_24ff;
 -extern int charset_mule_unicode_2500_33ff;
 -extern int charset_mule_unicode_e000_ffff;
 -
 -/* Check if CH is an ASCII character or a base leading-code.
 -   Nowadays, any byte can be the first byte of a character in a
 -   multibyte buffer/string.  So this macro name is not appropriate.  */
 -#define CHAR_HEAD_P(ch) ((unsigned char) (ch) < 0xA0)
 -
 -/*** GENERAL NOTE on CHARACTER REPRESENTATION ***
 -
 -  Firstly, the term "character" or "char" is used for a multilingual
 -  character (of course, including ASCII characters), not for a byte in
 -  computer memory.  We use the term "code" or "byte" for the latter
 -  case.
 -
 -  A character is identified by charset and one or two POSITION-CODEs.
 -  POSITION-CODE is the position of the character in the charset.  A
 -  character of DIMENSION1 charset has one POSITION-CODE: POSITION-CODE-1.
 -  A character of DIMENSION2 charset has two POSITION-CODE:
 -  POSITION-CODE-1 and POSITION-CODE-2.  The code range of
 -  POSITION-CODE is 0x20..0x7F.
 -
 -  Emacs has two kinds of representation of a character: multi-byte
 -  form (for buffers and strings) and single-word form (for character
 -  objects in Emacs Lisp).  The latter is called "character code"
 -  hereafter.  Both representations encode the information of charset
 -  and POSITION-CODE but in a different way (for instance, the MSB of
 -  POSITION-CODE is set in multi-byte form).
 -
 -  For details of the multi-byte form, see the section "2. Emacs
 -  internal format handlers" of `coding.c'.
 -
 -  Emacs uses 19 bits for a character code.  The bits are divided into
 -  3 fields: FIELD1(5bits):FIELD2(7bits):FIELD3(7bits).
 -
 -  A character code of DIMENSION1 character uses FIELD2 to hold charset
 -  and FIELD3 to hold POSITION-CODE-1.  A character code of DIMENSION2
 -  character uses FIELD1 to hold charset, FIELD2 and FIELD3 to hold
 -  POSITION-CODE-1 and POSITION-CODE-2 respectively.
 -
 -  More precisely...
 -
 -  FIELD2 of DIMENSION1 character (except for ascii, eight-bit-control,
 -  and eight-bit-graphic) is "charset - 0x70".  This is to make all
 -  character codes except for ASCII and 8-bit codes greater than 256.
 -  So, the range of FIELD2 of DIMENSION1 character is 0, 1, or
 -  0x11..0x7F.
 -
 -  FIELD1 of DIMENSION2 character is "charset - 0x8F" for official
 -  charset and "charset - 0xE0" for private charset.  So, the range of
 -  FIELD1 of DIMENSION2 character is 0x01..0x1E.
 -
 -  -----------------------------------------------------------------------------
 -  charset             FIELD1 (5-bit)      FIELD2 (7-bit)      FIELD3 (7-bit)
 -  -----------------------------------------------------------------------------
 -  ascii                       0                   0                   0x00..0x7F
 -  eight-bit-control   0                   1                   0x00..0x1F
 -  eight-bit-graphic   0                   1                   0x20..0x7F
 -  DIMENSION1          0                   charset - 0x70      POSITION-CODE-1
 -  DIMENSION2(o)               charset - 0x8F      POSITION-CODE-1     POSITION-CODE-2
 -  DIMENSION2(p)               charset - 0xE0      POSITION-CODE-1     POSITION-CODE-2
 -  -----------------------------------------------------------------------------
 -  "(o)": official, "(p)": private
 -  -----------------------------------------------------------------------------
 -*/
 -
 -/* Masks of each field of character code.  */
 -#define CHAR_FIELD1_MASK (0x1F << 14)
 -#define CHAR_FIELD2_MASK (0x7F << 7)
 -#define CHAR_FIELD3_MASK 0x7F
 -
 -/* Macros to access each field of character C.  */
 -#define CHAR_FIELD1(c) (((c) & CHAR_FIELD1_MASK) >> 14)
 -#define CHAR_FIELD2(c) (((c) & CHAR_FIELD2_MASK) >> 7)
 -#define CHAR_FIELD3(c) ((c) & CHAR_FIELD3_MASK)
 -
 -/* Minimum character code of character of each DIMENSION.  */
 -#define MIN_CHAR_OFFICIAL_DIMENSION1 \
 -  ((0x81 - 0x70) << 7)
 -#define MIN_CHAR_PRIVATE_DIMENSION1 \
 -  ((MIN_CHARSET_PRIVATE_DIMENSION1 - 0x70) << 7)
 -#define MIN_CHAR_OFFICIAL_DIMENSION2 \
 -  ((MIN_CHARSET_OFFICIAL_DIMENSION2 - 0x8F) << 14)
 -#define MIN_CHAR_PRIVATE_DIMENSION2 \
 -  ((MIN_CHARSET_PRIVATE_DIMENSION2 - 0xE0) << 14)
 -/* Maximum character code currently used plus 1.  */
 -#define MAX_CHAR (0x1F << 14)
 -
 -/* 1 if C is a single byte character, else 0.  */
 -#define SINGLE_BYTE_CHAR_P(c) (((unsigned)(c) & 0xFF) == (c))
 -
 -/* 1 if BYTE is an ASCII character in itself, in multibyte mode.  */
 -#define ASCII_BYTE_P(byte) ((byte) < 0x80)
 -
 -/* A char-table containing information on each character set.
 -
 -   Unlike ordinary char-tables, this doesn't contain any nested tables.
 -   Only the top level elements are used.  Each element is a vector of
 -   the following information:
 -      CHARSET-ID, BYTES, DIMENSION, CHARS, WIDTH, DIRECTION,
 -      LEADING-CODE-BASE, LEADING-CODE-EXT,
 -      ISO-FINAL-CHAR, ISO-GRAPHIC-PLANE,
 -      REVERSE-CHARSET, SHORT-NAME, LONG-NAME, DESCRIPTION,
 -      PLIST.
 -
 -   CHARSET-ID (integer) is the identification number of the charset.
 -
 -   BYTES (integer) is the length of the multi-byte form of a character
 -   in the charset: one of 1, 2, 3, and 4.
 -
 -   DIMENSION (integer) is the number of bytes to represent a character: 1 or 2.
 -
 -   CHARS (integer) is the number of characters in a dimension: 94 or 96.
 -
 -   WIDTH (integer) is the number of columns a character in the charset
 -   occupies on the screen: one of 0, 1, and 2..
 -
 -   DIRECTION (integer) is the rendering direction of characters in the
 -   charset when rendering.  If 0, render from left to right, else
 -   render from right to left.
 -
 -   LEADING-CODE-BASE (integer) is the base leading-code for the
 -   charset.
 -
 -   LEADING-CODE-EXT (integer) is the extended leading-code for the
 -   charset.  All charsets of less than 0xA0 have the value 0.
 -
 -   ISO-FINAL-CHAR (character) is the final character of the
 -   corresponding ISO 2022 charset.  It is -1 for such a character
 -   that is used only internally (e.g. `eight-bit-control').
 -
 -   ISO-GRAPHIC-PLANE (integer) is the graphic plane to be invoked
 -   while encoding to variants of ISO 2022 coding system, one of the
 -   following: 0/graphic-plane-left(GL), 1/graphic-plane-right(GR).  It
 -   is -1 for such a character that is used only internally
 -   (e.g. `eight-bit-control').
 -
 -   REVERSE-CHARSET (integer) is the charset which differs only in
 -   LEFT-TO-RIGHT value from the charset.  If there's no such a
 -   charset, the value is -1.
 -
 -   SHORT-NAME (string) is the short name to refer to the charset.
 -
 -   LONG-NAME (string) is the long name to refer to the charset.
 -
 -   DESCRIPTION (string) is the description string of the charset.
 -
 -   PLIST (property list) may contain any type of information a user
 -   wants to put and get by functions `put-charset-property' and
 -   `get-charset-property' respectively.  */
 -extern Lisp_Object Vcharset_table;
 -
 -/* Macros to access various information of CHARSET in Vcharset_table.
 -   We provide these macros for efficiency.  No range check of CHARSET.  */
 -
 -/* Return entry of CHARSET (C integer) in Vcharset_table.  */
 -#define CHARSET_TABLE_ENTRY(charset)                                  \
 -  XCHAR_TABLE (Vcharset_table)->contents[((charset) == CHARSET_ASCII  \
 -                                        ? 0 : (charset) + 128)]
 -
 -/* Return information INFO-IDX of CHARSET.  */
 -#define CHARSET_TABLE_INFO(charset, info_idx) \
 -  XVECTOR (CHARSET_TABLE_ENTRY (charset))->contents[info_idx]
 -
 -#define CHARSET_ID_IDX (0)
 -#define CHARSET_BYTES_IDX (1)
 -#define CHARSET_DIMENSION_IDX (2)
 -#define CHARSET_CHARS_IDX (3)
 -#define CHARSET_WIDTH_IDX (4)
 -#define CHARSET_DIRECTION_IDX (5)
 -#define CHARSET_LEADING_CODE_BASE_IDX (6)
 -#define CHARSET_LEADING_CODE_EXT_IDX (7)
 -#define CHARSET_ISO_FINAL_CHAR_IDX (8)
 -#define CHARSET_ISO_GRAPHIC_PLANE_IDX (9)
 -#define CHARSET_REVERSE_CHARSET_IDX (10)
 -#define CHARSET_SHORT_NAME_IDX (11)
 -#define CHARSET_LONG_NAME_IDX (12)
 -#define CHARSET_DESCRIPTION_IDX (13)
 -#define CHARSET_PLIST_IDX (14)
 -/* Size of a vector of each entry of Vcharset_table.  */
 -#define CHARSET_MAX_IDX (15)
 -
 -/* And several more macros to be used frequently.  */
 -#define CHARSET_BYTES(charset) \
 -  XFASTINT (CHARSET_TABLE_INFO (charset, CHARSET_BYTES_IDX))
 -#define CHARSET_DIMENSION(charset) \
 -  XFASTINT (CHARSET_TABLE_INFO (charset, CHARSET_DIMENSION_IDX))
 -#define CHARSET_CHARS(charset) \
 -  XFASTINT (CHARSET_TABLE_INFO (charset, CHARSET_CHARS_IDX))
 -#define CHARSET_WIDTH(charset) \
 -  XFASTINT (CHARSET_TABLE_INFO (charset, CHARSET_WIDTH_IDX))
 -#define CHARSET_DIRECTION(charset) \
 -  XFASTINT (CHARSET_TABLE_INFO (charset, CHARSET_DIRECTION_IDX))
 -#define CHARSET_LEADING_CODE_BASE(charset) \
 -  XFASTINT (CHARSET_TABLE_INFO (charset, CHARSET_LEADING_CODE_BASE_IDX))
 -#define CHARSET_LEADING_CODE_EXT(charset) \
 -  XFASTINT (CHARSET_TABLE_INFO (charset, CHARSET_LEADING_CODE_EXT_IDX))
 -#define CHARSET_ISO_FINAL_CHAR(charset) \
 -  XINT (CHARSET_TABLE_INFO (charset, CHARSET_ISO_FINAL_CHAR_IDX))
 -#define CHARSET_ISO_GRAPHIC_PLANE(charset) \
 -  XINT (CHARSET_TABLE_INFO (charset, CHARSET_ISO_GRAPHIC_PLANE_IDX))
 -#define CHARSET_REVERSE_CHARSET(charset) \
 -  XINT (CHARSET_TABLE_INFO (charset, CHARSET_REVERSE_CHARSET_IDX))
 -
 -/* Macros to specify direction of a charset.  */
 -#define CHARSET_DIRECTION_LEFT_TO_RIGHT 0
 -#define CHARSET_DIRECTION_RIGHT_TO_LEFT 1
 -
 -/* A vector of charset symbol indexed by charset-id.  This is used
 -   only for returning charset symbol from C functions.  */
 -extern Lisp_Object Vcharset_symbol_table;
 -
 -/* Return symbol of CHARSET.  */
 -#define CHARSET_SYMBOL(charset) \
 -  XVECTOR (Vcharset_symbol_table)->contents[charset]
 -
 -/* 1 if CHARSET is in valid value range, else 0.  */
 -#define CHARSET_VALID_P(charset)                                       \
 -  ((charset) == 0                                                      \
 -   || ((charset) > 0x80 && (charset) <= MAX_CHARSET_OFFICIAL_DIMENSION2) \
 -   || ((charset) >= MIN_CHARSET_PRIVATE_DIMENSION1                     \
 -       && (charset) <= MAX_CHARSET)                                    \
 -   || ((charset) == CHARSET_8_BIT_CONTROL)                             \
 -   || ((charset) == CHARSET_8_BIT_GRAPHIC))
 -
 -/* 1 if CHARSET is already defined, else 0.  */
 -#define CHARSET_DEFINED_P(charset)                    \
 -  (((charset) >= 0) && ((charset) <= MAX_CHARSET)     \
 -   && !NILP (CHARSET_TABLE_ENTRY (charset)))
 -
 -/* Since the information CHARSET-BYTES and CHARSET-WIDTH of
 -   Vcharset_table can be retrieved only by the first byte of
 -   multi-byte form (an ASCII code or a base leading-code), we provide
 -   here tables to be used by macros BYTES_BY_CHAR_HEAD and
 -   WIDTH_BY_CHAR_HEAD for faster information retrieval.  */
 -extern int bytes_by_char_head[256];
 -extern int width_by_char_head[256];
 -
 -#define BYTES_BY_CHAR_HEAD(char_head) \
 -  (ASCII_BYTE_P (char_head) ? 1 : bytes_by_char_head[char_head])
 -#define WIDTH_BY_CHAR_HEAD(char_head) \
 -  (ASCII_BYTE_P (char_head) ? 1 : width_by_char_head[char_head])
 -
 -/* Charset of the character C.  */
 -#define CHAR_CHARSET(c)                                                       \
 -  (SINGLE_BYTE_CHAR_P (c)                                             \
 -   ? (ASCII_BYTE_P (c)                                                        \
 -      ? CHARSET_ASCII                                                 \
 -      : (c) < 0xA0 ? CHARSET_8_BIT_CONTROL : CHARSET_8_BIT_GRAPHIC)   \
 -   : ((c) < MIN_CHAR_OFFICIAL_DIMENSION2                              \
 -      ? CHAR_FIELD2 (c) + 0x70                                                \
 -      : ((c) < MIN_CHAR_PRIVATE_DIMENSION2                            \
 -       ? CHAR_FIELD1 (c) + 0x8F                                       \
 -       : CHAR_FIELD1 (c) + 0xE0)))
 +/* Index to arguments of Fdefine_charset_internal.  */
 +
 +enum define_charset_arg_index
 +  {
 +    charset_arg_name,
 +    charset_arg_dimension,
 +    charset_arg_code_space,
 +    charset_arg_min_code,
 +    charset_arg_max_code,
 +    charset_arg_iso_final,
 +    charset_arg_iso_revision,
 +    charset_arg_emacs_mule_id,
 +    charset_arg_ascii_compatible_p,
 +    charset_arg_supplementary_p,
 +    charset_arg_invalid_code,
 +    charset_arg_code_offset,
 +    charset_arg_map,
 +    charset_arg_subset,
 +    charset_arg_superset,
 +    charset_arg_unify_map,
 +    charset_arg_plist,
 +    charset_arg_max
 +  };
 +
 +
 +/* Indices to charset attributes vector.  */
 +
 +enum charset_attr_index
 +  {
 +    /* ID number of the charset.  */
 +    charset_id,
 +
 +    /* Name of the charset (symbol).  */
 +    charset_name,
 +
 +    /* Property list of the charset.  */
 +    charset_plist,
 +
 +    /* If the method of the charset is `MAP_DEFERRED', the value is a
 +       mapping vector or a file name that contains mapping vector.
 +       Otherwise, nil.  */
 +    charset_map,
 +
 +    /* If the method of the charset is `MAP', the value is a vector
 +       that maps code points of the charset to characters.  The vector
 +       is indexed by a character index.  A character index is
 +       calculated from a code point and the code-space table of the
 +       charset.  */
 +    charset_decoder,
 +
 +    /* If the method of the charset is `MAP', the value is a
 +       char-table that maps characters of the charset to code
 +       points.  */
 +    charset_encoder,
 +
 +    /* If the method of the charset is `SUBSET', the value is a vector
 +       that has this form:
 +
 +      [ CHARSET-ID MIN-CODE MAX-CODE OFFSET ]
 +
 +       CHARSET-ID is an ID number of a parent charset.  MIN-CODE and
 +       MAX-CODE specify the range of characters inherited from the
 +       parent.  OFFSET is an integer value to add to a code point of
 +       the parent charset to get the corresponding code point of this
 +       charset.  */
 +    charset_subset,
 +
 +    /* If the method of the charset is `SUPERSET', the value is a list
 +       whose elements have this form:
 +
 +      (CHARSET-ID . OFFSET)
 +
 +      CHARSET-IDs are ID numbers of parent charsets.  OFFSET is an
 +      integer value to add to a code point of the parent charset to
 +      get the corresponding code point of this charset.  */
 +    charset_superset,
 +
 +    /* The value is a mapping vector or a file name that contains the
 +       mapping.  This defines how characters in the charset should be
 +       unified with Unicode.  The value of the member
 +       `charset_deunifier' is created from this information.  */
 +    charset_unify_map,
 +
 +    /* If characters in the charset must be unified Unicode, the value
 +       is a char table that maps a unified Unicode character code to
 +       the non-unified character code in the charset.  */
 +    charset_deunifier,
 +
 +    /* The length of the charset attribute vector.  */
 +    charset_attr_max
 +  };
 +
 +/* Methods for converting code points and characters of charsets.  */
 +
 +enum charset_method
 +  {
 +    /* For a charset of this method, a character code is calculated
 +       from a character index (which is calculated from a code point)
 +       simply by adding an offset value.  */
 +    CHARSET_METHOD_OFFSET,
 +
 +    /* For a charset of this method, a decoder vector and an encoder
 +       char-table is used for code point <-> character code
 +       conversion.  */
 +    CHARSET_METHOD_MAP,
 +
 +    /* Same as above but decoder and encoder are loaded from a file on
 +       demand.  Once loaded, the method is changed to
 +       CHARSET_METHOD_MAP.  */
 +    CHARSET_METHOD_MAP_DEFERRED,
 +
 +    /* A charset of this method is a subset of another charset.  */
 +    CHARSET_METHOD_SUBSET,
 +
 +    /* A charset of this method is a superset of other charsets.  */
 +    CHARSET_METHOD_SUPERSET
 +  };
 +
 +struct charset
 +{
 +  /* Index to charset_table.  */
 +  int id;
  
 -/* Check if two characters C1 and C2 belong to the same charset.  */
 -#define SAME_CHARSET_P(c1, c2)                                \
 -  (c1 < MIN_CHAR_OFFICIAL_DIMENSION2                  \
 -   ? (c1 & CHAR_FIELD2_MASK) == (c2 & CHAR_FIELD2_MASK)       \
 -   : (c1 & CHAR_FIELD1_MASK) == (c2 & CHAR_FIELD1_MASK))
 -
 -/* Return a character of which charset is CHARSET and position-codes
 -   are C1 and C2.  DIMENSION1 character ignores C2.  */
 -#define MAKE_CHAR(charset, c1, c2)                                        \
 -  ((charset) == CHARSET_ASCII                                             \
 -   ? (c1) & 0x7F                                                          \
 -   : (((charset) == CHARSET_8_BIT_CONTROL                                 \
 -       || (charset) == CHARSET_8_BIT_GRAPHIC)                             \
 -      ? ((c1) & 0x7F) | 0x80                                              \
 -      : ((CHARSET_DEFINED_P (charset)                                     \
 -        ? CHARSET_DIMENSION (charset) == 1                                \
 -        : (charset) < MIN_CHARSET_PRIVATE_DIMENSION2)                     \
 -       ? (((charset) - 0x70) << 7) | ((c1) <= 0 ? 0 : ((c1) & 0x7F))      \
 -       : ((((charset)                                                     \
 -            - ((charset) < MIN_CHARSET_PRIVATE_DIMENSION2 ? 0x8F : 0xE0)) \
 -           << 14)                                                         \
 -          | ((c2) <= 0 ? 0 : ((c2) & 0x7F))                               \
 -          | ((c1) <= 0 ? 0 : (((c1) & 0x7F) << 7))))))
 -
 -
 -/* If GENERICP is nonzero, return nonzero iff C is a valid normal or
 -   generic character.  If GENERICP is zero, return nonzero iff C is a
 -   valid normal character.  */
 -#define CHAR_VALID_P(c, genericp)     \
 -  ((c) >= 0                           \
 -   && (SINGLE_BYTE_CHAR_P (c) || char_valid_p (c, genericp)))
 -
 -/* This default value is used when nonascii-translation-table or
 -   nonascii-insert-offset fail to convert unibyte character to a valid
 -   multibyte character.  This makes a Latin-1 character.  */
 -
 -#define DEFAULT_NONASCII_INSERT_OFFSET 0x800
 -
 -/* Parse multibyte string STR of length LENGTH and set BYTES to the
 -   byte length of a character at STR.  */
 -
 -#ifdef BYTE_COMBINING_DEBUG
 -
 -#define PARSE_MULTIBYTE_SEQ(str, length, bytes)                       \
 +  /* Index to Vcharset_hash_table.  */
 +  int hash_index;
 +
 +  /* Dimension of the charset: 1, 2, 3, or 4.  */
 +  int dimension;
 +
 +  /* Byte code range of each dimension.  <code_space>[4N] is a mininum
 +     byte code of the (N+1)th dimension, <code_space>[4N+1] is a
 +     maximum byte code of the (N+1)th dimension, <code_space>[4N+2] is
 +     (<code_space>[4N+1] - <code_space>[4N] + 1), <code_space>[4N+3]
 +     is a number of characters containd in the first to (N+1)th
 +     dismesions.  We get `char-index' of a `code-point' from this
 +     information.  */
 +  int code_space[16];
 +
 +  /* If B is a byte of Nth dimension of a code-point, the (N-1)th bit
 +     of code_space_mask[B] is set.  This array is used to quickly
 +     check if a code-point is in a valid range.  */
 +  unsigned char *code_space_mask;
 +
 +  /* 1 if there's no gap in code-points.  */
 +  int code_linear_p;
 +
 +  /* If the charset is treated as 94-chars in ISO-2022, the value is 0.
 +     If the charset is treated as 96-chars in ISO-2022, the value is 1.  */
 +  int iso_chars_96;
 +
 +  /* ISO final byte of the charset: 48..127.  It may be -1 if the
 +     charset doesn't conform to ISO-2022.  */
 +  int iso_final;
 +
 +  /* ISO revision number of the charset.  */
 +  int iso_revision;
 +
 +  /* If the charset is identical to what supported by Emacs 21 and the
 +     priors, the identification number of the charset used in those
 +     version.  Otherwise, -1.  */
 +  int emacs_mule_id;
 +
 +  /* Nonzero iff the charset is compatible with ASCII.  */
 +  int ascii_compatible_p;
 +
 +  /* Nonzero iff the charset is supplementary.  */
 +  int supplementary_p;
 +
 +  /* Nonzero iff all the code points are representable by Lisp_Int.  */
 +  int compact_codes_p;
 +
 +  /* The method for encoding/decoding characters of the charset.  */
 +  enum charset_method method;
 +
 +  /* Mininum and Maximum code points of the charset.  */
 +  unsigned min_code, max_code;
 +
 +  /* Offset value used by macros CODE_POINT_TO_INDEX and
 +      INDEX_TO_CODE_POINT. .  */
 +  unsigned char_index_offset;
 +
 +  /* Mininum and Maximum character codes of the charset.  If the
 +     charset is compatible with ASCII, min_char is a minimum non-ASCII
 +     character of the charset.  If the method of charset is
 +     CHARSET_METHOD_OFFSET, even if the charset is unified, min_char
 +     and max_char doesn't change.  */
 +  int min_char, max_char;
 +
 +  /* The code returned by ENCODE_CHAR if a character is not encodable
 +     by the charset.  */
 +  unsigned invalid_code;
 +
 +  /* If the method of the charset is CHARSET_METHOD_MAP, this is a
 +     table of bits used to quickly and roughly guess if a character
 +     belongs to the charset.
 +
 +     The first 64 elements are 512 bits for characters less than
 +     0x10000.  Each bit corresponds to 128-character block.  The last
 +     126 elements are 1008 bits for the greater characters
 +     (0x10000..0x3FFFFF).  Each bit corresponds to 4096-character
 +     block.
 +
 +     If a bit is 1, at least one character in the corresponding block is
 +     in this charset.  */
 +  unsigned char fast_map[190];
 +
 +  /* Offset value to calculate a character code from code-point, and
 +     visa versa.  */
 +  int code_offset;
 +
 +  int unified_p;
 +};
 +
 +/* Hash table of charset symbols vs. the correponding attribute
 +   vectors.  */
 +extern Lisp_Object Vcharset_hash_table;
 +
 +/* Table of struct charset.  */
 +extern struct charset *charset_table;
 +
 +#define CHARSET_FROM_ID(id) (charset_table + (id))
 +
 +extern Lisp_Object Vcharset_ordered_list;
 +
 +/* Incremented everytime we change the priority of charsets.  */
 +extern unsigned short charset_ordered_list_tick;
 +
 +extern Lisp_Object Vcharset_list;
 +extern Lisp_Object Viso_2022_charset_list;
 +extern Lisp_Object Vemacs_mule_charset_list;
 +
 +extern struct charset *emacs_mule_charset[256];
 +
 +
 +/* Macros to access information about charset.  */
 +
 +/* Return the attribute vector of charset whose symbol is SYMBOL.  */
 +#define CHARSET_SYMBOL_ATTRIBUTES(symbol)     \
 +  Fgethash ((symbol), Vcharset_hash_table, Qnil)
 +
 +#define CHARSET_ATTR_ID(attrs)                AREF ((attrs), charset_id)
 +#define CHARSET_ATTR_NAME(attrs)      AREF ((attrs), charset_name)
 +#define CHARSET_ATTR_PLIST(attrs)     AREF ((attrs), charset_plist)
 +#define CHARSET_ATTR_MAP(attrs)               AREF ((attrs), charset_map)
 +#define CHARSET_ATTR_DECODER(attrs)   AREF ((attrs), charset_decoder)
 +#define CHARSET_ATTR_ENCODER(attrs)   AREF ((attrs), charset_encoder)
 +#define CHARSET_ATTR_SUBSET(attrs)    AREF ((attrs), charset_subset)
 +#define CHARSET_ATTR_SUPERSET(attrs)  AREF ((attrs), charset_superset)
 +#define CHARSET_ATTR_UNIFY_MAP(attrs) AREF ((attrs), charset_unify_map)
 +#define CHARSET_ATTR_DEUNIFIER(attrs) AREF ((attrs), charset_deunifier)
 +
 +#define CHARSET_SYMBOL_ID(symbol)     \
 +  CHARSET_ATTR_ID (CHARSET_SYMBOL_ATTRIBUTES (symbol))
 +
 +/* Return an index to Vcharset_hash_table of the charset whose symbol
 +   is SYMBOL.  */
 +#define CHARSET_SYMBOL_HASH_INDEX(symbol)     \
 +  hash_lookup (XHASH_TABLE (Vcharset_hash_table), symbol, NULL)
 +
 +/* Return the attribute vector of CHARSET.  */
 +#define CHARSET_ATTRIBUTES(charset)   \
 +  (HASH_VALUE (XHASH_TABLE (Vcharset_hash_table), (charset)->hash_index))
 +
 +#define CHARSET_ID(charset)           ((charset)->id)
 +#define CHARSET_HASH_INDEX(charset)   ((charset)->hash_index)
 +#define CHARSET_DIMENSION(charset)    ((charset)->dimension)
 +#define CHARSET_CODE_SPACE(charset)   ((charset)->code_space)
 +#define CHARSET_CODE_LINEAR_P(charset)        ((charset)->code_linear_p)
 +#define CHARSET_ISO_CHARS_96(charset) ((charset)->iso_chars_96)
 +#define CHARSET_ISO_FINAL(charset)    ((charset)->iso_final)
 +#define CHARSET_ISO_PLANE(charset)    ((charset)->iso_plane)
 +#define CHARSET_ISO_REVISION(charset) ((charset)->iso_revision)
 +#define CHARSET_EMACS_MULE_ID(charset)        ((charset)->emacs_mule_id)
 +#define CHARSET_ASCII_COMPATIBLE_P(charset) ((charset)->ascii_compatible_p)
 +#define CHARSET_COMPACT_CODES_P(charset) ((charset)->compact_codes_p)
 +#define CHARSET_METHOD(charset)               ((charset)->method)
 +#define CHARSET_MIN_CODE(charset)     ((charset)->min_code)
 +#define CHARSET_MAX_CODE(charset)     ((charset)->max_code)
 +#define CHARSET_INVALID_CODE(charset) ((charset)->invalid_code)
 +#define CHARSET_MIN_CHAR(charset)     ((charset)->min_char)
 +#define CHARSET_MAX_CHAR(charset)     ((charset)->max_char)
 +#define CHARSET_CODE_OFFSET(charset)  ((charset)->code_offset)
 +#define CHARSET_UNIFIED_P(charset)    ((charset)->unified_p)
 +
 +#define CHARSET_NAME(charset)         \
 +  (CHARSET_ATTR_NAME (CHARSET_ATTRIBUTES (charset)))
 +#define CHARSET_MAP(charset)  \
 +  (CHARSET_ATTR_MAP (CHARSET_ATTRIBUTES (charset)))
 +#define CHARSET_DECODER(charset)      \
 +  (CHARSET_ATTR_DECODER (CHARSET_ATTRIBUTES (charset)))
 +#define CHARSET_ENCODER(charset)      \
 +  (CHARSET_ATTR_ENCODER (CHARSET_ATTRIBUTES (charset)))
 +#define CHARSET_SUBSET(charset)       \
 +  (CHARSET_ATTR_SUBSET (CHARSET_ATTRIBUTES (charset)))
 +#define CHARSET_SUPERSET(charset)     \
 +  (CHARSET_ATTR_SUPERSET (CHARSET_ATTRIBUTES (charset)))
 +#define CHARSET_UNIFY_MAP(charset)    \
 +  (CHARSET_ATTR_UNIFY_MAP (CHARSET_ATTRIBUTES (charset)))
 +#define CHARSET_DEUNIFIER(charset)    \
 +  (CHARSET_ATTR_DEUNIFIER (CHARSET_ATTRIBUTES (charset)))
 +
 +
 +/* Nonzero iff OBJ is a valid charset symbol.  */
 +#define CHARSETP(obj) (CHARSET_SYMBOL_HASH_INDEX (obj) >= 0)
 +
 +/* Check if X is a valid charset symbol.  If not, signal an error.  */
 +#define CHECK_CHARSET(x)                                      \
    do {                                                                \
 -    int i = 1;                                                        \
 -    while (i < (length) && ! CHAR_HEAD_P ((str)[i])) i++;     \
 -    (bytes) = BYTES_BY_CHAR_HEAD ((str)[0]);                  \
 -    if ((bytes) > i)                                          \
 -      abort ();                                                       \
 +    if (! SYMBOLP (x) || CHARSET_SYMBOL_HASH_INDEX (x) < 0)   \
 +      x = wrong_type_argument (Qcharsetp, (x));                       \
    } while (0)
  
 -#else  /* not BYTE_COMBINING_DEBUG */
 -
 -#define PARSE_MULTIBYTE_SEQ(str, length, bytes)       \
 -  ((void)(length), (bytes) = BYTES_BY_CHAR_HEAD ((str)[0]))
 -
 -#endif /* not BYTE_COMBINING_DEBUG */
 -
 -#define VALID_LEADING_CODE_P(code)    \
 -  (! NILP (CHARSET_TABLE_ENTRY (code)))
 -
 -/* Return 1 iff the byte sequence at unibyte string STR (LENGTH bytes)
 -   is valid as a multibyte form.  If valid, by a side effect, BYTES is
 -   set to the byte length of the multibyte form.  */
 -
 -#define UNIBYTE_STR_AS_MULTIBYTE_P(str, length, bytes)                \
 -  (((str)[0] < 0x80 || (str)[0] >= 0xA0)                      \
 -   ? ((bytes) = 1)                                            \
 -   : (((bytes) = BYTES_BY_CHAR_HEAD ((str)[0])),              \
 -      ((bytes) <= (length)                                    \
 -       && !CHAR_HEAD_P ((str)[1])                             \
 -       && ((bytes) == 2                                               \
 -         ? (str)[0] != LEADING_CODE_8_BIT_CONTROL             \
 -         : (!CHAR_HEAD_P ((str)[2])                           \
 -            && ((bytes) == 3                                  \
 -                ? (((str)[0] != LEADING_CODE_PRIVATE_11       \
 -                    && (str)[0] != LEADING_CODE_PRIVATE_12)   \
 -                   || VALID_LEADING_CODE_P (str[1]))          \
 -                : (!CHAR_HEAD_P ((str)[3])                    \
 -                   && VALID_LEADING_CODE_P (str[1]))))))))
 -
 -
 -/* Return 1 iff the byte sequence at multibyte string STR is valid as
 -   a unibyte form.  By a side effect, BYTES is set to the byte length
 -   of one character at STR.  */
 -
 -#define MULTIBYTE_STR_AS_UNIBYTE_P(str, bytes)        \
 -  ((bytes) = BYTES_BY_CHAR_HEAD ((str)[0]),   \
 -   (str)[0] != LEADING_CODE_8_BIT_CONTROL)
 -
 -/* The charset of character C is stored in CHARSET, and the
 -   position-codes of C are stored in C1 and C2.
 -   We store -1 in C2 if the dimension of the charset is 1.  */
 -
 -#define SPLIT_CHAR(c, charset, c1, c2)                                            \
 -  (SINGLE_BYTE_CHAR_P (c)                                                 \
 -   ? ((charset                                                                    \
 -       = (ASCII_BYTE_P (c)                                                \
 -        ? CHARSET_ASCII                                                   \
 -        : ((c) < 0xA0 ? CHARSET_8_BIT_CONTROL : CHARSET_8_BIT_GRAPHIC))), \
 -      c1 = (c), c2 = -1)                                                  \
 -   : ((c) & CHAR_FIELD1_MASK                                              \
 -      ? (charset = (CHAR_FIELD1 (c)                                       \
 -                  + ((c) < MIN_CHAR_PRIVATE_DIMENSION2 ? 0x8F : 0xE0)),   \
 -       c1 = CHAR_FIELD2 (c),                                              \
 -       c2 = CHAR_FIELD3 (c))                                              \
 -      : (charset = CHAR_FIELD2 (c) + 0x70,                                \
 -       c1 = CHAR_FIELD3 (c),                                              \
 -       c2 = -1)))
 -
 -/* Return 1 iff character C has valid printable glyph.  */
 -#define CHAR_PRINTABLE_P(c) (ASCII_BYTE_P (c) || char_printable_p (c))
 -
 -/* The charset of the character at STR is stored in CHARSET, and the
 -   position-codes are stored in C1 and C2.
 -   We store -1 in C2 if the character is just 2 bytes.  */
 -
 -#define SPLIT_STRING(str, len, charset, c1, c2)                       \
 -  ((BYTES_BY_CHAR_HEAD ((unsigned char) *(str)) < 2           \
 -    || BYTES_BY_CHAR_HEAD ((unsigned char) *(str)) > len      \
 -    || split_string (str, len, &charset, &c1, &c2) < 0)               \
 -   ? c1 = *(str), charset = CHARSET_ASCII                     \
 -   : charset)
  
 -/* Mapping table from ISO2022's charset (specified by DIMENSION,
 -   CHARS, and FINAL_CHAR) to Emacs' charset.  Should be accessed by
 -   macro ISO_CHARSET_TABLE (DIMENSION, CHARS, FINAL_CHAR).  */
 -extern int iso_charset_table[2][2][128];
 -
 -#define ISO_CHARSET_TABLE(dimension, chars, final_char) \
 -  iso_charset_table[XINT (dimension) - 1][XINT (chars) > 94][XINT (final_char)]
 -
 -#define BASE_LEADING_CODE_P(c) (BYTES_BY_CHAR_HEAD ((unsigned char) (c)) > 1)
 -
 -/* Return how many bytes C will occupy in a multibyte buffer.  */
 -#define CHAR_BYTES(c)                                 \
 -  (SINGLE_BYTE_CHAR_P (c)                             \
 -   ? ((ASCII_BYTE_P (c) || (c) >= 0xA0) ? 1 : 2)      \
 -   : char_bytes (c))
 -
 -/* The following two macros CHAR_STRING and STRING_CHAR are the main
 -   entry points to convert between Emacs's two types of character
 -   representations: multi-byte form and single-word form (character
 -   code).  */
 -
 -/* Store multi-byte form of the character C in STR.  The caller should
 -   allocate at least MAX_MULTIBYTE_LENGTH bytes area at STR in
 -   advance.  Returns the length of the multi-byte form.  If C is an
 -   invalid character code, signal an error.  */
 -
 -#define CHAR_STRING(c, str)                                             \
 -  (SINGLE_BYTE_CHAR_P (c)                                               \
 -   ? ((ASCII_BYTE_P (c) || c >= 0xA0)                   \
 -      ? (*(str) = (unsigned char)(c), 1)                                \
 -      : (*(str) = LEADING_CODE_8_BIT_CONTROL, *((str)+ 1) = c + 0x20, 2)) \
 -   : char_to_string (c, (unsigned char *) str))
 -
 -/* Like CHAR_STRING but don't signal an error if C is invalid.
 -   Value is -1 in this case.  */
 -
 -#define CHAR_STRING_NO_SIGNAL(c, str)                                   \
 -  (SINGLE_BYTE_CHAR_P (c)                                               \
 -   ? ((ASCII_BYTE_P (c) || c >= 0xA0)                                   \
 -      ? (*(str) = (unsigned char)(c), 1)                                \
 -      : (*(str) = LEADING_CODE_8_BIT_CONTROL, *((str)+ 1) = c + 0x20, 2)) \
 -   : char_to_string_1 (c, (unsigned char *) str))
 -
 -/* Return a character code of the character of which multi-byte form
 -   is at STR and the length is LEN.  If STR doesn't contain valid
 -   multi-byte form, only the first byte in STR is returned.  */
 -
 -#define STRING_CHAR(str, len)                         \
 -  (BYTES_BY_CHAR_HEAD ((unsigned char) *(str)) == 1   \
 -   ? (unsigned char) *(str)                           \
 -   : string_to_char (str, len, 0))
 -
 -/* This is like STRING_CHAR but the third arg ACTUAL_LEN is set to the
 -   length of the multi-byte form.  Just to know the length, use
 -   MULTIBYTE_FORM_LENGTH.  */
 -
 -#define STRING_CHAR_AND_LENGTH(str, len, actual_len)  \
 -  (BYTES_BY_CHAR_HEAD ((unsigned char) *(str)) == 1   \
 -   ? ((actual_len) = 1), (unsigned char) *(str)               \
 -   : string_to_char (str, len, &(actual_len)))
 -
 -/* Fetch the "next" character from Lisp string STRING at byte position
 -   BYTEIDX, character position CHARIDX.  Store it into OUTPUT.
 -
 -   All the args must be side-effect-free.
 -   BYTEIDX and CHARIDX must be lvalues;
 -   we increment them past the character fetched.  */
 -
 -#define FETCH_STRING_CHAR_ADVANCE(OUTPUT, STRING, CHARIDX, BYTEIDX)      \
 -if (1)                                                                           \
 -  {                                                                      \
 -    CHARIDX++;                                                                   \
 -    if (STRING_MULTIBYTE (STRING))                                       \
 -      {                                                                          \
 -      const unsigned char *ptr = SDATA (STRING) + BYTEIDX;               \
 -      int space_left = SBYTES (STRING) - BYTEIDX;                        \
 -      int actual_len;                                                    \
 -                                                                         \
 -      OUTPUT = STRING_CHAR_AND_LENGTH (ptr, space_left, actual_len);     \
 -      BYTEIDX += actual_len;                                             \
 -      }                                                                          \
 -    else                                                                 \
 -      OUTPUT = SREF (STRING, BYTEIDX++);                                 \
 -  }                                                                      \
 -else
 -
 -/* Like FETCH_STRING_CHAR_ADVANCE but assume STRING is multibyte.  */
 -
 -#define FETCH_STRING_CHAR_ADVANCE_NO_CHECK(OUTPUT, STRING, CHARIDX, BYTEIDX)  \
 -if (1)                                                                              \
 -  {                                                                         \
 -    const unsigned char *fetch_string_char_ptr = SDATA (STRING) + BYTEIDX;    \
 -    int fetch_string_char_space_left = SBYTES (STRING) - BYTEIDX;           \
 -    int actual_len;                                                         \
 -                                                                            \
 -    OUTPUT                                                                  \
 -      = STRING_CHAR_AND_LENGTH (fetch_string_char_ptr,                              \
 -                              fetch_string_char_space_left, actual_len);    \
 -                                                                            \
 -    BYTEIDX += actual_len;                                                  \
 -    CHARIDX++;                                                                      \
 -  }                                                                         \
 -else
 -
 -/* Like FETCH_STRING_CHAR_ADVANCE but fetch character from the current
 -   buffer.  */
 -
 -#define FETCH_CHAR_ADVANCE(OUTPUT, CHARIDX, BYTEIDX)                    \
 -if (1)                                                                          \
 -  {                                                                     \
 -    CHARIDX++;                                                                  \
 -    if (!NILP (current_buffer->enable_multibyte_characters))            \
 -      {                                                                         \
 -      unsigned char *ptr = BYTE_POS_ADDR (BYTEIDX);                     \
 -      int space_left = ((CHARIDX < GPT ? GPT_BYTE : Z_BYTE) - BYTEIDX); \
 -      int actual_len;                                                   \
 -                                                                        \
 -      OUTPUT= STRING_CHAR_AND_LENGTH (ptr, space_left, actual_len);     \
 -      BYTEIDX += actual_len;                                            \
 -      }                                                                         \
 -    else                                                                \
 -      {                                                                         \
 -      OUTPUT = *(BYTE_POS_ADDR (BYTEIDX));                              \
 -      BYTEIDX++;                                                        \
 -      }                                                                         \
 -  }                                                                     \
 -else
 -
 -/* Return the length of the multi-byte form at string STR of length LEN.  */
 -
 -#define MULTIBYTE_FORM_LENGTH(str, len)                       \
 -  (BYTES_BY_CHAR_HEAD (*(unsigned char *)(str)) == 1  \
 -   ? 1                                                        \
 -   : multibyte_form_length (str, len))
 -
 -/* If P is before LIMIT, advance P to the next character boundary.  It
 -   assumes that P is already at a character boundary of the sane
 -   mulitbyte form whose end address is LIMIT.  */
 -
 -#define NEXT_CHAR_BOUNDARY(p, limit)  \
 -  do {                                        \
 -    if ((p) < (limit))                        \
 -      (p) += BYTES_BY_CHAR_HEAD (*(p));       \
 +/* Check if X is a valid charset symbol.  If valid, set ID to the id
 +   number of the charset.  Otherwise, signal an error. */
 +#define CHECK_CHARSET_GET_ID(x, id)                                   \
 +  do {                                                                        \
 +    int idx;                                                          \
 +                                                                      \
 +    if (! SYMBOLP (x) || (idx = CHARSET_SYMBOL_HASH_INDEX (x)) < 0)   \
 +      x = wrong_type_argument (Qcharsetp, (x));                               \
 +    id = XINT (AREF (HASH_VALUE (XHASH_TABLE (Vcharset_hash_table), idx), \
 +                   charset_id));                                      \
    } while (0)
  
  
 -/* If P is after LIMIT, advance P to the previous character boundary.  */
 -
 -#define PREV_CHAR_BOUNDARY(p, limit)                                  \
 +/* Check if X is a valid charset symbol.  If valid, set ATTR to the
 +   attr vector of the charset.  Otherwise, signal an error. */
 +#define CHECK_CHARSET_GET_ATTR(x, attr)                               \
    do {                                                                        \
 -    if ((p) > (limit))                                                        \
 -      {                                                                       \
 -      const unsigned char *p0 = (p);                                  \
 -      const unsigned char *p_limit = max (limit, p0 - MAX_MULTIBYTE_LENGTH);\
 -      do {                                                            \
 -        p0--;                                                         \
 -      } while (p0 >= p_limit && ! CHAR_HEAD_P (*p0));                 \
 -      /* If BBCH(*p0) > p-p0, it means we were not on a boundary.  */ \
 -      (p) = (BYTES_BY_CHAR_HEAD (*p0) >= (p) - p0) ? p0 : (p) - 1;    \
 -      }                                                                       \
 +    if (!SYMBOLP (x) || NILP (attr = CHARSET_SYMBOL_ATTRIBUTES (x)))  \
 +      x = wrong_type_argument (Qcharsetp, (x));                               \
    } while (0)
  
 -#define AT_CHAR_BOUNDARY_P(result, p, limit)  \
 +
 +#define CHECK_CHARSET_GET_CHARSET(x, charset) \
    do {                                                \
 -    if (CHAR_HEAD_P (*(p)) || (p) <= limit)   \
 -      /* Optimization for the common case. */ \
 -      (result) = 1;                           \
 -    else                                      \
 -      {                                               \
 -      const unsigned char *p_aux = (p)+1;     \
 -      PREV_CHAR_BOUNDARY (p_aux, limit);      \
 -      (result) = (p_aux == (p));              \
 -      }                                               \
 -} while (0)
 -
 -#ifdef emacs
 -
 -/* Increase the buffer byte position POS_BYTE of the current buffer to
 -   the next character boundary.  This macro relies on the fact that
 -   *GPT_ADDR and *Z_ADDR are always accessible and the values are
 -   '\0'.  No range checking of POS.  */
 -
 -#ifdef BYTE_COMBINING_DEBUG
 -
 -#define INC_POS(pos_byte)                             \
 -  do {                                                        \
 -    unsigned char *p = BYTE_POS_ADDR (pos_byte);      \
 -    if (BASE_LEADING_CODE_P (*p))                     \
 -      {                                                       \
 -      int len, bytes;                                 \
 -      len = Z_BYTE - pos_byte;                        \
 -      PARSE_MULTIBYTE_SEQ (p, len, bytes);            \
 -      pos_byte += bytes;                              \
 -      }                                                       \
 -    else                                              \
 -      pos_byte++;                                     \
 +    int id;                                   \
 +    CHECK_CHARSET_GET_ID (x, id);             \
 +    charset = CHARSET_FROM_ID (id);           \
    } while (0)
  
 -#else  /* not BYTE_COMBINING_DEBUG */
  
 -#define INC_POS(pos_byte)                             \
 -  do {                                                        \
 -    unsigned char *p = BYTE_POS_ADDR (pos_byte);      \
 -    pos_byte += BYTES_BY_CHAR_HEAD (*p);              \
 -  } while (0)
 +/* Lookup Vcharset_order_list and return the first charset that
 +   contains the character C.  */
 +#define CHAR_CHARSET(c)                               \
 +  ((c) < 0x80 ? CHARSET_FROM_ID (charset_ascii)       \
 +   : char_charset ((c), Qnil, NULL))
  
 -#endif /* not BYTE_COMBINING_DEBUG */
 +#if 0
 +/* Char-table of charset-sets.  Each element is a bool vector indexed
 +   by a charset ID.  */
 +extern Lisp_Object Vchar_charset_set;
  
 -/* Decrease the buffer byte position POS_BYTE of the current buffer to
 -   the previous character boundary.  No range checking of POS.  */
 -#define DEC_POS(pos_byte)                                             \
 -  do {                                                                        \
 -    unsigned char *p, *p_min;                                         \
 -                                                                      \
 -    pos_byte--;                                                               \
 -    if (pos_byte < GPT_BYTE)                                          \
 -      p = BEG_ADDR + pos_byte - BEG_BYTE, p_min = BEG_ADDR;           \
 -    else                                                              \
 -      p = BEG_ADDR + GAP_SIZE + pos_byte - BEG_BYTE, p_min = GAP_END_ADDR;\
 -    if (p > p_min && !CHAR_HEAD_P (*p))                                       \
 -      {                                                                       \
 -      unsigned char *pend = p--;                                      \
 -      int len, bytes;                                                 \
 -        if (p_min < p - MAX_MULTIBYTE_LENGTH)                         \
 -          p_min = p - MAX_MULTIBYTE_LENGTH;                           \
 -      while (p > p_min && !CHAR_HEAD_P (*p)) p--;                     \
 -      len = pend + 1 - p;                                             \
 -      PARSE_MULTIBYTE_SEQ (p, len, bytes);                            \
 -      if (bytes == len)                                               \
 -        pos_byte -= len - 1;                                          \
 -      }                                                                       \
 -  } while (0)
 +/* Charset-bag of character C.  */
 +#define CHAR_CHARSET_SET(c) \
 +  CHAR_TABLE_REF (Vchar_charset_set, c)
  
 -/* Increment both CHARPOS and BYTEPOS, each in the appropriate way.  */
 +/* Check if two characters C1 and C2 belong to the same charset.  */
 +#define SAME_CHARSET_P(c1, c2)        \
 +  intersection_p (CHAR_CHARSET_SET (c1), CHAR_CHARSET_SET (c2))
 +
 +#endif
 +
 +
 +/* Return a character correponding to the code-point CODE of CHARSET.
 +   Try some optimization before calling decode_char.  */
 +
 +#define DECODE_CHAR(charset, code)                                    \
 +  ((ASCII_BYTE_P (code) && (charset)->ascii_compatible_p)             \
 +   ? (code)                                                           \
 +   : ((code) < (charset)->min_code || (code) > (charset)->max_code)   \
 +   ? -1                                                                       \
 +   : (charset)->unified_p                                             \
 +   ? decode_char ((charset), (code))                                  \
 +   : (charset)->method == CHARSET_METHOD_OFFSET                               \
 +   ? ((charset)->code_linear_p                                                \
 +      ? (code) - (charset)->min_code + (charset)->code_offset         \
 +      : decode_char ((charset), (code)))                              \
 +   : (charset)->method == CHARSET_METHOD_MAP                          \
 +   ? ((charset)->code_linear_p                                                \
 +      ? XINT (AREF (CHARSET_DECODER (charset),                                \
 +                      (code) - (charset)->min_code))                  \
 +      : decode_char ((charset), (code)))                              \
 +   : decode_char ((charset), (code)))
 +
 +
 +/* If CHARSET is a simple offset base charset, return it's offset,
 +   otherwise return -1.  */
 +#define CHARSET_OFFSET(charset)                               \
 +  (((charset)->method == CHARSET_METHOD_OFFSET                \
 +    && (charset)->code_linear_p                               \
 +    && ! (charset)->unified_p)                                \
 +   ? (charset)->code_offset - (charset)->min_code     \
 +   : -1)
 +
 +extern Lisp_Object charset_work;
 +
 +/* Return a code point of CHAR in CHARSET.
 +   Try some optimization before calling encode_char.  */
 +
 +#define ENCODE_CHAR(charset, c)                                                \
 +  ((ASCII_CHAR_P (c) && (charset)->ascii_compatible_p)                         \
 +   ? (c)                                                               \
 +   : ((charset)->unified_p                                             \
 +      || (charset)->method == CHARSET_METHOD_SUBSET                    \
 +      || (charset)->method == CHARSET_METHOD_SUPERSET)                         \
 +   ? encode_char ((charset), (c))                                      \
 +   : ((c) < (charset)->min_char || (c) > (charset)->max_char)          \
 +   ? (charset)->invalid_code                                           \
 +   : (charset)->method == CHARSET_METHOD_OFFSET                                \
 +   ? ((charset)->code_linear_p                                                 \
 +      ? (c) - (charset)->code_offset + (charset)->min_code             \
 +      : encode_char ((charset), (c)))                                  \
 +   : (charset)->method == CHARSET_METHOD_MAP                           \
 +   ? ((charset)->compact_codes_p                                       \
 +      ? (charset_work = CHAR_TABLE_REF (CHARSET_ENCODER (charset), (c)), \
 +       (NILP (charset_work)                                            \
 +        ? (charset)->invalid_code                                      \
 +        : XFASTINT (charset_work)))                                    \
 +      : encode_char ((charset), (c)))                                  \
 +   : encode_char ((charset), (c)))
 +
 +
 +/* Set to 1 when a charset map is loaded to warn that a buffer text
 +   and a string data may be relocated.  */
 +extern int charset_map_loaded;
 +
 +
 +/* Set CHARSET to the charset highest priority of C, CODE to the
 +   code-point of C in CHARSET.  */
 +#define SPLIT_CHAR(c, charset, code)  \
 +  ((charset) = char_charset ((c), Qnil, &(code)))
 +
 +
 +#define ISO_MAX_DIMENSION 3
 +#define ISO_MAX_CHARS 2
 +#define ISO_MAX_FINAL 0x80    /* only 0x30..0xFF are used */
  
 -#define INC_BOTH(charpos, bytepos)                            \
 -do                                                            \
 -  {                                                           \
 -    (charpos)++;                                              \
 -    if (NILP (current_buffer->enable_multibyte_characters))   \
 -      (bytepos)++;                                            \
 -    else                                                      \
 -      INC_POS ((bytepos));                                    \
 -  }                                                           \
 -while (0)
 -
 -/* Decrement both CHARPOS and BYTEPOS, each in the appropriate way.  */
 -
 -#define DEC_BOTH(charpos, bytepos)                            \
 -do                                                            \
 -  {                                                           \
 -    (charpos)--;                                              \
 -    if (NILP (current_buffer->enable_multibyte_characters))   \
 -      (bytepos)--;                                            \
 -    else                                                      \
 -      DEC_POS ((bytepos));                                    \
 -  }                                                           \
 -while (0)
 +/* Mapping table from ISO2022's charset (specified by DIMENSION,
 +   CHARS, and FINAL_CHAR) to Emacs' charset ID.  Should be accessed by
 +   macro ISO_CHARSET_TABLE (DIMENSION, CHARS, FINAL_CHAR).  */
 +extern int iso_charset_table[ISO_MAX_DIMENSION][ISO_MAX_CHARS][ISO_MAX_FINAL];
  
 -/* Increase the buffer byte position POS_BYTE of the current buffer to
 -   the next character boundary.  This macro relies on the fact that
 -   *GPT_ADDR and *Z_ADDR are always accessible and the values are
 -   '\0'.  No range checking of POS_BYTE.  */
 +/* A charset of type iso2022 who has DIMENSION, CHARS, and FINAL
 +   (final character).  */
 +#define ISO_CHARSET_TABLE(dimension, chars_96, final) \
 +  iso_charset_table[(dimension) - 1][(chars_96)][(final)]
  
 -#ifdef BYTE_COMBINING_DEBUG
 +/* Nonzero iff the charset who has FAST_MAP may contain C.  */
 +#define CHARSET_FAST_MAP_REF(c, fast_map)             \
 +  ((c) < 0x10000                                      \
 +   ? fast_map[(c) >> 10] & (1 << (((c) >> 7) & 7))    \
 +   : fast_map[((c) >> 15) + 62] & (1 << (((c) >> 12) & 7)))
  
 -#define BUF_INC_POS(buf, pos_byte)                            \
 +#define CHARSET_FAST_MAP_SET(c, fast_map)                     \
    do {                                                                \
 -    unsigned char *p = BUF_BYTE_ADDRESS (buf, pos_byte);      \
 -    if (BASE_LEADING_CODE_P (*p))                             \
 -      {                                                               \
 -      int len, bytes;                                         \
 -      len = BUF_Z_BYTE (buf) - pos_byte;                      \
 -      PARSE_MULTIBYTE_SEQ (p, len, bytes);                    \
 -      pos_byte += bytes;                                      \
 -      }                                                               \
 +    if ((c) < 0x10000)                                                \
 +      (fast_map)[(c) >> 10] |= 1 << (((c) >> 7) & 7);         \
      else                                                      \
 -      pos_byte++;                                             \
 +      (fast_map)[((c) >> 15) + 62] |= 1 << (((c) >> 12) & 7); \
    } while (0)
  
 -#else  /* not BYTE_COMBINING_DEBUG */
  
 -#define BUF_INC_POS(buf, pos_byte)                            \
 -  do {                                                                \
 -    unsigned char *p = BUF_BYTE_ADDRESS (buf, pos_byte);      \
 -    pos_byte += BYTES_BY_CHAR_HEAD (*p);                      \
 -  } while (0)
  
 -#endif /* not BYTE_COMBINING_DEBUG */
 +/* 1 iff CHARSET may contain the character C.  */
 +#define CHAR_CHARSET_P(c, charset)                                     \
 +  ((ASCII_CHAR_P (c) && (charset)->ascii_compatible_p)                         \
 +   || ((CHARSET_UNIFIED_P (charset)                                    \
 +      || (charset)->method == CHARSET_METHOD_SUBSET                    \
 +      || (charset)->method == CHARSET_METHOD_SUPERSET)                 \
 +       ? encode_char ((charset), (c)) != (charset)->invalid_code       \
 +       : (CHARSET_FAST_MAP_REF ((c), (charset)->fast_map)              \
 +        && ((charset)->method == CHARSET_METHOD_OFFSET                 \
 +            ? (c) >= (charset)->min_char && (c) <= (charset)->max_char \
 +            : ((charset)->method == CHARSET_METHOD_MAP                 \
 +               && (charset)->compact_codes_p)                          \
 +            ? ! NILP (CHAR_TABLE_REF (CHARSET_ENCODER (charset), (c))) \
 +            : encode_char ((charset), (c)) != (charset)->invalid_code))))
  
 -/* Decrease the buffer byte position POS_BYTE of the current buffer to
 -   the previous character boundary.  No range checking of POS_BYTE.  */
 -#define BUF_DEC_POS(buf, pos_byte)                                    \
 -  do {                                                                        \
 -    unsigned char *p, *p_min;                                         \
 -    pos_byte--;                                                               \
 -    if (pos_byte < BUF_GPT_BYTE (buf))                                        \
 -      {                                                                       \
 -      p = BUF_BEG_ADDR (buf) + pos_byte - BEG_BYTE;                   \
 -      p_min = BUF_BEG_ADDR (buf);                                     \
 -      }                                                                       \
 -    else                                                              \
 -      {                                                                       \
 -      p = BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + pos_byte - BEG_BYTE;\
 -      p_min = BUF_GAP_END_ADDR (buf);                                 \
 -      }                                                                       \
 -    if (p > p_min && !CHAR_HEAD_P (*p))                                       \
 -      {                                                                       \
 -      unsigned char *pend = p--;                                      \
 -      int len, bytes;                                                 \
 -        if (p_min < p - MAX_MULTIBYTE_LENGTH)                         \
 -          p_min = p - MAX_MULTIBYTE_LENGTH;                           \
 -      while (p > p_min && !CHAR_HEAD_P (*p)) p--;                     \
 -      len = pend + 1 - p;                                             \
 -      PARSE_MULTIBYTE_SEQ (p, len, bytes);                            \
 -      if (bytes == len)                                               \
 -        pos_byte -= len - 1;                                          \
 -      }                                                                       \
 -  } while (0)
 +\f
 +/* Special macros for emacs-mule encoding.  */
  
 -#endif /* emacs */
 -
 -/* This is the maximum byte length of multi-byte sequence.  */
 -#define MAX_MULTIBYTE_LENGTH 4
 -
 -extern void invalid_character P_ ((int)) NO_RETURN;
 -
 -extern int translate_char P_ ((Lisp_Object, int, int, int, int));
 -extern int split_string P_ ((const unsigned char *, int, int *,
 -                                     unsigned char *, unsigned char *));
 -extern int char_to_string P_ ((int, unsigned char *));
 -extern int char_to_string_1 P_ ((int, unsigned char *));
 -extern int string_to_char P_ ((const unsigned char *, int, int *));
 -extern int char_printable_p P_ ((int c));
 -extern int multibyte_form_length P_ ((const unsigned char *, int));
 -extern void parse_str_as_multibyte P_ ((const unsigned char *, int, int *,
 -                                      int *));
 -extern int str_as_multibyte P_ ((unsigned char *, int, int, int *));
 -extern int parse_str_to_multibyte P_ ((unsigned char *, int));
 -extern int str_to_multibyte P_ ((unsigned char *, int, int));
 -extern int str_as_unibyte P_ ((unsigned char *, int));
 -extern int get_charset_id P_ ((Lisp_Object));
 -extern int find_charset_in_text P_ ((const unsigned char *, int, int, int *,
 -                                  Lisp_Object));
 -extern int strwidth P_ ((unsigned char *, int));
 -extern int c_string_width P_ ((const unsigned char *, int, int, int *, int *));
 -extern int lisp_string_width P_ ((Lisp_Object, int, int *, int *));
 -extern int char_bytes P_ ((int));
 -extern int char_valid_p P_ ((int, int));
 -
 -EXFUN (Funibyte_char_to_multibyte, 1);
 -
 -extern Lisp_Object Vtranslation_table_vector;
 -
 -/* Return a translation table of id number ID.  */
 -#define GET_TRANSLATION_TABLE(id) \
 -  (XCDR(XVECTOR(Vtranslation_table_vector)->contents[(id)]))
 -
 -/* A char-table for characters which may invoke auto-filling.  */
 -extern Lisp_Object Vauto_fill_chars;
 -
 -/* Copy LEN bytes from FROM to TO.  This macro should be used only
 -   when a caller knows that LEN is short and the obvious copy loop is
 -   faster than calling bcopy which has some overhead.  Copying a
 -   multibyte sequence of a multibyte character is the typical case.  */
 -
 -#define BCOPY_SHORT(from, to, len)            \
 -  do {                                                \
 -    int i = len;                              \
 -    const unsigned char *from_p = from;               \
 -    unsigned char *to_p = to;                 \
 -    while (i--) *to_p++ = *from_p++;          \
 -  } while (0)
 +/* Leading-code followed by extended leading-code.    DIMENSION/COLUMN */
 +#define EMACS_MULE_LEADING_CODE_PRIVATE_11    0x9A /* 1/1 */
 +#define EMACS_MULE_LEADING_CODE_PRIVATE_12    0x9B /* 1/2 */
 +#define EMACS_MULE_LEADING_CODE_PRIVATE_21    0x9C /* 2/2 */
 +#define EMACS_MULE_LEADING_CODE_PRIVATE_22    0x9D /* 2/2 */
 +
 +extern struct charset *emacs_mule_charset[256];
 +
 +\f
 +
 +extern Lisp_Object Qcharsetp;
 +
 +extern Lisp_Object Qascii, Qunicode;
 +extern int charset_ascii, charset_eight_bit;
 +extern int charset_iso_8859_1;
 +extern int charset_unicode;
 +extern int charset_jisx0201_roman;
 +extern int charset_jisx0208_1978;
 +extern int charset_jisx0208;
 +
 +extern int charset_unibyte;
 +
 +extern struct charset *char_charset P_ ((int, Lisp_Object, unsigned *));
 +extern Lisp_Object charset_attributes P_ ((int));
 +
 +extern int decode_char P_ ((struct charset *, unsigned));
 +extern unsigned encode_char P_ ((struct charset *, int));
 +extern int string_xstring_p P_ ((Lisp_Object));
 +
 +extern void map_charset_chars P_ ((void (*) (Lisp_Object, Lisp_Object),
 +                                 Lisp_Object, Lisp_Object,
 +                                 struct charset *, unsigned, unsigned));
 +
 +EXFUN (Funify_charset, 3);
  
  #endif /* EMACS_CHARSET_H */
  
diff --combined src/cmds.c
index 096b63dd4531555ea5c965f3f0b8b0455e85b65e,7e07ce1dc6fbe501df8078e2f048bd13c77e4ec1..e8f775d9c3510f51b0111ba10b9f6579045abf55
@@@ -1,6 -1,6 +1,6 @@@
  /* Simple built-in editing commands.
     Copyright (C) 1985, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002,
-                  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -24,7 -24,7 +24,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "lisp.h"
  #include "commands.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "syntax.h"
  #include "window.h"
  #include "keyboard.h"
@@@ -327,11 -327,11 +327,11 @@@ Whichever character you type to run thi
    CHECK_NUMBER (n);
  
    /* Barf if the key that invoked this was not a character.  */
 -  if (!INTEGERP (last_command_char))
 +  if (!CHARACTERP (last_command_char))
      bitch_at_user ();
    {
      int character = translate_char (Vtranslation_table_for_input,
 -                                  XINT (last_command_char), 0, 0, 0);
 +                                  XINT (last_command_char));
      if (XINT (n) >= 2 && NILP (current_buffer->overwrite_mode))
        {
        int modified_char = character;
@@@ -395,6 -395,7 +395,6 @@@ internal_self_insert (c, noautofill
    /* At first, get multi-byte form of C in STR.  */
    if (!NILP (current_buffer->enable_multibyte_characters))
      {
 -      c = unibyte_char_to_multibyte (c);
        len = CHAR_STRING (c, str);
        if (len == 1)
        /* If C has modifier bits, this makes C an appropriate
        }
        hairy = 2;
      }
 +
 +  if (NILP (current_buffer->enable_multibyte_characters))
 +    MAKE_CHAR_MULTIBYTE (c);
 +  synt = SYNTAX (c);
 +
    if (!NILP (current_buffer->abbrev_mode)
 -      && SYNTAX (c) != Sword
 +      && synt != Sword
        && NILP (current_buffer->read_only)
 -      && PT > BEGV && SYNTAX (XFASTINT (Fprevious_char ())) == Sword)
 +      && PT > BEGV
 +      && (!NILP (current_buffer->enable_multibyte_characters)
 +        ? SYNTAX (XFASTINT (Fprevious_char ())) == Sword
 +        : (SYNTAX (unibyte_char_to_multibyte (XFASTINT (Fprevious_char ())))
 +           == Sword)))
      {
        int modiff = MODIFF;
        Lisp_Object sym;
        Vself_insert_face = Qnil;
      }
  
 -  synt = SYNTAX (c);
    if ((synt == Sclose || synt == Smath)
        && !NILP (Vblink_paren_function) && INTERACTIVE
        && !noautofill)
diff --combined src/coding.c
index 50c63b4beb8cce92f9fd4f20a2aaf0c263058459,6bb9f8225c9896aa6da3dfa608acac169df78adc..aa58884fdedfcba80b97f3cce8c76dcb76ffccbc
@@@ -1,13 -1,10 +1,13 @@@
 -/* Coding system handler (conversion, detection, and etc).
 +/* Coding system handler (conversion, detection, etc).
     Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+                  2006, 2007 Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -30,325 -27,383 +30,325 @@@ Boston, MA 02110-1301, USA.  *
  
    0. General comments
    1. Preamble
 -  2. Emacs' internal format (emacs-mule) handlers
 -  3. ISO2022 handlers
 -  4. Shift-JIS and BIG5 handlers
 -  5. CCL handlers
 -  6. End-of-line handlers
 -  7. C library functions
 -  8. Emacs Lisp library functions
 -  9. Post-amble
 +  2. Emacs' internal format (emacs-utf-8) handlers
 +  3. UTF-8 handlers
 +  4. UTF-16 handlers
 +  5. Charset-base coding systems handlers
 +  6. emacs-mule (old Emacs' internal format) handlers
 +  7. ISO2022 handlers
 +  8. Shift-JIS and BIG5 handlers
 +  9. CCL handlers
 +  10. C library functions
 +  11. Emacs Lisp library functions
 +  12. Postamble
  
  */
  
 -/*** 0. General comments ***/
 +/*** 0. General comments ***
  
  
 -/*** GENERAL NOTE on CODING SYSTEMS ***
 +CODING SYSTEM
  
 -  A coding system is an encoding mechanism for one or more character
 -  sets.  Here's a list of coding systems which Emacs can handle.  When
 -  we say "decode", it means converting some other coding system to
 -  Emacs' internal format (emacs-mule), and when we say "encode",
 -  it means converting the coding system emacs-mule to some other
 +  A coding system is an object for an encoding mechanism that contains
 +  information about how to convert byte sequences to character
 +  sequences and vice versa.  When we say "decode", it means converting
 +  a byte sequence of a specific coding system into a character
 +  sequence that is represented by Emacs' internal coding system
 +  `emacs-utf-8', and when we say "encode", it means converting a
 +  character sequence of emacs-utf-8 to a byte sequence of a specific
    coding system.
  
 -  0. Emacs' internal format (emacs-mule)
 +  In Emacs Lisp, a coding system is represented by a Lisp symbol.  In
 +  C level, a coding system is represented by a vector of attributes
 +  stored in the hash table Vcharset_hash_table.  The conversion from
 +  coding system symbol to attributes vector is done by looking up
 +  Vcharset_hash_table by the symbol.
 +
 +  Coding systems are classified into the following types depending on
 +  the encoding mechanism.  Here's a brief description of the types.
 +
 +  o UTF-8
 +
 +  o UTF-16
  
 -  Emacs itself holds a multi-lingual character in buffers and strings
 -  in a special format.  Details are described in section 2.
 +  o Charset-base coding system
  
 -  1. ISO2022
 +  A coding system defined by one or more (coded) character sets.
 +  Decoding and encoding are done by a code converter defined for each
 +  character set.
 +
 +  o Old Emacs internal format (emacs-mule)
 +
 +  The coding system adopted by old versions of Emacs (20 and 21).
 +
 +  o ISO2022-base coding system
  
    The most famous coding system for multiple character sets.  X's
 -  Compound Text, various EUCs (Extended Unix Code), and coding
 -  systems used in Internet communication such as ISO-2022-JP are
 -  all variants of ISO2022.  Details are described in section 3.
 +  Compound Text, various EUCs (Extended Unix Code), and coding systems
 +  used in the Internet communication such as ISO-2022-JP are all
 +  variants of ISO2022.
  
 -  2. SJIS (or Shift-JIS or MS-Kanji-Code)
 +  o SJIS (or Shift-JIS or MS-Kanji-Code)
  
    A coding system to encode character sets: ASCII, JISX0201, and
    JISX0208.  Widely used for PC's in Japan.  Details are described in
 -  section 4.
 +  section 8.
  
 -  3. BIG5
 +  o BIG5
  
 -  A coding system to encode the character sets ASCII and Big5.  Widely
 +  A coding system to encode character sets: ASCII and Big5.  Widely
    used for Chinese (mainly in Taiwan and Hong Kong).  Details are
 -  described in section 4.  In this file, when we write "BIG5"
 -  (all uppercase), we mean the coding system, and when we write
 -  "Big5" (capitalized), we mean the character set.
 +  described in section 8.  In this file, when we write "big5" (all
 +  lowercase), we mean the coding system, and when we write "Big5"
 +  (capitalized), we mean the character set.
  
 -  4. Raw text
 +  o CCL
  
 -  A coding system for text containing random 8-bit code.  Emacs does
 -  no code conversion on such text except for end-of-line format.
 +  If a user wants to decode/encode text encoded in a coding system
 +  not listed above, he can supply a decoder and an encoder for it in
 +  CCL (Code Conversion Language) programs.  Emacs executes the CCL
 +  program while decoding/encoding.
  
 -  5. Other
 +  o Raw-text
  
 -  If a user wants to read/write text encoded in a coding system not
 -  listed above, he can supply a decoder and an encoder for it as CCL
 -  (Code Conversion Language) programs.  Emacs executes the CCL program
 -  while reading/writing.
 +  A coding system for text containing raw eight-bit data.  Emacs
 +  treats each byte of source text as a character (except for
 +  end-of-line conversion).
  
 -  Emacs represents a coding system by a Lisp symbol that has a property
 -  `coding-system'.  But, before actually using the coding system, the
 -  information about it is set in a structure of type `struct
 -  coding_system' for rapid processing.  See section 6 for more details.
 +  o No-conversion
  
 -*/
 +  Like raw text, but don't do end-of-line conversion.
  
 -/*** GENERAL NOTES on END-OF-LINE FORMAT ***
  
 -  How end-of-line of text is encoded depends on the operating system.
 -  For instance, Unix's format is just one byte of `line-feed' code,
 +END-OF-LINE FORMAT
 +
 +  How text end-of-line is encoded depends on operating system.  For
 +  instance, Unix's format is just one byte of LF (line-feed) code,
    whereas DOS's format is two-byte sequence of `carriage-return' and
    `line-feed' codes.  MacOS's format is usually one byte of
    `carriage-return'.
  
    Since text character encoding and end-of-line encoding are
 -  independent, any coding system described above can have any
 -  end-of-line format.  So Emacs has information about end-of-line
 -  format in each coding-system.  See section 6 for more details.
 +  independent, any coding system described above can take any format
 +  of end-of-line (except for no-conversion).
 +
 +STRUCT CODING_SYSTEM
 +
 +  Before using a coding system for code conversion (i.e. decoding and
 +  encoding), we setup a structure of type `struct coding_system'.
 +  This structure keeps various information about a specific code
 +  conversion (e.g. the location of source and destination data).
  
  */
  
 +/* COMMON MACROS */
 +
 +
  /*** GENERAL NOTES on `detect_coding_XXX ()' functions ***
  
 -  These functions check if a text between SRC and SRC_END is encoded
 -  in the coding system category XXX.  Each returns an integer value in
 -  which appropriate flag bits for the category XXX are set.  The flag
 -  bits are defined in macros CODING_CATEGORY_MASK_XXX.  Below is the
 -  template for these functions.  If MULTIBYTEP is nonzero, 8-bit codes
 -  of the range 0x80..0x9F are in multibyte form.  */
 +  These functions check if a byte sequence specified as a source in
 +  CODING conforms to the format of XXX, and update the members of
 +  DETECT_INFO.
 +
 +  Return 1 if the byte sequence conforms to XXX, otherwise return 0.
 +
 +  Below is the template of these functions.  */
 +
  #if 0
 -int
 -detect_coding_emacs_mule (src, src_end, multibytep)
 -     unsigned char *src, *src_end;
 -     int multibytep;
 +static int
 +detect_coding_XXX (coding, detect_info)
 +     struct coding_system *coding;
 +     struct coding_detection_info *detect_info;
  {
 -  ...
 +  const unsigned char *src = coding->source;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  int found = 0;
 +  ...;
 +
 +  while (1)
 +    {
 +      /* Get one byte from the source.  If the souce is exausted, jump
 +       to no_more_source:.  */
 +      ONE_MORE_BYTE (c);
 +
 +      if (! __C_conforms_to_XXX___ (c))
 +      break;
 +      if (! __C_strongly_suggests_XXX__ (c))
 +      found = CATEGORY_MASK_XXX;
 +    }
 +  /* The byte sequence is invalid for XXX.  */
 +  detect_info->rejected |= CATEGORY_MASK_XXX;
 +  return 0;
 +
 + no_more_source:
 +  /* The source exausted successfully.  */
 +  detect_info->found |= found;
 +  return 1;
  }
  #endif
  
  /*** GENERAL NOTES on `decode_coding_XXX ()' functions ***
  
 -  These functions decode SRC_BYTES length of unibyte text at SOURCE
 -  encoded in CODING to Emacs' internal format.  The resulting
 -  multibyte text goes to a place pointed to by DESTINATION, the length
 -  of which should not exceed DST_BYTES.
 +  These functions decode a byte sequence specified as a source by
 +  CODING.  The resulting multibyte text goes to a place pointed to by
 +  CODING->charbuf, the length of which should not exceed
 +  CODING->charbuf_size;
  
 -  These functions set the information about original and decoded texts
 -  in the members `produced', `produced_char', `consumed', and
 -  `consumed_char' of the structure *CODING.  They also set the member
 -  `result' to one of CODING_FINISH_XXX indicating how the decoding
 -  finished.
 +  These functions set the information of original and decoded texts in
 +  CODING->consumed, CODING->consumed_char, and CODING->charbuf_used.
 +  They also set CODING->result to one of CODING_RESULT_XXX indicating
 +  how the decoding is finished.
  
 -  DST_BYTES zero means that the source area and destination area are
 -  overlapped, which means that we can produce a decoded text until it
 -  reaches the head of the not-yet-decoded source text.
 +  Below is the template of these functions.  */
  
 -  Below is a template for these functions.  */
  #if 0
  static void
 -decode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)
 +decode_coding_XXXX (coding)
       struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
  {
 -  ...
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  /* SRC_BASE remembers the start position in source in each loop.
 +     The loop will be exited when there's not enough source code, or
 +     when there's no room in CHARBUF for a decoded character.  */
 +  const unsigned char *src_base;
 +  /* A buffer to produce decoded characters.  */
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end = coding->charbuf + coding->charbuf_size;
 +  int multibytep = coding->src_multibyte;
 +
 +  while (1)
 +    {
 +      src_base = src;
 +      if (charbuf < charbuf_end)
 +      /* No more room to produce a decoded character.  */
 +      break;
 +      ONE_MORE_BYTE (c);
 +      /* Decode it. */
 +    }
 +
 + no_more_source:
 +  if (src_base < src_end
 +      && coding->mode & CODING_MODE_LAST_BLOCK)
 +    /* If the source ends by partial bytes to construct a character,
 +       treat them as eight-bit raw data.  */
 +    while (src_base < src_end && charbuf < charbuf_end)
 +      *charbuf++ = *src_base++;
 +  /* Remember how many bytes and characters we consumed.  If the
 +     source is multibyte, the bytes and chars are not identical.  */
 +  coding->consumed = coding->consumed_char = src_base - coding->source;
 +  /* Remember how many characters we produced.  */
 +  coding->charbuf_used = charbuf - coding->charbuf;
  }
  #endif
  
  /*** GENERAL NOTES on `encode_coding_XXX ()' functions ***
  
 -  These functions encode SRC_BYTES length text at SOURCE from Emacs'
 -  internal multibyte format to CODING.  The resulting unibyte text
 +  These functions encode SRC_BYTES length text at SOURCE of Emacs'
 +  internal multibyte format by CODING.  The resulting byte sequence
    goes to a place pointed to by DESTINATION, the length of which
    should not exceed DST_BYTES.
  
 -  These functions set the information about original and encoded texts
 -  in the members `produced', `produced_char', `consumed', and
 -  `consumed_char' of the structure *CODING.  They also set the member
 -  `result' to one of CODING_FINISH_XXX indicating how the encoding
 -  finished.
 +  These functions set the information of original and encoded texts in
 +  the members produced, produced_char, consumed, and consumed_char of
 +  the structure *CODING.  They also set the member result to one of
 +  CODING_RESULT_XXX indicating how the encoding finished.
  
 -  DST_BYTES zero means that the source area and destination area are
 -  overlapped, which means that we can produce encoded text until it
 -  reaches at the head of the not-yet-encoded source text.
 +  DST_BYTES zero means that source area and destination area are
 +  overlapped, which means that we can produce encoded text until it
 +  reaches at the head of not-yet-encoded source text.
  
 -  Below is a template for these functions.  */
 +  Below is a template of these functions.  */
  #if 0
  static void
 -encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)
 +encode_coding_XXX (coding)
       struct coding_system *coding;
 -     unsigned char *source, *destination;
 -     int src_bytes, dst_bytes;
  {
 -  ...
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf->charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  unsigned char *adjusted_dst_end = dst_end - _MAX_BYTES_PRODUCED_IN_LOOP_;
 +  int produced_chars = 0;
 +
 +  for (; charbuf < charbuf_end && dst < adjusted_dst_end; charbuf++)
 +    {
 +      int c = *charbuf;
 +      /* Encode C into DST, and increment DST.  */
 +    }
 + label_no_more_destination:
 +  /* How many chars and bytes we produced.  */
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
  }
  #endif
  
 -/*** COMMONLY USED MACROS ***/
 -
 -/* The following two macros ONE_MORE_BYTE and TWO_MORE_BYTES safely
 -   get one, two, and three bytes from the source text respectively.
 -   If there are not enough bytes in the source, they jump to
 -   `label_end_of_loop'.  The caller should set variables `coding',
 -   `src' and `src_end' to appropriate pointer in advance.  These
 -   macros are called from decoding routines `decode_coding_XXX', thus
 -   it is assumed that the source text is unibyte.  */
 -
 -#define ONE_MORE_BYTE(c1)                                     \
 -  do {                                                                \
 -    if (src >= src_end)                                               \
 -      {                                                               \
 -      coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \
 -      goto label_end_of_loop;                                 \
 -      }                                                               \
 -    c1 = *src++;                                              \
 -  } while (0)
 -
 -#define TWO_MORE_BYTES(c1, c2)                                        \
 -  do {                                                                \
 -    if (src + 1 >= src_end)                                   \
 -      {                                                               \
 -      coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \
 -      goto label_end_of_loop;                                 \
 -      }                                                               \
 -    c1 = *src++;                                              \
 -    c2 = *src++;                                              \
 -  } while (0)
 -
 -
 -/* Like ONE_MORE_BYTE, but 8-bit bytes of data at SRC are in multibyte
 -   form if MULTIBYTEP is nonzero.  In addition, if SRC is not less
 -   than SRC_END, return with RET.  */
 -
 -#define ONE_MORE_BYTE_CHECK_MULTIBYTE(c1, multibytep, ret)    \
 -  do {                                                                \
 -    if (src >= src_end)                                               \
 -      {                                                               \
 -      coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \
 -      return ret;                                             \
 -      }                                                               \
 -    c1 = *src++;                                              \
 -    if (multibytep && c1 == LEADING_CODE_8_BIT_CONTROL)               \
 -      c1 = *src++ - 0x20;                                     \
 -  } while (0)
 -
 -/* Set C to the next character at the source text pointed by `src'.
 -   If there are not enough characters in the source, jump to
 -   `label_end_of_loop'.  The caller should set variables `coding'
 -   `src', `src_end', and `translation_table' to appropriate pointers
 -   in advance.  This macro is used in encoding routines
 -   `encode_coding_XXX', thus it assumes that the source text is in
 -   multibyte form except for 8-bit characters.  8-bit characters are
 -   in multibyte form if coding->src_multibyte is nonzero, else they
 -   are represented by a single byte.  */
 -
 -#define ONE_MORE_CHAR(c)                                      \
 -  do {                                                                \
 -    int len = src_end - src;                                  \
 -    int bytes;                                                        \
 -    if (len <= 0)                                             \
 -      {                                                               \
 -      coding->result = CODING_FINISH_INSUFFICIENT_SRC;        \
 -      goto label_end_of_loop;                                 \
 -      }                                                               \
 -    if (coding->src_multibyte                                 \
 -      || UNIBYTE_STR_AS_MULTIBYTE_P (src, len, bytes))        \
 -      c = STRING_CHAR_AND_LENGTH (src, len, bytes);           \
 -    else                                                      \
 -      c = *src, bytes = 1;                                    \
 -    if (!NILP (translation_table))                            \
 -      c = translate_char (translation_table, c, -1, 0, 0);    \
 -    src += bytes;                                             \
 -  } while (0)
 -
 -
 -/* Produce a multibyte form of character C to `dst'.  Jump to
 -   `label_end_of_loop' if there's not enough space at `dst'.
 -
 -   If we are now in the middle of a composition sequence, the decoded
 -   character may be ALTCHAR (for the current composition).  In that
 -   case, the character goes to coding->cmp_data->data instead of
 -   `dst'.
 -
 -   This macro is used in decoding routines.  */
 -
 -#define EMIT_CHAR(c)                                                  \
 -  do {                                                                        \
 -    if (! COMPOSING_P (coding)                                                \
 -      || coding->composing == COMPOSITION_RELATIVE                    \
 -      || coding->composing == COMPOSITION_WITH_RULE)                  \
 -      {                                                                       \
 -      int bytes = CHAR_BYTES (c);                                     \
 -      if ((dst + bytes) > (dst_bytes ? dst_end : src))                \
 -        {                                                             \
 -          coding->result = CODING_FINISH_INSUFFICIENT_DST;            \
 -          goto label_end_of_loop;                                     \
 -        }                                                             \
 -      dst += CHAR_STRING (c, dst);                                    \
 -      coding->produced_char++;                                        \
 -      }                                                                       \
 -                                                                      \
 -    if (COMPOSING_P (coding)                                          \
 -      && coding->composing != COMPOSITION_RELATIVE)                   \
 -      {                                                                       \
 -      CODING_ADD_COMPOSITION_COMPONENT (coding, c);                   \
 -      coding->composition_rule_follows                                \
 -        = coding->composing != COMPOSITION_WITH_ALTCHARS;             \
 -      }                                                                       \
 -  } while (0)
 -
 -
 -#define EMIT_ONE_BYTE(c)                                      \
 -  do {                                                                \
 -    if (dst >= (dst_bytes ? dst_end : src))                   \
 -      {                                                               \
 -      coding->result = CODING_FINISH_INSUFFICIENT_DST;        \
 -      goto label_end_of_loop;                                 \
 -      }                                                               \
 -    *dst++ = c;                                                       \
 -  } while (0)
 -
 -#define EMIT_TWO_BYTES(c1, c2)                                        \
 -  do {                                                                \
 -    if (dst + 2 > (dst_bytes ? dst_end : src))                        \
 -      {                                                               \
 -      coding->result = CODING_FINISH_INSUFFICIENT_DST;        \
 -      goto label_end_of_loop;                                 \
 -      }                                                               \
 -    *dst++ = c1, *dst++ = c2;                                 \
 -  } while (0)
 -
 -#define EMIT_BYTES(from, to)                                  \
 -  do {                                                                \
 -    if (dst + (to - from) > (dst_bytes ? dst_end : src))      \
 -      {                                                               \
 -      coding->result = CODING_FINISH_INSUFFICIENT_DST;        \
 -      goto label_end_of_loop;                                 \
 -      }                                                               \
 -    while (from < to)                                         \
 -      *dst++ = *from++;                                               \
 -  } while (0)
 -
  \f
  /*** 1. Preamble ***/
  
 -#ifdef emacs
  #include <config.h>
 -#endif
 -
  #include <stdio.h>
  
 -#ifdef emacs
 -
  #include "lisp.h"
  #include "buffer.h"
 +#include "character.h"
  #include "charset.h"
 -#include "composite.h"
  #include "ccl.h"
 +#include "composite.h"
  #include "coding.h"
  #include "window.h"
 -#include "intervals.h"
 -
 -#else  /* not emacs */
  
 -#include "mulelib.h"
 +Lisp_Object Vcoding_system_hash_table;
  
 -#endif /* not emacs */
 -
 -Lisp_Object Qcoding_system, Qeol_type;
 +Lisp_Object Qcoding_system, Qcoding_aliases, Qeol_type;
 +Lisp_Object Qunix, Qdos;
 +extern Lisp_Object Qmac;      /* frame.c */
  Lisp_Object Qbuffer_file_coding_system;
  Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
 +Lisp_Object Qdefault_char;
  Lisp_Object Qno_conversion, Qundecided;
 +Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qshift_jis, Qbig5;
 +Lisp_Object Qbig, Qlittle;
  Lisp_Object Qcoding_system_history;
 -Lisp_Object Qsafe_chars;
  Lisp_Object Qvalid_codes;
 -Lisp_Object Qascii_incompatible;
 +Lisp_Object QCcategory, QCmnemonic, QCdefalut_char;
 +Lisp_Object QCdecode_translation_table, QCencode_translation_table;
 +Lisp_Object QCpost_read_conversion, QCpre_write_conversion;
 +Lisp_Object QCascii_compatible_p;
  
  extern Lisp_Object Qinsert_file_contents, Qwrite_region;
  Lisp_Object Qcall_process, Qcall_process_region;
  Lisp_Object Qstart_process, Qopen_network_stream;
  Lisp_Object Qtarget_idx;
  
 +Lisp_Object Qinsufficient_source, Qinconsistent_eol, Qinvalid_source;
 +Lisp_Object Qinterrupted, Qinsufficient_memory;
 +
  /* If a symbol has this property, evaluate the value to define the
     symbol as a coding system.  */
 -Lisp_Object Qcoding_system_define_form;
 -
 -Lisp_Object Vselect_safe_coding_system_function;
 +static Lisp_Object Qcoding_system_define_form;
  
  int coding_system_require_warning;
  
 +Lisp_Object Vselect_safe_coding_system_function;
 +
  /* Mnemonic string for each format of end-of-line.  */
  Lisp_Object eol_mnemonic_unix, eol_mnemonic_dos, eol_mnemonic_mac;
  /* Mnemonic string to indicate format of end-of-line is not yet
     decided.  */
  Lisp_Object eol_mnemonic_undecided;
  
 -/* Format of end-of-line decided by system.  This is CODING_EOL_LF on
 -   Unix, CODING_EOL_CRLF on DOS/Windows, and CODING_EOL_CR on Mac.
 +/* Format of end-of-line decided by system.  This is Qunix on
 +   Unix and Mac, Qdos on DOS/Windows.
     This has an effect only for external encoding (i.e. for output to
     file and process), not for in-buffer or Lisp string encoding.  */
 -int system_eol_type;
 +static Lisp_Object system_eol_type;
  
  #ifdef emacs
  
 -/* Information about which coding system is safe for which chars.
 -   The value has the form (GENERIC-LIST . NON-GENERIC-ALIST).
 -
 -   GENERIC-LIST is a list of generic coding systems which can encode
 -   any characters.
 -
 -   NON-GENERIC-ALIST is an alist of non generic coding systems vs the
 -   corresponding char table that contains safe chars.  */
 -Lisp_Object Vcoding_system_safe_chars;
 -
  Lisp_Object Vcoding_system_list, Vcoding_system_alist;
  
  Lisp_Object Qcoding_system_p, Qcoding_system_error;
  /* Coding system emacs-mule and raw-text are for converting only
     end-of-line format.  */
  Lisp_Object Qemacs_mule, Qraw_text;
 -
 -Lisp_Object Qutf_8;
 +Lisp_Object Qutf_8_emacs;
  
  /* Coding-systems are handed between Emacs Lisp programs and C internal
     routines by the following three variables.  */
@@@ -366,8 -422,7 +366,8 @@@ Lisp_Object Vcoding_system_for_read
  Lisp_Object Vcoding_system_for_write;
  /* Coding-system actually used in the latest I/O.  */
  Lisp_Object Vlast_coding_system_used;
 -
 +/* Set to non-nil when an error is detected while code conversion.  */
 +Lisp_Object Vlast_code_conversion_error;
  /* A vector of length 256 which contains information about special
     Latin codes (especially for dealing with Microsoft codes).  */
  Lisp_Object Vlatin_extra_code_table;
@@@ -391,6 -446,9 +391,6 @@@ struct coding_system safe_terminal_codi
  /* Coding system of what is sent from terminal keyboard.  */
  struct coding_system keyboard_coding;
  
 -/* Default coding system to be used to write a file.  */
 -struct coding_system default_buffer_file_coding;
 -
  Lisp_Object Vfile_coding_system_alist;
  Lisp_Object Vprocess_coding_system_alist;
  Lisp_Object Vnetwork_coding_system_alist;
@@@ -399,6 -457,42 +399,6 @@@ Lisp_Object Vlocale_coding_system
  
  #endif /* emacs */
  
 -Lisp_Object Qcoding_category, Qcoding_category_index;
 -
 -/* List of symbols `coding-category-xxx' ordered by priority.  */
 -Lisp_Object Vcoding_category_list;
 -
 -/* Table of coding categories (Lisp symbols).  */
 -Lisp_Object Vcoding_category_table;
 -
 -/* Table of names of symbol for each coding-category.  */
 -char *coding_category_name[CODING_CATEGORY_IDX_MAX] = {
 -  "coding-category-emacs-mule",
 -  "coding-category-sjis",
 -  "coding-category-iso-7",
 -  "coding-category-iso-7-tight",
 -  "coding-category-iso-8-1",
 -  "coding-category-iso-8-2",
 -  "coding-category-iso-7-else",
 -  "coding-category-iso-8-else",
 -  "coding-category-ccl",
 -  "coding-category-big5",
 -  "coding-category-utf-8",
 -  "coding-category-utf-16-be",
 -  "coding-category-utf-16-le",
 -  "coding-category-raw-text",
 -  "coding-category-binary"
 -};
 -
 -/* Table of pointers to coding systems corresponding to each coding
 -   categories.  */
 -struct coding_system *coding_system_table[CODING_CATEGORY_IDX_MAX];
 -
 -/* Table of coding category masks.  Nth element is a mask for a coding
 -   category of which priority is Nth.  */
 -static
 -int coding_priorities[CODING_CATEGORY_IDX_MAX];
 -
  /* Flag to tell if we look up translation table on character code
     conversion.  */
  Lisp_Object Venable_character_translation;
@@@ -413,7 -507,7 +413,7 @@@ Lisp_Object Qtranslation_table_for_deco
  Lisp_Object Qtranslation_table_for_encode;
  
  /* Alist of charsets vs revision number.  */
 -Lisp_Object Vcharset_revision_alist;
 +static Lisp_Object Vcharset_revision_table;
  
  /* Default coding systems used for process I/O.  */
  Lisp_Object Vdefault_process_coding_system;
  /* Char table for translating Quail and self-inserting input.  */
  Lisp_Object Vtranslation_table_for_input;
  
 -/* Global flag to tell that we can't call post-read-conversion and
 -   pre-write-conversion functions.  Usually the value is zero, but it
 -   is set to 1 temporarily while such functions are running.  This is
 -   to avoid infinite recursive call.  */
 -static int inhibit_pre_post_conversion;
 +/* Two special coding systems.  */
 +Lisp_Object Vsjis_coding_system;
 +Lisp_Object Vbig5_coding_system;
 +
 +/* ISO2022 section */
 +
 +#define CODING_ISO_INITIAL(coding, reg)                       \
 +  (XINT (AREF (AREF (CODING_ID_ATTRS ((coding)->id),  \
 +                   coding_attr_iso_initial),          \
 +             reg)))
 +
 +
 +#define CODING_ISO_REQUEST(coding, charset_id)        \
 +  ((charset_id <= (coding)->max_charset_id    \
 +    ? (coding)->safe_charsets[charset_id]     \
 +    : -1))
 +
 +
 +#define CODING_ISO_FLAGS(coding)      \
 +  ((coding)->spec.iso_2022.flags)
 +#define CODING_ISO_DESIGNATION(coding, reg)   \
 +  ((coding)->spec.iso_2022.current_designation[reg])
 +#define CODING_ISO_INVOCATION(coding, plane)  \
 +  ((coding)->spec.iso_2022.current_invocation[plane])
 +#define CODING_ISO_SINGLE_SHIFTING(coding)    \
 +  ((coding)->spec.iso_2022.single_shifting)
 +#define CODING_ISO_BOL(coding)        \
 +  ((coding)->spec.iso_2022.bol)
 +#define CODING_ISO_INVOKED_CHARSET(coding, plane)     \
 +  CODING_ISO_DESIGNATION ((coding), CODING_ISO_INVOCATION ((coding), (plane)))
 +
 +/* Control characters of ISO2022.  */
 +                      /* code */      /* function */
 +#define ISO_CODE_LF   0x0A            /* line-feed */
 +#define ISO_CODE_CR   0x0D            /* carriage-return */
 +#define ISO_CODE_SO   0x0E            /* shift-out */
 +#define ISO_CODE_SI   0x0F            /* shift-in */
 +#define ISO_CODE_SS2_7        0x19            /* single-shift-2 for 7-bit code */
 +#define ISO_CODE_ESC  0x1B            /* escape */
 +#define ISO_CODE_SS2  0x8E            /* single-shift-2 */
 +#define ISO_CODE_SS3  0x8F            /* single-shift-3 */
 +#define ISO_CODE_CSI  0x9B            /* control-sequence-introducer */
 +
 +/* All code (1-byte) of ISO2022 is classified into one of the
 +   followings.  */
 +enum iso_code_class_type
 +  {
 +    ISO_control_0,            /* Control codes in the range
 +                                 0x00..0x1F and 0x7F, except for the
 +                                 following 5 codes.  */
 +    ISO_shift_out,            /* ISO_CODE_SO (0x0E) */
 +    ISO_shift_in,             /* ISO_CODE_SI (0x0F) */
 +    ISO_single_shift_2_7,     /* ISO_CODE_SS2_7 (0x19) */
 +    ISO_escape,                       /* ISO_CODE_SO (0x1B) */
 +    ISO_control_1,            /* Control codes in the range
 +                                 0x80..0x9F, except for the
 +                                 following 3 codes.  */
 +    ISO_single_shift_2,               /* ISO_CODE_SS2 (0x8E) */
 +    ISO_single_shift_3,               /* ISO_CODE_SS3 (0x8F) */
 +    ISO_control_sequence_introducer, /* ISO_CODE_CSI (0x9B) */
 +    ISO_0x20_or_0x7F,         /* Codes of the values 0x20 or 0x7F.  */
 +    ISO_graphic_plane_0,      /* Graphic codes in the range 0x21..0x7E.  */
 +    ISO_0xA0_or_0xFF,         /* Codes of the values 0xA0 or 0xFF.  */
 +    ISO_graphic_plane_1               /* Graphic codes in the range 0xA1..0xFE.  */
 +  };
  
 -Lisp_Object Qchar_coding_system;
 +/** The macros CODING_ISO_FLAG_XXX defines a flag bit of the
 +    `iso-flags' attribute of an iso2022 coding system.  */
  
 -/* Return `safe-chars' property of CODING_SYSTEM (symbol).  Don't check
 -   its validity.  */
 +/* If set, produce long-form designation sequence (e.g. ESC $ ( A)
 +   instead of the correct short-form sequence (e.g. ESC $ A).  */
 +#define CODING_ISO_FLAG_LONG_FORM     0x0001
  
 -Lisp_Object
 -coding_safe_chars (coding_system)
 -     Lisp_Object coding_system;
 -{
 -  Lisp_Object coding_spec, plist, safe_chars;
 +/* If set, reset graphic planes and registers at end-of-line to the
 +   initial state.  */
 +#define CODING_ISO_FLAG_RESET_AT_EOL  0x0002
  
 -  coding_spec = Fget (coding_system, Qcoding_system);
 -  plist = XVECTOR (coding_spec)->contents[3];
 -  safe_chars = Fplist_get (XVECTOR (coding_spec)->contents[3], Qsafe_chars);
 -  return (CHAR_TABLE_P (safe_chars) ? safe_chars : Qt);
 -}
 +/* If set, reset graphic planes and registers before any control
 +   characters to the initial state.  */
 +#define CODING_ISO_FLAG_RESET_AT_CNTL 0x0004
  
 -#define CODING_SAFE_CHAR_P(safe_chars, c) \
 -  (EQ (safe_chars, Qt) || !NILP (CHAR_TABLE_REF (safe_chars, c)))
 +/* If set, encode by 7-bit environment.  */
 +#define CODING_ISO_FLAG_SEVEN_BITS    0x0008
  
 -\f
 -/*** 2. Emacs internal format (emacs-mule) handlers ***/
 +/* If set, use locking-shift function.  */
 +#define CODING_ISO_FLAG_LOCKING_SHIFT 0x0010
  
 -/* Emacs' internal format for representation of multiple character
 -   sets is a kind of multi-byte encoding, i.e. characters are
 -   represented by variable-length sequences of one-byte codes.
 +/* If set, use single-shift function.  Overwrite
 +   CODING_ISO_FLAG_LOCKING_SHIFT.  */
 +#define CODING_ISO_FLAG_SINGLE_SHIFT  0x0020
  
 -   ASCII characters and control characters (e.g. `tab', `newline') are
 -   represented by one-byte sequences which are their ASCII codes, in
 -   the range 0x00 through 0x7F.
 +/* If set, use designation escape sequence.  */
 +#define CODING_ISO_FLAG_DESIGNATION   0x0040
  
 -   8-bit characters of the range 0x80..0x9F are represented by
 -   two-byte sequences of LEADING_CODE_8_BIT_CONTROL and (their 8-bit
 -   code + 0x20).
 +/* If set, produce revision number sequence.  */
 +#define CODING_ISO_FLAG_REVISION      0x0080
  
 -   8-bit characters of the range 0xA0..0xFF are represented by
 -   one-byte sequences which are their 8-bit code.
 +/* If set, produce ISO6429's direction specifying sequence.  */
 +#define CODING_ISO_FLAG_DIRECTION     0x0100
  
 -   The other characters are represented by a sequence of `base
 -   leading-code', optional `extended leading-code', and one or two
 -   `position-code's.  The length of the sequence is determined by the
 -   base leading-code.  Leading-code takes the range 0x81 through 0x9D,
 -   whereas extended leading-code and position-code take the range 0xA0
 -   through 0xFF.  See `charset.h' for more details about leading-code
 -   and position-code.
 +/* If set, assume designation states are reset at beginning of line on
 +   output.  */
 +#define CODING_ISO_FLAG_INIT_AT_BOL   0x0200
  
 -   --- CODE RANGE of Emacs' internal format ---
 -   character set      range
 -   -------------      -----
 -   ascii              0x00..0x7F
 -   eight-bit-control  LEADING_CODE_8_BIT_CONTROL + 0xA0..0xBF
 -   eight-bit-graphic  0xA0..0xBF
 -   ELSE                       0x81..0x9D + [0xA0..0xFF]+
 -   ---------------------------------------------
 +/* If set, designation sequence should be placed at beginning of line
 +   on output.  */
 +#define CODING_ISO_FLAG_DESIGNATE_AT_BOL 0x0400
  
 -   As this is the internal character representation, the format is
 -   usually not used externally (i.e. in a file or in a data sent to a
 -   process).  But, it is possible to have a text externally in this
 -   format (i.e. by encoding by the coding system `emacs-mule').
 +/* If set, do not encode unsafe charactes on output.  */
 +#define CODING_ISO_FLAG_SAFE          0x0800
  
 -   In that case, a sequence of one-byte codes has a slightly different
 -   form.
 +/* If set, extra latin codes (128..159) are accepted as a valid code
 +   on input.  */
 +#define CODING_ISO_FLAG_LATIN_EXTRA   0x1000
  
 -   Firstly, all characters in eight-bit-control are represented by
 -   one-byte sequences which are their 8-bit code.
 +#define CODING_ISO_FLAG_COMPOSITION   0x2000
  
 -   Next, character composition data are represented by the byte
 -   sequence of the form: 0x80 METHOD BYTES CHARS COMPONENT ...,
 -   where,
 -      METHOD is 0xF0 plus one of composition method (enum
 -      composition_method),
 +#define CODING_ISO_FLAG_EUC_TW_SHIFT  0x4000
  
 -      BYTES is 0xA0 plus the byte length of these composition data,
 +#define CODING_ISO_FLAG_USE_ROMAN     0x8000
  
 -      CHARS is 0xA0 plus the number of characters composed by these
 -      data,
 +#define CODING_ISO_FLAG_USE_OLDJIS    0x10000
  
 -      COMPONENTs are characters of multibyte form or composition
 -      rules encoded by two-byte of ASCII codes.
 +#define CODING_ISO_FLAG_FULL_SUPPORT  0x100000
  
 -   In addition, for backward compatibility, the following formats are
 -   also recognized as composition data on decoding.
 +/* A character to be produced on output if encoding of the original
 +   character is prohibited by CODING_ISO_FLAG_SAFE.  */
 +#define CODING_INHIBIT_CHARACTER_SUBSTITUTION  '?'
  
 -   0x80 MSEQ ...
 -   0x80 0xFF MSEQ RULE MSEQ RULE ... MSEQ
  
 -   Here,
 -      MSEQ is a multibyte form but in these special format:
 -        ASCII: 0xA0 ASCII_CODE+0x80,
 -        other: LEADING_CODE+0x20 FOLLOWING-BYTE ...,
 -      RULE is a one byte code of the range 0xA0..0xF0 that
 -      represents a composition rule.
 -  */
 +/* UTF-16 section */
 +#define CODING_UTF_16_BOM(coding)     \
 +  ((coding)->spec.utf_16.bom)
  
 -enum emacs_code_class_type emacs_code_class[256];
 +#define CODING_UTF_16_ENDIAN(coding)  \
 +  ((coding)->spec.utf_16.endian)
  
 -/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 -   Check if a text is encoded in Emacs' internal format.  If it is,
 -   return CODING_CATEGORY_MASK_EMACS_MULE, else return 0.  */
 +#define CODING_UTF_16_SURROGATE(coding)       \
 +  ((coding)->spec.utf_16.surrogate)
  
 -static int
 -detect_coding_emacs_mule (src, src_end, multibytep)
 -      unsigned char *src, *src_end;
 -      int multibytep;
 -{
 -  unsigned char c;
 -  int composing = 0;
 -  /* Dummy for ONE_MORE_BYTE.  */
 -  struct coding_system dummy_coding;
 -  struct coding_system *coding = &dummy_coding;
  
 -  while (1)
 -    {
 -      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep,
 -                                   CODING_CATEGORY_MASK_EMACS_MULE);
 -      if (composing)
 -      {
 -        if (c < 0xA0)
 -          composing = 0;
 -        else if (c == 0xA0)
 -          {
 -            ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, 0);
 -            c &= 0x7F;
 -          }
 -        else
 -          c -= 0x20;
 -      }
 +/* CCL section */
 +#define CODING_CCL_DECODER(coding)    \
 +  AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_decoder)
 +#define CODING_CCL_ENCODER(coding)    \
 +  AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_encoder)
 +#define CODING_CCL_VALIDS(coding)                                        \
 +  (SDATA (AREF (CODING_ID_ATTRS ((coding)->id), coding_attr_ccl_valids)))
  
 -      if (c < 0x20)
 -      {
 -        if (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO)
 -          return 0;
 -      }
 -      else if (c >= 0x80 && c < 0xA0)
 -      {
 -        if (c == 0x80)
 -          /* Old leading code for a composite character.  */
 -          composing = 1;
 -        else
 -          {
 -            unsigned char *src_base = src - 1;
 -            int bytes;
 +/* Index for each coding category in `coding_categories' */
  
 -            if (!UNIBYTE_STR_AS_MULTIBYTE_P (src_base, src_end - src_base,
 -                                             bytes))
 -              return 0;
 -            src = src_base + bytes;
 -          }
 -      }
 -    }
 -}
 +enum coding_category
 +  {
 +    coding_category_iso_7,
 +    coding_category_iso_7_tight,
 +    coding_category_iso_8_1,
 +    coding_category_iso_8_2,
 +    coding_category_iso_7_else,
 +    coding_category_iso_8_else,
 +    coding_category_utf_8,
 +    coding_category_utf_16_auto,
 +    coding_category_utf_16_be,
 +    coding_category_utf_16_le,
 +    coding_category_utf_16_be_nosig,
 +    coding_category_utf_16_le_nosig,
 +    coding_category_charset,
 +    coding_category_sjis,
 +    coding_category_big5,
 +    coding_category_ccl,
 +    coding_category_emacs_mule,
 +    /* All above are targets of code detection.  */
 +    coding_category_raw_text,
 +    coding_category_undecided,
 +    coding_category_max
 +  };
 +
 +/* Definitions of flag bits used in detect_coding_XXXX.  */
 +#define CATEGORY_MASK_ISO_7           (1 << coding_category_iso_7)
 +#define CATEGORY_MASK_ISO_7_TIGHT     (1 << coding_category_iso_7_tight)
 +#define CATEGORY_MASK_ISO_8_1         (1 << coding_category_iso_8_1)
 +#define CATEGORY_MASK_ISO_8_2         (1 << coding_category_iso_8_2)
 +#define CATEGORY_MASK_ISO_7_ELSE      (1 << coding_category_iso_7_else)
 +#define CATEGORY_MASK_ISO_8_ELSE      (1 << coding_category_iso_8_else)
 +#define CATEGORY_MASK_UTF_8           (1 << coding_category_utf_8)
 +#define CATEGORY_MASK_UTF_16_AUTO     (1 << coding_category_utf_16_auto)
 +#define CATEGORY_MASK_UTF_16_BE               (1 << coding_category_utf_16_be)
 +#define CATEGORY_MASK_UTF_16_LE               (1 << coding_category_utf_16_le)
 +#define CATEGORY_MASK_UTF_16_BE_NOSIG (1 << coding_category_utf_16_be_nosig)
 +#define CATEGORY_MASK_UTF_16_LE_NOSIG (1 << coding_category_utf_16_le_nosig)
 +#define CATEGORY_MASK_CHARSET         (1 << coding_category_charset)
 +#define CATEGORY_MASK_SJIS            (1 << coding_category_sjis)
 +#define CATEGORY_MASK_BIG5            (1 << coding_category_big5)
 +#define CATEGORY_MASK_CCL             (1 << coding_category_ccl)
 +#define CATEGORY_MASK_EMACS_MULE      (1 << coding_category_emacs_mule)
 +#define CATEGORY_MASK_RAW_TEXT                (1 << coding_category_raw_text)
 +
 +/* This value is returned if detect_coding_mask () find nothing other
 +   than ASCII characters.  */
 +#define CATEGORY_MASK_ANY             \
 +  (CATEGORY_MASK_ISO_7                        \
 +   | CATEGORY_MASK_ISO_7_TIGHT                \
 +   | CATEGORY_MASK_ISO_8_1            \
 +   | CATEGORY_MASK_ISO_8_2            \
 +   | CATEGORY_MASK_ISO_7_ELSE         \
 +   | CATEGORY_MASK_ISO_8_ELSE         \
 +   | CATEGORY_MASK_UTF_8              \
 +   | CATEGORY_MASK_UTF_16_BE          \
 +   | CATEGORY_MASK_UTF_16_LE          \
 +   | CATEGORY_MASK_UTF_16_BE_NOSIG    \
 +   | CATEGORY_MASK_UTF_16_LE_NOSIG    \
 +   | CATEGORY_MASK_CHARSET            \
 +   | CATEGORY_MASK_SJIS                       \
 +   | CATEGORY_MASK_BIG5                       \
 +   | CATEGORY_MASK_CCL                        \
 +   | CATEGORY_MASK_EMACS_MULE)
 +
 +
 +#define CATEGORY_MASK_ISO_7BIT \
 +  (CATEGORY_MASK_ISO_7 | CATEGORY_MASK_ISO_7_TIGHT)
 +
 +#define CATEGORY_MASK_ISO_8BIT \
 +  (CATEGORY_MASK_ISO_8_1 | CATEGORY_MASK_ISO_8_2)
 +
 +#define CATEGORY_MASK_ISO_ELSE \
 +  (CATEGORY_MASK_ISO_7_ELSE | CATEGORY_MASK_ISO_8_ELSE)
 +
 +#define CATEGORY_MASK_ISO_ESCAPE      \
 +  (CATEGORY_MASK_ISO_7                        \
 +   | CATEGORY_MASK_ISO_7_TIGHT                \
 +   | CATEGORY_MASK_ISO_7_ELSE         \
 +   | CATEGORY_MASK_ISO_8_ELSE)
 +
 +#define CATEGORY_MASK_ISO     \
 +  (  CATEGORY_MASK_ISO_7BIT   \
 +     | CATEGORY_MASK_ISO_8BIT \
 +     | CATEGORY_MASK_ISO_ELSE)
 +
 +#define CATEGORY_MASK_UTF_16          \
 +  (CATEGORY_MASK_UTF_16_BE            \
 +   | CATEGORY_MASK_UTF_16_LE          \
 +   | CATEGORY_MASK_UTF_16_BE_NOSIG    \
 +   | CATEGORY_MASK_UTF_16_LE_NOSIG)
 +
 +
 +/* List of symbols `coding-category-xxx' ordered by priority.  This
 +   variable is exposed to Emacs Lisp.  */
 +static Lisp_Object Vcoding_category_list;
 +
 +/* Table of coding categories (Lisp symbols).  This variable is for
 +   internal use oly.  */
 +static Lisp_Object Vcoding_category_table;
 +
 +/* Table of coding-categories ordered by priority.  */
 +static enum coding_category coding_priorities[coding_category_max];
 +
 +/* Nth element is a coding context for the coding system bound to the
 +   Nth coding category.  */
 +static struct coding_system coding_categories[coding_category_max];
 +
 +/*** Commonly used macros and functions ***/
 +
 +#ifndef min
 +#define min(a, b) ((a) < (b) ? (a) : (b))
 +#endif
 +#ifndef max
 +#define max(a, b) ((a) > (b) ? (a) : (b))
 +#endif
 +
 +#define CODING_GET_INFO(coding, attrs, charset_list)  \
 +  do {                                                        \
 +    (attrs) = CODING_ID_ATTRS ((coding)->id);         \
 +    (charset_list) = CODING_ATTR_CHARSET_LIST (attrs);        \
 +  } while (0)
  
  
 -/* Record the starting position START and METHOD of one composition.  */
 +/* Safely get one byte from the source text pointed by SRC which ends
 +   at SRC_END, and set C to that byte.  If there are not enough bytes
 +   in the source, it jumps to `no_more_source'.  If multibytep is
 +   nonzero, and a multibyte character is found at SRC, set C to the
 +   negative value of the character code.  The caller should declare
 +   and set these variables appropriately in advance:
 +      src, src_end, multibytep */
  
 -#define CODING_ADD_COMPOSITION_START(coding, start, method)   \
 -  do {                                                                \
 -    struct composition_data *cmp_data = coding->cmp_data;     \
 -    int *data = cmp_data->data + cmp_data->used;              \
 -    coding->cmp_data_start = cmp_data->used;                  \
 -    data[0] = -1;                                             \
 -    data[1] = cmp_data->char_offset + start;                  \
 -    data[3] = (int) method;                                   \
 -    cmp_data->used += 4;                                      \
 +#define ONE_MORE_BYTE(c)                              \
 +  do {                                                        \
 +    if (src == src_end)                                       \
 +      {                                                       \
 +      if (src_base < src)                             \
 +        record_conversion_result                      \
 +          (coding, CODING_RESULT_INSUFFICIENT_SRC);   \
 +      goto no_more_source;                            \
 +      }                                                       \
 +    c = *src++;                                               \
 +    if (multibytep && (c & 0x80))                     \
 +      {                                                       \
 +      if ((c & 0xFE) == 0xC0)                         \
 +        c = ((c & 1) << 6) | *src++;                  \
 +      else                                            \
 +        {                                             \
 +          src--;                                      \
 +          c = - string_char (src, &src, NULL);        \
 +          record_conversion_result                    \
 +            (coding, CODING_RESULT_INVALID_SRC);      \
 +        }                                             \
 +      }                                                       \
 +    consumed_chars++;                                 \
    } while (0)
  
 -/* Record the ending position END of the current composition.  */
  
 -#define CODING_ADD_COMPOSITION_END(coding, end)                       \
 -  do {                                                                \
 -    struct composition_data *cmp_data = coding->cmp_data;     \
 -    int *data = cmp_data->data + coding->cmp_data_start;      \
 -    data[0] = cmp_data->used - coding->cmp_data_start;                \
 -    data[2] = cmp_data->char_offset + end;                    \
 +#define ONE_MORE_BYTE_NO_CHECK(c)                     \
 +  do {                                                        \
 +    c = *src++;                                               \
 +    if (multibytep && (c & 0x80))                     \
 +      {                                                       \
 +      if ((c & 0xFE) == 0xC0)                         \
 +        c = ((c & 1) << 6) | *src++;                  \
 +      else                                            \
 +        {                                             \
 +          src--;                                      \
 +          c = - string_char (src, &src, NULL);        \
 +          record_conversion_result                    \
 +            (coding, CODING_RESULT_INVALID_SRC);      \
 +        }                                             \
 +      }                                                       \
 +    consumed_chars++;                                 \
    } while (0)
  
 -/* Record one COMPONENT (alternate character or composition rule).  */
  
 -#define CODING_ADD_COMPOSITION_COMPONENT(coding, component)           \
 -  do {                                                                        \
 -    coding->cmp_data->data[coding->cmp_data->used++] = component;     \
 -    if (coding->cmp_data->used - coding->cmp_data_start                       \
 -      == COMPOSITION_DATA_MAX_BUNCH_LENGTH)                           \
 -      {                                                                       \
 -      CODING_ADD_COMPOSITION_END (coding, coding->produced_char);     \
 -      coding->composing = COMPOSITION_NO;                             \
 -      }                                                                       \
 -  } while (0)
 +/* Store a byte C in the place pointed by DST and increment DST to the
 +   next free point, and increment PRODUCED_CHARS.  The caller should
 +   assure that C is 0..127, and declare and set the variable `dst'
 +   appropriately in advance.
 +*/
  
  
 -/* Get one byte from a data pointed by SRC and increment SRC.  If SRC
 -   is not less than SRC_END, return -1 without incrementing Src.  */
 +#define EMIT_ONE_ASCII_BYTE(c)        \
 +  do {                                \
 +    produced_chars++;         \
 +    *dst++ = (c);             \
 +  } while (0)
  
 -#define SAFE_ONE_MORE_BYTE() (src >= src_end ? -1 : *src++)
  
 +/* Like EMIT_ONE_ASCII_BYTE byt store two bytes; C1 and C2.  */
  
 -/* Decode a character represented as a component of composition
 -   sequence of Emacs 20 style at SRC.  Set C to that character, store
 -   its multibyte form sequence at P, and set P to the end of that
 -   sequence.  If no valid character is found, set C to -1.  */
 +#define EMIT_TWO_ASCII_BYTES(c1, c2)  \
 +  do {                                        \
 +    produced_chars += 2;              \
 +    *dst++ = (c1), *dst++ = (c2);     \
 +  } while (0)
  
 -#define DECODE_EMACS_MULE_COMPOSITION_CHAR(c, p)              \
 -  do {                                                                \
 -    int bytes;                                                        \
 -                                                              \
 -    c = SAFE_ONE_MORE_BYTE ();                                        \
 -    if (c < 0)                                                        \
 -      break;                                                  \
 -    if (CHAR_HEAD_P (c))                                      \
 -      c = -1;                                                 \
 -    else if (c == 0xA0)                                               \
 -      {                                                               \
 -      c = SAFE_ONE_MORE_BYTE ();                              \
 -      if (c < 0xA0)                                           \
 -        c = -1;                                               \
 -      else                                                    \
 -        {                                                     \
 -          c -= 0x80;                                          \
 -          *p++ = c;                                           \
 -        }                                                     \
 -      }                                                               \
 -    else if (BASE_LEADING_CODE_P (c - 0x20))                  \
 -      {                                                               \
 -      unsigned char *p0 = p;                                  \
 -                                                              \
 -      c -= 0x20;                                              \
 -      *p++ = c;                                               \
 -      bytes = BYTES_BY_CHAR_HEAD (c);                         \
 -      while (--bytes)                                         \
 -        {                                                     \
 -          c = SAFE_ONE_MORE_BYTE ();                          \
 -          if (c < 0)                                          \
 -            break;                                            \
 -          *p++ = c;                                           \
 -        }                                                     \
 -      if (UNIBYTE_STR_AS_MULTIBYTE_P (p0, p - p0, bytes)      \
 -          || (coding->flags /* We are recovering a file.  */  \
 -              && p0[0] == LEADING_CODE_8_BIT_CONTROL          \
 -              && ! CHAR_HEAD_P (p0[1])))                      \
 -        c = STRING_CHAR (p0, bytes);                          \
 -      else                                                    \
 -        c = -1;                                               \
 -      }                                                               \
 -    else                                                      \
 -      c = -1;                                                 \
 +
 +/* Store a byte C in the place pointed by DST and increment DST to the
 +   next free point, and increment PRODUCED_CHARS.  If MULTIBYTEP is
 +   nonzero, store in an appropriate multibyte from.  The caller should
 +   declare and set the variables `dst' and `multibytep' appropriately
 +   in advance.  */
 +
 +#define EMIT_ONE_BYTE(c)              \
 +  do {                                        \
 +    produced_chars++;                 \
 +    if (multibytep)                   \
 +      {                                       \
 +      int ch = (c);                   \
 +      if (ch >= 0x80)                 \
 +        ch = BYTE8_TO_CHAR (ch);      \
 +      CHAR_STRING_ADVANCE (ch, dst);  \
 +      }                                       \
 +    else                              \
 +      *dst++ = (c);                   \
    } while (0)
  
  
 -/* Decode a composition rule represented as a component of composition
 -   sequence of Emacs 20 style at SRC.  Set C to the rule.  If not
 -   valid rule is found, set C to -1.  */
 +/* Like EMIT_ONE_BYTE, but emit two bytes; C1 and C2.  */
 +
 +#define EMIT_TWO_BYTES(c1, c2)                \
 +  do {                                        \
 +    produced_chars += 2;              \
 +    if (multibytep)                   \
 +      {                                       \
 +      int ch;                         \
 +                                      \
 +      ch = (c1);                      \
 +      if (ch >= 0x80)                 \
 +        ch = BYTE8_TO_CHAR (ch);      \
 +      CHAR_STRING_ADVANCE (ch, dst);  \
 +      ch = (c2);                      \
 +      if (ch >= 0x80)                 \
 +        ch = BYTE8_TO_CHAR (ch);      \
 +      CHAR_STRING_ADVANCE (ch, dst);  \
 +      }                                       \
 +    else                              \
 +      {                                       \
 +      *dst++ = (c1);                  \
 +      *dst++ = (c2);                  \
 +      }                                       \
 +  } while (0)
  
 -#define DECODE_EMACS_MULE_COMPOSITION_RULE(c)         \
 -  do {                                                        \
 -    c = SAFE_ONE_MORE_BYTE ();                                \
 -    c -= 0xA0;                                                \
 -    if (c < 0 || c >= 81)                             \
 -      c = -1;                                         \
 -    else                                              \
 -      {                                                       \
 -      gref = c / 9, nref = c % 9;                     \
 -      c = COMPOSITION_ENCODE_RULE (gref, nref);       \
 -      }                                                       \
 +
 +#define EMIT_THREE_BYTES(c1, c2, c3)  \
 +  do {                                        \
 +    EMIT_ONE_BYTE (c1);                       \
 +    EMIT_TWO_BYTES (c2, c3);          \
    } while (0)
  
  
 -/* Decode composition sequence encoded by `emacs-mule' at the source
 -   pointed by SRC.  SRC_END is the end of source.  Store information
 -   of the composition in CODING->cmp_data.
 +#define EMIT_FOUR_BYTES(c1, c2, c3, c4)               \
 +  do {                                                \
 +    EMIT_TWO_BYTES (c1, c2);                  \
 +    EMIT_TWO_BYTES (c3, c4);                  \
 +  } while (0)
  
 -   For backward compatibility, decode also a composition sequence of
 -   Emacs 20 style.  In that case, the composition sequence contains
 -   characters that should be extracted into a buffer or string.  Store
 -   those characters at *DESTINATION in multibyte form.
  
 -   If we encounter an invalid byte sequence, return 0.
 -   If we encounter an insufficient source or destination, or
 -   insufficient space in CODING->cmp_data, return 1.
 -   Otherwise, return consumed bytes in the source.
 +/* Prototypes for static functions.  */
 +static void record_conversion_result P_ ((struct coding_system *coding,
 +                                        enum coding_result_code result));
 +static int detect_coding_utf_8 P_ ((struct coding_system *,
 +                                  struct coding_detection_info *info));
 +static void decode_coding_utf_8 P_ ((struct coding_system *));
 +static int encode_coding_utf_8 P_ ((struct coding_system *));
 +
 +static int detect_coding_utf_16 P_ ((struct coding_system *,
 +                                   struct coding_detection_info *info));
 +static void decode_coding_utf_16 P_ ((struct coding_system *));
 +static int encode_coding_utf_16 P_ ((struct coding_system *));
 +
 +static int detect_coding_iso_2022 P_ ((struct coding_system *,
 +                                     struct coding_detection_info *info));
 +static void decode_coding_iso_2022 P_ ((struct coding_system *));
 +static int encode_coding_iso_2022 P_ ((struct coding_system *));
 +
 +static int detect_coding_emacs_mule P_ ((struct coding_system *,
 +                                       struct coding_detection_info *info));
 +static void decode_coding_emacs_mule P_ ((struct coding_system *));
 +static int encode_coding_emacs_mule P_ ((struct coding_system *));
 +
 +static int detect_coding_sjis P_ ((struct coding_system *,
 +                                 struct coding_detection_info *info));
 +static void decode_coding_sjis P_ ((struct coding_system *));
 +static int encode_coding_sjis P_ ((struct coding_system *));
 +
 +static int detect_coding_big5 P_ ((struct coding_system *,
 +                                 struct coding_detection_info *info));
 +static void decode_coding_big5 P_ ((struct coding_system *));
 +static int encode_coding_big5 P_ ((struct coding_system *));
 +
 +static int detect_coding_ccl P_ ((struct coding_system *,
 +                                struct coding_detection_info *info));
 +static void decode_coding_ccl P_ ((struct coding_system *));
 +static int encode_coding_ccl P_ ((struct coding_system *));
 +
 +static void decode_coding_raw_text P_ ((struct coding_system *));
 +static int encode_coding_raw_text P_ ((struct coding_system *));
 +
 +static void coding_set_source P_ ((struct coding_system *));
 +static void coding_set_destination P_ ((struct coding_system *));
 +static void coding_alloc_by_realloc P_ ((struct coding_system *, EMACS_INT));
 +static void coding_alloc_by_making_gap P_ ((struct coding_system *,
 +                                          EMACS_INT));
 +static unsigned char *alloc_destination P_ ((struct coding_system *,
 +                                           EMACS_INT, unsigned char *));
 +static void setup_iso_safe_charsets P_ ((Lisp_Object));
 +static unsigned char *encode_designation_at_bol P_ ((struct coding_system *,
 +                                                   int *, int *,
 +                                                   unsigned char *));
 +static int detect_eol P_ ((const unsigned char *,
 +                         EMACS_INT, enum coding_category));
 +static Lisp_Object adjust_coding_eol_type P_ ((struct coding_system *, int));
 +static void decode_eol P_ ((struct coding_system *));
 +static Lisp_Object get_translation_table P_ ((Lisp_Object, int, int *));
 +static Lisp_Object get_translation P_ ((Lisp_Object, int *, int *,
 +                                      int, int *, int *));
 +static int produce_chars P_ ((struct coding_system *, Lisp_Object, int));
 +static INLINE void produce_composition P_ ((struct coding_system *, int *,
 +                                          EMACS_INT));
 +static INLINE void produce_charset P_ ((struct coding_system *, int *,
 +                                      EMACS_INT));
 +static void produce_annotation P_ ((struct coding_system *, EMACS_INT));
 +static int decode_coding P_ ((struct coding_system *));
 +static INLINE int *handle_composition_annotation P_ ((EMACS_INT, EMACS_INT,
 +                                                    struct coding_system *, 
 +                                                    int *, EMACS_INT *));
 +static INLINE int *handle_charset_annotation P_ ((EMACS_INT, EMACS_INT,
 +                                                struct coding_system *,
 +                                                int *, EMACS_INT *));
 +static void consume_chars P_ ((struct coding_system *, Lisp_Object, int));
 +static int encode_coding P_ ((struct coding_system *));
 +static Lisp_Object make_conversion_work_buffer P_ ((int));
 +static Lisp_Object code_conversion_restore P_ ((Lisp_Object));
 +static INLINE int char_encodable_p P_ ((int, Lisp_Object));
 +static Lisp_Object make_subsidiaries P_ ((Lisp_Object));
  
 -*/
 -static INLINE int
 -decode_composition_emacs_mule (coding, src, src_end,
 -                             destination, dst_end, dst_bytes)
 -     struct coding_system *coding;
 -     const unsigned char *src, *src_end;
 -     unsigned char **destination, *dst_end;
 -     int dst_bytes;
 +static void
 +record_conversion_result (struct coding_system *coding,
 +                        enum coding_result_code result)
  {
 -  unsigned char *dst = *destination;
 -  int method, data_len, nchars;
 -  const unsigned char *src_base = src++;
 -  /* Store components of composition.  */
 -  int component[COMPOSITION_DATA_MAX_BUNCH_LENGTH];
 -  int ncomponent;
 -  /* Store multibyte form of characters to be composed.  This is for
 -     Emacs 20 style composition sequence.  */
 -  unsigned char buf[MAX_COMPOSITION_COMPONENTS * MAX_MULTIBYTE_LENGTH];
 -  unsigned char *bufp = buf;
 -  int c, i, gref, nref;
 -
 -  if (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH
 -      >= COMPOSITION_DATA_SIZE)
 +  coding->result = result;
 +  switch (result)
      {
 -      coding->result = CODING_FINISH_INSUFFICIENT_CMP;
 -      return -1;
 +    case CODING_RESULT_INSUFFICIENT_SRC:
 +      Vlast_code_conversion_error = Qinsufficient_source;
 +      break;
 +    case CODING_RESULT_INCONSISTENT_EOL:
 +      Vlast_code_conversion_error = Qinconsistent_eol;
 +      break;
 +    case CODING_RESULT_INVALID_SRC:
 +      Vlast_code_conversion_error = Qinvalid_source;
 +      break;
 +    case CODING_RESULT_INTERRUPT:
 +      Vlast_code_conversion_error = Qinterrupted;
 +      break;
 +    case CODING_RESULT_INSUFFICIENT_MEM:
 +      Vlast_code_conversion_error = Qinsufficient_memory;
 +      break;
 +    default:
 +      Vlast_code_conversion_error = intern ("Unknown error");
      }
 +}
  
 -  ONE_MORE_BYTE (c);
 -  if (c - 0xF0 >= COMPOSITION_RELATIVE
 -         && c - 0xF0 <= COMPOSITION_WITH_RULE_ALTCHARS)
 -    {
 -      int with_rule;
 +#define CODING_DECODE_CHAR(coding, src, src_base, src_end, charset, code, c) \
 +  do {                                                                             \
 +    charset_map_loaded = 0;                                                \
 +    c = DECODE_CHAR (charset, code);                                       \
 +    if (charset_map_loaded)                                                \
 +      {                                                                            \
 +      const unsigned char *orig = coding->source;                          \
 +      EMACS_INT offset;                                                    \
 +                                                                           \
 +      coding_set_source (coding);                                          \
 +      offset = coding->source - orig;                                      \
 +      src += offset;                                                       \
 +      src_base += offset;                                                  \
 +      src_end += offset;                                                   \
 +      }                                                                            \
 +  } while (0)
  
 -      method = c - 0xF0;
 -      with_rule = (method == COMPOSITION_WITH_RULE
 -                 || method == COMPOSITION_WITH_RULE_ALTCHARS);
 -      ONE_MORE_BYTE (c);
 -      data_len = c - 0xA0;
 -      if (data_len < 4
 -        || src_base + data_len > src_end)
 -      return 0;
 +
 +#define ASSURE_DESTINATION(bytes)                             \
 +  do {                                                                \
 +    if (dst + (bytes) >= dst_end)                             \
 +      {                                                               \
 +      int more_bytes = charbuf_end - charbuf + (bytes);       \
 +                                                              \
 +      dst = alloc_destination (coding, more_bytes, dst);      \
 +      dst_end = coding->destination + coding->dst_bytes;      \
 +      }                                                               \
 +  } while (0)
 +
 +
 +
 +static void
 +coding_set_source (coding)
 +     struct coding_system *coding;
 +{
 +  if (BUFFERP (coding->src_object))
 +    {
 +      struct buffer *buf = XBUFFER (coding->src_object);
 +
 +      if (coding->src_pos < 0)
 +      coding->source = BUF_GAP_END_ADDR (buf) + coding->src_pos_byte;
 +      else
 +      coding->source = BUF_BYTE_ADDRESS (buf, coding->src_pos_byte);
 +    }
 +  else if (STRINGP (coding->src_object))
 +    {
 +      coding->source = SDATA (coding->src_object) + coding->src_pos_byte;
 +    }
 +  else
 +    /* Otherwise, the source is C string and is never relocated
 +       automatically.  Thus we don't have to update anything.  */
 +    ;
 +}
 +
 +static void
 +coding_set_destination (coding)
 +     struct coding_system *coding;
 +{
 +  if (BUFFERP (coding->dst_object))
 +    {
 +      if (coding->src_pos < 0)
 +      {
 +        coding->destination = BEG_ADDR + coding->dst_pos_byte - 1;
 +        coding->dst_bytes = (GAP_END_ADDR
 +                             - (coding->src_bytes - coding->consumed)
 +                             - coding->destination);
 +      }
 +      else
 +      {
 +        /* We are sure that coding->dst_pos_byte is before the gap
 +           of the buffer. */
 +        coding->destination = (BUF_BEG_ADDR (XBUFFER (coding->dst_object))
 +                               + coding->dst_pos_byte - 1);
 +        coding->dst_bytes = (BUF_GAP_END_ADDR (XBUFFER (coding->dst_object))
 +                             - coding->destination);
 +      }
 +    }
 +  else
 +    /* Otherwise, the destination is C string and is never relocated
 +       automatically.  Thus we don't have to update anything.  */
 +    ;
 +}
 +
 +
 +static void
 +coding_alloc_by_realloc (coding, bytes)
 +     struct coding_system *coding;
 +     EMACS_INT bytes;
 +{
 +  coding->destination = (unsigned char *) xrealloc (coding->destination,
 +                                                  coding->dst_bytes + bytes);
 +  coding->dst_bytes += bytes;
 +}
 +
 +static void
 +coding_alloc_by_making_gap (coding, bytes)
 +     struct coding_system *coding;
 +     EMACS_INT bytes;
 +{
 +  if (BUFFERP (coding->dst_object)
 +      && EQ (coding->src_object, coding->dst_object))
 +    {
 +      EMACS_INT add = coding->src_bytes - coding->consumed;
 +
 +      GAP_SIZE -= add; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
 +      make_gap (bytes);
 +      GAP_SIZE += add; ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
 +    }
 +  else
 +    {
 +      Lisp_Object this_buffer;
 +
 +      this_buffer = Fcurrent_buffer ();
 +      set_buffer_internal (XBUFFER (coding->dst_object));
 +      make_gap (bytes);
 +      set_buffer_internal (XBUFFER (this_buffer));
 +    }
 +}
 +
 +
 +static unsigned char *
 +alloc_destination (coding, nbytes, dst)
 +     struct coding_system *coding;
 +     EMACS_INT nbytes;
 +     unsigned char *dst;
 +{
 +  EMACS_INT offset = dst - coding->destination;
 +
 +  if (BUFFERP (coding->dst_object))
 +    coding_alloc_by_making_gap (coding, nbytes);
 +  else
 +    coding_alloc_by_realloc (coding, nbytes);
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding_set_destination (coding);
 +  dst = coding->destination + offset;
 +  return dst;
 +}
 +
 +/** Macros for annotations.  */
 +
 +/* Maximum length of annotation data (sum of annotations for
 +   composition and charset).  */
 +#define MAX_ANNOTATION_LENGTH (4 + (MAX_COMPOSITION_COMPONENTS * 2) - 1 + 4)
 +
 +/* An annotation data is stored in the array coding->charbuf in this
 +   format:
 +     [ -LENGTH ANNOTATION_MASK NCHARS ... ]
 +   LENGTH is the number of elements in the annotation.
 +   ANNOTATION_MASK is one of CODING_ANNOTATE_XXX_MASK.
 +   NCHARS is the number of characters in the text annotated.
 +
 +   The format of the following elements depend on ANNOTATION_MASK.
 +
 +   In the case of CODING_ANNOTATE_COMPOSITION_MASK, these elements
 +   follows:
 +     ... METHOD [ COMPOSITION-COMPONENTS ... ]
 +   METHOD is one of enum composition_method.
 +   Optionnal COMPOSITION-COMPONENTS are characters and composition
 +   rules.
 +
 +   In the case of CODING_ANNOTATE_CHARSET_MASK, one element CHARSET-ID
 +   follows.  */
 +
 +#define ADD_ANNOTATION_DATA(buf, len, mask, nchars)   \
 +  do {                                                        \
 +    *(buf)++ = -(len);                                        \
 +    *(buf)++ = (mask);                                        \
 +    *(buf)++ = (nchars);                              \
 +    coding->annotated = 1;                            \
 +  } while (0);
 +
 +#define ADD_COMPOSITION_DATA(buf, nchars, method)                         \
 +  do {                                                                            \
 +    ADD_ANNOTATION_DATA (buf, 4, CODING_ANNOTATE_COMPOSITION_MASK, nchars); \
 +    *buf++ = method;                                                      \
 +  } while (0)
 +
 +
 +#define ADD_CHARSET_DATA(buf, nchars, id)                             \
 +  do {                                                                        \
 +    ADD_ANNOTATION_DATA (buf, 4, CODING_ANNOTATE_CHARSET_MASK, nchars);       \
 +    *buf++ = id;                                                      \
 +  } while (0)
 +
 +\f
 +/*** 2. Emacs' internal format (emacs-utf-8) ***/
 +
 +
 +
 +\f
 +/*** 3. UTF-8 ***/
 +
 +/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 +   Check if a text is encoded in UTF-8.  If it is, return 1, else
 +   return 0.  */
 +
 +#define UTF_8_1_OCTET_P(c)         ((c) < 0x80)
 +#define UTF_8_EXTRA_OCTET_P(c)     (((c) & 0xC0) == 0x80)
 +#define UTF_8_2_OCTET_LEADING_P(c) (((c) & 0xE0) == 0xC0)
 +#define UTF_8_3_OCTET_LEADING_P(c) (((c) & 0xF0) == 0xE0)
 +#define UTF_8_4_OCTET_LEADING_P(c) (((c) & 0xF8) == 0xF0)
 +#define UTF_8_5_OCTET_LEADING_P(c) (((c) & 0xFC) == 0xF8)
 +
 +static int
 +detect_coding_utf_8 (coding, detect_info)
 +     struct coding_system *coding;
 +     struct coding_detection_info *detect_info;
 +{
 +  const unsigned char *src = coding->source, *src_base;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  int found = 0;
 +
 +  detect_info->checked |= CATEGORY_MASK_UTF_8;
 +  /* A coding system of this category is always ASCII compatible.  */
 +  src += coding->head_ascii;
 +
 +  while (1)
 +    {
 +      int c, c1, c2, c3, c4;
 +
 +      src_base = src;
        ONE_MORE_BYTE (c);
 -      nchars = c - 0xA0;
 -      if (c < 1)
 -      return 0;
 -      for (ncomponent = 0; src < src_base + data_len; ncomponent++)
 +      if (c < 0 || UTF_8_1_OCTET_P (c))
 +      continue;
 +      ONE_MORE_BYTE (c1);
 +      if (c1 < 0 || ! UTF_8_EXTRA_OCTET_P (c1))
 +      break;
 +      if (UTF_8_2_OCTET_LEADING_P (c))
        {
 -        /* If it is longer than this, it can't be valid.  */
 -        if (ncomponent >= COMPOSITION_DATA_MAX_BUNCH_LENGTH)
 -          return 0;
 +        found = CATEGORY_MASK_UTF_8;
 +        continue;
 +      }
 +      ONE_MORE_BYTE (c2);
 +      if (c2 < 0 || ! UTF_8_EXTRA_OCTET_P (c2))
 +      break;
 +      if (UTF_8_3_OCTET_LEADING_P (c))
 +      {
 +        found = CATEGORY_MASK_UTF_8;
 +        continue;
 +      }
 +      ONE_MORE_BYTE (c3);
 +      if (c3 < 0 || ! UTF_8_EXTRA_OCTET_P (c3))
 +      break;
 +      if (UTF_8_4_OCTET_LEADING_P (c))
 +      {
 +        found = CATEGORY_MASK_UTF_8;
 +        continue;
 +      }
 +      ONE_MORE_BYTE (c4);
 +      if (c4 < 0 || ! UTF_8_EXTRA_OCTET_P (c4))
 +      break;
 +      if (UTF_8_5_OCTET_LEADING_P (c))
 +      {
 +        found = CATEGORY_MASK_UTF_8;
 +        continue;
 +      }
 +      break;
 +    }
 +  detect_info->rejected |= CATEGORY_MASK_UTF_8;
 +  return 0;
 +
 + no_more_source:
 +  if (src_base < src && coding->mode & CODING_MODE_LAST_BLOCK)
 +    {
 +      detect_info->rejected |= CATEGORY_MASK_UTF_8;
 +      return 0;
 +    }
 +  detect_info->found |= found;
 +  return 1;
 +}
 +
 +
 +static void
 +decode_coding_utf_8 (coding)
 +     struct coding_system *coding;
 +{
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  const unsigned char *src_base;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end = coding->charbuf + coding->charbuf_size;
 +  int consumed_chars = 0, consumed_chars_base;
 +  int multibytep = coding->src_multibyte;
 +  Lisp_Object attr, charset_list;
 +
 +  CODING_GET_INFO (coding, attr, charset_list);
 +
 +  while (1)
 +    {
 +      int c, c1, c2, c3, c4, c5;
 +
 +      src_base = src;
 +      consumed_chars_base = consumed_chars;
 +
 +      if (charbuf >= charbuf_end)
 +      break;
 +
 +      ONE_MORE_BYTE (c1);
 +      if (c1 < 0)
 +      {
 +        c = - c1;
 +      }
 +      else if (UTF_8_1_OCTET_P(c1))
 +      {
 +        c = c1;
 +      }
 +      else
 +      {
 +        ONE_MORE_BYTE (c2);
 +        if (c2 < 0 || ! UTF_8_EXTRA_OCTET_P (c2))
 +          goto invalid_code;
 +        if (UTF_8_2_OCTET_LEADING_P (c1))
 +          {
 +            c = ((c1 & 0x1F) << 6) | (c2 & 0x3F);
 +            /* Reject overlong sequences here and below.  Encoders
 +               producing them are incorrect, they can be misleading,
 +               and they mess up read/write invariance.  */
 +            if (c < 128)
 +              goto invalid_code;
 +          }
 +        else
 +          {
 +            ONE_MORE_BYTE (c3);
 +            if (c3 < 0 || ! UTF_8_EXTRA_OCTET_P (c3))
 +              goto invalid_code;
 +            if (UTF_8_3_OCTET_LEADING_P (c1))
 +              {
 +                c = (((c1 & 0xF) << 12)
 +                     | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
 +                if (c < 0x800
 +                    || (c >= 0xd800 && c < 0xe000)) /* surrogates (invalid) */
 +                  goto invalid_code;
 +              }
 +            else
 +              {
 +                ONE_MORE_BYTE (c4);
 +                if (c4 < 0 || ! UTF_8_EXTRA_OCTET_P (c4))
 +                  goto invalid_code;
 +                if (UTF_8_4_OCTET_LEADING_P (c1))
 +                  {
 +                  c = (((c1 & 0x7) << 18) | ((c2 & 0x3F) << 12)
 +                       | ((c3 & 0x3F) << 6) | (c4 & 0x3F));
 +                  if (c < 0x10000)
 +                    goto invalid_code;
 +                  }
 +                else
 +                  {
 +                    ONE_MORE_BYTE (c5);
 +                    if (c5 < 0 || ! UTF_8_EXTRA_OCTET_P (c5))
 +                      goto invalid_code;
 +                    if (UTF_8_5_OCTET_LEADING_P (c1))
 +                      {
 +                        c = (((c1 & 0x3) << 24) | ((c2 & 0x3F) << 18)
 +                             | ((c3 & 0x3F) << 12) | ((c4 & 0x3F) << 6)
 +                             | (c5 & 0x3F));
 +                        if ((c > MAX_CHAR) || (c < 0x200000))
 +                          goto invalid_code;
 +                      }
 +                    else
 +                      goto invalid_code;
 +                  }
 +              }
 +          }
 +      }
 +
 +      *charbuf++ = c;
 +      continue;
 +
 +    invalid_code:
 +      src = src_base;
 +      consumed_chars = consumed_chars_base;
 +      ONE_MORE_BYTE (c);
 +      *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
 +      coding->errors++;
 +    }
 +
 + no_more_source:
 +  coding->consumed_char += consumed_chars_base;
 +  coding->consumed = src_base - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
 +}
 +
 +
 +static int
 +encode_coding_utf_8 (coding)
 +     struct coding_system *coding;
 +{
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int produced_chars = 0;
 +  int c;
 +
 +  if (multibytep)
 +    {
 +      int safe_room = MAX_MULTIBYTE_LENGTH * 2;
 +
 +      while (charbuf < charbuf_end)
 +      {
 +        unsigned char str[MAX_MULTIBYTE_LENGTH], *p, *pend = str;
 +
 +        ASSURE_DESTINATION (safe_room);
 +        c = *charbuf++;
 +        if (CHAR_BYTE8_P (c))
 +          {
 +            c = CHAR_TO_BYTE8 (c);
 +            EMIT_ONE_BYTE (c);
 +          }
 +        else
 +          {
 +            CHAR_STRING_ADVANCE (c, pend);
 +            for (p = str; p < pend; p++)
 +              EMIT_ONE_BYTE (*p);
 +          }
 +      }
 +    }
 +  else
 +    {
 +      int safe_room = MAX_MULTIBYTE_LENGTH;
 +
 +      while (charbuf < charbuf_end)
 +      {
 +        ASSURE_DESTINATION (safe_room);
 +        c = *charbuf++;
 +        if (CHAR_BYTE8_P (c))
 +          *dst++ = CHAR_TO_BYTE8 (c);
 +        else
 +          dst += CHAR_STRING (c, dst);
 +        produced_chars++;
 +      }
 +    }
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
 +  return 0;
 +}
 +
 +
 +/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 +   Check if a text is encoded in one of UTF-16 based coding systems.
 +   If it is, return 1, else return 0.  */
 +
 +#define UTF_16_HIGH_SURROGATE_P(val) \
 +  (((val) & 0xFC00) == 0xD800)
 +
 +#define UTF_16_LOW_SURROGATE_P(val) \
 +  (((val) & 0xFC00) == 0xDC00)
 +
 +#define UTF_16_INVALID_P(val) \
 +  (((val) == 0xFFFE)          \
 +   || ((val) == 0xFFFF)               \
 +   || UTF_16_LOW_SURROGATE_P (val))
 +
 +
 +static int
 +detect_coding_utf_16 (coding, detect_info)
 +     struct coding_system *coding;
 +     struct coding_detection_info *detect_info;
 +{
 +  const unsigned char *src = coding->source, *src_base = src;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  int c1, c2;
 +
 +  detect_info->checked |= CATEGORY_MASK_UTF_16;
 +  if (coding->mode & CODING_MODE_LAST_BLOCK
 +      && (coding->src_chars & 1))
 +    {
 +      detect_info->rejected |= CATEGORY_MASK_UTF_16;
 +      return 0;
 +    }
 +
 +  ONE_MORE_BYTE (c1);
 +  ONE_MORE_BYTE (c2);
 +  if ((c1 == 0xFF) && (c2 == 0xFE))
 +    {
 +      detect_info->found |= (CATEGORY_MASK_UTF_16_LE
 +                           | CATEGORY_MASK_UTF_16_AUTO);
 +      detect_info->rejected |= (CATEGORY_MASK_UTF_16_BE
 +                              | CATEGORY_MASK_UTF_16_BE_NOSIG
 +                              | CATEGORY_MASK_UTF_16_LE_NOSIG);
 +    }
 +  else if ((c1 == 0xFE) && (c2 == 0xFF))
 +    {
 +      detect_info->found |= (CATEGORY_MASK_UTF_16_BE
 +                           | CATEGORY_MASK_UTF_16_AUTO);
 +      detect_info->rejected |= (CATEGORY_MASK_UTF_16_LE
 +                              | CATEGORY_MASK_UTF_16_BE_NOSIG
 +                              | CATEGORY_MASK_UTF_16_LE_NOSIG);
 +    }
 +  else if (c1 >= 0 && c2 >= 0)
 +    {
 +      detect_info->rejected
 +      |= (CATEGORY_MASK_UTF_16_BE | CATEGORY_MASK_UTF_16_LE);
 +    }
 + no_more_source:
 +  return 1;
 +}
 +
 +static void
 +decode_coding_utf_16 (coding)
 +     struct coding_system *coding;
 +{
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  const unsigned char *src_base;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end = coding->charbuf + coding->charbuf_size;
 +  int consumed_chars = 0, consumed_chars_base;
 +  int multibytep = coding->src_multibyte;
 +  enum utf_16_bom_type bom = CODING_UTF_16_BOM (coding);
 +  enum utf_16_endian_type endian = CODING_UTF_16_ENDIAN (coding);
 +  int surrogate = CODING_UTF_16_SURROGATE (coding);
 +  Lisp_Object attr, charset_list;
 +
 +  CODING_GET_INFO (coding, attr, charset_list);
 +
 +  if (bom == utf_16_with_bom)
 +    {
 +      int c, c1, c2;
 +
 +      src_base = src;
 +      ONE_MORE_BYTE (c1);
 +      ONE_MORE_BYTE (c2);
 +      c = (c1 << 8) | c2;
 +
 +      if (endian == utf_16_big_endian
 +        ? c != 0xFEFF : c != 0xFFFE)
 +      {
 +        /* The first two bytes are not BOM.  Treat them as bytes
 +           for a normal character.  */
 +        src = src_base;
 +        coding->errors++;
 +      }
 +      CODING_UTF_16_BOM (coding) = utf_16_without_bom;
 +    }
 +  else if (bom == utf_16_detect_bom)
 +    {
 +      /* We have already tried to detect BOM and failed in
 +       detect_coding.  */
 +      CODING_UTF_16_BOM (coding) = utf_16_without_bom;
 +    }
 +
 +  while (1)
 +    {
 +      int c, c1, c2;
 +
 +      src_base = src;
 +      consumed_chars_base = consumed_chars;
 +
 +      if (charbuf + 2 >= charbuf_end)
 +      break;
 +
 +      ONE_MORE_BYTE (c1);
 +      if (c1 < 0)
 +      {
 +        *charbuf++ = -c1;
 +        continue;
 +      }
 +      ONE_MORE_BYTE (c2);
 +      if (c2 < 0)
 +      {
 +        *charbuf++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
 +        *charbuf++ = -c2;
 +        continue;
 +      }
 +      c = (endian == utf_16_big_endian
 +         ? ((c1 << 8) | c2) : ((c2 << 8) | c1));
 +      if (surrogate)
 +      {
 +        if (! UTF_16_LOW_SURROGATE_P (c))
 +          {
 +            if (endian == utf_16_big_endian)
 +              c1 = surrogate >> 8, c2 = surrogate & 0xFF;
 +            else
 +              c1 = surrogate & 0xFF, c2 = surrogate >> 8;
 +            *charbuf++ = c1;
 +            *charbuf++ = c2;
 +            coding->errors++;
 +            if (UTF_16_HIGH_SURROGATE_P (c))
 +              CODING_UTF_16_SURROGATE (coding) = surrogate = c;
 +            else
 +              *charbuf++ = c;
 +          }
 +        else
 +          {
 +            c = ((surrogate - 0xD800) << 10) | (c - 0xDC00);
 +            CODING_UTF_16_SURROGATE (coding) = surrogate = 0;
 +            *charbuf++ = 0x10000 + c;
 +          }
 +      }
 +      else
 +      {
 +        if (UTF_16_HIGH_SURROGATE_P (c))
 +          CODING_UTF_16_SURROGATE (coding) = surrogate = c;
 +        else
 +          *charbuf++ = c;
 +      }
 +    }
 +
 + no_more_source:
 +  coding->consumed_char += consumed_chars_base;
 +  coding->consumed = src_base - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
 +}
 +
 +static int
 +encode_coding_utf_16 (coding)
 +     struct coding_system *coding;
 +{
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int safe_room = 8;
 +  enum utf_16_bom_type bom = CODING_UTF_16_BOM (coding);
 +  int big_endian = CODING_UTF_16_ENDIAN (coding) == utf_16_big_endian;
 +  int produced_chars = 0;
 +  Lisp_Object attrs, charset_list;
 +  int c;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +
 +  if (bom != utf_16_without_bom)
 +    {
 +      ASSURE_DESTINATION (safe_room);
 +      if (big_endian)
 +      EMIT_TWO_BYTES (0xFE, 0xFF);
 +      else
 +      EMIT_TWO_BYTES (0xFF, 0xFE);
 +      CODING_UTF_16_BOM (coding) = utf_16_without_bom;
 +    }
 +
 +  while (charbuf < charbuf_end)
 +    {
 +      ASSURE_DESTINATION (safe_room);
 +      c = *charbuf++;
 +      if (c >= MAX_UNICODE_CHAR)
 +      c = coding->default_char;
 +
 +      if (c < 0x10000)
 +      {
 +        if (big_endian)
 +          EMIT_TWO_BYTES (c >> 8, c & 0xFF);
 +        else
 +          EMIT_TWO_BYTES (c & 0xFF, c >> 8);
 +      }
 +      else
 +      {
 +        int c1, c2;
 +
 +        c -= 0x10000;
 +        c1 = (c >> 10) + 0xD800;
 +        c2 = (c & 0x3FF) + 0xDC00;
 +        if (big_endian)
 +          EMIT_FOUR_BYTES (c1 >> 8, c1 & 0xFF, c2 >> 8, c2 & 0xFF);
 +        else
 +          EMIT_FOUR_BYTES (c1 & 0xFF, c1 >> 8, c2 & 0xFF, c2 >> 8);
 +      }
 +    }
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->produced = dst - coding->destination;
 +  coding->produced_char += produced_chars;
 +  return 0;
 +}
 +
 +\f
 +/*** 6. Old Emacs' internal format (emacs-mule) ***/
 +
 +/* Emacs' internal format for representation of multiple character
 +   sets is a kind of multi-byte encoding, i.e. characters are
 +   represented by variable-length sequences of one-byte codes.
 +
 +   ASCII characters and control characters (e.g. `tab', `newline') are
 +   represented by one-byte sequences which are their ASCII codes, in
 +   the range 0x00 through 0x7F.
 +
 +   8-bit characters of the range 0x80..0x9F are represented by
 +   two-byte sequences of LEADING_CODE_8_BIT_CONTROL and (their 8-bit
 +   code + 0x20).
 +
 +   8-bit characters of the range 0xA0..0xFF are represented by
 +   one-byte sequences which are their 8-bit code.
 +
 +   The other characters are represented by a sequence of `base
 +   leading-code', optional `extended leading-code', and one or two
 +   `position-code's.  The length of the sequence is determined by the
 +   base leading-code.  Leading-code takes the range 0x81 through 0x9D,
 +   whereas extended leading-code and position-code take the range 0xA0
 +   through 0xFF.  See `charset.h' for more details about leading-code
 +   and position-code.
 +
 +   --- CODE RANGE of Emacs' internal format ---
 +   character set      range
 +   -------------      -----
 +   ascii              0x00..0x7F
 +   eight-bit-control  LEADING_CODE_8_BIT_CONTROL + 0xA0..0xBF
 +   eight-bit-graphic  0xA0..0xBF
 +   ELSE                       0x81..0x9D + [0xA0..0xFF]+
 +   ---------------------------------------------
 +
 +   As this is the internal character representation, the format is
 +   usually not used externally (i.e. in a file or in a data sent to a
 +   process).  But, it is possible to have a text externally in this
 +   format (i.e. by encoding by the coding system `emacs-mule').
 +
 +   In that case, a sequence of one-byte codes has a slightly different
 +   form.
 +
 +   At first, all characters in eight-bit-control are represented by
 +   one-byte sequences which are their 8-bit code.
 +
 +   Next, character composition data are represented by the byte
 +   sequence of the form: 0x80 METHOD BYTES CHARS COMPONENT ...,
 +   where,
 +      METHOD is 0xF0 plus one of composition method (enum
 +      composition_method),
 +
 +      BYTES is 0xA0 plus a byte length of this composition data,
 +
 +      CHARS is 0x20 plus a number of characters composed by this
 +      data,
 +
 +      COMPONENTs are characters of multibye form or composition
 +      rules encoded by two-byte of ASCII codes.
 +
 +   In addition, for backward compatibility, the following formats are
 +   also recognized as composition data on decoding.
 +
 +   0x80 MSEQ ...
 +   0x80 0xFF MSEQ RULE MSEQ RULE ... MSEQ
 +
 +   Here,
 +      MSEQ is a multibyte form but in these special format:
 +        ASCII: 0xA0 ASCII_CODE+0x80,
 +        other: LEADING_CODE+0x20 FOLLOWING-BYTE ...,
 +      RULE is a one byte code of the range 0xA0..0xF0 that
 +      represents a composition rule.
 +  */
 +
 +char emacs_mule_bytes[256];
 +
 +int
 +emacs_mule_char (coding, src, nbytes, nchars, id)
 +     struct coding_system *coding;
 +     const unsigned char *src;
 +     int *nbytes, *nchars, *id;
 +{
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  const unsigned char *src_base = src;
 +  int multibytep = coding->src_multibyte;
 +  struct charset *charset;
 +  unsigned code;
 +  int c;
 +  int consumed_chars = 0;
  
 -        if (ncomponent % 2 && with_rule)
 +  ONE_MORE_BYTE (c);
 +  if (c < 0)
 +    {
 +      c = -c;
 +      charset = emacs_mule_charset[0];
 +    }
 +  else
 +    {
 +      if (c >= 0xA0)
 +      {
 +        /* Old style component character of a compostion.  */
 +        if (c == 0xA0)
            {
 -            ONE_MORE_BYTE (gref);
 -            gref -= 32;
 -            ONE_MORE_BYTE (nref);
 -            nref -= 32;
 -            c = COMPOSITION_ENCODE_RULE (gref, nref);
 +            ONE_MORE_BYTE (c);
 +            c -= 0x80;
            }
          else
 -          {
 -            int bytes;
 -            if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)
 -                || (coding->flags /* We are recovering a file.  */
 -                    && src[0] == LEADING_CODE_8_BIT_CONTROL
 -                    && ! CHAR_HEAD_P (src[1])))
 -              c = STRING_CHAR (src, bytes);
 -            else
 -              c = *src, bytes = 1;
 -            src += bytes;
 -          }
 -        component[ncomponent] = c;
 +          c -= 0x20;
        }
 -    }
 -  else if (c >= 0x80)
 -    {
 -      /* This may be an old Emacs 20 style format.  See the comment at
 -       the section 2 of this file.  */
 -      while (src < src_end && !CHAR_HEAD_P (*src)) src++;
 -      if (src == src_end
 -        && !(coding->mode & CODING_MODE_LAST_BLOCK))
 -      goto label_end_of_loop;
  
 -      src_end = src;
 -      src = src_base + 1;
 -      if (c < 0xC0)
 +      switch (emacs_mule_bytes[c])
        {
 -        method = COMPOSITION_RELATIVE;
 -        for (ncomponent = 0; ncomponent < MAX_COMPOSITION_COMPONENTS;)
 +      case 2:
 +        if (! (charset = emacs_mule_charset[c]))
 +          goto invalid_code;
 +        ONE_MORE_BYTE (c);
 +        if (c < 0xA0)
 +          goto invalid_code;
 +        code = c & 0x7F;
 +        break;
 +
 +      case 3:
 +        if (c == EMACS_MULE_LEADING_CODE_PRIVATE_11
 +            || c == EMACS_MULE_LEADING_CODE_PRIVATE_12)
            {
 -            DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp);
 -            if (c < 0)
 -              break;
 -            component[ncomponent++] = c;
 +            ONE_MORE_BYTE (c);
 +            if (c < 0xA0 || ! (charset = emacs_mule_charset[c]))
 +              goto invalid_code;
 +            ONE_MORE_BYTE (c);
 +            if (c < 0xA0)
 +              goto invalid_code;
 +            code = c & 0x7F;
            }
 -        if (ncomponent < 2)
 -          return 0;
 -        nchars = ncomponent;
 -      }
 -      else if (c == 0xFF)
 -      {
 -        method = COMPOSITION_WITH_RULE;
 -        src++;
 -        DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp);
 -        if (c < 0)
 -          return 0;
 -        component[0] = c;
 -        for (ncomponent = 1;
 -             ncomponent < MAX_COMPOSITION_COMPONENTS * 2 - 1;)
 +        else
            {
 -            DECODE_EMACS_MULE_COMPOSITION_RULE (c);
 -            if (c < 0)
 -              break;
 -            component[ncomponent++] = c;
 -            DECODE_EMACS_MULE_COMPOSITION_CHAR (c, bufp);
 -            if (c < 0)
 -              break;
 -            component[ncomponent++] = c;
 +            if (! (charset = emacs_mule_charset[c]))
 +              goto invalid_code;
 +            ONE_MORE_BYTE (c);
 +            if (c < 0xA0)
 +              goto invalid_code;
 +            code = (c & 0x7F) << 8;
 +            ONE_MORE_BYTE (c);
 +            if (c < 0xA0)
 +              goto invalid_code;
 +            code |= c & 0x7F;
            }
 -        if (ncomponent < 3)
 -          return 0;
 -        nchars = (ncomponent + 1) / 2;
 -      }
 -      else
 -      return 0;
 -    }
 -  else
 -    return 0;
 +        break;
  
 -  if (buf == bufp || dst + (bufp - buf) <= (dst_bytes ? dst_end : src))
 -    {
 -      CODING_ADD_COMPOSITION_START (coding, coding->produced_char, method);
 -      for (i = 0; i < ncomponent; i++)
 -      CODING_ADD_COMPOSITION_COMPONENT (coding, component[i]);
 -      CODING_ADD_COMPOSITION_END (coding, coding->produced_char + nchars);
 -      if (buf < bufp)
 -      {
 -        unsigned char *p = buf;
 -        EMIT_BYTES (p, bufp);
 -        *destination += bufp - buf;
 -        coding->produced_char += nchars;
 +      case 4:
 +        ONE_MORE_BYTE (c);
 +        if (c < 0 || ! (charset = emacs_mule_charset[c]))
 +          goto invalid_code;
 +        ONE_MORE_BYTE (c);
 +        if (c < 0xA0)
 +          goto invalid_code;
 +        code = (c & 0x7F) << 8;
 +        ONE_MORE_BYTE (c);
 +        if (c < 0xA0)
 +          goto invalid_code;
 +        code |= c & 0x7F;
 +        break;
 +
 +      case 1:
 +        code = c;
 +        charset = CHARSET_FROM_ID (ASCII_BYTE_P (code)
 +                                   ? charset_ascii : charset_eight_bit);
 +        break;
 +
 +      default:
 +        abort ();
        }
 -      return (src - src_base);
 +      c = DECODE_CHAR (charset, code);
 +      if (c < 0)
 +      goto invalid_code;
      }
 - label_end_of_loop:
 +  *nbytes = src - src_base;
 +  *nchars = consumed_chars;
 +  if (id)
 +    *id = charset->id;
 +  return c;
 +
 + no_more_source:
 +  return -2;
 +
 + invalid_code:
    return -1;
  }
  
 -/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
  
 -static void
 -decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
 +/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 +   Check if a text is encoded in `emacs-mule'.  If it is, return 1,
 +   else return 0.  */
 +
 +static int
 +detect_coding_emacs_mule (coding, detect_info)
       struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
 +     struct coding_detection_info *detect_info;
  {
 -  const unsigned char *src = source;
 -  const unsigned char *src_end = source + src_bytes;
 -  unsigned char *dst = destination;
 -  unsigned char *dst_end = destination + dst_bytes;
 -  /* SRC_BASE remembers the start position in source in each loop.
 -     The loop will be exited when there's not enough source code, or
 -     when there's not enough destination area to produce a
 -     character.  */
 -  const unsigned char *src_base;
 +  const unsigned char *src = coding->source, *src_base;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  int c;
 +  int found = 0;
  
 -  coding->produced_char = 0;
 -  while ((src_base = src) < src_end)
 -    {
 -      unsigned char tmp[MAX_MULTIBYTE_LENGTH];
 -      const unsigned char *p;
 -      int bytes;
 +  detect_info->checked |= CATEGORY_MASK_EMACS_MULE;
 +  /* A coding system of this category is always ASCII compatible.  */
 +  src += coding->head_ascii;
  
 -      if (*src == '\r')
 +  while (1)
 +    {
 +      src_base = src;
 +      ONE_MORE_BYTE (c);
 +      if (c < 0)
 +      continue;
 +      if (c == 0x80)
        {
 -        int c = *src++;
 +        /* Perhaps the start of composite character.  We simple skip
 +           it because analyzing it is too heavy for detecting.  But,
 +           at least, we check that the composite character
 +           constitues of more than 4 bytes.  */
 +        const unsigned char *src_base;
  
 -        if (coding->eol_type == CODING_EOL_CR)
 -          c = '\n';
 -        else if (coding->eol_type == CODING_EOL_CRLF)
 +      repeat:
 +        src_base = src;
 +        do
            {
              ONE_MORE_BYTE (c);
 -            if (c != '\n')
 -              {
 -                src--;
 -                c = '\r';
 -              }
 -          }
 -        *dst++ = c;
 -        coding->produced_char++;
 -        continue;
 -      }
 -      else if (*src == '\n')
 -      {
 -        if ((coding->eol_type == CODING_EOL_CR
 -             || coding->eol_type == CODING_EOL_CRLF)
 -            && coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
 -          {
 -            coding->result = CODING_FINISH_INCONSISTENT_EOL;
 -            goto label_end_of_loop;
 -          }
 -        *dst++ = *src++;
 -        coding->produced_char++;
 -        continue;
 -      }
 -      else if (*src == 0x80 && coding->cmp_data)
 -      {
 -        /* Start of composition data.  */
 -        int consumed  = decode_composition_emacs_mule (coding, src, src_end,
 -                                                       &dst, dst_end,
 -                                                       dst_bytes);
 -        if (consumed < 0)
 -          goto label_end_of_loop;
 -        else if (consumed > 0)
 -          {
 -            src += consumed;
 -            continue;
            }
 -        bytes = CHAR_STRING (*src, tmp);
 -        p = tmp;
 -        src++;
 +        while (c >= 0xA0);
 +
 +        if (src - src_base <= 4)
 +          break;
 +        found = CATEGORY_MASK_EMACS_MULE;
 +        if (c == 0x80)
 +          goto repeat;
        }
 -      else if (UNIBYTE_STR_AS_MULTIBYTE_P (src, src_end - src, bytes)
 -             || (coding->flags /* We are recovering a file.  */
 -                 && src[0] == LEADING_CODE_8_BIT_CONTROL
 -                 && ! CHAR_HEAD_P (src[1])))
 +
 +      if (c < 0x80)
        {
 -        p = src;
 -        src += bytes;
 +        if (c < 0x20
 +            && (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO))
 +          break;
        }
        else
        {
 -        int i, c;
 +        int more_bytes = emacs_mule_bytes[*src_base] - 1;
  
 -        bytes = BYTES_BY_CHAR_HEAD (*src);
 -        src++;
 -        for (i = 1; i < bytes; i++)
 +        while (more_bytes > 0)
            {
              ONE_MORE_BYTE (c);
 -            if (CHAR_HEAD_P (c))
 -              break;
 -          }
 -        if (i < bytes)
 -          {
 -            bytes = CHAR_STRING (*src_base, tmp);
 -            p = tmp;
 -            src = src_base + 1;
 -          }
 -        else
 -          {
 -            p = src_base;
 +            if (c < 0xA0)
 +              {
 +                src--;        /* Unread the last byte.  */
 +                break;
 +              }
 +            more_bytes--;
            }
 +        if (more_bytes != 0)
 +          break;
 +        found = CATEGORY_MASK_EMACS_MULE;
        }
 -      if (dst + bytes >= (dst_bytes ? dst_end : src))
 -      {
 -        coding->result = CODING_FINISH_INSUFFICIENT_DST;
 -        break;
 -      }
 -      while (bytes--) *dst++ = *p++;
 -      coding->produced_char++;
      }
 - label_end_of_loop:
 -  coding->consumed = coding->consumed_char = src_base - source;
 -  coding->produced = dst - destination;
 +  detect_info->rejected |= CATEGORY_MASK_EMACS_MULE;
 +  return 0;
 +
 + no_more_source:
 +  if (src_base < src && coding->mode & CODING_MODE_LAST_BLOCK)
 +    {
 +      detect_info->rejected |= CATEGORY_MASK_EMACS_MULE;
 +      return 0;
 +    }
 +  detect_info->found |= found;
 +  return 1;
  }
  
  
 -/* Encode composition data stored at DATA into a special byte sequence
 -   starting by 0x80.  Update CODING->cmp_data_start and maybe
 -   CODING->cmp_data for the next call.  */
 +/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
 +
 +/* Decode a character represented as a component of composition
 +   sequence of Emacs 20/21 style at SRC.  Set C to that character and
 +   update SRC to the head of next character (or an encoded composition
 +   rule).  If SRC doesn't points a composition component, set C to -1.
 +   If SRC points an invalid byte sequence, global exit by a return
 +   value 0.  */
 +
 +#define DECODE_EMACS_MULE_COMPOSITION_CHAR(buf)                       \
 +  if (1)                                                      \
 +    {                                                         \
 +      int c;                                                  \
 +      int nbytes, nchars;                                     \
 +                                                              \
 +      if (src == src_end)                                     \
 +      break;                                                  \
 +      c = emacs_mule_char (coding, src, &nbytes, &nchars, NULL);\
 +      if (c < 0)                                              \
 +      {                                                       \
 +        if (c == -2)                                          \
 +          break;                                              \
 +        goto invalid_code;                                    \
 +      }                                                       \
 +      *buf++ = c;                                             \
 +      src += nbytes;                                          \
 +      consumed_chars += nchars;                                       \
 +    }                                                         \
 +  else
 +
 +
 +/* Decode a composition rule represented as a component of composition
 +   sequence of Emacs 20 style at SRC.  Store the decoded rule in *BUF,
 +   and increment BUF.  If SRC points an invalid byte sequence, set C
 +   to -1.  */
 +
 +#define DECODE_EMACS_MULE_COMPOSITION_RULE_20(buf)    \
 +  do {                                                        \
 +    int c, gref, nref;                                        \
 +                                                      \
 +    if (src >= src_end)                                       \
 +      goto invalid_code;                              \
 +    ONE_MORE_BYTE_NO_CHECK (c);                               \
 +    c -= 0xA0;                                                \
 +    if (c < 0 || c >= 81)                             \
 +      goto invalid_code;                              \
 +                                                      \
 +    gref = c / 9, nref = c % 9;                               \
 +    *buf++ = COMPOSITION_ENCODE_RULE (gref, nref);    \
 +  } while (0)
 +
 +
 +/* Decode a composition rule represented as a component of composition
 +   sequence of Emacs 21 style at SRC.  Store the decoded rule in *BUF,
 +   and increment BUF.  If SRC points an invalid byte sequence, set C
 +   to -1.  */
 +
 +#define DECODE_EMACS_MULE_COMPOSITION_RULE_21(buf)    \
 +  do {                                                        \
 +    int gref, nref;                                   \
 +                                                      \
 +    if (src + 1>= src_end)                            \
 +      goto invalid_code;                              \
 +    ONE_MORE_BYTE_NO_CHECK (gref);                    \
 +    gref -= 0x20;                                     \
 +    ONE_MORE_BYTE_NO_CHECK (nref);                    \
 +    nref -= 0x20;                                     \
 +    if (gref < 0 || gref >= 81                                \
 +      || nref < 0 || nref >= 81)                      \
 +      goto invalid_code;                              \
 +    *buf++ = COMPOSITION_ENCODE_RULE (gref, nref);    \
 +  } while (0)
 +
  
 -#define ENCODE_COMPOSITION_EMACS_MULE(coding, data)                   \
 +#define DECODE_EMACS_MULE_21_COMPOSITION(c)                           \
    do {                                                                        \
 -    unsigned char buf[1024], *p0 = buf, *p;                           \
 -    int len = data[0];                                                        \
 -    int i;                                                            \
 -                                                                      \
 -    buf[0] = 0x80;                                                    \
 -    buf[1] = 0xF0 + data[3];  /* METHOD */                            \
 -    buf[3] = 0xA0 + (data[2] - data[1]); /* COMPOSED-CHARS */         \
 -    p = buf + 4;                                                      \
 -    if (data[3] == COMPOSITION_WITH_RULE                              \
 -      || data[3] == COMPOSITION_WITH_RULE_ALTCHARS)                   \
 +    /* Emacs 21 style format.  The first three bytes at SRC are               \
 +       (METHOD - 0xF2), (BYTES - 0xA0), (CHARS - 0xA0), where BYTES is        \
 +       the byte length of this composition information, CHARS is the  \
 +       number of characters composed by this composition.  */         \
 +    enum composition_method method = c - 0xF2;                                \
 +    int *charbuf_base = charbuf;                                      \
 +    int consumed_chars_limit;                                         \
 +    int nbytes, nchars;                                                       \
 +                                                                      \
 +    ONE_MORE_BYTE (c);                                                        \
 +    if (c < 0)                                                                \
 +      goto invalid_code;                                              \
 +    nbytes = c - 0xA0;                                                        \
 +    if (nbytes < 3)                                                   \
 +      goto invalid_code;                                              \
 +    ONE_MORE_BYTE (c);                                                        \
 +    if (c < 0)                                                                \
 +      goto invalid_code;                                              \
 +    nchars = c - 0xA0;                                                        \
 +    ADD_COMPOSITION_DATA (charbuf, nchars, method);                   \
 +    consumed_chars_limit = consumed_chars_base + nbytes;              \
 +    if (method != COMPOSITION_RELATIVE)                                       \
        {                                                                       \
 -      p += CHAR_STRING (data[4], p);                                  \
 -      for (i = 5; i < len; i += 2)                                    \
 +      int i = 0;                                                      \
 +      while (consumed_chars < consumed_chars_limit)                   \
          {                                                             \
 -          int gref, nref;                                             \
 -           COMPOSITION_DECODE_RULE (data[i], gref, nref);             \
 -          *p++ = 0x20 + gref;                                         \
 -          *p++ = 0x20 + nref;                                         \
 -          p += CHAR_STRING (data[i + 1], p);                          \
 +          if (i % 2 && method != COMPOSITION_WITH_ALTCHARS)           \
 +            DECODE_EMACS_MULE_COMPOSITION_RULE_21 (charbuf);          \
 +          else                                                        \
 +            DECODE_EMACS_MULE_COMPOSITION_CHAR (charbuf);             \
 +          i++;                                                        \
          }                                                             \
 +      if (consumed_chars < consumed_chars_limit)                      \
 +        goto invalid_code;                                            \
 +      charbuf_base[0] -= i;                                           \
        }                                                                       \
 -    else                                                              \
 -      {                                                                       \
 -      for (i = 4; i < len; i++)                                       \
 -        p += CHAR_STRING (data[i], p);                                \
 -      }                                                                       \
 -    buf[2] = 0xA0 + (p - buf);        /* COMPONENTS-BYTES */                  \
 +  } while (0)
 +
 +
 +#define DECODE_EMACS_MULE_20_RELATIVE_COMPOSITION(c)                  \
 +  do {                                                                        \
 +    /* Emacs 20 style format for relative composition.  */            \
 +    /* Store multibyte form of characters to be composed.  */         \
 +    enum composition_method method = COMPOSITION_RELATIVE;            \
 +    int components[MAX_COMPOSITION_COMPONENTS * 2 - 1];                       \
 +    int *buf = components;                                            \
 +    int i, j;                                                         \
                                                                        \
 -    if (dst + (p - buf) + 4 > (dst_bytes ? dst_end : src))            \
 -      {                                                                       \
 -      coding->result = CODING_FINISH_INSUFFICIENT_DST;                \
 -      goto label_end_of_loop;                                         \
 -      }                                                                       \
 -    while (p0 < p)                                                    \
 -      *dst++ = *p0++;                                                 \
 -    coding->cmp_data_start += data[0];                                        \
 -    if (coding->cmp_data_start == coding->cmp_data->used              \
 -      && coding->cmp_data->next)                                      \
 -      {                                                                       \
 -      coding->cmp_data = coding->cmp_data->next;                      \
 -      coding->cmp_data_start = 0;                                     \
 -      }                                                                       \
 +    src = src_base;                                                   \
 +    ONE_MORE_BYTE (c);                /* skip 0x80 */                         \
 +    for (i = 0; *src >= 0xA0 && i < MAX_COMPOSITION_COMPONENTS; i++)  \
 +      DECODE_EMACS_MULE_COMPOSITION_CHAR (buf);                               \
 +    if (i < 2)                                                                \
 +      goto invalid_code;                                              \
 +    ADD_COMPOSITION_DATA (charbuf, i, method);                                \
 +    for (j = 0; j < i; j++)                                           \
 +      *charbuf++ = components[j];                                     \
    } while (0)
  
  
 -static void encode_eol P_ ((struct coding_system *, const unsigned char *,
 -                          unsigned char *, int, int));
 +#define DECODE_EMACS_MULE_20_RULEBASE_COMPOSITION(c)          \
 +  do {                                                                \
 +    /* Emacs 20 style format for rule-base composition.  */   \
 +    /* Store multibyte form of characters to be composed.  */ \
 +    enum composition_method method = COMPOSITION_WITH_RULE;   \
 +    int *charbuf_base = charbuf;                              \
 +    int components[MAX_COMPOSITION_COMPONENTS * 2 - 1];               \
 +    int *buf = components;                                    \
 +    int i, j;                                                 \
 +                                                              \
 +    DECODE_EMACS_MULE_COMPOSITION_CHAR (buf);                 \
 +    for (i = 1; i < MAX_COMPOSITION_COMPONENTS; i++)          \
 +      {                                                               \
 +      if (*src < 0xA0)                                        \
 +        break;                                                \
 +      DECODE_EMACS_MULE_COMPOSITION_RULE_20 (buf);            \
 +      DECODE_EMACS_MULE_COMPOSITION_CHAR (buf);               \
 +      }                                                               \
 +    if (i <= 1 || (buf - components) % 2 == 0)                        \
 +      goto invalid_code;                                      \
 +    if (charbuf + i + (i / 2) + 1 >= charbuf_end)             \
 +      goto no_more_source;                                    \
 +    ADD_COMPOSITION_DATA (charbuf, i, method);                        \
 +    i = i * 2 - 1;                                            \
 +    for (j = 0; j < i; j++)                                   \
 +      *charbuf++ = components[j];                             \
 +    charbuf_base[0] -= i;                                     \
 +    for (j = 0; j < i; j += 2)                                        \
 +      *charbuf++ = components[j];                             \
 +  } while (0)
 +
  
  static void
 -encode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
 +decode_coding_emacs_mule (coding)
       struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
  {
 -  const unsigned char *src = source;
 -  const unsigned char *src_end = source + src_bytes;
 -  unsigned char *dst = destination;
 -  unsigned char *dst_end = destination + dst_bytes;
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
    const unsigned char *src_base;
 -  int c;
 -  int char_offset;
 -  int *data;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end
 +    = coding->charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
 +  int consumed_chars = 0, consumed_chars_base;
 +  int multibytep = coding->src_multibyte;
 +  Lisp_Object attrs, charset_list;
 +  int char_offset = coding->produced_char;
 +  int last_offset = char_offset;
 +  int last_id = charset_ascii;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
  
 -  Lisp_Object translation_table;
 +  while (1)
 +    {
 +      int c;
 +
 +      src_base = src;
 +      consumed_chars_base = consumed_chars;
 +
 +      if (charbuf >= charbuf_end)
 +      break;
 +
 +      ONE_MORE_BYTE (c);
 +      if (c < 0)
 +      {
 +        *charbuf++ = -c;
 +        char_offset++;
 +      }
 +      else if (c < 0x80)
 +      {
 +        *charbuf++ = c;
 +        char_offset++;
 +      }
 +      else if (c == 0x80)
 +      {
 +        ONE_MORE_BYTE (c);
 +        if (c < 0)
 +          goto invalid_code;
 +        if (c - 0xF2 >= COMPOSITION_RELATIVE
 +            && c - 0xF2 <= COMPOSITION_WITH_RULE_ALTCHARS)
 +          DECODE_EMACS_MULE_21_COMPOSITION (c);
 +        else if (c < 0xC0)
 +          DECODE_EMACS_MULE_20_RELATIVE_COMPOSITION (c);
 +        else if (c == 0xFF)
 +          DECODE_EMACS_MULE_20_RULEBASE_COMPOSITION (c);
 +        else
 +          goto invalid_code;
 +      }
 +      else if (c < 0xA0 && emacs_mule_bytes[c] > 1)
 +      {
 +        int nbytes, nchars;
 +        int id;
 +
 +        src = src_base;
 +        consumed_chars = consumed_chars_base;
 +        c = emacs_mule_char (coding, src, &nbytes, &nchars, &id);
 +        if (c < 0)
 +          {
 +            if (c == -2)
 +              break;
 +            goto invalid_code;
 +          }
 +        if (last_id != id)
 +          {
 +            if (last_id != charset_ascii)
 +              ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +            last_id = id;
 +            last_offset = char_offset;
 +          }
 +        *charbuf++ = c;
 +        src += nbytes;
 +        consumed_chars += nchars;
 +        char_offset++;
 +      }
 +      else
 +      goto invalid_code;
 +      continue;
 +
 +    invalid_code:
 +      src = src_base;
 +      consumed_chars = consumed_chars_base;
 +      ONE_MORE_BYTE (c);
 +      *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
 +      char_offset++;
 +      coding->errors++;
 +    }
  
 -  translation_table = Qnil;
 + no_more_source:
 +  if (last_id != charset_ascii)
 +    ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +  coding->consumed_char += consumed_chars_base;
 +  coding->consumed = src_base - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
 +}
 +
 +
 +#define EMACS_MULE_LEADING_CODES(id, codes)   \
 +  do {                                                \
 +    if (id < 0xA0)                            \
 +      codes[0] = id, codes[1] = 0;            \
 +    else if (id < 0xE0)                               \
 +      codes[0] = 0x9A, codes[1] = id;         \
 +    else if (id < 0xF0)                               \
 +      codes[0] = 0x9B, codes[1] = id;         \
 +    else if (id < 0xF5)                               \
 +      codes[0] = 0x9C, codes[1] = id;         \
 +    else                                      \
 +      codes[0] = 0x9D, codes[1] = id;         \
 +  } while (0);
 +
 +
 +static int
 +encode_coding_emacs_mule (coding)
 +     struct coding_system *coding;
 +{
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int safe_room = 8;
 +  int produced_chars = 0;
 +  Lisp_Object attrs, charset_list;
 +  int c;
 +  int preferred_charset_id = -1;
  
 -  /* Optimization for the case that there's no composition.  */
 -  if (!coding->cmp_data || coding->cmp_data->used == 0)
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  if (! EQ (charset_list, Vemacs_mule_charset_list))
      {
 -      encode_eol (coding, source, destination, src_bytes, dst_bytes);
 -      return;
 +      CODING_ATTR_CHARSET_LIST (attrs)
 +      = charset_list = Vemacs_mule_charset_list;
      }
  
 -  char_offset = coding->cmp_data->char_offset;
 -  data = coding->cmp_data->data + coding->cmp_data_start;
 -  while (1)
 +  while (charbuf < charbuf_end)
      {
 -      src_base = src;
 +      ASSURE_DESTINATION (safe_room);
 +      c = *charbuf++;
  
 -      /* If SRC starts a composition, encode the information about the
 -       composition in advance.  */
 -      if (coding->cmp_data_start < coding->cmp_data->used
 -        && char_offset + coding->consumed_char == data[1])
 +      if (c < 0)
        {
 -        ENCODE_COMPOSITION_EMACS_MULE (coding, data);
 -        char_offset = coding->cmp_data->char_offset;
 -        data = coding->cmp_data->data + coding->cmp_data_start;
 +        /* Handle an annotation.  */
 +        switch (*charbuf)
 +          {
 +          case CODING_ANNOTATE_COMPOSITION_MASK:
 +            /* Not yet implemented.  */
 +            break;
 +          case CODING_ANNOTATE_CHARSET_MASK:
 +            preferred_charset_id = charbuf[3];
 +            if (preferred_charset_id >= 0
 +                && NILP (Fmemq (make_number (preferred_charset_id),
 +                                charset_list)))
 +              preferred_charset_id = -1;
 +            break;
 +          default:
 +            abort ();
 +          }
 +        charbuf += -c - 1;
 +        continue;
        }
  
 -      ONE_MORE_CHAR (c);
 -      if (c == '\n' && (coding->eol_type == CODING_EOL_CRLF
 -                      || coding->eol_type == CODING_EOL_CR))
 +      if (ASCII_CHAR_P (c))
 +      EMIT_ONE_ASCII_BYTE (c);
 +      else if (CHAR_BYTE8_P (c))
        {
 -        if (coding->eol_type == CODING_EOL_CRLF)
 -          EMIT_TWO_BYTES ('\r', c);
 -        else
 -          EMIT_ONE_BYTE ('\r');
 +        c = CHAR_TO_BYTE8 (c);
 +        EMIT_ONE_BYTE (c);
        }
 -      else if (SINGLE_BYTE_CHAR_P (c))
 +      else
        {
 -        if (coding->flags && ! ASCII_BYTE_P (c))
 -          {
 -            /* As we are auto saving, retain the multibyte form for
 -               8-bit chars.  */
 -            unsigned char buf[MAX_MULTIBYTE_LENGTH];
 -            int bytes = CHAR_STRING (c, buf);
 +        struct charset *charset;
 +        unsigned code;
 +        int dimension;
 +        int emacs_mule_id;
 +        unsigned char leading_codes[2];
  
 -            if (bytes == 1)
 -              EMIT_ONE_BYTE (buf[0]);
 -            else
 -              EMIT_TWO_BYTES (buf[0], buf[1]);
 +        if (preferred_charset_id >= 0)
 +          {
 +            charset = CHARSET_FROM_ID (preferred_charset_id);
 +            if (! CHAR_CHARSET_P (c, charset))
 +              charset = char_charset (c, charset_list, NULL);
            }
          else
 -          EMIT_ONE_BYTE (c);
 +          charset = char_charset (c, charset_list, &code);
 +        if (! charset)
 +          {
 +            c = coding->default_char;
 +            if (ASCII_CHAR_P (c))
 +              {
 +                EMIT_ONE_ASCII_BYTE (c);
 +                continue;
 +              }
 +            charset = char_charset (c, charset_list, &code);
 +          }
 +        dimension = CHARSET_DIMENSION (charset);
 +        emacs_mule_id = CHARSET_EMACS_MULE_ID (charset);
 +        EMACS_MULE_LEADING_CODES (emacs_mule_id, leading_codes);
 +        EMIT_ONE_BYTE (leading_codes[0]);
 +        if (leading_codes[1])
 +          EMIT_ONE_BYTE (leading_codes[1]);
 +        if (dimension == 1)
 +          EMIT_ONE_BYTE (code | 0x80);
 +        else
 +          {
 +            code |= 0x8080;
 +            EMIT_ONE_BYTE (code >> 8);
 +            EMIT_ONE_BYTE (code & 0xFF);
 +          }
        }
 -      else
 -      EMIT_BYTES (src_base, src);
 -      coding->consumed_char++;
      }
 - label_end_of_loop:
 -  coding->consumed = src_base - source;
 -  coding->produced = coding->produced_char = dst - destination;
 -  return;
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
 +  return 0;
  }
  
  \f
 -/*** 3. ISO2022 handlers ***/
 +/*** 7. ISO2022 handlers ***/
  
  /* The following note describes the coding system ISO2022 briefly.
     Since the intention of this note is to help understand the
     7-bit environment, non-locking-shift, and non-single-shift.
  
     Note (**): If <F> is '@', 'A', or 'B', the intermediate character
 -   '(' can be omitted.  We refer to this as "short-form" hereafter.
 +   '(' must be omitted.  We refer to this as "short-form" hereafter.
  
     Now you may notice that there are a lot of ways of encoding the
     same multilingual text in ISO2022.  Actually, there exist many
    Since these are not standard escape sequences of any ISO standard,
    the use of them with these meanings is restricted to Emacs only.
  
 -  (*) This form is used only in Emacs 20.5 and older versions,
 -  but the newer versions can safely decode it.
 +  (*) This form is used only in Emacs 20.7 and older versions,
 +  but newer versions can safely decode it.
    (**) This form is used only in Emacs 21.1 and newer versions,
 -  and the older versions can't decode it.
 +  and older versions can't decode it.
  
    Here's a list of example usages of these composition escape
    sequences (categorized by `enum composition_method').
  
  enum iso_code_class_type iso_code_class[256];
  
 -#define CHARSET_OK(idx, charset, c)                                   \
 -  (coding_system_table[idx]                                           \
 -   && (charset == CHARSET_ASCII                                               \
 -       || (safe_chars = coding_safe_chars (coding_system_table[idx]->symbol), \
 -         CODING_SAFE_CHAR_P (safe_chars, c)))                         \
 -   && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding_system_table[idx],       \
 -                                            charset)                  \
 -       != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION))
 +#define SAFE_CHARSET_P(coding, id)    \
 +  ((id) <= (coding)->max_charset_id   \
 +   && (coding)->safe_charsets[id] >= 0)
 +
 +
 +#define SHIFT_OUT_OK(category)        \
 +  (CODING_ISO_INITIAL (&coding_categories[category], 1) >= 0)
 +
 +static void
 +setup_iso_safe_charsets (attrs)
 +     Lisp_Object attrs;
 +{
 +  Lisp_Object charset_list, safe_charsets;
 +  Lisp_Object request;
 +  Lisp_Object reg_usage;
 +  Lisp_Object tail;
 +  int reg94, reg96;
 +  int flags = XINT (AREF (attrs, coding_attr_iso_flags));
 +  int max_charset_id;
 +
 +  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
 +  if ((flags & CODING_ISO_FLAG_FULL_SUPPORT)
 +      && ! EQ (charset_list, Viso_2022_charset_list))
 +    {
 +      CODING_ATTR_CHARSET_LIST (attrs)
 +      = charset_list = Viso_2022_charset_list;
 +      ASET (attrs, coding_attr_safe_charsets, Qnil);
 +    }
 +
 +  if (STRINGP (AREF (attrs, coding_attr_safe_charsets)))
 +    return;
 +
 +  max_charset_id = 0;
 +  for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
 +    {
 +      int id = XINT (XCAR (tail));
 +      if (max_charset_id < id)
 +      max_charset_id = id;
 +    }
 +
 +  safe_charsets = Fmake_string (make_number (max_charset_id + 1),
 +                              make_number (255));
 +  request = AREF (attrs, coding_attr_iso_request);
 +  reg_usage = AREF (attrs, coding_attr_iso_usage);
 +  reg94 = XINT (XCAR (reg_usage));
 +  reg96 = XINT (XCDR (reg_usage));
 +
 +  for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
 +    {
 +      Lisp_Object id;
 +      Lisp_Object reg;
 +      struct charset *charset;
  
 -#define SHIFT_OUT_OK(idx) \
 -  (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding_system_table[idx], 1) >= 0)
 +      id = XCAR (tail);
 +      charset = CHARSET_FROM_ID (XINT (id));
 +      reg = Fcdr (Fassq (id, request));
 +      if (! NILP (reg))
 +      SSET (safe_charsets, XINT (id), XINT (reg));
 +      else if (charset->iso_chars_96)
 +      {
 +        if (reg96 < 4)
 +          SSET (safe_charsets, XINT (id), reg96);
 +      }
 +      else
 +      {
 +        if (reg94 < 4)
 +          SSET (safe_charsets, XINT (id), reg94);
 +      }
 +    }
 +  ASET (attrs, coding_attr_safe_charsets, safe_charsets);
 +}
  
 -#define COMPOSITION_OK(idx)   \
 -  (coding_system_table[idx]->composing != COMPOSITION_DISABLED)
  
  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 -   Check if a text is encoded in ISO2022.  If it is, return an
 -   integer in which appropriate flag bits any of:
 -      CODING_CATEGORY_MASK_ISO_7
 -      CODING_CATEGORY_MASK_ISO_7_TIGHT
 -      CODING_CATEGORY_MASK_ISO_8_1
 -      CODING_CATEGORY_MASK_ISO_8_2
 -      CODING_CATEGORY_MASK_ISO_7_ELSE
 -      CODING_CATEGORY_MASK_ISO_8_ELSE
 -   are set.  If a code which should never appear in ISO2022 is found,
 -   returns 0.  */
 +   Check if a text is encoded in one of ISO-2022 based codig systems.
 +   If it is, return 1, else return 0.  */
  
  static int
 -detect_coding_iso2022 (src, src_end, multibytep)
 -     unsigned char *src, *src_end;
 -     int multibytep;
 +detect_coding_iso_2022 (coding, detect_info)
 +     struct coding_system *coding;
 +     struct coding_detection_info *detect_info;
  {
 -  int mask = CODING_CATEGORY_MASK_ISO;
 -  int mask_found = 0;
 -  int reg[4], shift_out = 0, single_shifting = 0;
 -  int c, c1, charset;
 -  /* Dummy for ONE_MORE_BYTE.  */
 -  struct coding_system dummy_coding;
 -  struct coding_system *coding = &dummy_coding;
 -  Lisp_Object safe_chars;
 -
 -  reg[0] = CHARSET_ASCII, reg[1] = reg[2] = reg[3] = -1;
 -  while (mask)
 -    {
 -      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, mask & mask_found);
 -    retry:
 +  const unsigned char *src = coding->source, *src_base = src;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int single_shifting = 0;
 +  int id;
 +  int c, c1;
 +  int consumed_chars = 0;
 +  int i;
 +  int rejected = 0;
 +  int found = 0;
 +
 +  detect_info->checked |= CATEGORY_MASK_ISO;
 +
 +  for (i = coding_category_iso_7; i <= coding_category_iso_8_else; i++)
 +    {
 +      struct coding_system *this = &(coding_categories[i]);
 +      Lisp_Object attrs, val;
 +
 +      attrs = CODING_ID_ATTRS (this->id);
 +      if (CODING_ISO_FLAGS (this) & CODING_ISO_FLAG_FULL_SUPPORT
 +        && ! EQ (CODING_ATTR_SAFE_CHARSETS (attrs), Viso_2022_charset_list))
 +      setup_iso_safe_charsets (attrs);
 +      val = CODING_ATTR_SAFE_CHARSETS (attrs);
 +      this->max_charset_id = SCHARS (val) - 1;
 +      this->safe_charsets = (char *) SDATA (val);
 +    }
 +
 +  /* A coding system of this category is always ASCII compatible.  */
 +  src += coding->head_ascii;
 +
 +  while (rejected != CATEGORY_MASK_ISO)
 +    {
 +      src_base = src;
 +      ONE_MORE_BYTE (c);
        switch (c)
        {
        case ISO_CODE_ESC:
          if (inhibit_iso_escape_detection)
            break;
          single_shifting = 0;
 -        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, mask & mask_found);
 +        ONE_MORE_BYTE (c);
          if (c >= '(' && c <= '/')
            {
              /* Designation sequence for a charset of dimension 1.  */
 -            ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep, mask & mask_found);
 +            ONE_MORE_BYTE (c1);
              if (c1 < ' ' || c1 >= 0x80
 -                || (charset = iso_charset_table[0][c >= ','][c1]) < 0)
 +                || (id = iso_charset_table[0][c >= ','][c1]) < 0)
                /* Invalid designation sequence.  Just ignore.  */
                break;
 -            reg[(c - '(') % 4] = charset;
            }
          else if (c == '$')
            {
              /* Designation sequence for a charset of dimension 2.  */
 -            ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, mask & mask_found);
 +            ONE_MORE_BYTE (c);
              if (c >= '@' && c <= 'B')
                /* Designation for JISX0208.1978, GB2312, or JISX0208.  */
 -              reg[0] = charset = iso_charset_table[1][0][c];
 +              id = iso_charset_table[1][0][c];
              else if (c >= '(' && c <= '/')
                {
 -                ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep,
 -                                               mask & mask_found);
 +                ONE_MORE_BYTE (c1);
                  if (c1 < ' ' || c1 >= 0x80
 -                    || (charset = iso_charset_table[1][c >= ','][c1]) < 0)
 +                    || (id = iso_charset_table[1][c >= ','][c1]) < 0)
                    /* Invalid designation sequence.  Just ignore.  */
                    break;
 -                reg[(c - '(') % 4] = charset;
                }
              else
 -              /* Invalid designation sequence.  Just ignore.  */
 +              /* Invalid designation sequence.  Just ignore it.  */
                break;
            }
          else if (c == 'N' || c == 'O')
            {
              /* ESC <Fe> for SS2 or SS3.  */
 -            mask &= CODING_CATEGORY_MASK_ISO_7_ELSE;
 +            single_shifting = 1;
 +            rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_8BIT;
              break;
            }
          else if (c >= '0' && c <= '4')
            {
              /* ESC <Fp> for start/end composition.  */
 -            if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7))
 -              mask_found |= CODING_CATEGORY_MASK_ISO_7;
 -            else
 -              mask &= ~CODING_CATEGORY_MASK_ISO_7;
 -            if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7_TIGHT))
 -              mask_found |= CODING_CATEGORY_MASK_ISO_7_TIGHT;
 -            else
 -              mask &= ~CODING_CATEGORY_MASK_ISO_7_TIGHT;
 -            if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_1))
 -              mask_found |= CODING_CATEGORY_MASK_ISO_8_1;
 -            else
 -              mask &= ~CODING_CATEGORY_MASK_ISO_8_1;
 -            if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_2))
 -              mask_found |= CODING_CATEGORY_MASK_ISO_8_2;
 -            else
 -              mask &= ~CODING_CATEGORY_MASK_ISO_8_2;
 -            if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_7_ELSE))
 -              mask_found |= CODING_CATEGORY_MASK_ISO_7_ELSE;
 -            else
 -              mask &= ~CODING_CATEGORY_MASK_ISO_7_ELSE;
 -            if (COMPOSITION_OK (CODING_CATEGORY_IDX_ISO_8_ELSE))
 -              mask_found |= CODING_CATEGORY_MASK_ISO_8_ELSE;
 -            else
 -              mask &= ~CODING_CATEGORY_MASK_ISO_8_ELSE;
 +            found |= CATEGORY_MASK_ISO;
              break;
            }
          else
 -          /* Invalid escape sequence.  Just ignore.  */
 -          break;
 +          {
 +            /* Invalid escape sequence.  Just ignore it.  */
 +            break;
 +          }
  
          /* We found a valid designation sequence for CHARSET.  */
 -        mask &= ~CODING_CATEGORY_MASK_ISO_8BIT;
 -        c = MAKE_CHAR (charset, 0, 0);
 -        if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7, charset, c))
 -          mask_found |= CODING_CATEGORY_MASK_ISO_7;
 +        rejected |= CATEGORY_MASK_ISO_8BIT;
 +        if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7],
 +                            id))
 +          found |= CATEGORY_MASK_ISO_7;
          else
 -          mask &= ~CODING_CATEGORY_MASK_ISO_7;
 -        if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7_TIGHT, charset, c))
 -          mask_found |= CODING_CATEGORY_MASK_ISO_7_TIGHT;
 +          rejected |= CATEGORY_MASK_ISO_7;
 +        if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_tight],
 +                            id))
 +          found |= CATEGORY_MASK_ISO_7_TIGHT;
          else
 -          mask &= ~CODING_CATEGORY_MASK_ISO_7_TIGHT;
 -        if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_7_ELSE, charset, c))
 -          mask_found |= CODING_CATEGORY_MASK_ISO_7_ELSE;
 +          rejected |= CATEGORY_MASK_ISO_7_TIGHT;
 +        if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_else],
 +                            id))
 +          found |= CATEGORY_MASK_ISO_7_ELSE;
          else
 -          mask &= ~CODING_CATEGORY_MASK_ISO_7_ELSE;
 -        if (CHARSET_OK (CODING_CATEGORY_IDX_ISO_8_ELSE, charset, c))
 -          mask_found |= CODING_CATEGORY_MASK_ISO_8_ELSE;
 +          rejected |= CATEGORY_MASK_ISO_7_ELSE;
 +        if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_8_else],
 +                            id))
 +          found |= CATEGORY_MASK_ISO_8_ELSE;
          else
 -          mask &= ~CODING_CATEGORY_MASK_ISO_8_ELSE;
 +          rejected |= CATEGORY_MASK_ISO_8_ELSE;
          break;
  
        case ISO_CODE_SO:
 -        if (inhibit_iso_escape_detection)
 -          break;
 -        single_shifting = 0;
 -        if (shift_out == 0
 -            && (reg[1] >= 0
 -                || SHIFT_OUT_OK (CODING_CATEGORY_IDX_ISO_7_ELSE)
 -                || SHIFT_OUT_OK (CODING_CATEGORY_IDX_ISO_8_ELSE)))
 -          {
 -            /* Locking shift out.  */
 -            mask &= ~CODING_CATEGORY_MASK_ISO_7BIT;
 -            mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT;
 -          }
 -        break;
 -
        case ISO_CODE_SI:
 +        /* Locking shift out/in.  */
          if (inhibit_iso_escape_detection)
            break;
          single_shifting = 0;
 -        if (shift_out == 1)
 -          {
 -            /* Locking shift in.  */
 -            mask &= ~CODING_CATEGORY_MASK_ISO_7BIT;
 -            mask_found |= CODING_CATEGORY_MASK_ISO_SHIFT;
 -          }
 +        rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_8BIT;
 +        found |= CATEGORY_MASK_ISO_ELSE;
          break;
  
        case ISO_CODE_CSI:
 +        /* Control sequence introducer.  */
          single_shifting = 0;
 +        rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_7_ELSE;
 +        found |= CATEGORY_MASK_ISO_8_ELSE;
 +        goto check_extra_latin;
 +
        case ISO_CODE_SS2:
        case ISO_CODE_SS3:
 -        {
 -          int newmask = CODING_CATEGORY_MASK_ISO_8_ELSE;
 -
 -          if (inhibit_iso_escape_detection)
 -            break;
 -          if (c != ISO_CODE_CSI)
 -            {
 -              if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags
 -                  & CODING_FLAG_ISO_SINGLE_SHIFT)
 -                newmask |= CODING_CATEGORY_MASK_ISO_8_1;
 -              if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags
 -                  & CODING_FLAG_ISO_SINGLE_SHIFT)
 -                newmask |= CODING_CATEGORY_MASK_ISO_8_2;
 -              single_shifting = 1;
 -            }
 -          if (VECTORP (Vlatin_extra_code_table)
 -              && !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
 -            {
 -              if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags
 -                  & CODING_FLAG_ISO_LATIN_EXTRA)
 -                newmask |= CODING_CATEGORY_MASK_ISO_8_1;
 -              if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags
 -                  & CODING_FLAG_ISO_LATIN_EXTRA)
 -                newmask |= CODING_CATEGORY_MASK_ISO_8_2;
 -            }
 -          mask &= newmask;
 -          mask_found |= newmask;
 -        }
 -        break;
 +        /* Single shift.   */
 +        if (inhibit_iso_escape_detection)
 +          break;
 +        single_shifting = 0;
 +        rejected |= CATEGORY_MASK_ISO_7BIT;
 +        if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
 +            & CODING_ISO_FLAG_SINGLE_SHIFT)
 +          found |= CATEGORY_MASK_ISO_8_1, single_shifting = 1;
 +        if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2])
 +            & CODING_ISO_FLAG_SINGLE_SHIFT)
 +          found |= CATEGORY_MASK_ISO_8_2, single_shifting = 1;
 +        if (single_shifting)
 +          break;
 +        goto check_extra_latin;
  
        default:
 +        if (c < 0)
 +          continue;
          if (c < 0x80)
            {
              single_shifting = 0;
              break;
            }
 -        else if (c < 0xA0)
 -          {
 -            single_shifting = 0;
 -            if (VECTORP (Vlatin_extra_code_table)
 -                && !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
 -              {
 -                int newmask = 0;
 -
 -                if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_1]->flags
 -                    & CODING_FLAG_ISO_LATIN_EXTRA)
 -                  newmask |= CODING_CATEGORY_MASK_ISO_8_1;
 -                if (coding_system_table[CODING_CATEGORY_IDX_ISO_8_2]->flags
 -                    & CODING_FLAG_ISO_LATIN_EXTRA)
 -                  newmask |= CODING_CATEGORY_MASK_ISO_8_2;
 -                mask &= newmask;
 -                mask_found |= newmask;
 -              }
 -            else
 -              return 0;
 -          }
 -        else
 +        if (c >= 0xA0)
            {
 -            mask &= ~(CODING_CATEGORY_MASK_ISO_7BIT
 -                      | CODING_CATEGORY_MASK_ISO_7_ELSE);
 -            mask_found |= CODING_CATEGORY_MASK_ISO_8_1;
 +            rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_7_ELSE;
 +            found |= CATEGORY_MASK_ISO_8_1;
              /* Check the length of succeeding codes of the range
 -                 0xA0..0FF.  If the byte length is odd, we exclude
 -                 CODING_CATEGORY_MASK_ISO_8_2.  We can check this only
 -                 when we are not single shifting.  */
 -            if (!single_shifting
 -                && mask & CODING_CATEGORY_MASK_ISO_8_2)
 +                 0xA0..0FF.  If the byte length is even, we include
 +                 CATEGORY_MASK_ISO_8_2 in `found'.  We can check this
 +                 only when we are not single shifting.  */
 +            if (! single_shifting
 +                && ! (rejected & CATEGORY_MASK_ISO_8_2))
                {
                  int i = 1;
 -
 -                c = -1;
                  while (src < src_end)
                    {
 -                    ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep,
 -                                                   mask & mask_found);
 +                    ONE_MORE_BYTE (c);
                      if (c < 0xA0)
                        break;
                      i++;
                    }
  
                  if (i & 1 && src < src_end)
 -                  mask &= ~CODING_CATEGORY_MASK_ISO_8_2;
 +                  rejected |= CATEGORY_MASK_ISO_8_2;
                  else
 -                  mask_found |= CODING_CATEGORY_MASK_ISO_8_2;
 -                if (c >= 0)
 -                  /* This means that we have read one extra byte.  */
 -                  goto retry;
 +                  found |= CATEGORY_MASK_ISO_8_2;
                }
 +            break;
            }
 -        break;
 +      check_extra_latin:
 +        single_shifting = 0;
 +        if (! VECTORP (Vlatin_extra_code_table)
 +            || NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
 +          {
 +            rejected = CATEGORY_MASK_ISO;
 +            break;
 +          }
 +        if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
 +            & CODING_ISO_FLAG_LATIN_EXTRA)
 +          found |= CATEGORY_MASK_ISO_8_1;
 +        else
 +          rejected |= CATEGORY_MASK_ISO_8_1;
 +        rejected |= CATEGORY_MASK_ISO_8_2;
        }
      }
 -  return (mask & mask_found);
 -}
 +  detect_info->rejected |= CATEGORY_MASK_ISO;
 +  return 0;
  
 -/* Decode a character of which charset is CHARSET, the 1st position
 -   code is C1, the 2nd position code is C2, and return the decoded
 -   character code.  If the variable `translation_table' is non-nil,
 -   returned the translated code.  */
 + no_more_source:
 +  detect_info->rejected |= rejected;
 +  detect_info->found |= (found & ~rejected);
 +  return 1;
 +}
  
 -#define DECODE_ISO_CHARACTER(charset, c1, c2) \
 -  (NILP (translation_table)                   \
 -   ? MAKE_CHAR (charset, c1, c2)              \
 -   : translate_char (translation_table, -1, charset, c1, c2))
  
 -/* Set designation state into CODING.  */
 -#define DECODE_DESIGNATION(reg, dimension, chars, final_char)            \
 -  do {                                                                           \
 -    int charset, c;                                                      \
 -                                                                         \
 -    if (final_char < '0' || final_char >= 128)                                   \
 -      goto label_invalid_code;                                                   \
 -    charset = ISO_CHARSET_TABLE (make_number (dimension),                \
 -                               make_number (chars),                      \
 -                               make_number (final_char));                \
 -    c = MAKE_CHAR (charset, 0, 0);                                       \
 -    if (charset >= 0                                                     \
 -      && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) == reg \
 -          || CODING_SAFE_CHAR_P (safe_chars, c)))                        \
 -      {                                                                          \
 -      if (coding->spec.iso2022.last_invalid_designation_register == 0    \
 -          && reg == 0                                                    \
 -          && charset == CHARSET_ASCII)                                   \
 -        {                                                                \
 -          /* We should insert this designation sequence as is so         \
 -               that it is surely written back to a file.  */             \
 -          coding->spec.iso2022.last_invalid_designation_register = -1;   \
 -          goto label_invalid_code;                                       \
 -        }                                                                \
 -      coding->spec.iso2022.last_invalid_designation_register = -1;       \
 -        if ((coding->mode & CODING_MODE_DIRECTION)                       \
 -          && CHARSET_REVERSE_CHARSET (charset) >= 0)                     \
 -          charset = CHARSET_REVERSE_CHARSET (charset);                           \
 -        CODING_SPEC_ISO_DESIGNATION (coding, reg) = charset;             \
 -      }                                                                          \
 -    else                                                                 \
 -      {                                                                          \
 -      coding->spec.iso2022.last_invalid_designation_register = reg;      \
 -      goto label_invalid_code;                                           \
 -      }                                                                          \
 +/* Set designation state into CODING.  Set CHARS_96 to -1 if the
 +   escape sequence should be kept.  */
 +#define DECODE_DESIGNATION(reg, dim, chars_96, final)                 \
 +  do {                                                                        \
 +    int id, prev;                                                     \
 +                                                                      \
 +    if (final < '0' || final >= 128                                   \
 +      || ((id = ISO_CHARSET_TABLE (dim, chars_96, final)) < 0)        \
 +      || !SAFE_CHARSET_P (coding, id))                                \
 +      {                                                                       \
 +      CODING_ISO_DESIGNATION (coding, reg) = -2;                      \
 +      chars_96 = -1;                                                  \
 +      break;                                                          \
 +      }                                                                       \
 +    prev = CODING_ISO_DESIGNATION (coding, reg);                      \
 +    if (id == charset_jisx0201_roman)                                 \
 +      {                                                                       \
 +      if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_ROMAN)      \
 +        id = charset_ascii;                                           \
 +      }                                                                       \
 +    else if (id == charset_jisx0208_1978)                             \
 +      {                                                                       \
 +      if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_OLDJIS)     \
 +        id = charset_jisx0208;                                        \
 +      }                                                                       \
 +    CODING_ISO_DESIGNATION (coding, reg) = id;                                \
 +    /* If there was an invalid designation to REG previously, and this        \
 +       designation is ASCII to REG, we should keep this designation   \
 +       sequence.  */                                                  \
 +    if (prev == -2 && id == charset_ascii)                            \
 +      chars_96 = -1;                                                  \
    } while (0)
  
 -/* Allocate a memory block for storing information about compositions.
 -   The block is chained to the already allocated blocks.  */
  
 -void
 -coding_allocate_composition_data (coding, char_offset)
 -     struct coding_system *coding;
 -     int char_offset;
 -{
 -  struct composition_data *cmp_data
 -    = (struct composition_data *) xmalloc (sizeof *cmp_data);
 -
 -  cmp_data->char_offset = char_offset;
 -  cmp_data->used = 0;
 -  cmp_data->prev = coding->cmp_data;
 -  cmp_data->next = NULL;
 -  if (coding->cmp_data)
 -    coding->cmp_data->next = cmp_data;
 -  coding->cmp_data = cmp_data;
 -  coding->cmp_data_start = 0;
 -  coding->composing = COMPOSITION_NO;
 -}
 +#define MAYBE_FINISH_COMPOSITION()                            \
 +  do {                                                                \
 +    int i;                                                    \
 +    if (composition_state == COMPOSING_NO)                    \
 +      break;                                                  \
 +    /* It is assured that we have enough room for producing   \
 +       characters stored in the table `components'.  */               \
 +    if (charbuf + component_idx > charbuf_end)                        \
 +      goto no_more_source;                                    \
 +    composition_state = COMPOSING_NO;                         \
 +    if (method == COMPOSITION_RELATIVE                                \
 +      || method == COMPOSITION_WITH_ALTCHARS)                 \
 +      {                                                               \
 +      for (i = 0; i < component_idx; i++)                     \
 +        *charbuf++ = components[i];                           \
 +      char_offset += component_idx;                           \
 +      }                                                               \
 +    else                                                      \
 +      {                                                               \
 +      for (i = 0; i < component_idx; i += 2)                  \
 +        *charbuf++ = components[i];                           \
 +      char_offset += (component_idx / 2) + 1;                 \
 +      }                                                               \
 +  } while (0)
 +
  
  /* Handle composition start sequence ESC 0, ESC 2, ESC 3, or ESC 4.
     ESC 0 : relative composition : ESC 0 CHAR ... ESC 1
     ESC 2 : rulebase composition : ESC 2 CHAR RULE CHAR RULE ... CHAR ESC 1
 -   ESC 3 : altchar composition :  ESC 3 ALT ... ESC 0 CHAR ... ESC 1
 -   ESC 4 : alt&rule composition : ESC 4 ALT RULE .. ALT ESC 0 CHAR ... ESC 1
 +   ESC 3 : altchar composition :  ESC 3 CHAR ... ESC 0 CHAR ... ESC 1
 +   ESC 4 : alt&rule composition : ESC 4 CHAR RULE ... CHAR ESC 0 CHAR ... ESC 1
    */
  
 -#define DECODE_COMPOSITION_START(c1)                                     \
 -  do {                                                                           \
 -    if (coding->composing == COMPOSITION_DISABLED)                       \
 -      {                                                                          \
 -              *dst++ = ISO_CODE_ESC;                                             \
 -      *dst++ = c1 & 0x7f;                                                \
 -      coding->produced_char += 2;                                        \
 -      }                                                                          \
 -    else if (!COMPOSING_P (coding))                                      \
 -      {                                                                          \
 -      /* This is surely the start of a composition.  We must be sure     \
 -           that coding->cmp_data has enough space to store the                   \
 -           information about the composition.  If not, terminate the     \
 -           current decoding loop, allocate one more memory block for     \
 -           coding->cmp_data in the caller, then start the decoding       \
 -           loop again.  We can't allocate memory here directly because           \
 -           it may cause buffer/string relocation.  */                    \
 -      if (!coding->cmp_data                                              \
 -          || (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH \
 -              >= COMPOSITION_DATA_SIZE))                                 \
 -        {                                                                \
 -          coding->result = CODING_FINISH_INSUFFICIENT_CMP;               \
 -          goto label_end_of_loop;                                        \
 -        }                                                                \
 -      coding->composing = (c1 == '0' ? COMPOSITION_RELATIVE              \
 -                           : c1 == '2' ? COMPOSITION_WITH_RULE           \
 -                           : c1 == '3' ? COMPOSITION_WITH_ALTCHARS       \
 -                           : COMPOSITION_WITH_RULE_ALTCHARS);            \
 -      CODING_ADD_COMPOSITION_START (coding, coding->produced_char,       \
 -                                    coding->composing);                  \
 -      coding->composition_rule_follows = 0;                              \
 -      }                                                                          \
 -    else                                                                 \
 -      {                                                                          \
 -      /* We are already handling a composition.  If the method is        \
 -           the following two, the codes following the current escape     \
 -           sequence are actual characters stored in a buffer.  */        \
 -      if (coding->composing == COMPOSITION_WITH_ALTCHARS                 \
 -          || coding->composing == COMPOSITION_WITH_RULE_ALTCHARS)        \
 -        {                                                                \
 -          coding->composing = COMPOSITION_RELATIVE;                      \
 -          coding->composition_rule_follows = 0;                          \
 -        }                                                                \
 -      }                                                                          \
 +#define DECODE_COMPOSITION_START(c1)                                  \
 +  do {                                                                        \
 +    if (c1 == '0'                                                     \
 +      && composition_state == COMPOSING_COMPONENT_RULE)               \
 +      {                                                                       \
 +      component_len = component_idx;                                  \
 +      composition_state = COMPOSING_CHAR;                             \
 +      }                                                                       \
 +    else                                                              \
 +      {                                                                       \
 +      const unsigned char *p;                                         \
 +                                                                      \
 +      MAYBE_FINISH_COMPOSITION ();                                    \
 +      if (charbuf + MAX_COMPOSITION_COMPONENTS > charbuf_end)         \
 +        goto no_more_source;                                          \
 +      for (p = src; p < src_end - 1; p++)                             \
 +        if (*p == ISO_CODE_ESC && p[1] == '1')                        \
 +          break;                                                      \
 +      if (p == src_end - 1)                                           \
 +        {                                                             \
 +          /* The current composition doesn't end in the current       \
 +             source.  */                                              \
 +          record_conversion_result                                    \
 +            (coding, CODING_RESULT_INSUFFICIENT_SRC);                 \
 +          goto no_more_source;                                        \
 +        }                                                             \
 +                                                                      \
 +      /* This is surely the start of a composition.  */               \
 +      method = (c1 == '0' ? COMPOSITION_RELATIVE                      \
 +                : c1 == '2' ? COMPOSITION_WITH_RULE                   \
 +                : c1 == '3' ? COMPOSITION_WITH_ALTCHARS               \
 +                : COMPOSITION_WITH_RULE_ALTCHARS);                    \
 +      composition_state = (c1 <= '2' ? COMPOSING_CHAR                 \
 +                           : COMPOSING_COMPONENT_CHAR);               \
 +      component_idx = component_len = 0;                              \
 +      }                                                                       \
    } while (0)
  
 -/* Handle composition end sequence ESC 1.  */
  
 -#define DECODE_COMPOSITION_END(c1)                                    \
 +/* Handle compositoin end sequence ESC 1.  */
 +
 +#define DECODE_COMPOSITION_END()                                      \
    do {                                                                        \
 -    if (! COMPOSING_P (coding))                                               \
 +    int nchars = (component_len > 0 ? component_idx - component_len   \
 +                : method == COMPOSITION_RELATIVE ? component_idx      \
 +                : (component_idx + 1) / 2);                           \
 +    int i;                                                            \
 +    int *saved_charbuf = charbuf;                                     \
 +                                                                      \
 +    ADD_COMPOSITION_DATA (charbuf, nchars, method);                   \
 +    if (method != COMPOSITION_RELATIVE)                                       \
        {                                                                       \
 -      *dst++ = ISO_CODE_ESC;                                          \
 -      *dst++ = c1;                                                    \
 -      coding->produced_char += 2;                                     \
 +      if (component_len == 0)                                         \
 +        for (i = 0; i < component_idx; i++)                           \
 +          *charbuf++ = components[i];                                 \
 +      else                                                            \
 +        for (i = 0; i < component_len; i++)                           \
 +          *charbuf++ = components[i];                                 \
 +      *saved_charbuf = saved_charbuf - charbuf;                       \
        }                                                                       \
 +    if (method == COMPOSITION_WITH_RULE)                              \
 +      for (i = 0; i < component_idx; i += 2, char_offset++)           \
 +      *charbuf++ = components[i];                                     \
      else                                                              \
 -      {                                                                       \
 -      CODING_ADD_COMPOSITION_END (coding, coding->produced_char);     \
 -      coding->composing = COMPOSITION_NO;                             \
 -      }                                                                       \
 +      for (i = component_len; i < component_idx; i++, char_offset++)  \
 +      *charbuf++ = components[i];                                     \
 +    coding->annotated = 1;                                            \
 +    composition_state = COMPOSING_NO;                                 \
    } while (0)
  
 +
  /* Decode a composition rule from the byte C1 (and maybe one more byte
     from SRC) and store one encoded composition rule in
     coding->cmp_data.  */
  
  #define DECODE_COMPOSITION_RULE(c1)                                   \
    do {                                                                        \
 -    int rule = 0;                                                     \
      (c1) -= 32;                                                               \
      if (c1 < 81)              /* old format (before ver.21) */        \
        {                                                                       \
        int nref = (c1) % 9;                                            \
        if (gref == 4) gref = 10;                                       \
        if (nref == 4) nref = 10;                                       \
 -      rule = COMPOSITION_ENCODE_RULE (gref, nref);                    \
 +      c1 = COMPOSITION_ENCODE_RULE (gref, nref);                      \
        }                                                                       \
      else if (c1 < 93)         /* new format (after ver.21) */         \
        {                                                                       \
        ONE_MORE_BYTE (c2);                                             \
 -      rule = COMPOSITION_ENCODE_RULE (c1 - 81, c2 - 32);              \
 +      c1 = COMPOSITION_ENCODE_RULE (c1 - 81, c2 - 32);                \
        }                                                                       \
 -    CODING_ADD_COMPOSITION_COMPONENT (coding, rule);                  \
 -    coding->composition_rule_follows = 0;                             \
 +    else                                                              \
 +      c1 = 0;                                                         \
    } while (0)
  
  
  /* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
  
  static void
 -decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
 +decode_coding_iso_2022 (coding)
       struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
  {
 -  const unsigned char *src = source;
 -  const unsigned char *src_end = source + src_bytes;
 -  unsigned char *dst = destination;
 -  unsigned char *dst_end = destination + dst_bytes;
 -  /* Charsets invoked to graphic plane 0 and 1 respectively.  */
 -  int charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
 -  int charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);
 -  /* SRC_BASE remembers the start position in source in each loop.
 -     The loop will be exited when there's not enough source code
 -     (within macro ONE_MORE_BYTE), or when there's not enough
 -     destination area to produce a character (within macro
 -     EMIT_CHAR).  */
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
    const unsigned char *src_base;
 -  int c, charset;
 -  Lisp_Object translation_table;
 -  Lisp_Object safe_chars;
 -
 -  safe_chars = coding_safe_chars (coding->symbol);
 -
 -  if (NILP (Venable_character_translation))
 -    translation_table = Qnil;
 -  else
 -    {
 -      translation_table = coding->translation_table_for_decode;
 -      if (NILP (translation_table))
 -      translation_table = Vstandard_translation_table_for_decode;
 -    }
 -
 -  coding->result = CODING_FINISH_NORMAL;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end
 +    = coding->charbuf + coding->charbuf_size - 4 - MAX_ANNOTATION_LENGTH;
 +  int consumed_chars = 0, consumed_chars_base;
 +  int multibytep = coding->src_multibyte;
 +  /* Charsets invoked to graphic plane 0 and 1 respectively.  */
 +  int charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
 +  int charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
 +  int charset_id_2, charset_id_3;
 +  struct charset *charset;
 +  int c;
 +  /* For handling composition sequence.  */
 +#define COMPOSING_NO                  0
 +#define COMPOSING_CHAR                        1
 +#define COMPOSING_RULE                        2
 +#define COMPOSING_COMPONENT_CHAR      3
 +#define COMPOSING_COMPONENT_RULE      4
 +
 +  int composition_state = COMPOSING_NO;
 +  enum composition_method method;
 +  int components[MAX_COMPOSITION_COMPONENTS * 2 + 1];
 +  int component_idx;
 +  int component_len;
 +  Lisp_Object attrs, charset_list;
 +  int char_offset = coding->produced_char;
 +  int last_offset = char_offset;
 +  int last_id = charset_ascii;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  setup_iso_safe_charsets (attrs);
  
    while (1)
      {
 -      int c1, c2 = 0;
 +      int c1, c2;
  
        src_base = src;
 +      consumed_chars_base = consumed_chars;
 +
 +      if (charbuf >= charbuf_end)
 +      break;
 +
        ONE_MORE_BYTE (c1);
 +      if (c1 < 0)
 +      goto invalid_code;
  
 -      /* We produce no character or one character.  */
 +      /* We produce at most one character.  */
        switch (iso_code_class [c1])
        {
        case ISO_0x20_or_0x7F:
 -        if (COMPOSING_P (coding) && coding->composition_rule_follows)
 -          {
 -            DECODE_COMPOSITION_RULE (c1);
 -            continue;
 -          }
 -        if (charset0 < 0 || CHARSET_CHARS (charset0) == 94)
 +        if (composition_state != COMPOSING_NO)
            {
 -            /* This is SPACE or DEL.  */
 -            charset = CHARSET_ASCII;
 -            break;
 +            if (composition_state == COMPOSING_RULE
 +                || composition_state == COMPOSING_COMPONENT_RULE)
 +              {
 +                DECODE_COMPOSITION_RULE (c1);
 +                components[component_idx++] = c1;
 +                composition_state--;
 +                continue;
 +              }
            }
 -        /* This is a graphic character, we fall down ...  */
 +        if (charset_id_0 < 0
 +            || ! CHARSET_ISO_CHARS_96 (CHARSET_FROM_ID (charset_id_0)))
 +          /* This is SPACE or DEL.  */
 +          charset = CHARSET_FROM_ID (charset_ascii);
 +        else
 +          charset = CHARSET_FROM_ID (charset_id_0);
 +        break;
  
        case ISO_graphic_plane_0:
 -        if (COMPOSING_P (coding) && coding->composition_rule_follows)
 +        if (composition_state != COMPOSING_NO)
            {
 -            DECODE_COMPOSITION_RULE (c1);
 -            continue;
 +            if (composition_state == COMPOSING_RULE
 +                || composition_state == COMPOSING_COMPONENT_RULE)
 +              {
 +                DECODE_COMPOSITION_RULE (c1);
 +                components[component_idx++] = c1;
 +                composition_state--;
 +                continue;
 +              }
            }
 -        charset = charset0;
 +        if (charset_id_0 < 0)
 +          charset = CHARSET_FROM_ID (charset_ascii);
 +        else
 +          charset = CHARSET_FROM_ID (charset_id_0);
          break;
  
        case ISO_0xA0_or_0xFF:
 -        if (charset1 < 0 || CHARSET_CHARS (charset1) == 94
 -            || coding->flags & CODING_FLAG_ISO_SEVEN_BITS)
 -          goto label_invalid_code;
 +        if (charset_id_1 < 0
 +            || ! CHARSET_ISO_CHARS_96 (CHARSET_FROM_ID (charset_id_1))
 +            || CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)
 +          goto invalid_code;
          /* This is a graphic character, we fall down ... */
  
        case ISO_graphic_plane_1:
 -        if (charset1 < 0)
 -          goto label_invalid_code;
 -        charset = charset1;
 +        if (charset_id_1 < 0)
 +          goto invalid_code;
 +        charset = CHARSET_FROM_ID (charset_id_1);
          break;
  
        case ISO_control_0:
 -        if (COMPOSING_P (coding))
 -          DECODE_COMPOSITION_END ('1');
 -
 -        /* All ISO2022 control characters in this class have the
 -             same representation in Emacs internal format.  */
 -        if (c1 == '\n'
 -            && (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
 -            && (coding->eol_type == CODING_EOL_CR
 -                || coding->eol_type == CODING_EOL_CRLF))
 -          {
 -            coding->result = CODING_FINISH_INCONSISTENT_EOL;
 -            goto label_end_of_loop;
 -          }
 -        charset = CHARSET_ASCII;
 +        MAYBE_FINISH_COMPOSITION ();
 +        charset = CHARSET_FROM_ID (charset_ascii);
          break;
  
        case ISO_control_1:
 -        if (COMPOSING_P (coding))
 -          DECODE_COMPOSITION_END ('1');
 -        goto label_invalid_code;
 -
 -      case ISO_carriage_return:
 -        if (COMPOSING_P (coding))
 -          DECODE_COMPOSITION_END ('1');
 -
 -        if (coding->eol_type == CODING_EOL_CR)
 -          c1 = '\n';
 -        else if (coding->eol_type == CODING_EOL_CRLF)
 -          {
 -            ONE_MORE_BYTE (c1);
 -            if (c1 != ISO_CODE_LF)
 -              {
 -                src--;
 -                c1 = '\r';
 -              }
 -          }
 -        charset = CHARSET_ASCII;
 -        break;
 +        MAYBE_FINISH_COMPOSITION ();
 +        goto invalid_code;
  
        case ISO_shift_out:
 -        if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT)
 -            || CODING_SPEC_ISO_DESIGNATION (coding, 1) < 0)
 -          goto label_invalid_code;
 -        CODING_SPEC_ISO_INVOCATION (coding, 0) = 1;
 -        charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
 +        if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT)
 +            || CODING_ISO_DESIGNATION (coding, 1) < 0)
 +          goto invalid_code;
 +        CODING_ISO_INVOCATION (coding, 0) = 1;
 +        charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
          continue;
  
        case ISO_shift_in:
 -        if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT))
 -          goto label_invalid_code;
 -        CODING_SPEC_ISO_INVOCATION (coding, 0) = 0;
 -        charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
 +        if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT))
 +          goto invalid_code;
 +        CODING_ISO_INVOCATION (coding, 0) = 0;
 +        charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
          continue;
  
        case ISO_single_shift_2_7:
        case ISO_single_shift_2:
 -        if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT))
 -          goto label_invalid_code;
 +        if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT))
 +          goto invalid_code;
          /* SS2 is handled as an escape sequence of ESC 'N' */
          c1 = 'N';
          goto label_escape_sequence;
  
        case ISO_single_shift_3:
 -        if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT))
 -          goto label_invalid_code;
 +        if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT))
 +          goto invalid_code;
          /* SS2 is handled as an escape sequence of ESC 'O' */
          c1 = 'O';
          goto label_escape_sequence;
        case ISO_escape:
          ONE_MORE_BYTE (c1);
        label_escape_sequence:
 -        /* Escape sequences handled by Emacs are invocation,
 +        /* Escape sequences handled here are invocation,
             designation, direction specification, and character
             composition specification.  */
          switch (c1)
            case '&':           /* revision of following character set */
              ONE_MORE_BYTE (c1);
              if (!(c1 >= '@' && c1 <= '~'))
 -              goto label_invalid_code;
 +              goto invalid_code;
              ONE_MORE_BYTE (c1);
              if (c1 != ISO_CODE_ESC)
 -              goto label_invalid_code;
 +              goto invalid_code;
              ONE_MORE_BYTE (c1);
              goto label_escape_sequence;
  
            case '$':           /* designation of 2-byte character set */
 -            if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION))
 -              goto label_invalid_code;
 -            ONE_MORE_BYTE (c1);
 -            if (c1 >= '@' && c1 <= 'B')
 -              {       /* designation of JISX0208.1978, GB2312.1980,
 +            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION))
 +              goto invalid_code;
 +            {
 +              int reg, chars96;
 +
 +              ONE_MORE_BYTE (c1);
 +              if (c1 >= '@' && c1 <= 'B')
 +                {     /* designation of JISX0208.1978, GB2312.1980,
                           or JISX0208.1980 */
 -                DECODE_DESIGNATION (0, 2, 94, c1);
 -              }
 -            else if (c1 >= 0x28 && c1 <= 0x2B)
 -              {       /* designation of DIMENSION2_CHARS94 character set */
 -                ONE_MORE_BYTE (c2);
 -                DECODE_DESIGNATION (c1 - 0x28, 2, 94, c2);
 -              }
 -            else if (c1 >= 0x2C && c1 <= 0x2F)
 -              {       /* designation of DIMENSION2_CHARS96 character set */
 -                ONE_MORE_BYTE (c2);
 -                DECODE_DESIGNATION (c1 - 0x2C, 2, 96, c2);
 -              }
 -            else
 -              goto label_invalid_code;
 -            /* We must update these variables now.  */
 -            charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
 -            charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);
 +                  reg = 0, chars96 = 0;
 +                }
 +              else if (c1 >= 0x28 && c1 <= 0x2B)
 +                { /* designation of DIMENSION2_CHARS94 character set */
 +                  reg = c1 - 0x28, chars96 = 0;
 +                  ONE_MORE_BYTE (c1);
 +                }
 +              else if (c1 >= 0x2C && c1 <= 0x2F)
 +                { /* designation of DIMENSION2_CHARS96 character set */
 +                  reg = c1 - 0x2C, chars96 = 1;
 +                  ONE_MORE_BYTE (c1);
 +                }
 +              else
 +                goto invalid_code;
 +              DECODE_DESIGNATION (reg, 2, chars96, c1);
 +              /* We must update these variables now.  */
 +              if (reg == 0)
 +                charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
 +              else if (reg == 1)
 +                charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
 +              if (chars96 < 0)
 +                goto invalid_code;
 +            }
              continue;
  
            case 'n':           /* invocation of locking-shift-2 */
 -            if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT)
 -                || CODING_SPEC_ISO_DESIGNATION (coding, 2) < 0)
 -              goto label_invalid_code;
 -            CODING_SPEC_ISO_INVOCATION (coding, 0) = 2;
 -            charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
 +            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT)
 +                || CODING_ISO_DESIGNATION (coding, 2) < 0)
 +              goto invalid_code;
 +            CODING_ISO_INVOCATION (coding, 0) = 2;
 +            charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
              continue;
  
            case 'o':           /* invocation of locking-shift-3 */
 -            if (! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT)
 -                || CODING_SPEC_ISO_DESIGNATION (coding, 3) < 0)
 -              goto label_invalid_code;
 -            CODING_SPEC_ISO_INVOCATION (coding, 0) = 3;
 -            charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
 +            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LOCKING_SHIFT)
 +                || CODING_ISO_DESIGNATION (coding, 3) < 0)
 +              goto invalid_code;
 +            CODING_ISO_INVOCATION (coding, 0) = 3;
 +            charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
              continue;
  
            case 'N':           /* invocation of single-shift-2 */
 -            if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)
 -                || CODING_SPEC_ISO_DESIGNATION (coding, 2) < 0)
 -              goto label_invalid_code;
 -            charset = CODING_SPEC_ISO_DESIGNATION (coding, 2);
 +            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
 +                || CODING_ISO_DESIGNATION (coding, 2) < 0)
 +              goto invalid_code;
 +            charset_id_2 = CODING_ISO_DESIGNATION (coding, 2);
 +            if (charset_id_2 < 0)
 +              charset = CHARSET_FROM_ID (charset_ascii);
 +            else
 +              charset = CHARSET_FROM_ID (charset_id_2);
              ONE_MORE_BYTE (c1);
              if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))
 -              goto label_invalid_code;
 +              goto invalid_code;
              break;
  
            case 'O':           /* invocation of single-shift-3 */
 -            if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)
 -                || CODING_SPEC_ISO_DESIGNATION (coding, 3) < 0)
 -              goto label_invalid_code;
 -            charset = CODING_SPEC_ISO_DESIGNATION (coding, 3);
 +            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
 +                || CODING_ISO_DESIGNATION (coding, 3) < 0)
 +              goto invalid_code;
 +            charset_id_3 = CODING_ISO_DESIGNATION (coding, 3);
 +            if (charset_id_3 < 0)
 +              charset = CHARSET_FROM_ID (charset_ascii);
 +            else
 +              charset = CHARSET_FROM_ID (charset_id_3);
              ONE_MORE_BYTE (c1);
              if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0))
 -              goto label_invalid_code;
 +              goto invalid_code;
              break;
  
            case '0': case '2': case '3': case '4': /* start composition */
 +            if (! (coding->common_flags & CODING_ANNOTATE_COMPOSITION_MASK))
 +              goto invalid_code;
              DECODE_COMPOSITION_START (c1);
              continue;
  
            case '1':           /* end composition */
 -            DECODE_COMPOSITION_END (c1);
 +            if (composition_state == COMPOSING_NO)
 +              goto invalid_code;
 +            DECODE_COMPOSITION_END ();
              continue;
  
            case '[':           /* specification of direction */
 -            if (coding->flags & CODING_FLAG_ISO_NO_DIRECTION)
 -              goto label_invalid_code;
 +            if (! CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DIRECTION)
 +              goto invalid_code;
              /* For the moment, nested direction is not supported.
                 So, `coding->mode & CODING_MODE_DIRECTION' zero means
 -               left-to-right, and nonzero means right-to-left.  */
 +               left-to-right, and nozero means right-to-left.  */
              ONE_MORE_BYTE (c1);
              switch (c1)
                {
                  if (c1 == ']')
                    coding->mode &= ~CODING_MODE_DIRECTION;
                  else
 -                  goto label_invalid_code;
 +                  goto invalid_code;
                  break;
  
                case '2':       /* start of right-to-left direction */
                  if (c1 == ']')
                    coding->mode |= CODING_MODE_DIRECTION;
                  else
 -                  goto label_invalid_code;
 +                  goto invalid_code;
                  break;
  
                default:
 -                goto label_invalid_code;
 +                goto invalid_code;
                }
              continue;
  
            case '%':
 -            if (COMPOSING_P (coding))
 -              DECODE_COMPOSITION_END ('1');
              ONE_MORE_BYTE (c1);
              if (c1 == '/')
                {
                     We keep these bytes as is for the moment.
                     They may be decoded by post-read-conversion.  */
                  int dim, M, L;
 -                int size, required;
 -                int produced_chars;
 +                int size;
  
                  ONE_MORE_BYTE (dim);
                  ONE_MORE_BYTE (M);
                  ONE_MORE_BYTE (L);
                  size = ((M - 128) * 128) + (L - 128);
 -                required = 8 + size * 2;
 -                if (dst + required > (dst_bytes ? dst_end : src))
 -                  goto label_end_of_loop;
 -                *dst++ = ISO_CODE_ESC;
 -                *dst++ = '%';
 -                *dst++ = '/';
 -                *dst++ = dim;
 -                produced_chars = 4;
 -                dst += CHAR_STRING (M, dst), produced_chars++;
 -                dst += CHAR_STRING (L, dst), produced_chars++;
 +                if (charbuf + 8 + size > charbuf_end)
 +                  goto break_loop;
 +                *charbuf++ = ISO_CODE_ESC;
 +                *charbuf++ = '%';
 +                *charbuf++ = '/';
 +                *charbuf++ = dim;
 +                *charbuf++ = BYTE8_TO_CHAR (M);
 +                *charbuf++ = BYTE8_TO_CHAR (L);
                  while (size-- > 0)
                    {
                      ONE_MORE_BYTE (c1);
 -                    dst += CHAR_STRING (c1, dst), produced_chars++;
 +                    *charbuf++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
                    }
 -                coding->produced_char += produced_chars;
                }
              else if (c1 == 'G')
                {
 -                unsigned char *d = dst;
 -                int produced_chars;
 -
                  /* XFree86 extension for embedding UTF-8 in CTEXT:
                     ESC % G --UTF-8-BYTES-- ESC % @
                     We keep these bytes as is for the moment.
                     They may be decoded by post-read-conversion.  */
 -                if (d + 6 > (dst_bytes ? dst_end : src))
 -                  goto label_end_of_loop;
 -                *d++ = ISO_CODE_ESC;
 -                *d++ = '%';
 -                *d++ = 'G';
 -                produced_chars = 3;
 -                while (d + 1 < (dst_bytes ? dst_end : src))
 +                int *p = charbuf;
 +
 +                if (p + 6 > charbuf_end)
 +                  goto break_loop;
 +                *p++ = ISO_CODE_ESC;
 +                *p++ = '%';
 +                *p++ = 'G';
 +                while (p < charbuf_end)
                    {
                      ONE_MORE_BYTE (c1);
                      if (c1 == ISO_CODE_ESC
                          src += 2;
                          break;
                        }
 -                    d += CHAR_STRING (c1, d), produced_chars++;
 +                    *p++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
                    }
 -                if (d + 3 > (dst_bytes ? dst_end : src))
 -                  goto label_end_of_loop;
 -                *d++ = ISO_CODE_ESC;
 -                *d++ = '%';
 -                *d++ = '@';
 -                dst = d;
 -                coding->produced_char += produced_chars + 3;
 +                if (p + 3 > charbuf_end)
 +                  goto break_loop;
 +                *p++ = ISO_CODE_ESC;
 +                *p++ = '%';
 +                *p++ = '@';
 +                charbuf = p;
                }
              else
 -              goto label_invalid_code;
 +              goto invalid_code;
              continue;
 +            break;
  
            default:
 -            if (! (coding->flags & CODING_FLAG_ISO_DESIGNATION))
 -              goto label_invalid_code;
 -            if (c1 >= 0x28 && c1 <= 0x2B)
 -              {       /* designation of DIMENSION1_CHARS94 character set */
 -                ONE_MORE_BYTE (c2);
 -                DECODE_DESIGNATION (c1 - 0x28, 1, 94, c2);
 -              }
 -            else if (c1 >= 0x2C && c1 <= 0x2F)
 -              {       /* designation of DIMENSION1_CHARS96 character set */
 -                ONE_MORE_BYTE (c2);
 -                DECODE_DESIGNATION (c1 - 0x2C, 1, 96, c2);
 -              }
 -            else
 -              goto label_invalid_code;
 -            /* We must update these variables now.  */
 -            charset0 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 0);
 -            charset1 = CODING_SPEC_ISO_PLANE_CHARSET (coding, 1);
 +            if (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATION))
 +              goto invalid_code;
 +            {
 +              int reg, chars96;
 +
 +              if (c1 >= 0x28 && c1 <= 0x2B)
 +                { /* designation of DIMENSION1_CHARS94 character set */
 +                  reg = c1 - 0x28, chars96 = 0;
 +                  ONE_MORE_BYTE (c1);
 +                }
 +              else if (c1 >= 0x2C && c1 <= 0x2F)
 +                { /* designation of DIMENSION1_CHARS96 character set */
 +                  reg = c1 - 0x2C, chars96 = 1;
 +                  ONE_MORE_BYTE (c1);
 +                }
 +              else
 +                goto invalid_code;
 +              DECODE_DESIGNATION (reg, 1, chars96, c1);
 +              /* We must update these variables now.  */
 +              if (reg == 0)
 +                charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
 +              else if (reg == 1)
 +                charset_id_1 = CODING_ISO_INVOKED_CHARSET (coding, 1);
 +              if (chars96 < 0)
 +                goto invalid_code;
 +            }
              continue;
            }
        }
  
 +      if (charset->id != charset_ascii
 +        && last_id != charset->id)
 +      {
 +        if (last_id != charset_ascii)
 +          ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +        last_id = charset->id;
 +        last_offset = char_offset;
 +      }
 +
        /* Now we know CHARSET and 1st position code C1 of a character.
 -         Produce a multibyte sequence for that character while getting
 -         2nd position code C2 if necessary.  */
 -      if (CHARSET_DIMENSION (charset) == 2)
 +         Produce a decoded character while getting 2nd position code
 +         C2 if necessary.  */
 +      c1 &= 0x7F;
 +      if (CHARSET_DIMENSION (charset) > 1)
        {
          ONE_MORE_BYTE (c2);
 -        if (c1 < 0x80 ? c2 < 0x20 || c2 >= 0x80 : c2 < 0xA0)
 +        if (c2 < 0x20 || (c2 >= 0x80 && c2 < 0xA0))
            /* C2 is not in a valid range.  */
 -          goto label_invalid_code;
 +          goto invalid_code;
 +        c1 = (c1 << 8) | (c2 & 0x7F);
 +        if (CHARSET_DIMENSION (charset) > 2)
 +          {
 +            ONE_MORE_BYTE (c2);
 +            if (c2 < 0x20 || (c2 >= 0x80 && c2 < 0xA0))
 +              /* C2 is not in a valid range.  */
 +              goto invalid_code;
 +            c1 = (c1 << 8) | (c2 & 0x7F);
 +          }
 +      }
 +
 +      CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c1, c);
 +      if (c < 0)
 +      {
 +        MAYBE_FINISH_COMPOSITION ();
 +        for (; src_base < src; src_base++, char_offset++)
 +          {
 +            if (ASCII_BYTE_P (*src_base))
 +              *charbuf++ = *src_base;
 +            else
 +              *charbuf++ = BYTE8_TO_CHAR (*src_base);
 +          }
 +      }
 +      else if (composition_state == COMPOSING_NO)
 +      {
 +        *charbuf++ = c;
 +        char_offset++;
 +      }
 +      else
 +      {
 +        components[component_idx++] = c;
 +        if (method == COMPOSITION_WITH_RULE
 +            || (method == COMPOSITION_WITH_RULE_ALTCHARS
 +                && composition_state == COMPOSING_COMPONENT_CHAR))
 +          composition_state++;
        }
 -      c = DECODE_ISO_CHARACTER (charset, c1, c2);
 -      EMIT_CHAR (c);
        continue;
  
 -    label_invalid_code:
 -      coding->errors++;
 -      if (COMPOSING_P (coding))
 -      DECODE_COMPOSITION_END ('1');
 +    invalid_code:
 +      MAYBE_FINISH_COMPOSITION ();
        src = src_base;
 -      c = *src++;
 -      if (! NILP (translation_table))
 -      c = translate_char (translation_table, c, 0, 0, 0);
 -      EMIT_CHAR (c);
 +      consumed_chars = consumed_chars_base;
 +      ONE_MORE_BYTE (c);
 +      *charbuf++ = c < 0 ? -c : ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
 +      char_offset++;
 +      coding->errors++;
 +      continue;
 +
 +    break_loop:
 +      break;
      }
  
 - label_end_of_loop:
 -  coding->consumed = coding->consumed_char = src_base - source;
 -  coding->produced = dst - destination;
 -  return;
 + no_more_source:
 +  if (last_id != charset_ascii)
 +    ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +  coding->consumed_char += consumed_chars_base;
 +  coding->consumed = src_base - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
  }
  
  
  
  /*
     It is not enough to say just "ISO2022" on encoding, we have to
 -   specify more details.  In Emacs, each ISO2022 coding system
 +   specify more details.  In Emacs, each coding system of ISO2022
     variant has the following specifications:
 -      1. Initial designation to G0 through G3.
 +      1. Initial designation to G0 thru G3.
        2. Allows short-form designation?
        3. ASCII should be designated to G0 before control characters?
        4. ASCII should be designated to G0 at end of line?
     And the following two are only for Japanese:
        8. Use ASCII in place of JIS0201-1976-Roman?
        9. Use JISX0208-1983 in place of JISX0208-1978?
 -   These specifications are encoded in `coding->flags' as flag bits
 -   defined by macros CODING_FLAG_ISO_XXX.  See `coding.h' for more
 +   These specifications are encoded in CODING_ISO_FLAGS (coding) as flag bits
 +   defined by macros CODING_ISO_FLAG_XXX.  See `coding.h' for more
     details.
  */
  
  
  #define ENCODE_DESIGNATION(charset, reg, coding)                      \
    do {                                                                        \
 -    unsigned char final_char = CHARSET_ISO_FINAL_CHAR (charset);      \
 +    unsigned char final_char = CHARSET_ISO_FINAL (charset);           \
      char *intermediate_char_94 = "()*+";                              \
      char *intermediate_char_96 = ",-./";                              \
 -    int revision = CODING_SPEC_ISO_REVISION_NUMBER(coding, charset);  \
 -                                                                      \
 -    if (revision < 255)                                                       \
 +    int revision = -1;                                                        \
 +    int c;                                                            \
 +                                                                      \
 +    if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_REVISION)         \
 +      revision = CHARSET_ISO_REVISION (charset);                      \
 +                                                                      \
 +    if (revision >= 0)                                                        \
        {                                                                       \
 -      *dst++ = ISO_CODE_ESC;                                          \
 -      *dst++ = '&';                                                   \
 -      *dst++ = '@' + revision;                                        \
 +      EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, '&');                       \
 +      EMIT_ONE_BYTE ('@' + revision);                                 \
        }                                                                       \
 -    *dst++ = ISO_CODE_ESC;                                            \
 +    EMIT_ONE_ASCII_BYTE (ISO_CODE_ESC);                                       \
      if (CHARSET_DIMENSION (charset) == 1)                             \
        {                                                                       \
 -      if (CHARSET_CHARS (charset) == 94)                              \
 -        *dst++ = (unsigned char) (intermediate_char_94[reg]);         \
 +      if (! CHARSET_ISO_CHARS_96 (charset))                           \
 +        c = intermediate_char_94[reg];                                \
        else                                                            \
 -        *dst++ = (unsigned char) (intermediate_char_96[reg]);         \
 +        c = intermediate_char_96[reg];                                \
 +      EMIT_ONE_ASCII_BYTE (c);                                        \
        }                                                                       \
      else                                                              \
        {                                                                       \
 -      *dst++ = '$';                                                   \
 -      if (CHARSET_CHARS (charset) == 94)                              \
 +      EMIT_ONE_ASCII_BYTE ('$');                                      \
 +      if (! CHARSET_ISO_CHARS_96 (charset))                           \
          {                                                             \
 -          if (! (coding->flags & CODING_FLAG_ISO_SHORT_FORM)          \
 +          if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LONG_FORM   \
                || reg != 0                                             \
                || final_char < '@' || final_char > 'B')                \
 -            *dst++ = (unsigned char) (intermediate_char_94[reg]);     \
 +            EMIT_ONE_ASCII_BYTE (intermediate_char_94[reg]);          \
          }                                                             \
        else                                                            \
 -        *dst++ = (unsigned char) (intermediate_char_96[reg]);         \
 +        EMIT_ONE_ASCII_BYTE (intermediate_char_96[reg]);              \
        }                                                                       \
 -    *dst++ = final_char;                                              \
 -    CODING_SPEC_ISO_DESIGNATION (coding, reg) = charset;              \
 +    EMIT_ONE_ASCII_BYTE (final_char);                                 \
 +                                                                      \
 +    CODING_ISO_DESIGNATION (coding, reg) = CHARSET_ID (charset);      \
    } while (0)
  
 +
  /* The following two macros produce codes (control character or escape
     sequence) for ISO2022 single-shift functions (single-shift-2 and
     single-shift-3).  */
  
 -#define ENCODE_SINGLE_SHIFT_2                         \
 -  do {                                                        \
 -    if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)   \
 -      *dst++ = ISO_CODE_ESC, *dst++ = 'N';            \
 -    else                                              \
 -      *dst++ = ISO_CODE_SS2;                          \
 -    CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 1;     \
 +#define ENCODE_SINGLE_SHIFT_2                                         \
 +  do {                                                                        \
 +    if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)               \
 +      EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'N');                               \
 +    else                                                              \
 +      EMIT_ONE_BYTE (ISO_CODE_SS2);                                   \
 +    CODING_ISO_SINGLE_SHIFTING (coding) = 1;                          \
    } while (0)
  
 -#define ENCODE_SINGLE_SHIFT_3                         \
 -  do {                                                        \
 -    if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)   \
 -      *dst++ = ISO_CODE_ESC, *dst++ = 'O';            \
 -    else                                              \
 -      *dst++ = ISO_CODE_SS3;                          \
 -    CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 1;     \
 +
 +#define ENCODE_SINGLE_SHIFT_3                                         \
 +  do {                                                                        \
 +    if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)               \
 +      EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'O');                               \
 +    else                                                              \
 +      EMIT_ONE_BYTE (ISO_CODE_SS3);                                   \
 +    CODING_ISO_SINGLE_SHIFTING (coding) = 1;                          \
    } while (0)
  
 +
  /* The following four macros produce codes (control character or
     escape sequence) for ISO2022 locking-shift functions (shift-in,
     shift-out, locking-shift-2, and locking-shift-3).  */
  
 -#define ENCODE_SHIFT_IN                               \
 -  do {                                                \
 -    *dst++ = ISO_CODE_SI;                     \
 -    CODING_SPEC_ISO_INVOCATION (coding, 0) = 0;       \
 +#define ENCODE_SHIFT_IN                                       \
 +  do {                                                        \
 +    EMIT_ONE_ASCII_BYTE (ISO_CODE_SI);                        \
 +    CODING_ISO_INVOCATION (coding, 0) = 0;            \
    } while (0)
  
 -#define ENCODE_SHIFT_OUT                      \
 -  do {                                                \
 -    *dst++ = ISO_CODE_SO;                     \
 -    CODING_SPEC_ISO_INVOCATION (coding, 0) = 1;       \
 +
 +#define ENCODE_SHIFT_OUT                              \
 +  do {                                                        \
 +    EMIT_ONE_ASCII_BYTE (ISO_CODE_SO);                        \
 +    CODING_ISO_INVOCATION (coding, 0) = 1;            \
    } while (0)
  
 -#define ENCODE_LOCKING_SHIFT_2                        \
 -  do {                                                \
 -    *dst++ = ISO_CODE_ESC, *dst++ = 'n';      \
 -    CODING_SPEC_ISO_INVOCATION (coding, 0) = 2;       \
 +
 +#define ENCODE_LOCKING_SHIFT_2                                \
 +  do {                                                        \
 +    EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'n');         \
 +    CODING_ISO_INVOCATION (coding, 0) = 2;            \
    } while (0)
  
 -#define ENCODE_LOCKING_SHIFT_3                        \
 -  do {                                                \
 -    *dst++ = ISO_CODE_ESC, *dst++ = 'o';      \
 -    CODING_SPEC_ISO_INVOCATION (coding, 0) = 3;       \
 +
 +#define ENCODE_LOCKING_SHIFT_3                                \
 +  do {                                                        \
 +    EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, 'n');         \
 +    CODING_ISO_INVOCATION (coding, 0) = 3;            \
    } while (0)
  
 +
  /* Produce codes for a DIMENSION1 character whose character set is
     CHARSET and whose position-code is C1.  Designation and invocation
     sequences are also produced in advance if necessary.  */
  
  #define ENCODE_ISO_CHARACTER_DIMENSION1(charset, c1)                  \
    do {                                                                        \
 -    if (CODING_SPEC_ISO_SINGLE_SHIFTING (coding))                     \
 +    int id = CHARSET_ID (charset);                                    \
 +                                                                      \
 +    if ((CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_ROMAN)               \
 +      && id == charset_ascii)                                         \
 +      {                                                                       \
 +      id = charset_jisx0201_roman;                                    \
 +      charset = CHARSET_FROM_ID (id);                                 \
 +      }                                                                       \
 +                                                                      \
 +    if (CODING_ISO_SINGLE_SHIFTING (coding))                          \
        {                                                                       \
 -      if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)                 \
 -        *dst++ = c1 & 0x7F;                                           \
 +      if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)     \
 +        EMIT_ONE_ASCII_BYTE (c1 & 0x7F);                              \
        else                                                            \
 -        *dst++ = c1 | 0x80;                                           \
 -      CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0;                   \
 +        EMIT_ONE_BYTE (c1 | 0x80);                                    \
 +      CODING_ISO_SINGLE_SHIFTING (coding) = 0;                        \
        break;                                                          \
        }                                                                       \
 -    else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 0))    \
 +    else if (id == CODING_ISO_INVOKED_CHARSET (coding, 0))            \
        {                                                                       \
 -      *dst++ = c1 & 0x7F;                                             \
 +      EMIT_ONE_ASCII_BYTE (c1 & 0x7F);                                \
        break;                                                          \
        }                                                                       \
 -    else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 1))    \
 +    else if (id == CODING_ISO_INVOKED_CHARSET (coding, 1))            \
        {                                                                       \
 -      *dst++ = c1 | 0x80;                                             \
 +      EMIT_ONE_BYTE (c1 | 0x80);                                      \
        break;                                                          \
        }                                                                       \
      else                                                              \
         must invoke it, or, at first, designate it to some graphic     \
         register.  Then repeat the loop to actually produce the        \
         character.  */                                                 \
 -      dst = encode_invocation_designation (charset, coding, dst);     \
 +      dst = encode_invocation_designation (charset, coding, dst,      \
 +                                         &produced_chars);            \
    } while (1)
  
 +
  /* Produce codes for a DIMENSION2 character whose character set is
     CHARSET and whose position-codes are C1 and C2.  Designation and
     invocation codes are also produced in advance if necessary.  */
  
  #define ENCODE_ISO_CHARACTER_DIMENSION2(charset, c1, c2)              \
    do {                                                                        \
 -    if (CODING_SPEC_ISO_SINGLE_SHIFTING (coding))                     \
 +    int id = CHARSET_ID (charset);                                    \
 +                                                                      \
 +    if ((CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_USE_OLDJIS)      \
 +      && id == charset_jisx0208)                                      \
 +      {                                                                       \
 +      id = charset_jisx0208_1978;                                     \
 +      charset = CHARSET_FROM_ID (id);                                 \
 +      }                                                                       \
 +                                                                      \
 +    if (CODING_ISO_SINGLE_SHIFTING (coding))                          \
        {                                                                       \
 -      if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)                 \
 -        *dst++ = c1 & 0x7F, *dst++ = c2 & 0x7F;                       \
 +      if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)     \
 +        EMIT_TWO_ASCII_BYTES ((c1) & 0x7F, (c2) & 0x7F);              \
        else                                                            \
 -        *dst++ = c1 | 0x80, *dst++ = c2 | 0x80;                       \
 -      CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0;                   \
 +        EMIT_TWO_BYTES ((c1) | 0x80, (c2) | 0x80);                    \
 +      CODING_ISO_SINGLE_SHIFTING (coding) = 0;                        \
        break;                                                          \
        }                                                                       \
 -    else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 0))    \
 +    else if (id == CODING_ISO_INVOKED_CHARSET (coding, 0))            \
        {                                                                       \
 -      *dst++ = c1 & 0x7F, *dst++= c2 & 0x7F;                          \
 +      EMIT_TWO_ASCII_BYTES ((c1) & 0x7F, (c2) & 0x7F);                \
        break;                                                          \
        }                                                                       \
 -    else if (charset == CODING_SPEC_ISO_PLANE_CHARSET (coding, 1))    \
 +    else if (id == CODING_ISO_INVOKED_CHARSET (coding, 1))            \
        {                                                                       \
 -      *dst++ = c1 | 0x80, *dst++= c2 | 0x80;                          \
 +      EMIT_TWO_BYTES ((c1) | 0x80, (c2) | 0x80);                      \
        break;                                                          \
        }                                                                       \
      else                                                              \
         must invoke it, or, at first, designate it to some graphic     \
         register.  Then repeat the loop to actually produce the        \
         character.  */                                                 \
 -      dst = encode_invocation_designation (charset, coding, dst);     \
 +      dst = encode_invocation_designation (charset, coding, dst,      \
 +                                         &produced_chars);            \
    } while (1)
  
 -#define ENCODE_ISO_CHARACTER(c)                                       \
 -  do {                                                                \
 -    int charset, c1, c2;                                      \
 -                                                              \
 -    SPLIT_CHAR (c, charset, c1, c2);                          \
 -    if (CHARSET_DEFINED_P (charset))                          \
 -      {                                                               \
 -      if (CHARSET_DIMENSION (charset) == 1)                   \
 -        {                                                     \
 -          if (charset == CHARSET_ASCII                        \
 -              && coding->flags & CODING_FLAG_ISO_USE_ROMAN)   \
 -            charset = charset_latin_jisx0201;                 \
 -          ENCODE_ISO_CHARACTER_DIMENSION1 (charset, c1);      \
 -        }                                                     \
 -      else                                                    \
 -        {                                                     \
 -          if (charset == charset_jisx0208                     \
 -              && coding->flags & CODING_FLAG_ISO_USE_OLDJIS)  \
 -            charset = charset_jisx0208_1978;                  \
 -          ENCODE_ISO_CHARACTER_DIMENSION2 (charset, c1, c2);  \
 -        }                                                     \
 -      }                                                               \
 -    else                                                      \
 -      {                                                               \
 -      *dst++ = c1;                                            \
 -      if (c2 >= 0)                                            \
 -        *dst++ = c2;                                          \
 -      }                                                               \
 -  } while (0)
 -
  
 -/* Instead of encoding character C, produce one or two `?'s.  */
 -
 -#define ENCODE_UNSAFE_CHARACTER(c)                            \
 -  do {                                                                \
 -    ENCODE_ISO_CHARACTER (CODING_REPLACEMENT_CHARACTER);      \
 -    if (CHARSET_WIDTH (CHAR_CHARSET (c)) > 1)                 \
 -      ENCODE_ISO_CHARACTER (CODING_REPLACEMENT_CHARACTER);    \
 +#define ENCODE_ISO_CHARACTER(charset, c)                                 \
 +  do {                                                                           \
 +    int code = ENCODE_CHAR ((charset),(c));                              \
 +                                                                         \
 +    if (CHARSET_DIMENSION (charset) == 1)                                \
 +      ENCODE_ISO_CHARACTER_DIMENSION1 ((charset), code);                 \
 +    else                                                                 \
 +      ENCODE_ISO_CHARACTER_DIMENSION2 ((charset), code >> 8, code & 0xFF); \
    } while (0)
  
  
  /* Produce designation and invocation codes at a place pointed by DST
 -   to use CHARSET.  The element `spec.iso2022' of *CODING is updated.
 +   to use CHARSET.  The element `spec.iso_2022' of *CODING is updated.
     Return new DST.  */
  
  unsigned char *
 -encode_invocation_designation (charset, coding, dst)
 -     int charset;
 +encode_invocation_designation (charset, coding, dst, p_nchars)
 +     struct charset *charset;
       struct coding_system *coding;
       unsigned char *dst;
 +     int *p_nchars;
  {
 +  int multibytep = coding->dst_multibyte;
 +  int produced_chars = *p_nchars;
    int reg;                    /* graphic register number */
 +  int id = CHARSET_ID (charset);
  
    /* At first, check designations.  */
    for (reg = 0; reg < 4; reg++)
 -    if (charset == CODING_SPEC_ISO_DESIGNATION (coding, reg))
 +    if (id == CODING_ISO_DESIGNATION (coding, reg))
        break;
  
    if (reg >= 4)
      {
        /* CHARSET is not yet designated to any graphic registers.  */
        /* At first check the requested designation.  */
 -      reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset);
 -      if (reg == CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION)
 +      reg = CODING_ISO_REQUEST (coding, id);
 +      if (reg < 0)
        /* Since CHARSET requests no special designation, designate it
           to graphic register 0.  */
        reg = 0;
        ENCODE_DESIGNATION (charset, reg, coding);
      }
  
 -  if (CODING_SPEC_ISO_INVOCATION (coding, 0) != reg
 -      && CODING_SPEC_ISO_INVOCATION (coding, 1) != reg)
 +  if (CODING_ISO_INVOCATION (coding, 0) != reg
 +      && CODING_ISO_INVOCATION (coding, 1) != reg)
      {
        /* Since the graphic register REG is not invoked to any graphic
         planes, invoke it to graphic plane 0.  */
          break;
  
        case 2:                 /* graphic register 2 */
 -        if (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)
 +        if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
            ENCODE_SINGLE_SHIFT_2;
          else
            ENCODE_LOCKING_SHIFT_2;
          break;
  
        case 3:                 /* graphic register 3 */
 -        if (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT)
 +        if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SINGLE_SHIFT)
            ENCODE_SINGLE_SHIFT_3;
          else
            ENCODE_LOCKING_SHIFT_3;
        }
      }
  
 +  *p_nchars = produced_chars;
    return dst;
  }
  
 -/* Produce 2-byte codes for encoded composition rule RULE.  */
 -
 -#define ENCODE_COMPOSITION_RULE(rule)         \
 -  do {                                                \
 -    int gref, nref;                           \
 -    COMPOSITION_DECODE_RULE (rule, gref, nref);       \
 -    *dst++ = 32 + 81 + gref;                  \
 -    *dst++ = 32 + nref;                               \
 -  } while (0)
 -
 -/* Produce codes for indicating the start of a composition sequence
 -   (ESC 0, ESC 3, or ESC 4).  DATA points to an array of integers
 -   which specify information about the composition.  See the comment
 -   in coding.h for the format of DATA.  */
 -
 -#define ENCODE_COMPOSITION_START(coding, data)                                \
 +/* The following three macros produce codes for indicating direction
 +   of text.  */
 +#define ENCODE_CONTROL_SEQUENCE_INTRODUCER                            \
    do {                                                                        \
 -    coding->composing = data[3];                                      \
 -    *dst++ = ISO_CODE_ESC;                                            \
 -    if (coding->composing == COMPOSITION_RELATIVE)                    \
 -      *dst++ = '0';                                                   \
 -    else                                                              \
 -      {                                                                       \
 -      *dst++ = (coding->composing == COMPOSITION_WITH_ALTCHARS        \
 -                ? '3' : '4');                                         \
 -      coding->cmp_data_index = coding->cmp_data_start + 4;            \
 -      coding->composition_rule_follows = 0;                           \
 -      }                                                                       \
 -  } while (0)
 -
 -/* Produce codes for indicating the end of the current composition.  */
 -
 -#define ENCODE_COMPOSITION_END(coding, data)                  \
 -  do {                                                                \
 -    *dst++ = ISO_CODE_ESC;                                    \
 -    *dst++ = '1';                                             \
 -    coding->cmp_data_start += data[0];                                \
 -    coding->composing = COMPOSITION_NO;                               \
 -    if (coding->cmp_data_start == coding->cmp_data->used      \
 -      && coding->cmp_data->next)                              \
 -      {                                                               \
 -      coding->cmp_data = coding->cmp_data->next;              \
 -      coding->cmp_data_start = 0;                             \
 -      }                                                               \
 +    if (CODING_ISO_FLAGS (coding) == CODING_ISO_FLAG_SEVEN_BITS)      \
 +      EMIT_TWO_ASCII_BYTES (ISO_CODE_ESC, '[');                               \
 +    else                                                              \
 +      EMIT_ONE_BYTE (ISO_CODE_CSI);                                   \
    } while (0)
  
 -/* Produce composition start sequence ESC 0.  Here, this sequence
 -   doesn't mean the start of a new composition but means that we have
 -   just produced components (alternate chars and composition rules) of
 -   the composition and the actual text follows in SRC.  */
  
 -#define ENCODE_COMPOSITION_FAKE_START(coding) \
 +#define ENCODE_DIRECTION_R2L()                        \
    do {                                                \
 -    *dst++ = ISO_CODE_ESC;                    \
 -    *dst++ = '0';                             \
 -    coding->composing = COMPOSITION_RELATIVE; \
 +    ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst); \
 +    EMIT_TWO_ASCII_BYTES ('2', ']');          \
    } while (0)
  
 -/* The following three macros produce codes for indicating direction
 -   of text.  */
 -#define ENCODE_CONTROL_SEQUENCE_INTRODUCER            \
 -  do {                                                        \
 -    if (coding->flags == CODING_FLAG_ISO_SEVEN_BITS)  \
 -      *dst++ = ISO_CODE_ESC, *dst++ = '[';            \
 -    else                                              \
 -      *dst++ = ISO_CODE_CSI;                          \
 -  } while (0)
  
 -#define ENCODE_DIRECTION_R2L  \
 -  ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst), *dst++ = '2', *dst++ = ']'
 +#define ENCODE_DIRECTION_L2R()                        \
 +  do {                                                \
 +    ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst); \
 +    EMIT_TWO_ASCII_BYTES ('0', ']');          \
 +  } while (0)
  
 -#define ENCODE_DIRECTION_L2R  \
 -  ENCODE_CONTROL_SEQUENCE_INTRODUCER (dst), *dst++ = '0', *dst++ = ']'
  
  /* Produce codes for designation and invocation to reset the graphic
     planes and registers to initial state.  */
 -#define ENCODE_RESET_PLANE_AND_REGISTER                                           \
 -  do {                                                                            \
 -    int reg;                                                              \
 -    if (CODING_SPEC_ISO_INVOCATION (coding, 0) != 0)                      \
 -      ENCODE_SHIFT_IN;                                                            \
 -    for (reg = 0; reg < 4; reg++)                                         \
 -      if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg) >= 0          \
 -        && (CODING_SPEC_ISO_DESIGNATION (coding, reg)                     \
 -            != CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg)))        \
 -      ENCODE_DESIGNATION                                                  \
 -        (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, reg), reg, coding); \
 +#define ENCODE_RESET_PLANE_AND_REGISTER()                             \
 +  do {                                                                        \
 +    int reg;                                                          \
 +    struct charset *charset;                                          \
 +                                                                      \
 +    if (CODING_ISO_INVOCATION (coding, 0) != 0)                               \
 +      ENCODE_SHIFT_IN;                                                        \
 +    for (reg = 0; reg < 4; reg++)                                     \
 +      if (CODING_ISO_INITIAL (coding, reg) >= 0                               \
 +        && (CODING_ISO_DESIGNATION (coding, reg)                      \
 +            != CODING_ISO_INITIAL (coding, reg)))                     \
 +      {                                                               \
 +        charset = CHARSET_FROM_ID (CODING_ISO_INITIAL (coding, reg)); \
 +        ENCODE_DESIGNATION (charset, reg, coding);                    \
 +      }                                                               \
    } while (0)
  
 +
  /* Produce designation sequences of charsets in the line started from
     SRC to a place pointed by DST, and return updated DST.
  
     find all the necessary designations.  */
  
  static unsigned char *
 -encode_designation_at_bol (coding, translation_table, src, src_end, dst)
 +encode_designation_at_bol (coding, charbuf, charbuf_end, dst)
       struct coding_system *coding;
 -     Lisp_Object translation_table;
 -     const unsigned char *src, *src_end;
 +     int *charbuf, *charbuf_end;
       unsigned char *dst;
  {
 -  int charset, c, found = 0, reg;
 +  struct charset *charset;
    /* Table of charsets to be designated to each graphic register.  */
    int r[4];
 +  int c, found = 0, reg;
 +  int produced_chars = 0;
 +  int multibytep = coding->dst_multibyte;
 +  Lisp_Object attrs;
 +  Lisp_Object charset_list;
 +
 +  attrs = CODING_ID_ATTRS (coding->id);
 +  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
 +  if (EQ (charset_list, Qiso_2022))
 +    charset_list = Viso_2022_charset_list;
  
    for (reg = 0; reg < 4; reg++)
      r[reg] = -1;
  
    while (found < 4)
      {
 -      ONE_MORE_CHAR (c);
 +      int id;
 +
 +      c = *charbuf++;
        if (c == '\n')
        break;
 -
 -      charset = CHAR_CHARSET (c);
 -      reg = CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset);
 -      if (reg != CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION && r[reg] < 0)
 +      charset = char_charset (c, charset_list, NULL);
 +      id = CHARSET_ID (charset);
 +      reg = CODING_ISO_REQUEST (coding, id);
 +      if (reg >= 0 && r[reg] < 0)
        {
          found++;
 -        r[reg] = charset;
 +        r[reg] = id;
        }
      }
  
 - label_end_of_loop:
    if (found)
      {
        for (reg = 0; reg < 4; reg++)
        if (r[reg] >= 0
 -          && CODING_SPEC_ISO_DESIGNATION (coding, reg) != r[reg])
 -        ENCODE_DESIGNATION (r[reg], reg, coding);
 +          && CODING_ISO_DESIGNATION (coding, reg) != r[reg])
 +        ENCODE_DESIGNATION (CHARSET_FROM_ID (r[reg]), reg, coding);
      }
  
    return dst;
  
  /* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".  */
  
 -static void
 -encode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
 +static int
 +encode_coding_iso_2022 (coding)
       struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
  {
 -  const unsigned char *src = source;
 -  const unsigned char *src_end = source + src_bytes;
 -  unsigned char *dst = destination;
 -  unsigned char *dst_end = destination + dst_bytes;
 -  /* Since the maximum bytes produced by each loop is 20, we subtract 19
 -     from DST_END to assure overflow checking is necessary only at the
 -     head of loop.  */
 -  unsigned char *adjusted_dst_end = dst_end - 19;
 -  /* SRC_BASE remembers the start position in source in each loop.
 -     The loop will be exited when there's not enough source text to
 -     analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
 -     there's not enough destination area to produce encoded codes
 -     (within macro EMIT_BYTES).  */
 -  const unsigned char *src_base;
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int safe_room = 16;
 +  int bol_designation
 +    = (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATE_AT_BOL
 +       && CODING_ISO_BOL (coding));
 +  int produced_chars = 0;
 +  Lisp_Object attrs, eol_type, charset_list;
 +  int ascii_compatible;
    int c;
 -  Lisp_Object translation_table;
 -  Lisp_Object safe_chars;
 +  int preferred_charset_id = -1;
  
 -  if (coding->flags & CODING_FLAG_ISO_SAFE)
 -    coding->mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  eol_type = CODING_ID_EOL_TYPE (coding->id);
 +  if (VECTORP (eol_type))
 +    eol_type = Qunix;
  
 -  safe_chars = coding_safe_chars (coding->symbol);
 +  setup_iso_safe_charsets (attrs);
 +  /* Charset list may have been changed.  */
 +  charset_list = CODING_ATTR_CHARSET_LIST (attrs);            \
 +  coding->safe_charsets = (char *) SDATA (CODING_ATTR_SAFE_CHARSETS(attrs));
  
 -  if (NILP (Venable_character_translation))
 -    translation_table = Qnil;
 -  else
 -    {
 -      translation_table = coding->translation_table_for_encode;
 -      if (NILP (translation_table))
 -      translation_table = Vstandard_translation_table_for_encode;
 -    }
 +  ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
  
 -  coding->consumed_char = 0;
 -  coding->errors = 0;
 -  while (1)
 +  while (charbuf < charbuf_end)
      {
 -      src_base = src;
 +      ASSURE_DESTINATION (safe_room);
  
 -      if (dst >= (dst_bytes ? adjusted_dst_end : (src - 19)))
 +      if (bol_designation)
        {
 -        coding->result = CODING_FINISH_INSUFFICIENT_DST;
 -        break;
 -      }
 +        unsigned char *dst_prev = dst;
  
 -      if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
 -        && CODING_SPEC_ISO_BOL (coding))
 -      {
          /* We have to produce designation sequences if any now.  */
 -        dst = encode_designation_at_bol (coding, translation_table,
 -                                         src, src_end, dst);
 -        CODING_SPEC_ISO_BOL (coding) = 0;
 +        dst = encode_designation_at_bol (coding, charbuf, charbuf_end, dst);
 +        bol_designation = 0;
 +        /* We are sure that designation sequences are all ASCII bytes.  */
 +        produced_chars += dst - dst_prev;
        }
  
 -      /* Check composition start and end.  */
 -      if (coding->composing != COMPOSITION_DISABLED
 -        && coding->cmp_data_start < coding->cmp_data->used)
 -      {
 -        struct composition_data *cmp_data = coding->cmp_data;
 -        int *data = cmp_data->data + coding->cmp_data_start;
 -        int this_pos = cmp_data->char_offset + coding->consumed_char;
 +      c = *charbuf++;
  
 -        if (coding->composing == COMPOSITION_RELATIVE)
 -          {
 -            if (this_pos == data[2])
 -              {
 -                ENCODE_COMPOSITION_END (coding, data);
 -                cmp_data = coding->cmp_data;
 -                data = cmp_data->data + coding->cmp_data_start;
 -              }
 -          }
 -        else if (COMPOSING_P (coding))
 -          {
 -            /* COMPOSITION_WITH_ALTCHARS or COMPOSITION_WITH_RULE_ALTCHAR  */
 -            if (coding->cmp_data_index == coding->cmp_data_start + data[0])
 -              /* We have consumed components of the composition.
 -                   What follows in SRC is the composition's base
 -                   text.  */
 -              ENCODE_COMPOSITION_FAKE_START (coding);
 -            else
 -              {
 -                int c = cmp_data->data[coding->cmp_data_index++];
 -                if (coding->composition_rule_follows)
 -                  {
 -                    ENCODE_COMPOSITION_RULE (c);
 -                    coding->composition_rule_follows = 0;
 -                  }
 -                else
 -                  {
 -                    if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR
 -                        && ! CODING_SAFE_CHAR_P (safe_chars, c))
 -                      ENCODE_UNSAFE_CHARACTER (c);
 -                    else
 -                      ENCODE_ISO_CHARACTER (c);
 -                    if (coding->composing == COMPOSITION_WITH_RULE_ALTCHARS)
 -                      coding->composition_rule_follows = 1;
 -                  }
 -                continue;
 -              }
 -          }
 -        if (!COMPOSING_P (coding))
 +      if (c < 0)
 +      {
 +        /* Handle an annotation.  */
 +        switch (*charbuf)
            {
 -            if (this_pos == data[1])
 -              {
 -                ENCODE_COMPOSITION_START (coding, data);
 -                continue;
 -              }
 +          case CODING_ANNOTATE_COMPOSITION_MASK:
 +            /* Not yet implemented.  */
 +            break;
 +          case CODING_ANNOTATE_CHARSET_MASK:
 +            preferred_charset_id = charbuf[2];
 +            if (preferred_charset_id >= 0
 +                && NILP (Fmemq (make_number (preferred_charset_id),
 +                                charset_list)))
 +              preferred_charset_id = -1;
 +            break;
 +          default:
 +            abort ();
            }
 +        charbuf += -c - 1;
 +        continue;
        }
  
 -      ONE_MORE_CHAR (c);
 -
        /* Now encode the character C.  */
        if (c < 0x20 || c == 0x7F)
        {
 -        if (c == '\r')
 +        if (c == '\n'
 +            || (c == '\r' && EQ (eol_type, Qmac)))
            {
 -            if (! (coding->mode & CODING_MODE_SELECTIVE_DISPLAY))
 +            if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_EOL)
 +              ENCODE_RESET_PLANE_AND_REGISTER ();
 +            if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_INIT_AT_BOL)
                {
 -                if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL)
 -                  ENCODE_RESET_PLANE_AND_REGISTER;
 -                *dst++ = c;
 -                continue;
 +                int i;
 +
 +                for (i = 0; i < 4; i++)
 +                  CODING_ISO_DESIGNATION (coding, i)
 +                    = CODING_ISO_INITIAL (coding, i);
                }
 -            /* fall down to treat '\r' as '\n' ...  */
 -            c = '\n';
 -          }
 -        if (c == '\n')
 -          {
 -            if (coding->flags & CODING_FLAG_ISO_RESET_AT_EOL)
 -              ENCODE_RESET_PLANE_AND_REGISTER;
 -            if (coding->flags & CODING_FLAG_ISO_INIT_AT_BOL)
 -              bcopy (coding->spec.iso2022.initial_designation,
 -                     coding->spec.iso2022.current_designation,
 -                     sizeof coding->spec.iso2022.initial_designation);
 -            if (coding->eol_type == CODING_EOL_LF
 -                || coding->eol_type == CODING_EOL_UNDECIDED)
 -              *dst++ = ISO_CODE_LF;
 -            else if (coding->eol_type == CODING_EOL_CRLF)
 -              *dst++ = ISO_CODE_CR, *dst++ = ISO_CODE_LF;
 -            else
 -              *dst++ = ISO_CODE_CR;
 -            CODING_SPEC_ISO_BOL (coding) = 1;
 +            bol_designation
 +              = CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATE_AT_BOL;
            }
 +        else if (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_CNTL)
 +          ENCODE_RESET_PLANE_AND_REGISTER ();
 +        EMIT_ONE_ASCII_BYTE (c);
 +      }
 +      else if (ASCII_CHAR_P (c))
 +      {
 +        if (ascii_compatible)
 +          EMIT_ONE_ASCII_BYTE (c);
          else
            {
 -            if (coding->flags & CODING_FLAG_ISO_RESET_AT_CNTL)
 -              ENCODE_RESET_PLANE_AND_REGISTER;
 -            *dst++ = c;
 +            struct charset *charset = CHARSET_FROM_ID (charset_ascii);
 +            ENCODE_ISO_CHARACTER (charset, c);
            }
        }
 -      else if (ASCII_BYTE_P (c))
 -      ENCODE_ISO_CHARACTER (c);
 -      else if (SINGLE_BYTE_CHAR_P (c))
 +      else if (CHAR_BYTE8_P (c))
        {
 -        *dst++ = c;
 -        coding->errors++;
 +        c = CHAR_TO_BYTE8 (c);
 +        EMIT_ONE_BYTE (c);
        }
 -      else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR
 -             && ! CODING_SAFE_CHAR_P (safe_chars, c))
 -      ENCODE_UNSAFE_CHARACTER (c);
        else
 -      ENCODE_ISO_CHARACTER (c);
 +      {
 +        struct charset *charset;
  
 -      coding->consumed_char++;
 +        if (preferred_charset_id >= 0)
 +          {
 +            charset = CHARSET_FROM_ID (preferred_charset_id);
 +            if (! CHAR_CHARSET_P (c, charset))
 +              charset = char_charset (c, charset_list, NULL);
 +          }
 +        else
 +          charset = char_charset (c, charset_list, NULL);
 +        if (!charset)
 +          {
 +            if (coding->mode & CODING_MODE_SAFE_ENCODING)
 +              {
 +                c = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
 +                charset = CHARSET_FROM_ID (charset_ascii);
 +              }
 +            else
 +              {
 +                c = coding->default_char;
 +                charset = char_charset (c, charset_list, NULL);
 +              }
 +          }
 +        ENCODE_ISO_CHARACTER (charset, c);
 +      }
      }
  
 - label_end_of_loop:
 -  coding->consumed = src_base - source;
 -  coding->produced = coding->produced_char = dst - destination;
 +  if (coding->mode & CODING_MODE_LAST_BLOCK
 +      && CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_RESET_AT_EOL)
 +    {
 +      ASSURE_DESTINATION (safe_room);
 +      ENCODE_RESET_PLANE_AND_REGISTER ();
 +    }
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  CODING_ISO_BOL (coding) = bol_designation;
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
 +  return 0;
  }
  
  \f
 -/*** 4. SJIS and BIG5 handlers ***/
 +/*** 8,9. SJIS and BIG5 handlers ***/
  
 -/* Although SJIS and BIG5 are not ISO coding systems, they are used
 +/* Although SJIS and BIG5 are not ISO's coding system, they are used
     quite widely.  So, for the moment, Emacs supports them in the bare
     C code.  But, in the future, they may be supported only by CCL.  */
  
     as is.  A character of charset katakana-jisx0201 is encoded by
     "position-code + 0x80".  A character of charset japanese-jisx0208
     is encoded in 2-byte but two position-codes are divided and shifted
 -   so that it fits in the range below.
 +   so that it fit in the range below.
  
     --- CODE RANGE of SJIS ---
     (character set)    (range)
     ASCII              0x00 .. 0x7F
 -   KATAKANA-JISX0201  0xA1 .. 0xDF
 +   KATAKANA-JISX0201  0xA0 .. 0xDF
     JISX0208 (1st byte)        0x81 .. 0x9F and 0xE0 .. 0xEF
            (2nd byte)  0x40 .. 0x7E and 0x80 .. 0xFC
     -------------------------------
  
  /* BIG5 is a coding system encoding two character sets: ASCII and
     Big5.  An ASCII character is encoded as is.  Big5 is a two-byte
 -   character set and is encoded in two bytes.
 +   character set and is encoded in two-byte.
  
     --- CODE RANGE of BIG5 ---
     (character set)    (range)
        (2nd byte)      0x40 .. 0x7E and 0xA1 .. 0xFE
     --------------------------
  
 -   Since the number of characters in Big5 is larger than maximum
 -   characters in Emacs' charset (96x96), it can't be handled as one
 -   charset.  So, in Emacs, Big5 is divided into two: `charset-big5-1'
 -   and `charset-big5-2'.  Both are DIMENSION2 and CHARS94.  The former
 -   contains frequently used characters and the latter contains less
 -   frequently used characters.  */
 -
 -/* Macros to decode or encode a character of Big5 in BIG5.  B1 and B2
 -   are the 1st and 2nd position-codes of Big5 in BIG5 coding system.
 -   C1 and C2 are the 1st and 2nd position-codes of Emacs' internal
 -   format.  CHARSET is `charset_big5_1' or `charset_big5_2'.  */
 -
 -/* Number of Big5 characters which have the same code in 1st byte.  */
 -#define BIG5_SAME_ROW (0xFF - 0xA1 + 0x7F - 0x40)
 -
 -#define DECODE_BIG5(b1, b2, charset, c1, c2)                          \
 -  do {                                                                        \
 -    unsigned int temp                                                 \
 -      = (b1 - 0xA1) * BIG5_SAME_ROW + b2 - (b2 < 0x7F ? 0x40 : 0x62); \
 -    if (b1 < 0xC9)                                                    \
 -      charset = charset_big5_1;                                               \
 -    else                                                              \
 -      {                                                                       \
 -      charset = charset_big5_2;                                       \
 -      temp -= (0xC9 - 0xA1) * BIG5_SAME_ROW;                          \
 -      }                                                                       \
 -    c1 = temp / (0xFF - 0xA1) + 0x21;                                 \
 -    c2 = temp % (0xFF - 0xA1) + 0x21;                                 \
 -  } while (0)
 -
 -#define ENCODE_BIG5(charset, c1, c2, b1, b2)                          \
 -  do {                                                                        \
 -    unsigned int temp = (c1 - 0x21) * (0xFF - 0xA1) + (c2 - 0x21);    \
 -    if (charset == charset_big5_2)                                    \
 -      temp += BIG5_SAME_ROW * (0xC9 - 0xA1);                          \
 -    b1 = temp / BIG5_SAME_ROW + 0xA1;                                 \
 -    b2 = temp % BIG5_SAME_ROW;                                                \
 -    b2 += b2 < 0x3F ? 0x40 : 0x62;                                    \
 -  } while (0)
 +  */
  
  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
     Check if a text is encoded in SJIS.  If it is, return
 -   CODING_CATEGORY_MASK_SJIS, else return 0.  */
 +   CATEGORY_MASK_SJIS, else return 0.  */
  
  static int
 -detect_coding_sjis (src, src_end, multibytep)
 -     unsigned char *src, *src_end;
 -     int multibytep;
 +detect_coding_sjis (coding, detect_info)
 +     struct coding_system *coding;
 +     struct coding_detection_info *detect_info;
  {
 +  const unsigned char *src = coding->source, *src_base;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  int found = 0;
    int c;
 -  /* Dummy for ONE_MORE_BYTE.  */
 -  struct coding_system dummy_coding;
 -  struct coding_system *coding = &dummy_coding;
 +
 +  detect_info->checked |= CATEGORY_MASK_SJIS;
 +  /* A coding system of this category is always ASCII compatible.  */
 +  src += coding->head_ascii;
  
    while (1)
      {
 -      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, CODING_CATEGORY_MASK_SJIS);
 +      src_base = src;
 +      ONE_MORE_BYTE (c);
        if (c < 0x80)
        continue;
 -      if (c == 0x80 || c == 0xA0 || c > 0xEF)
 -      return 0;
 -      if (c <= 0x9F || c >= 0xE0)
 +      if ((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xEF))
        {
 -        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, 0);
 +        ONE_MORE_BYTE (c);
          if (c < 0x40 || c == 0x7F || c > 0xFC)
 -          return 0;
 +          break;
 +        found = CATEGORY_MASK_SJIS;
        }
 +      else if (c >= 0xA0 && c < 0xE0)
 +      found = CATEGORY_MASK_SJIS;
 +      else
 +      break;
 +    }
 +  detect_info->rejected |= CATEGORY_MASK_SJIS;
 +  return 0;
 +
 + no_more_source:
 +  if (src_base < src && coding->mode & CODING_MODE_LAST_BLOCK)
 +    {
 +      detect_info->rejected |= CATEGORY_MASK_SJIS;
 +      return 0;
      }
 +  detect_info->found |= found;
 +  return 1;
  }
  
  /* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
     Check if a text is encoded in BIG5.  If it is, return
 -   CODING_CATEGORY_MASK_BIG5, else return 0.  */
 +   CATEGORY_MASK_BIG5, else return 0.  */
  
  static int
 -detect_coding_big5 (src, src_end, multibytep)
 -     unsigned char *src, *src_end;
 -     int multibytep;
 +detect_coding_big5 (coding, detect_info)
 +     struct coding_system *coding;
 +     struct coding_detection_info *detect_info;
  {
 +  const unsigned char *src = coding->source, *src_base;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  int found = 0;
    int c;
 -  /* Dummy for ONE_MORE_BYTE.  */
 -  struct coding_system dummy_coding;
 -  struct coding_system *coding = &dummy_coding;
 +
 +  detect_info->checked |= CATEGORY_MASK_BIG5;
 +  /* A coding system of this category is always ASCII compatible.  */
 +  src += coding->head_ascii;
  
    while (1)
      {
 -      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, CODING_CATEGORY_MASK_BIG5);
 +      src_base = src;
 +      ONE_MORE_BYTE (c);
        if (c < 0x80)
        continue;
 -      if (c < 0xA1 || c > 0xFE)
 -      return 0;
 -      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, 0);
 -      if (c < 0x40 || (c > 0x7F && c < 0xA1) || c > 0xFE)
 -      return 0;
 +      if (c >= 0xA1)
 +      {
 +        ONE_MORE_BYTE (c);
 +        if (c < 0x40 || (c >= 0x7F && c <= 0xA0))
 +          return 0;
 +        found = CATEGORY_MASK_BIG5;
 +      }
 +      else
 +      break;
 +    }
 +  detect_info->rejected |= CATEGORY_MASK_BIG5;
 +  return 0;
 +
 + no_more_source:
 +  if (src_base < src && coding->mode & CODING_MODE_LAST_BLOCK)
 +    {
 +      detect_info->rejected |= CATEGORY_MASK_BIG5;
 +      return 0;
 +    }
 +  detect_info->found |= found;
 +  return 1;
 +}
 +
 +/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".
 +   If SJIS_P is 1, decode SJIS text, else decode BIG5 test.  */
 +
 +static void
 +decode_coding_sjis (coding)
 +     struct coding_system *coding;
 +{
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  const unsigned char *src_base;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end
 +    = coding->charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
 +  int consumed_chars = 0, consumed_chars_base;
 +  int multibytep = coding->src_multibyte;
 +  struct charset *charset_roman, *charset_kanji, *charset_kana;
 +  struct charset *charset_kanji2;
 +  Lisp_Object attrs, charset_list, val;
 +  int char_offset = coding->produced_char;
 +  int last_offset = char_offset;
 +  int last_id = charset_ascii;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +
 +  val = charset_list;
 +  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kanji2 = NILP (val) ? NULL : CHARSET_FROM_ID (XINT (XCAR (val)));
 +
 +  while (1)
 +    {
 +      int c, c1;
 +      struct charset *charset;
 +
 +      src_base = src;
 +      consumed_chars_base = consumed_chars;
 +
 +      if (charbuf >= charbuf_end)
 +      break;
 +
 +      ONE_MORE_BYTE (c);
 +      if (c < 0)
 +      goto invalid_code;
 +      if (c < 0x80)
 +      charset = charset_roman;
 +      else if (c == 0x80 || c == 0xA0)
 +      goto invalid_code;
 +      else if (c >= 0xA1 && c <= 0xDF)
 +      {
 +        /* SJIS -> JISX0201-Kana */
 +        c &= 0x7F;
 +        charset = charset_kana;
 +      }
 +      else if (c <= 0xEF)
 +      {
 +        /* SJIS -> JISX0208 */
 +        ONE_MORE_BYTE (c1);
 +        if (c1 < 0x40 || c1 == 0x7F || c1 > 0xFC)
 +          goto invalid_code;
 +        c = (c << 8) | c1;
 +        SJIS_TO_JIS (c);
 +        charset = charset_kanji;
 +      }
 +      else if (c <= 0xFC && charset_kanji2)
 +      {
 +        /* SJIS -> JISX0213-2 */
 +        ONE_MORE_BYTE (c1);
 +        if (c1 < 0x40 || c1 == 0x7F || c1 > 0xFC)
 +          goto invalid_code;
 +        c = (c << 8) | c1;
 +        SJIS_TO_JIS2 (c);
 +        charset = charset_kanji2;
 +      }
 +      else
 +      goto invalid_code;
 +      if (charset->id != charset_ascii
 +        && last_id != charset->id)
 +      {
 +        if (last_id != charset_ascii)
 +          ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +        last_id = charset->id;
 +        last_offset = char_offset;
 +      }
 +      CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c);
 +      *charbuf++ = c;
 +      char_offset++;
 +      continue;
 +
 +    invalid_code:
 +      src = src_base;
 +      consumed_chars = consumed_chars_base;
 +      ONE_MORE_BYTE (c);
 +      *charbuf++ = c < 0 ? -c : BYTE8_TO_CHAR (c);
 +      char_offset++;
 +      coding->errors++;
 +    }
 +
 + no_more_source:
 +  if (last_id != charset_ascii)
 +    ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +  coding->consumed_char += consumed_chars_base;
 +  coding->consumed = src_base - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
 +}
 +
 +static void
 +decode_coding_big5 (coding)
 +     struct coding_system *coding;
 +{
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  const unsigned char *src_base;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end
 +    = coding->charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
 +  int consumed_chars = 0, consumed_chars_base;
 +  int multibytep = coding->src_multibyte;
 +  struct charset *charset_roman, *charset_big5;
 +  Lisp_Object attrs, charset_list, val;
 +  int char_offset = coding->produced_char;
 +  int last_offset = char_offset;
 +  int last_id = charset_ascii;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  val = charset_list;
 +  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
 +
 +  while (1)
 +    {
 +      int c, c1;
 +      struct charset *charset;
 +
 +      src_base = src;
 +      consumed_chars_base = consumed_chars;
 +
 +      if (charbuf >= charbuf_end)
 +      break;
 +
 +      ONE_MORE_BYTE (c);
 +
 +      if (c < 0)
 +      goto invalid_code;
 +      if (c < 0x80)
 +      charset = charset_roman;
 +      else
 +      {
 +        /* BIG5 -> Big5 */
 +        if (c < 0xA1 || c > 0xFE)
 +          goto invalid_code;
 +        ONE_MORE_BYTE (c1);
 +        if (c1 < 0x40 || (c1 > 0x7E && c1 < 0xA1) || c1 > 0xFE)
 +          goto invalid_code;
 +        c = c << 8 | c1;
 +        charset = charset_big5;
 +      }
 +      if (charset->id != charset_ascii
 +        && last_id != charset->id)
 +      {
 +        if (last_id != charset_ascii)
 +          ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +        last_id = charset->id;
 +        last_offset = char_offset;
 +      }
 +      CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c);
 +      *charbuf++ = c;
 +      char_offset++;
 +      continue;
 +
 +    invalid_code:
 +      src = src_base;
 +      consumed_chars = consumed_chars_base;
 +      ONE_MORE_BYTE (c);
 +      *charbuf++ = c < 0 ? -c : BYTE8_TO_CHAR (c);
 +      char_offset++;
 +      coding->errors++;
 +    }
 +
 + no_more_source:
 +  if (last_id != charset_ascii)
 +    ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +  coding->consumed_char += consumed_chars_base;
 +  coding->consumed = src_base - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
 +}
 +
 +/* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".
 +   This function can encode charsets `ascii', `katakana-jisx0201',
 +   `japanese-jisx0208', `chinese-big5-1', and `chinese-big5-2'.  We
 +   are sure that all these charsets are registered as official charset
 +   (i.e. do not have extended leading-codes).  Characters of other
 +   charsets are produced without any encoding.  If SJIS_P is 1, encode
 +   SJIS text, else encode BIG5 text.  */
 +
 +static int
 +encode_coding_sjis (coding)
 +     struct coding_system *coding;
 +{
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int safe_room = 4;
 +  int produced_chars = 0;
 +  Lisp_Object attrs, charset_list, val;
 +  int ascii_compatible;
 +  struct charset *charset_roman, *charset_kanji, *charset_kana;
 +  struct charset *charset_kanji2;
 +  int c;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  val = charset_list;
 +  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kanji2 = NILP (val) ? NULL : CHARSET_FROM_ID (XINT (XCAR (val)));
 +
 +  ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
 +
 +  while (charbuf < charbuf_end)
 +    {
 +      ASSURE_DESTINATION (safe_room);
 +      c = *charbuf++;
 +      /* Now encode the character C.  */
 +      if (ASCII_CHAR_P (c) && ascii_compatible)
 +      EMIT_ONE_ASCII_BYTE (c);
 +      else if (CHAR_BYTE8_P (c))
 +      {
 +        c = CHAR_TO_BYTE8 (c);
 +        EMIT_ONE_BYTE (c);
 +      }
 +      else
 +      {
 +        unsigned code;
 +        struct charset *charset = char_charset (c, charset_list, &code);
 +
 +        if (!charset)
 +          {
 +            if (coding->mode & CODING_MODE_SAFE_ENCODING)
 +              {
 +                code = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
 +                charset = CHARSET_FROM_ID (charset_ascii);
 +              }
 +            else
 +              {
 +                c = coding->default_char;
 +                charset = char_charset (c, charset_list, &code);
 +              }
 +          }
 +        if (code == CHARSET_INVALID_CODE (charset))
 +          abort ();
 +        if (charset == charset_kanji)
 +          {
 +            int c1, c2;
 +            JIS_TO_SJIS (code);
 +            c1 = code >> 8, c2 = code & 0xFF;
 +            EMIT_TWO_BYTES (c1, c2);
 +          }
 +        else if (charset == charset_kana)
 +          EMIT_ONE_BYTE (code | 0x80);
 +        else if (charset_kanji2 && charset == charset_kanji2)
 +          {
 +            int c1, c2;
 +
 +            c1 = code >> 8;
 +            if (c1 == 0x21 || (c1 >= 0x23 && c1 < 0x25)
 +                || (c1 >= 0x2C && c1 <= 0x2F) || c1 >= 0x6E)
 +              {
 +                JIS_TO_SJIS2 (code);
 +                c1 = code >> 8, c2 = code & 0xFF;
 +                EMIT_TWO_BYTES (c1, c2);
 +              }
 +            else
 +              EMIT_ONE_ASCII_BYTE (code & 0x7F);
 +          }
 +        else
 +          EMIT_ONE_ASCII_BYTE (code & 0x7F);
 +      }
 +    }
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
 +  return 0;
 +}
 +
 +static int
 +encode_coding_big5 (coding)
 +     struct coding_system *coding;
 +{
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int safe_room = 4;
 +  int produced_chars = 0;
 +  Lisp_Object attrs, charset_list, val;
 +  int ascii_compatible;
 +  struct charset *charset_roman, *charset_big5;
 +  int c;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  val = charset_list;
 +  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
 +  ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
 +
 +  while (charbuf < charbuf_end)
 +    {
 +      ASSURE_DESTINATION (safe_room);
 +      c = *charbuf++;
 +      /* Now encode the character C.  */
 +      if (ASCII_CHAR_P (c) && ascii_compatible)
 +      EMIT_ONE_ASCII_BYTE (c);
 +      else if (CHAR_BYTE8_P (c))
 +      {
 +        c = CHAR_TO_BYTE8 (c);
 +        EMIT_ONE_BYTE (c);
 +      }
 +      else
 +      {
 +        unsigned code;
 +        struct charset *charset = char_charset (c, charset_list, &code);
 +
 +        if (! charset)
 +          {
 +            if (coding->mode & CODING_MODE_SAFE_ENCODING)
 +              {
 +                code = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
 +                charset = CHARSET_FROM_ID (charset_ascii);
 +              }
 +            else
 +              {
 +                c = coding->default_char;
 +                charset = char_charset (c, charset_list, &code);
 +              }
 +          }
 +        if (code == CHARSET_INVALID_CODE (charset))
 +          abort ();
 +        if (charset == charset_big5)
 +          {
 +            int c1, c2;
 +
 +            c1 = code >> 8, c2 = code & 0xFF;
 +            EMIT_TWO_BYTES (c1, c2);
 +          }
 +        else
 +          EMIT_ONE_ASCII_BYTE (code & 0x7F);
 +      }
      }
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
 +  return 0;
  }
  
 -/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 -   Check if a text is encoded in UTF-8.  If it is, return
 -   CODING_CATEGORY_MASK_UTF_8, else return 0.  */
 +\f
 +/*** 10. CCL handlers ***/
  
 -#define UTF_8_1_OCTET_P(c)         ((c) < 0x80)
 -#define UTF_8_EXTRA_OCTET_P(c)     (((c) & 0xC0) == 0x80)
 -#define UTF_8_2_OCTET_LEADING_P(c) (((c) & 0xE0) == 0xC0)
 -#define UTF_8_3_OCTET_LEADING_P(c) (((c) & 0xF0) == 0xE0)
 -#define UTF_8_4_OCTET_LEADING_P(c) (((c) & 0xF8) == 0xF0)
 -#define UTF_8_5_OCTET_LEADING_P(c) (((c) & 0xFC) == 0xF8)
 -#define UTF_8_6_OCTET_LEADING_P(c) (((c) & 0xFE) == 0xFC)
 +/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 +   Check if a text is encoded in a coding system of which
 +   encoder/decoder are written in CCL program.  If it is, return
 +   CATEGORY_MASK_CCL, else return 0.  */
  
  static int
 -detect_coding_utf_8 (src, src_end, multibytep)
 -     unsigned char *src, *src_end;
 -     int multibytep;
 +detect_coding_ccl (coding, detect_info)
 +     struct coding_system *coding;
 +     struct coding_detection_info *detect_info;
  {
 -  unsigned char c;
 -  int seq_maybe_bytes;
 -  /* Dummy for ONE_MORE_BYTE.  */
 -  struct coding_system dummy_coding;
 -  struct coding_system *coding = &dummy_coding;
 +  const unsigned char *src = coding->source, *src_base;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  int found = 0;
 +  unsigned char *valids;
 +  int head_ascii = coding->head_ascii;
 +  Lisp_Object attrs;
 +
 +  detect_info->checked |= CATEGORY_MASK_CCL;
 +
 +  coding = &coding_categories[coding_category_ccl];
 +  valids = CODING_CCL_VALIDS (coding);
 +  attrs = CODING_ID_ATTRS (coding->id);
 +  if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
 +    src += head_ascii;
  
    while (1)
      {
 -      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, CODING_CATEGORY_MASK_UTF_8);
 -      if (UTF_8_1_OCTET_P (c))
 -      continue;
 -      else if (UTF_8_2_OCTET_LEADING_P (c))
 -      seq_maybe_bytes = 1;
 -      else if (UTF_8_3_OCTET_LEADING_P (c))
 -      seq_maybe_bytes = 2;
 -      else if (UTF_8_4_OCTET_LEADING_P (c))
 -      seq_maybe_bytes = 3;
 -      else if (UTF_8_5_OCTET_LEADING_P (c))
 -      seq_maybe_bytes = 4;
 -      else if (UTF_8_6_OCTET_LEADING_P (c))
 -      seq_maybe_bytes = 5;
 -      else
 -      return 0;
 +      int c;
  
 -      do
 -      {
 -        ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, 0);
 -        if (!UTF_8_EXTRA_OCTET_P (c))
 -          return 0;
 -        seq_maybe_bytes--;
 -      }
 -      while (seq_maybe_bytes > 0);
 +      src_base = src;
 +      ONE_MORE_BYTE (c);
 +      if (c < 0 || ! valids[c])
 +      break;
 +      if ((valids[c] > 1))
 +      found = CATEGORY_MASK_CCL;
      }
 +  detect_info->rejected |= CATEGORY_MASK_CCL;
 +  return 0;
 +
 + no_more_source:
 +  detect_info->found |= found;
 +  return 1;
  }
  
 -/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 -   Check if a text is encoded in UTF-16 Big Endian (endian == 1) or
 -   Little Endian (otherwise).  If it is, return
 -   CODING_CATEGORY_MASK_UTF_16_BE or CODING_CATEGORY_MASK_UTF_16_LE,
 -   else return 0.  */
 +static void
 +decode_coding_ccl (coding)
 +     struct coding_system *coding;
 +{
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end = coding->charbuf + coding->charbuf_size;
 +  int consumed_chars = 0;
 +  int multibytep = coding->src_multibyte;
 +  struct ccl_program ccl;
 +  int source_charbuf[1024];
 +  int source_byteidx[1024];
 +  Lisp_Object attrs, charset_list;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  setup_ccl_program (&ccl, CODING_CCL_DECODER (coding));
 +
 +  while (src < src_end)
 +    {
 +      const unsigned char *p = src;
 +      int *source, *source_end;
 +      int i = 0;
 +
 +      if (multibytep)
 +      while (i < 1024 && p < src_end)
 +        {
 +          source_byteidx[i] = p - src;
 +          source_charbuf[i++] = STRING_CHAR_ADVANCE (p);
 +        }
 +      else
 +      while (i < 1024 && p < src_end)
 +        source_charbuf[i++] = *p++;
  
 -#define UTF_16_INVALID_P(val) \
 -  (((val) == 0xFFFE)          \
 -   || ((val) == 0xFFFF))
 +      if (p == src_end && coding->mode & CODING_MODE_LAST_BLOCK)
 +      ccl.last_block = 1;
  
 -#define UTF_16_HIGH_SURROGATE_P(val) \
 -  (((val) & 0xD800) == 0xD800)
 +      source = source_charbuf;
 +      source_end = source + i;
 +      while (source < source_end)
 +      {
 +        ccl_driver (&ccl, source, charbuf,
 +                    source_end - source, charbuf_end - charbuf,
 +                    charset_list);
 +        source += ccl.consumed;
 +        charbuf += ccl.produced;
 +        if (ccl.status != CCL_STAT_SUSPEND_BY_DST)
 +          break;
 +      }
 +      if (source < source_end)
 +      src += source_byteidx[source - source_charbuf];
 +      else
 +      src = p;
 +      consumed_chars += source - source_charbuf;
  
 -#define UTF_16_LOW_SURROGATE_P(val) \
 -  (((val) & 0xDC00) == 0xDC00)
 +      if (ccl.status != CCL_STAT_SUSPEND_BY_SRC
 +        && ccl.status != CODING_RESULT_INSUFFICIENT_SRC)
 +      break;
 +    }
 +
 +  switch (ccl.status)
 +    {
 +    case CCL_STAT_SUSPEND_BY_SRC:
 +      record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_SRC);
 +      break;
 +    case CCL_STAT_SUSPEND_BY_DST:
 +      break;
 +    case CCL_STAT_QUIT:
 +    case CCL_STAT_INVALID_CMD:
 +      record_conversion_result (coding, CODING_RESULT_INTERRUPT);
 +      break;
 +    default:
 +      record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +      break;
 +    }
 +  coding->consumed_char += consumed_chars;
 +  coding->consumed = src - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
 +}
  
  static int
 -detect_coding_utf_16 (src, src_end, multibytep)
 -     unsigned char *src, *src_end;
 -     int multibytep;
 +encode_coding_ccl (coding)
 +     struct coding_system *coding;
  {
 -  unsigned char c1, c2;
 -  /* Dummy for ONE_MORE_BYTE_CHECK_MULTIBYTE.  */
 -  struct coding_system dummy_coding;
 -  struct coding_system *coding = &dummy_coding;
 +  struct ccl_program ccl;
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int destination_charbuf[1024];
 +  int i, produced_chars = 0;
 +  Lisp_Object attrs, charset_list;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  setup_ccl_program (&ccl, CODING_CCL_ENCODER (coding));
 +
 +  ccl.last_block = coding->mode & CODING_MODE_LAST_BLOCK;
 +  ccl.dst_multibyte = coding->dst_multibyte;
 +
 +  while (charbuf < charbuf_end)
 +    {
 +      ccl_driver (&ccl, charbuf, destination_charbuf,
 +                charbuf_end - charbuf, 1024, charset_list);
 +      if (multibytep)
 +      {
 +        ASSURE_DESTINATION (ccl.produced * 2);
 +        for (i = 0; i < ccl.produced; i++)
 +          EMIT_ONE_BYTE (destination_charbuf[i] & 0xFF);
 +      }
 +      else
 +      {
 +        ASSURE_DESTINATION (ccl.produced);
 +        for (i = 0; i < ccl.produced; i++)    
 +          *dst++ = destination_charbuf[i] & 0xFF;
 +        produced_chars += ccl.produced;
 +      }
 +      charbuf += ccl.consumed;
 +      if (ccl.status == CCL_STAT_QUIT
 +        || ccl.status == CCL_STAT_INVALID_CMD)
 +      break;
 +    }
  
 -  ONE_MORE_BYTE_CHECK_MULTIBYTE (c1, multibytep, 0);
 -  ONE_MORE_BYTE_CHECK_MULTIBYTE (c2, multibytep, 0);
 +  switch (ccl.status)
 +    {
 +    case CCL_STAT_SUSPEND_BY_SRC:
 +      record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_SRC);
 +      break;
 +    case CCL_STAT_SUSPEND_BY_DST:
 +      record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_DST);
 +      break;
 +    case CCL_STAT_QUIT:
 +    case CCL_STAT_INVALID_CMD:
 +      record_conversion_result (coding, CODING_RESULT_INTERRUPT);
 +      break;
 +    default:
 +      record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +      break;
 +    }
  
 -  if ((c1 == 0xFF) && (c2 == 0xFE))
 -    return CODING_CATEGORY_MASK_UTF_16_LE;
 -  else if ((c1 == 0xFE) && (c2 == 0xFF))
 -    return CODING_CATEGORY_MASK_UTF_16_BE;
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
    return 0;
  }
  
 -/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".
 -   If SJIS_P is 1, decode SJIS text, else decode BIG5 test.  */
 +
 +\f
 +/*** 10, 11. no-conversion handlers ***/
 +
 +/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
  
  static void
 -decode_coding_sjis_big5 (coding, source, destination,
 -                       src_bytes, dst_bytes, sjis_p)
 +decode_coding_raw_text (coding)
       struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char  *destination;
 -     int src_bytes, dst_bytes;
 -     int sjis_p;
  {
 -  const unsigned char *src = source;
 -  const unsigned char *src_end = source + src_bytes;
 -  unsigned char *dst = destination;
 -  unsigned char *dst_end = destination + dst_bytes;
 -  /* SRC_BASE remembers the start position in source in each loop.
 -     The loop will be exited when there's not enough source code
 -     (within macro ONE_MORE_BYTE), or when there's not enough
 -     destination area to produce a character (within macro
 -     EMIT_CHAR).  */
 -  const unsigned char *src_base;
 -  Lisp_Object translation_table;
 +  coding->chars_at_source = 1;
 +  coding->consumed_char = 0;
 +  coding->consumed = 0;
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +}
  
 -  if (NILP (Venable_character_translation))
 -    translation_table = Qnil;
 -  else
 -    {
 -      translation_table = coding->translation_table_for_decode;
 -      if (NILP (translation_table))
 -      translation_table = Vstandard_translation_table_for_decode;
 -    }
 +static int
 +encode_coding_raw_text (coding)
 +     struct coding_system *coding;
 +{
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = coding->charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int produced_chars = 0;
 +  int c;
  
 -  coding->produced_char = 0;
 -  while (1)
 +  if (multibytep)
      {
 -      int c, charset, c1, c2 = 0;
 +      int safe_room = MAX_MULTIBYTE_LENGTH * 2;
  
 -      src_base = src;
 -      ONE_MORE_BYTE (c1);
 +      if (coding->src_multibyte)
 +      while (charbuf < charbuf_end)
 +        {
 +          ASSURE_DESTINATION (safe_room);
 +          c = *charbuf++;
 +          if (ASCII_CHAR_P (c))
 +            EMIT_ONE_ASCII_BYTE (c);
 +          else if (CHAR_BYTE8_P (c))
 +            {
 +              c = CHAR_TO_BYTE8 (c);
 +              EMIT_ONE_BYTE (c);
 +            }
 +          else
 +            {
 +              unsigned char str[MAX_MULTIBYTE_LENGTH], *p0 = str, *p1 = str;
  
 -      if (c1 < 0x80)
 +              CHAR_STRING_ADVANCE (c, p1);
 +              while (p0 < p1)
 +                {
 +                  EMIT_ONE_BYTE (*p0);
 +                  p0++;
 +                }
 +            }
 +        }
 +      else
 +      while (charbuf < charbuf_end)
 +        {
 +          ASSURE_DESTINATION (safe_room);
 +          c = *charbuf++;
 +          EMIT_ONE_BYTE (c);
 +        }
 +    }
 +  else
 +    {
 +      if (coding->src_multibyte)
        {
 -        charset = CHARSET_ASCII;
 -        if (c1 < 0x20)
 +        int safe_room = MAX_MULTIBYTE_LENGTH;
 +
 +        while (charbuf < charbuf_end)
            {
 -            if (c1 == '\r')
 -              {
 -                if (coding->eol_type == CODING_EOL_CRLF)
 -                  {
 -                    ONE_MORE_BYTE (c2);
 -                    if (c2 == '\n')
 -                      c1 = c2;
 -                    else
 -                      /* To process C2 again, SRC is subtracted by 1.  */
 -                      src--;
 -                  }
 -                else if (coding->eol_type == CODING_EOL_CR)
 -                  c1 = '\n';
 -              }
 -            else if (c1 == '\n'
 -                     && (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
 -                     && (coding->eol_type == CODING_EOL_CR
 -                         || coding->eol_type == CODING_EOL_CRLF))
 -              {
 -                coding->result = CODING_FINISH_INCONSISTENT_EOL;
 -                goto label_end_of_loop;
 -              }
 +            ASSURE_DESTINATION (safe_room);
 +            c = *charbuf++;
 +            if (ASCII_CHAR_P (c))
 +              *dst++ = c;
 +            else if (CHAR_BYTE8_P (c))
 +              *dst++ = CHAR_TO_BYTE8 (c);
 +            else
 +              CHAR_STRING_ADVANCE (c, dst);
 +            produced_chars++;
            }
        }
        else
 -        {
 -        if (sjis_p)
 -          {
 -            if (c1 == 0x80 || c1 == 0xA0 || c1 > 0xEF)
 -              goto label_invalid_code;
 -            if (c1 <= 0x9F || c1 >= 0xE0)
 -              {
 -                /* SJIS -> JISX0208 */
 -                ONE_MORE_BYTE (c2);
 -                if (c2 < 0x40 || c2 == 0x7F || c2 > 0xFC)
 -                  goto label_invalid_code;
 -                DECODE_SJIS (c1, c2, c1, c2);
 -                charset = charset_jisx0208;
 -              }
 -            else
 -              /* SJIS -> JISX0201-Kana */
 -              charset = charset_katakana_jisx0201;
 -          }
 -        else
 -          {
 -            /* BIG5 -> Big5 */
 -            if (c1 < 0xA0 || c1 > 0xFE)
 -              goto label_invalid_code;
 -            ONE_MORE_BYTE (c2);
 -            if (c2 < 0x40 || (c2 > 0x7E && c2 < 0xA1) || c2 > 0xFE)
 -              goto label_invalid_code;
 -            DECODE_BIG5 (c1, c2, charset, c1, c2);
 -          }
 +      {
 +        ASSURE_DESTINATION (charbuf_end - charbuf);
 +        while (charbuf < charbuf_end && dst < dst_end)
 +          *dst++ = *charbuf++;
 +        produced_chars = dst - (coding->destination + coding->dst_bytes);
        }
 -
 -      c = DECODE_ISO_CHARACTER (charset, c1, c2);
 -      EMIT_CHAR (c);
 -      continue;
 -
 -    label_invalid_code:
 -      coding->errors++;
 -      src = src_base;
 -      c = *src++;
 -      EMIT_CHAR (c);
      }
 -
 - label_end_of_loop:
 -  coding->consumed = coding->consumed_char = src_base - source;
 -  coding->produced = dst - destination;
 -  return;
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
 +  return 0;
  }
  
 -/* See the above "GENERAL NOTES on `encode_coding_XXX ()' functions".
 -   This function can encode charsets `ascii', `katakana-jisx0201',
 -   `japanese-jisx0208', `chinese-big5-1', and `chinese-big5-2'.  We
 -   are sure that all these charsets are registered as official charset
 -   (i.e. do not have extended leading-codes).  Characters of other
 -   charsets are produced without any encoding.  If SJIS_P is 1, encode
 -   SJIS text, else encode BIG5 text.  */
 +/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 +   Check if a text is encoded in a charset-based coding system.  If it
 +   is, return 1, else return 0.  */
  
 -static void
 -encode_coding_sjis_big5 (coding, source, destination,
 -                       src_bytes, dst_bytes, sjis_p)
 +static int
 +detect_coding_charset (coding, detect_info)
       struct coding_system *coding;
 -     unsigned char *source, *destination;
 -     int src_bytes, dst_bytes;
 -     int sjis_p;
 +     struct coding_detection_info *detect_info;
  {
 -  unsigned char *src = source;
 -  unsigned char *src_end = source + src_bytes;
 -  unsigned char *dst = destination;
 -  unsigned char *dst_end = destination + dst_bytes;
 -  /* SRC_BASE remembers the start position in source in each loop.
 -     The loop will be exited when there's not enough source text to
 -     analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
 -     there's not enough destination area to produce encoded codes
 -     (within macro EMIT_BYTES).  */
 -  unsigned char *src_base;
 -  Lisp_Object translation_table;
 +  const unsigned char *src = coding->source, *src_base;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  int multibytep = coding->src_multibyte;
 +  int consumed_chars = 0;
 +  Lisp_Object attrs, valids;
 +  int found = 0;
 +  int head_ascii = coding->head_ascii;
  
 -  if (NILP (Venable_character_translation))
 -    translation_table = Qnil;
 -  else
 -    {
 -      translation_table = coding->translation_table_for_encode;
 -      if (NILP (translation_table))
 -      translation_table = Vstandard_translation_table_for_encode;
 -    }
 +  detect_info->checked |= CATEGORY_MASK_CHARSET;
 +
 +  coding = &coding_categories[coding_category_charset];
 +  attrs = CODING_ID_ATTRS (coding->id);
 +  valids = AREF (attrs, coding_attr_charset_valids);
 +
 +  if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
 +    src += head_ascii;
  
    while (1)
      {
 -      int c, charset, c1, c2;
 +      int c;
 +      Lisp_Object val;
 +      struct charset *charset;
 +      int dim, idx;
  
        src_base = src;
 -      ONE_MORE_CHAR (c);
 -
 -      /* Now encode the character C.  */
 -      if (SINGLE_BYTE_CHAR_P (c))
 +      ONE_MORE_BYTE (c);
 +      if (c < 0)
 +      continue;
 +      val = AREF (valids, c);
 +      if (NILP (val))
 +      break;
 +      if (c >= 0x80)
 +      found = CATEGORY_MASK_CHARSET;
 +      if (INTEGERP (val))
        {
 -        switch (c)
 +        charset = CHARSET_FROM_ID (XFASTINT (val));
 +        dim = CHARSET_DIMENSION (charset);
 +        for (idx = 1; idx < dim; idx++)
            {
 -          case '\r':
 -            if (!(coding->mode & CODING_MODE_SELECTIVE_DISPLAY))
 -              {
 -                EMIT_ONE_BYTE (c);
 -                break;
 -              }
 -            c = '\n';
 -          case '\n':
 -            if (coding->eol_type == CODING_EOL_CRLF)
 -              {
 -                EMIT_TWO_BYTES ('\r', c);
 -                break;
 -              }
 -            else if (coding->eol_type == CODING_EOL_CR)
 -              c = '\r';
 -          default:
 -            EMIT_ONE_BYTE (c);
 +            if (src == src_end)
 +              goto too_short;
 +            ONE_MORE_BYTE (c);
 +            if (c < charset->code_space[(dim - 1 - idx) * 2] 
 +                || c > charset->code_space[(dim - 1 - idx) * 2 + 1])
 +              break;
            }
 +        if (idx < dim)
 +          break;
        }
        else
        {
 -        SPLIT_CHAR (c, charset, c1, c2);
 -        if (sjis_p)
 -          {
 -            if (charset == charset_jisx0208
 -                || charset == charset_jisx0208_1978)
 -              {
 -                ENCODE_SJIS (c1, c2, c1, c2);
 -                EMIT_TWO_BYTES (c1, c2);
 -              }
 -            else if (charset == charset_katakana_jisx0201)
 -              EMIT_ONE_BYTE (c1 | 0x80);
 -            else if (charset == charset_latin_jisx0201)
 -              EMIT_ONE_BYTE (c1);
 -            else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR)
 -              {
 -                EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
 -                if (CHARSET_WIDTH (charset) > 1)
 -                  EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
 -              }
 -            else
 -              /* There's no way other than producing the internal
 -                 codes as is.  */
 -              EMIT_BYTES (src_base, src);
 -          }
 -        else
 +        idx = 1;
 +        for (; CONSP (val); val = XCDR (val))
            {
 -            if (charset == charset_big5_1 || charset == charset_big5_2)
 +            charset = CHARSET_FROM_ID (XFASTINT (XCAR (val)));
 +            dim = CHARSET_DIMENSION (charset);
 +            while (idx < dim)
                {
 -                ENCODE_BIG5 (charset, c1, c2, c1, c2);
 -                EMIT_TWO_BYTES (c1, c2);
 +                if (src == src_end)
 +                  goto too_short;
 +                ONE_MORE_BYTE (c);
 +                if (c < charset->code_space[(dim - 1 - idx) * 4]
 +                    || c > charset->code_space[(dim - 1 - idx) * 4 + 1])
 +                  break;
 +                idx++;
                }
 -            else if (coding->mode & CODING_MODE_INHIBIT_UNENCODABLE_CHAR)
 +            if (idx == dim)
                {
 -                EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
 -                if (CHARSET_WIDTH (charset) > 1)
 -                  EMIT_ONE_BYTE (CODING_REPLACEMENT_CHARACTER);
 +                val = Qnil;
 +                break;
                }
 -            else
 -              /* There's no way other than producing the internal
 -                 codes as is.  */
 -              EMIT_BYTES (src_base, src);
            }
 +        if (CONSP (val))
 +          break;
        }
 -      coding->consumed_char++;
      }
 + too_short:
 +  detect_info->rejected |= CATEGORY_MASK_CHARSET;
 +  return 0;
  
 - label_end_of_loop:
 -  coding->consumed = src_base - source;
 -  coding->produced = coding->produced_char = dst - destination;
 + no_more_source:
 +  detect_info->found |= found;
 +  return 1;
  }
  
 -\f
 -/*** 5. CCL handlers ***/
 -
 -/* See the above "GENERAL NOTES on `detect_coding_XXX ()' functions".
 -   Check if a text is encoded in a coding system of which
 -   encoder/decoder are written in CCL program.  If it is, return
 -   CODING_CATEGORY_MASK_CCL, else return 0.  */
 -
 -static int
 -detect_coding_ccl (src, src_end, multibytep)
 -     unsigned char *src, *src_end;
 -     int multibytep;
 +static void
 +decode_coding_charset (coding)
 +     struct coding_system *coding;
  {
 -  unsigned char *valid;
 -  int c;
 -  /* Dummy for ONE_MORE_BYTE.  */
 -  struct coding_system dummy_coding;
 -  struct coding_system *coding = &dummy_coding;
 -
 -  /* No coding system is assigned to coding-category-ccl.  */
 -  if (!coding_system_table[CODING_CATEGORY_IDX_CCL])
 -    return 0;
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  const unsigned char *src_base;
 +  int *charbuf = coding->charbuf + coding->charbuf_used;
 +  int *charbuf_end
 +    = coding->charbuf + coding->charbuf_size - MAX_ANNOTATION_LENGTH;
 +  int consumed_chars = 0, consumed_chars_base;
 +  int multibytep = coding->src_multibyte;
 +  Lisp_Object attrs, charset_list, valids;
 +  int char_offset = coding->produced_char;
 +  int last_offset = char_offset;
 +  int last_id = charset_ascii;
 +
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  valids = AREF (attrs, coding_attr_charset_valids);
  
 -  valid = coding_system_table[CODING_CATEGORY_IDX_CCL]->spec.ccl.valid_codes;
    while (1)
      {
 -      ONE_MORE_BYTE_CHECK_MULTIBYTE (c, multibytep, CODING_CATEGORY_MASK_CCL);
 -      if (! valid[c])
 -      return 0;
 -    }
 -}
 +      int c;
 +      Lisp_Object val;
 +      struct charset *charset;
 +      int dim;
 +      int len = 1;
 +      unsigned code;
  
 -\f
 -/*** 6. End-of-line handlers ***/
 +      src_base = src;
 +      consumed_chars_base = consumed_chars;
  
 -/* See the above "GENERAL NOTES on `decode_coding_XXX ()' functions".  */
 +      if (charbuf >= charbuf_end)
 +      break;
  
 -static void
 -decode_eol (coding, source, destination, src_bytes, dst_bytes)
 -     struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
 -{
 -  const unsigned char *src = source;
 -  unsigned char *dst = destination;
 -  const unsigned char *src_end = src + src_bytes;
 -  unsigned char *dst_end = dst + dst_bytes;
 -  Lisp_Object translation_table;
 -  /* SRC_BASE remembers the start position in source in each loop.
 -     The loop will be exited when there's not enough source code
 -     (within macro ONE_MORE_BYTE), or when there's not enough
 -     destination area to produce a character (within macro
 -     EMIT_CHAR).  */
 -  const unsigned char *src_base;
 -  int c;
 +      ONE_MORE_BYTE (c);
 +      if (c < 0)
 +      goto invalid_code;
 +      code = c;
  
 -  translation_table = Qnil;
 -  switch (coding->eol_type)
 -    {
 -    case CODING_EOL_CRLF:
 -      while (1)
 +      val = AREF (valids, c);
 +      if (NILP (val))
 +      goto invalid_code;
 +      if (INTEGERP (val))
        {
 -        src_base = src;
 -        ONE_MORE_BYTE (c);
 -        if (c == '\r')
 +        charset = CHARSET_FROM_ID (XFASTINT (val));
 +        dim = CHARSET_DIMENSION (charset);
 +        while (len < dim)
            {
              ONE_MORE_BYTE (c);
 -            if (c != '\n')
 -              {
 -                src--;
 -                c = '\r';
 -              }
 -          }
 -        else if (c == '\n'
 -                 && (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL))
 -          {
 -            coding->result = CODING_FINISH_INCONSISTENT_EOL;
 -            goto label_end_of_loop;
 +            code = (code << 8) | c;
 +            len++;
            }
 -        EMIT_CHAR (c);
 +        CODING_DECODE_CHAR (coding, src, src_base, src_end,
 +                            charset, code, c);
        }
 -      break;
 -
 -    case CODING_EOL_CR:
 -      while (1)
 +      else
        {
 -        src_base = src;
 -        ONE_MORE_BYTE (c);
 -        if (c == '\n')
 +        /* VAL is a list of charset IDs.  It is assured that the
 +           list is sorted by charset dimensions (smaller one
 +           comes first).  */
 +        while (CONSP (val))
            {
 -            if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
 +            charset = CHARSET_FROM_ID (XFASTINT (XCAR (val)));
 +            dim = CHARSET_DIMENSION (charset);
 +            while (len < dim)
                {
 -                coding->result = CODING_FINISH_INCONSISTENT_EOL;
 -                goto label_end_of_loop;
 +                ONE_MORE_BYTE (c);
 +                code = (code << 8) | c;
 +                len++;
                }
 +            CODING_DECODE_CHAR (coding, src, src_base,
 +                                src_end, charset, code, c);
 +            if (c >= 0)
 +              break;
 +            val = XCDR (val);
            }
 -        else if (c == '\r')
 -          c = '\n';
 -        EMIT_CHAR (c);
        }
 -      break;
 -
 -    default:                  /* no need for EOL handling */
 -      while (1)
 +      if (c < 0)
 +      goto invalid_code;
 +      if (charset->id != charset_ascii
 +        && last_id != charset->id)
        {
 -        src_base = src;
 -        ONE_MORE_BYTE (c);
 -        EMIT_CHAR (c);
 +        if (last_id != charset_ascii)
 +          ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +        last_id = charset->id;
 +        last_offset = char_offset;
        }
 +
 +      *charbuf++ = c;
 +      char_offset++;
 +      continue;
 +
 +    invalid_code:
 +      src = src_base;
 +      consumed_chars = consumed_chars_base;
 +      ONE_MORE_BYTE (c);
 +      *charbuf++ = c < 0 ? -c : ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
 +      char_offset++;
 +      coding->errors++;
      }
  
 - label_end_of_loop:
 -  coding->consumed = coding->consumed_char = src_base - source;
 -  coding->produced = dst - destination;
 -  return;
 + no_more_source:
 +  if (last_id != charset_ascii)
 +    ADD_CHARSET_DATA (charbuf, char_offset - last_offset, last_id);
 +  coding->consumed_char += consumed_chars_base;
 +  coding->consumed = src_base - coding->source;
 +  coding->charbuf_used = charbuf - coding->charbuf;
  }
  
 -/* See "GENERAL NOTES about `encode_coding_XXX ()' functions".  Encode
 -   format of end-of-line according to `coding->eol_type'.  It also
 -   convert multibyte form 8-bit characters to unibyte if
 -   CODING->src_multibyte is nonzero.  If `coding->mode &
 -   CODING_MODE_SELECTIVE_DISPLAY' is nonzero, code '\r' in source text
 -   also means end-of-line.  */
 -
 -static void
 -encode_eol (coding, source, destination, src_bytes, dst_bytes)
 +static int
 +encode_coding_charset (coding)
       struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
  {
 -  const unsigned char *src = source;
 -  unsigned char *dst = destination;
 -  const unsigned char *src_end = src + src_bytes;
 -  unsigned char *dst_end = dst + dst_bytes;
 -  Lisp_Object translation_table;
 -  /* SRC_BASE remembers the start position in source in each loop.
 -     The loop will be exited when there's not enough source text to
 -     analyze multi-byte codes (within macro ONE_MORE_CHAR), or when
 -     there's not enough destination area to produce encoded codes
 -     (within macro EMIT_BYTES).  */
 -  const unsigned char *src_base;
 -  unsigned char *tmp;
 +  int multibytep = coding->dst_multibyte;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int safe_room = MAX_MULTIBYTE_LENGTH;
 +  int produced_chars = 0;
 +  Lisp_Object attrs, charset_list;
 +  int ascii_compatible;
    int c;
 -  int selective_display = coding->mode & CODING_MODE_SELECTIVE_DISPLAY;
  
 -  translation_table = Qnil;
 -  if (coding->src_multibyte
 -      && *(src_end - 1) == LEADING_CODE_8_BIT_CONTROL)
 -    {
 -      src_end--;
 -      src_bytes--;
 -      coding->result = CODING_FINISH_INSUFFICIENT_SRC;
 -    }
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
  
 -  if (coding->eol_type == CODING_EOL_CRLF)
 -    {
 -      while (src < src_end)
 -      {
 -        src_base = src;
 -        c = *src++;
 -        if (c >= 0x20)
 -          EMIT_ONE_BYTE (c);
 -        else if (c == '\n' || (c == '\r' && selective_display))
 -          EMIT_TWO_BYTES ('\r', '\n');
 -        else
 -          EMIT_ONE_BYTE (c);
 -      }
 -      src_base = src;
 -    label_end_of_loop:
 -      ;
 -    }
 -  else
 +  while (charbuf < charbuf_end)
      {
 -      if (!dst_bytes || src_bytes <= dst_bytes)
 +      struct charset *charset;
 +      unsigned code;
 +
 +      ASSURE_DESTINATION (safe_room);
 +      c = *charbuf++;
 +      if (ascii_compatible && ASCII_CHAR_P (c))
 +      EMIT_ONE_ASCII_BYTE (c);
 +      else if (CHAR_BYTE8_P (c))
        {
 -        safe_bcopy (src, dst, src_bytes);
 -        src_base = src_end;
 -        dst += src_bytes;
 +        c = CHAR_TO_BYTE8 (c);
 +        EMIT_ONE_BYTE (c);
        }
        else
        {
 -        if (coding->src_multibyte
 -            && *(src + dst_bytes - 1) == LEADING_CODE_8_BIT_CONTROL)
 -          dst_bytes--;
 -        safe_bcopy (src, dst, dst_bytes);
 -        src_base = src + dst_bytes;
 -        dst = destination + dst_bytes;
 -        coding->result = CODING_FINISH_INSUFFICIENT_DST;
 -      }
 -      if (coding->eol_type == CODING_EOL_CR)
 -      {
 -        for (tmp = destination; tmp < dst; tmp++)
 -          if (*tmp == '\n') *tmp = '\r';
 -      }
 -      else if (selective_display)
 -      {
 -        for (tmp = destination; tmp < dst; tmp++)
 -          if (*tmp == '\r') *tmp = '\n';
 +        charset = char_charset (c, charset_list, &code);
 +        if (charset)
 +          {
 +            if (CHARSET_DIMENSION (charset) == 1)
 +              EMIT_ONE_BYTE (code);
 +            else if (CHARSET_DIMENSION (charset) == 2)
 +              EMIT_TWO_BYTES (code >> 8, code & 0xFF);
 +            else if (CHARSET_DIMENSION (charset) == 3)
 +              EMIT_THREE_BYTES (code >> 16, (code >> 8) & 0xFF, code & 0xFF);
 +            else
 +              EMIT_FOUR_BYTES (code >> 24, (code >> 16) & 0xFF,
 +                               (code >> 8) & 0xFF, code & 0xFF);
 +          }
 +        else
 +          {
 +            if (coding->mode & CODING_MODE_SAFE_ENCODING)
 +              c = CODING_INHIBIT_CHARACTER_SUBSTITUTION;
 +            else
 +              c = coding->default_char;
 +            EMIT_ONE_BYTE (c);
 +          }
        }
      }
 -  if (coding->src_multibyte)
 -    dst = destination + str_as_unibyte (destination, dst - destination);
  
 -  coding->consumed = src_base - source;
 -  coding->produced = dst - destination;
 -  coding->produced_char = coding->produced;
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->produced_char += produced_chars;
 +  coding->produced = dst - coding->destination;
 +  return 0;
  }
  
  \f
  /*** 7. C library functions ***/
  
 -/* In Emacs Lisp, a coding system is represented by a Lisp symbol which
 -   has a property `coding-system'.  The value of this property is a
 -   vector of length 5 (called the coding-vector).  Among elements of
 -   this vector, the first (element[0]) and the fifth (element[4])
 -   carry important information for decoding/encoding.  Before
 -   decoding/encoding, this information should be set in fields of a
 -   structure of type `coding_system'.
 -
 -   The value of the property `coding-system' can be a symbol of another
 -   subsidiary coding-system.  In that case, Emacs gets coding-vector
 -   from that symbol.
 -
 -   `element[0]' contains information to be set in `coding->type'.  The
 -   value and its meaning is as follows:
 -
 -   0 -- coding_type_emacs_mule
 -   1 -- coding_type_sjis
 -   2 -- coding_type_iso2022
 -   3 -- coding_type_big5
 -   4 -- coding_type_ccl encoder/decoder written in CCL
 -   nil -- coding_type_no_conversion
 -   t -- coding_type_undecided (automatic conversion on decoding,
 -                             no-conversion on encoding)
 -
 -   `element[4]' contains information to be set in `coding->flags' and
 -   `coding->spec'.  The meaning varies by `coding->type'.
 -
 -   If `coding->type' is `coding_type_iso2022', element[4] is a vector
 -   of length 32 (of which the first 13 sub-elements are used now).
 -   Meanings of these sub-elements are:
 -
 -   sub-element[N] where N is 0 through 3: to be set in `coding->spec.iso2022'
 -      If the value is an integer of valid charset, the charset is
 -      assumed to be designated to graphic register N initially.
 -
 -      If the value is minus, it is a minus value of charset which
 -      reserves graphic register N, which means that the charset is
 -      not designated initially but should be designated to graphic
 -      register N just before encoding a character in that charset.
 -
 -      If the value is nil, graphic register N is never used on
 -      encoding.
 -
 -   sub-element[N] where N is 4 through 11: to be set in `coding->flags'
 -      Each value takes t or nil.  See the section ISO2022 of
 -      `coding.h' for more information.
 -
 -   If `coding->type' is `coding_type_big5', element[4] is t to denote
 -   BIG5-ETen or nil to denote BIG5-HKU.
 -
 -   If `coding->type' takes the other value, element[4] is ignored.
 -
 -   Emacs Lisp's coding systems also carry information about format of
 -   end-of-line in a value of property `eol-type'.  If the value is
 -   integer, 0 means CODING_EOL_LF, 1 means CODING_EOL_CRLF, and 2
 -   means CODING_EOL_CR.  If it is not integer, it should be a vector
 -   of subsidiary coding systems of which property `eol-type' has one
 -   of the above values.
 -
 -*/
 -
 -/* Extract information for decoding/encoding from CODING_SYSTEM_SYMBOL
 -   and set it in CODING.  If CODING_SYSTEM_SYMBOL is invalid, CODING
 -   is setup so that no conversion is necessary and return -1, else
 -   return 0.  */
 +/* Setup coding context CODING from information about CODING_SYSTEM.
 +   If CODING_SYSTEM is nil, `no-conversion' is assumed.  If
 +   CODING_SYSTEM is invalid, signal an error.  */
  
 -int
 +void
  setup_coding_system (coding_system, coding)
       Lisp_Object coding_system;
       struct coding_system *coding;
  {
 -  Lisp_Object coding_spec, coding_type, eol_type, plist;
 +  Lisp_Object attrs;
 +  Lisp_Object eol_type;
 +  Lisp_Object coding_type;
    Lisp_Object val;
  
 -  /* At first, zero clear all members.  */
 -  bzero (coding, sizeof (struct coding_system));
 -
 -  /* Initialize some fields required for all kinds of coding systems.  */
 -  coding->symbol = coding_system;
 -  coding->heading_ascii = -1;
 -  coding->post_read_conversion = coding->pre_write_conversion = Qnil;
 -  coding->composing = COMPOSITION_DISABLED;
 -  coding->cmp_data = NULL;
 -
    if (NILP (coding_system))
 -    goto label_invalid_coding_system;
 +    coding_system = Qundecided;
  
 -  coding_spec = Fget (coding_system, Qcoding_system);
 +  CHECK_CODING_SYSTEM_GET_ID (coding_system, coding->id);
  
 -  if (!VECTORP (coding_spec)
 -      || XVECTOR (coding_spec)->size != 5
 -      || !CONSP (XVECTOR (coding_spec)->contents[3]))
 -    goto label_invalid_coding_system;
 +  attrs = CODING_ID_ATTRS (coding->id);
 +  eol_type = CODING_ID_EOL_TYPE (coding->id);
  
 -  eol_type = inhibit_eol_conversion ? Qnil : Fget (coding_system, Qeol_type);
 +  coding->mode = 0;
 +  coding->head_ascii = -1;
    if (VECTORP (eol_type))
 +    coding->common_flags = (CODING_REQUIRE_DECODING_MASK
 +                          | CODING_REQUIRE_DETECTION_MASK);
 +  else if (! EQ (eol_type, Qunix))
 +    coding->common_flags = (CODING_REQUIRE_DECODING_MASK
 +                          | CODING_REQUIRE_ENCODING_MASK);
 +  else
 +    coding->common_flags = 0;
 +  if (! NILP (CODING_ATTR_POST_READ (attrs)))
 +    coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
 +  if (! NILP (CODING_ATTR_PRE_WRITE (attrs)))
 +    coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
 +  if (! NILP (CODING_ATTR_FOR_UNIBYTE (attrs)))
 +    coding->common_flags |= CODING_FOR_UNIBYTE_MASK;
 +
 +  val = CODING_ATTR_SAFE_CHARSETS (attrs);
 +  coding->max_charset_id = SCHARS (val) - 1;
 +  coding->safe_charsets = (char *) SDATA (val);
 +  coding->default_char = XINT (CODING_ATTR_DEFAULT_CHAR (attrs));
 +
 +  coding_type = CODING_ATTR_TYPE (attrs);
 +  if (EQ (coding_type, Qundecided))
 +    {
 +      coding->detector = NULL;
 +      coding->decoder = decode_coding_raw_text;
 +      coding->encoder = encode_coding_raw_text;
 +      coding->common_flags |= CODING_REQUIRE_DETECTION_MASK;
 +    }
 +  else if (EQ (coding_type, Qiso_2022))
      {
 -      coding->eol_type = CODING_EOL_UNDECIDED;
 -      coding->common_flags = CODING_REQUIRE_DETECTION_MASK;
 -      if (system_eol_type != CODING_EOL_LF)
 -      coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
 +      int i;
 +      int flags = XINT (AREF (attrs, coding_attr_iso_flags));
 +
 +      /* Invoke graphic register 0 to plane 0.  */
 +      CODING_ISO_INVOCATION (coding, 0) = 0;
 +      /* Invoke graphic register 1 to plane 1 if we can use 8-bit.  */
 +      CODING_ISO_INVOCATION (coding, 1)
 +      = (flags & CODING_ISO_FLAG_SEVEN_BITS ? -1 : 1);
 +      /* Setup the initial status of designation.  */
 +      for (i = 0; i < 4; i++)
 +      CODING_ISO_DESIGNATION (coding, i) = CODING_ISO_INITIAL (coding, i);
 +      /* Not single shifting initially.  */
 +      CODING_ISO_SINGLE_SHIFTING (coding) = 0;
 +      /* Beginning of buffer should also be regarded as bol. */
 +      CODING_ISO_BOL (coding) = 1;
 +      coding->detector = detect_coding_iso_2022;
 +      coding->decoder = decode_coding_iso_2022;
 +      coding->encoder = encode_coding_iso_2022;
 +      if (flags & CODING_ISO_FLAG_SAFE)
 +      coding->mode |= CODING_MODE_SAFE_ENCODING;
 +      coding->common_flags
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK
 +          | CODING_REQUIRE_FLUSHING_MASK);
 +      if (flags & CODING_ISO_FLAG_COMPOSITION)
 +      coding->common_flags |= CODING_ANNOTATE_COMPOSITION_MASK;
 +      if (flags & CODING_ISO_FLAG_DESIGNATION)
 +      coding->common_flags |= CODING_ANNOTATE_CHARSET_MASK;
 +      if (flags & CODING_ISO_FLAG_FULL_SUPPORT)
 +      {
 +        setup_iso_safe_charsets (attrs);
 +        val = CODING_ATTR_SAFE_CHARSETS (attrs);
 +        coding->max_charset_id = SCHARS (val) - 1;
 +        coding->safe_charsets = (char *) SDATA (val);
 +      }
 +      CODING_ISO_FLAGS (coding) = flags;
      }
 -  else if (XFASTINT (eol_type) == 1)
 +  else if (EQ (coding_type, Qcharset))
      {
 -      coding->eol_type = CODING_EOL_CRLF;
 +      coding->detector = detect_coding_charset;
 +      coding->decoder = decode_coding_charset;
 +      coding->encoder = encode_coding_charset;
        coding->common_flags
 -      = CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
      }
 -  else if (XFASTINT (eol_type) == 2)
 +  else if (EQ (coding_type, Qutf_8))
      {
 -      coding->eol_type = CODING_EOL_CR;
 +      coding->detector = detect_coding_utf_8;
 +      coding->decoder = decode_coding_utf_8;
 +      coding->encoder = encode_coding_utf_8;
 +      coding->common_flags
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
 +    }
 +  else if (EQ (coding_type, Qutf_16))
 +    {
 +      val = AREF (attrs, coding_attr_utf_16_bom);
 +      CODING_UTF_16_BOM (coding) = (CONSP (val) ? utf_16_detect_bom
 +                                  : EQ (val, Qt) ? utf_16_with_bom
 +                                  : utf_16_without_bom);
 +      val = AREF (attrs, coding_attr_utf_16_endian);
 +      CODING_UTF_16_ENDIAN (coding) = (EQ (val, Qbig) ? utf_16_big_endian
 +                                     : utf_16_little_endian);
 +      CODING_UTF_16_SURROGATE (coding) = 0;
 +      coding->detector = detect_coding_utf_16;
 +      coding->decoder = decode_coding_utf_16;
 +      coding->encoder = encode_coding_utf_16;
        coding->common_flags
 -      = CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
 +      if (CODING_UTF_16_BOM (coding) == utf_16_detect_bom)
 +      coding->common_flags |= CODING_REQUIRE_DETECTION_MASK;
      }
 -  else
 +  else if (EQ (coding_type, Qccl))
      {
 -      coding->common_flags = 0;
 -      coding->eol_type = CODING_EOL_LF;
 +      coding->detector = detect_coding_ccl;
 +      coding->decoder = decode_coding_ccl;
 +      coding->encoder = encode_coding_ccl;
 +      coding->common_flags
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK
 +          | CODING_REQUIRE_FLUSHING_MASK);
      }
 -
 -  coding_type = XVECTOR (coding_spec)->contents[0];
 -  /* Try short cut.  */
 -  if (SYMBOLP (coding_type))
 +  else if (EQ (coding_type, Qemacs_mule))
      {
 -      if (EQ (coding_type, Qt))
 +      coding->detector = detect_coding_emacs_mule;
 +      coding->decoder = decode_coding_emacs_mule;
 +      coding->encoder = encode_coding_emacs_mule;
 +      coding->common_flags
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
 +      if (! NILP (AREF (attrs, coding_attr_emacs_mule_full))
 +        && ! EQ (CODING_ATTR_CHARSET_LIST (attrs), Vemacs_mule_charset_list))
        {
 -        coding->type = coding_type_undecided;
 -        coding->common_flags |= CODING_REQUIRE_DETECTION_MASK;
 +        Lisp_Object tail, safe_charsets;
 +        int max_charset_id = 0;
 +
 +        for (tail = Vemacs_mule_charset_list; CONSP (tail);
 +             tail = XCDR (tail))
 +          if (max_charset_id < XFASTINT (XCAR (tail)))
 +            max_charset_id = XFASTINT (XCAR (tail));
 +        safe_charsets = Fmake_string (make_number (max_charset_id + 1),
 +                                      make_number (255));
 +        for (tail = Vemacs_mule_charset_list; CONSP (tail);
 +             tail = XCDR (tail))
 +          SSET (safe_charsets, XFASTINT (XCAR (tail)), 0);
 +        coding->max_charset_id = max_charset_id;
 +        coding->safe_charsets = (char *) SDATA (safe_charsets);
        }
 -      else
 -      coding->type = coding_type_no_conversion;
 -      /* Initialize this member.  Any thing other than
 -       CODING_CATEGORY_IDX_UTF_16_BE and
 -       CODING_CATEGORY_IDX_UTF_16_LE are ok because they have
 -       special treatment in detect_eol.  */
 -      coding->category_idx = CODING_CATEGORY_IDX_EMACS_MULE;
 -
 -      return 0;
 -    }
 -
 -  /* Get values of coding system properties:
 -     `post-read-conversion', `pre-write-conversion',
 -     `translation-table-for-decode', `translation-table-for-encode'.  */
 -  plist = XVECTOR (coding_spec)->contents[3];
 -  /* Pre & post conversion functions should be disabled if
 -     inhibit_eol_conversion is nonzero.  This is the case that a code
 -     conversion function is called while those functions are running.  */
 -  if (! inhibit_pre_post_conversion)
 -    {
 -      coding->post_read_conversion = Fplist_get (plist, Qpost_read_conversion);
 -      coding->pre_write_conversion = Fplist_get (plist, Qpre_write_conversion);
 -    }
 -  val = Fplist_get (plist, Qtranslation_table_for_decode);
 -  if (SYMBOLP (val))
 -    val = Fget (val, Qtranslation_table_for_decode);
 -  coding->translation_table_for_decode = CHAR_TABLE_P (val) ? val : Qnil;
 -  val = Fplist_get (plist, Qtranslation_table_for_encode);
 -  if (SYMBOLP (val))
 -    val = Fget (val, Qtranslation_table_for_encode);
 -  coding->translation_table_for_encode = CHAR_TABLE_P (val) ? val : Qnil;
 -  val = Fplist_get (plist, Qcoding_category);
 -  if (!NILP (val))
 -    {
 -      val = Fget (val, Qcoding_category_index);
 -      if (INTEGERP (val))
 -      coding->category_idx = XINT (val);
 -      else
 -      goto label_invalid_coding_system;
      }
 -  else
 -    goto label_invalid_coding_system;
 -
 -  /* If the coding system has non-nil `composition' property, enable
 -     composition handling.  */
 -  val = Fplist_get (plist, Qcomposition);
 -  if (!NILP (val))
 -    coding->composing = COMPOSITION_NO;
 -
 -  /* If the coding system is ascii-incompatible, record it in
 -     common_flags.   */
 -  val = Fplist_get (plist, Qascii_incompatible);
 -  if (! NILP (val))
 -    coding->common_flags |= CODING_ASCII_INCOMPATIBLE_MASK;
 -
 -  switch (XFASTINT (coding_type))
 +  else if (EQ (coding_type, Qshift_jis))
      {
 -    case 0:
 -      coding->type = coding_type_emacs_mule;
 -      coding->common_flags
 -      |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
 -      if (!NILP (coding->post_read_conversion))
 -      coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
 -      if (!NILP (coding->pre_write_conversion))
 -      coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
 -      break;
 -
 -    case 1:
 -      coding->type = coding_type_sjis;
 -      coding->common_flags
 -      |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
 -      break;
 -
 -    case 2:
 -      coding->type = coding_type_iso2022;
 -      coding->common_flags
 -      |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
 -      {
 -      Lisp_Object val, temp;
 -      Lisp_Object *flags;
 -      int i, charset, reg_bits = 0;
 -
 -      val = XVECTOR (coding_spec)->contents[4];
 -
 -      if (!VECTORP (val) || XVECTOR (val)->size != 32)
 -        goto label_invalid_coding_system;
 -
 -      flags = XVECTOR (val)->contents;
 -      coding->flags
 -        = ((NILP (flags[4]) ? 0 : CODING_FLAG_ISO_SHORT_FORM)
 -           | (NILP (flags[5]) ? 0 : CODING_FLAG_ISO_RESET_AT_EOL)
 -           | (NILP (flags[6]) ? 0 : CODING_FLAG_ISO_RESET_AT_CNTL)
 -           | (NILP (flags[7]) ? 0 : CODING_FLAG_ISO_SEVEN_BITS)
 -           | (NILP (flags[8]) ? 0 : CODING_FLAG_ISO_LOCKING_SHIFT)
 -           | (NILP (flags[9]) ? 0 : CODING_FLAG_ISO_SINGLE_SHIFT)
 -           | (NILP (flags[10]) ? 0 : CODING_FLAG_ISO_USE_ROMAN)
 -           | (NILP (flags[11]) ? 0 : CODING_FLAG_ISO_USE_OLDJIS)
 -           | (NILP (flags[12]) ? 0 : CODING_FLAG_ISO_NO_DIRECTION)
 -           | (NILP (flags[13]) ? 0 : CODING_FLAG_ISO_INIT_AT_BOL)
 -           | (NILP (flags[14]) ? 0 : CODING_FLAG_ISO_DESIGNATE_AT_BOL)
 -           | (NILP (flags[15]) ? 0 : CODING_FLAG_ISO_SAFE)
 -           | (NILP (flags[16]) ? 0 : CODING_FLAG_ISO_LATIN_EXTRA)
 -           );
 -
 -      /* Invoke graphic register 0 to plane 0.  */
 -      CODING_SPEC_ISO_INVOCATION (coding, 0) = 0;
 -      /* Invoke graphic register 1 to plane 1 if we can use full 8-bit.  */
 -      CODING_SPEC_ISO_INVOCATION (coding, 1)
 -        = (coding->flags & CODING_FLAG_ISO_SEVEN_BITS ? -1 : 1);
 -      /* Not single shifting at first.  */
 -      CODING_SPEC_ISO_SINGLE_SHIFTING (coding) = 0;
 -      /* Beginning of buffer should also be regarded as bol. */
 -      CODING_SPEC_ISO_BOL (coding) = 1;
 -
 -      for (charset = 0; charset <= MAX_CHARSET; charset++)
 -        CODING_SPEC_ISO_REVISION_NUMBER (coding, charset) = 255;
 -      val = Vcharset_revision_alist;
 -      while (CONSP (val))
 -        {
 -          charset = get_charset_id (Fcar_safe (XCAR (val)));
 -          if (charset >= 0
 -              && (temp = Fcdr_safe (XCAR (val)), INTEGERP (temp))
 -              && (i = XINT (temp), (i >= 0 && (i + '@') < 128)))
 -            CODING_SPEC_ISO_REVISION_NUMBER (coding, charset) = i;
 -          val = XCDR (val);
 -        }
 -
 -      /* Checks FLAGS[REG] (REG = 0, 1, 2 3) and decide designations.
 -         FLAGS[REG] can be one of below:
 -              integer CHARSET: CHARSET occupies register I,
 -              t: designate nothing to REG initially, but can be used
 -                by any charsets,
 -              list of integer, nil, or t: designate the first
 -                element (if integer) to REG initially, the remaining
 -                elements (if integer) is designated to REG on request,
 -                if an element is t, REG can be used by any charsets,
 -              nil: REG is never used.  */
 -      for (charset = 0; charset <= MAX_CHARSET; charset++)
 -        CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
 -          = CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION;
 -      for (i = 0; i < 4; i++)
 -        {
 -          if ((INTEGERP (flags[i])
 -               && (charset = XINT (flags[i]), CHARSET_VALID_P (charset)))
 -              || (charset = get_charset_id (flags[i])) >= 0)
 -            {
 -              CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;
 -              CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) = i;
 -            }
 -          else if (EQ (flags[i], Qt))
 -            {
 -              CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;
 -              reg_bits |= 1 << i;
 -              coding->flags |= CODING_FLAG_ISO_DESIGNATION;
 -            }
 -          else if (CONSP (flags[i]))
 -            {
 -              Lisp_Object tail;
 -              tail = flags[i];
 -
 -              coding->flags |= CODING_FLAG_ISO_DESIGNATION;
 -              if ((INTEGERP (XCAR (tail))
 -                   && (charset = XINT (XCAR (tail)),
 -                       CHARSET_VALID_P (charset)))
 -                  || (charset = get_charset_id (XCAR (tail))) >= 0)
 -                {
 -                  CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = charset;
 -                  CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset) =i;
 -                }
 -              else
 -                CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;
 -              tail = XCDR (tail);
 -              while (CONSP (tail))
 -                {
 -                  if ((INTEGERP (XCAR (tail))
 -                       && (charset = XINT (XCAR (tail)),
 -                           CHARSET_VALID_P (charset)))
 -                      || (charset = get_charset_id (XCAR (tail))) >= 0)
 -                    CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
 -                      = i;
 -                  else if (EQ (XCAR (tail), Qt))
 -                    reg_bits |= 1 << i;
 -                  tail = XCDR (tail);
 -                }
 -            }
 -          else
 -            CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i) = -1;
 -
 -          CODING_SPEC_ISO_DESIGNATION (coding, i)
 -            = CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, i);
 -        }
 -
 -      if (reg_bits && ! (coding->flags & CODING_FLAG_ISO_LOCKING_SHIFT))
 -        {
 -          /* REG 1 can be used only by locking shift in 7-bit env.  */
 -          if (coding->flags & CODING_FLAG_ISO_SEVEN_BITS)
 -            reg_bits &= ~2;
 -          if (! (coding->flags & CODING_FLAG_ISO_SINGLE_SHIFT))
 -            /* Without any shifting, only REG 0 and 1 can be used.  */
 -            reg_bits &= 3;
 -        }
 -
 -      if (reg_bits)
 -        for (charset = 0; charset <= MAX_CHARSET; charset++)
 -          {
 -            if (CHARSET_DEFINED_P (charset)
 -                && (CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
 -                    == CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION))
 -              {
 -                /* There exist some default graphic registers to be
 -                   used by CHARSET.  */
 -
 -                /* We had better avoid designating a charset of
 -                   CHARS96 to REG 0 as far as possible.  */
 -                if (CHARSET_CHARS (charset) == 96)
 -                  CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
 -                    = (reg_bits & 2
 -                       ? 1 : (reg_bits & 4 ? 2 : (reg_bits & 8 ? 3 : 0)));
 -                else
 -                  CODING_SPEC_ISO_REQUESTED_DESIGNATION (coding, charset)
 -                    = (reg_bits & 1
 -                       ? 0 : (reg_bits & 2 ? 1 : (reg_bits & 4 ? 2 : 3)));
 -              }
 -          }
 -      }
 -      coding->common_flags |= CODING_REQUIRE_FLUSHING_MASK;
 -      coding->spec.iso2022.last_invalid_designation_register = -1;
 -      break;
 -
 -    case 3:
 -      coding->type = coding_type_big5;
 +      coding->detector = detect_coding_sjis;
 +      coding->decoder = decode_coding_sjis;
 +      coding->encoder = encode_coding_sjis;
        coding->common_flags
 -      |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
 -      coding->flags
 -      = (NILP (XVECTOR (coding_spec)->contents[4])
 -         ? CODING_FLAG_BIG5_HKU
 -         : CODING_FLAG_BIG5_ETEN);
 -      break;
 -
 -    case 4:
 -      coding->type = coding_type_ccl;
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
 +    }
 +  else if (EQ (coding_type, Qbig5))
 +    {
 +      coding->detector = detect_coding_big5;
 +      coding->decoder = decode_coding_big5;
 +      coding->encoder = encode_coding_big5;
        coding->common_flags
 -      |= CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK;
 -      {
 -      val = XVECTOR (coding_spec)->contents[4];
 -      if (! CONSP (val)
 -          || setup_ccl_program (&(coding->spec.ccl.decoder),
 -                                XCAR (val)) < 0
 -          || setup_ccl_program (&(coding->spec.ccl.encoder),
 -                                XCDR (val)) < 0)
 -        goto label_invalid_coding_system;
 -
 -      bzero (coding->spec.ccl.valid_codes, 256);
 -      val = Fplist_get (plist, Qvalid_codes);
 -      if (CONSP (val))
 -        {
 -          Lisp_Object this;
 -
 -          for (; CONSP (val); val = XCDR (val))
 -            {
 -              this = XCAR (val);
 -              if (INTEGERP (this)
 -                  && XINT (this) >= 0 && XINT (this) < 256)
 -                coding->spec.ccl.valid_codes[XINT (this)] = 1;
 -              else if (CONSP (this)
 -                       && INTEGERP (XCAR (this))
 -                       && INTEGERP (XCDR (this)))
 -                {
 -                  int start = XINT (XCAR (this));
 -                  int end = XINT (XCDR (this));
 -
 -                  if (start >= 0 && start <= end && end < 256)
 -                    while (start <= end)
 -                      coding->spec.ccl.valid_codes[start++] = 1;
 -                }
 -            }
 -        }
 -      }
 -      coding->common_flags |= CODING_REQUIRE_FLUSHING_MASK;
 -      coding->spec.ccl.cr_carryover = 0;
 -      coding->spec.ccl.eight_bit_carryover[0] = 0;
 -      break;
 -
 -    case 5:
 -      coding->type = coding_type_raw_text;
 -      break;
 +      |= (CODING_REQUIRE_DECODING_MASK | CODING_REQUIRE_ENCODING_MASK);
 +    }
 +  else                                /* EQ (coding_type, Qraw_text) */
 +    {
 +      coding->detector = NULL;
 +      coding->decoder = decode_coding_raw_text;
 +      coding->encoder = encode_coding_raw_text;
 +      if (! EQ (eol_type, Qunix))
 +      {
 +        coding->common_flags |= CODING_REQUIRE_DECODING_MASK;
 +        if (! VECTORP (eol_type))
 +          coding->common_flags |= CODING_REQUIRE_ENCODING_MASK;
 +      }
  
 -    default:
 -      goto label_invalid_coding_system;
      }
 -  return 0;
  
 - label_invalid_coding_system:
 -  coding->type = coding_type_no_conversion;
 -  coding->category_idx = CODING_CATEGORY_IDX_BINARY;
 -  coding->common_flags = 0;
 -  coding->eol_type = CODING_EOL_UNDECIDED;
 -  coding->pre_write_conversion = coding->post_read_conversion = Qnil;
 -  return NILP (coding_system) ? 0 : -1;
 +  return;
  }
  
 -/* Free memory blocks allocated for storing composition information.  */
 +/* Return a list of charsets supported by CODING.  */
  
 -void
 -coding_free_composition_data (coding)
 +Lisp_Object
 +coding_charset_list (coding)
       struct coding_system *coding;
  {
 -  struct composition_data *cmp_data = coding->cmp_data, *next;
 +  Lisp_Object attrs, charset_list;
  
 -  if (!cmp_data)
 -    return;
 -  /* Memory blocks are chained.  At first, rewind to the first, then,
 -     free blocks one by one.  */
 -  while (cmp_data->prev)
 -    cmp_data = cmp_data->prev;
 -  while (cmp_data)
 +  CODING_GET_INFO (coding, attrs, charset_list);
 +  if (EQ (CODING_ATTR_TYPE (attrs), Qiso_2022))
 +    {
 +      int flags = XINT (AREF (attrs, coding_attr_iso_flags));
 +
 +      if (flags & CODING_ISO_FLAG_FULL_SUPPORT)
 +      charset_list = Viso_2022_charset_list;
 +    }
 +  else if (EQ (CODING_ATTR_TYPE (attrs), Qemacs_mule))
      {
 -      next = cmp_data->next;
 -      xfree (cmp_data);
 -      cmp_data = next;
 +      charset_list = Vemacs_mule_charset_list;
      }
 -  coding->cmp_data = NULL;
 +  return charset_list;
  }
  
 -/* Set `char_offset' member of all memory blocks pointed by
 -   coding->cmp_data to POS.  */
  
 -void
 -coding_adjust_composition_offset (coding, pos)
 -     struct coding_system *coding;
 -     int pos;
 +/* Return raw-text or one of its subsidiaries that has the same
 +   eol_type as CODING-SYSTEM.  */
 +
 +Lisp_Object
 +raw_text_coding_system (coding_system)
 +     Lisp_Object coding_system;
  {
 -  struct composition_data *cmp_data;
 +  Lisp_Object spec, attrs;
 +  Lisp_Object eol_type, raw_text_eol_type;
 +
 +  if (NILP (coding_system))
 +    return Qraw_text;
 +  spec = CODING_SYSTEM_SPEC (coding_system);
 +  attrs = AREF (spec, 0);
 +
 +  if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
 +    return coding_system;
  
 -  for (cmp_data = coding->cmp_data; cmp_data; cmp_data = cmp_data->next)
 -    cmp_data->char_offset = pos;
 +  eol_type = AREF (spec, 2);
 +  if (VECTORP (eol_type))
 +    return Qraw_text;
 +  spec = CODING_SYSTEM_SPEC (Qraw_text);
 +  raw_text_eol_type = AREF (spec, 2);
 +  return (EQ (eol_type, Qunix) ? AREF (raw_text_eol_type, 0)
 +        : EQ (eol_type, Qdos) ? AREF (raw_text_eol_type, 1)
 +        : AREF (raw_text_eol_type, 2));
  }
  
 -/* Setup raw-text or one of its subsidiaries in the structure
 -   coding_system CODING according to the already setup value eol_type
 -   in CODING.  CODING should be setup for some coding system in
 -   advance.  */
  
 -void
 -setup_raw_text_coding_system (coding)
 -     struct coding_system *coding;
 +/* If CODING_SYSTEM doesn't specify end-of-line format but PARENT
 +   does, return one of the subsidiary that has the same eol-spec as
 +   PARENT.  Otherwise, return CODING_SYSTEM.  If PARENT is nil,
 +   inherit end-of-line format from the system's setting
 +   (system_eol_type).  */
 +
 +Lisp_Object
 +coding_inherit_eol_type (coding_system, parent)
 +     Lisp_Object coding_system, parent;
  {
 -  if (coding->type != coding_type_raw_text)
 +  Lisp_Object spec, eol_type;
 +
 +  if (NILP (coding_system))
 +    coding_system = Qraw_text;
 +  spec = CODING_SYSTEM_SPEC (coding_system);
 +  eol_type = AREF (spec, 2);
 +  if (VECTORP (eol_type))
      {
 -      coding->symbol = Qraw_text;
 -      coding->type = coding_type_raw_text;
 -      if (coding->eol_type != CODING_EOL_UNDECIDED)
 +      Lisp_Object parent_eol_type;
 +
 +      if (! NILP (parent))
        {
 -        Lisp_Object subsidiaries;
 -        subsidiaries = Fget (Qraw_text, Qeol_type);
 +        Lisp_Object parent_spec;
  
 -        if (VECTORP (subsidiaries)
 -            && XVECTOR (subsidiaries)->size == 3)
 -          coding->symbol
 -            = XVECTOR (subsidiaries)->contents[coding->eol_type];
 +        parent_spec = CODING_SYSTEM_SPEC (parent);
 +        parent_eol_type = AREF (parent_spec, 2);
        }
 -      setup_coding_system (coding->symbol, coding);
 -    }
 -  return;
 +      else
 +      parent_eol_type = system_eol_type;
 +      if (EQ (parent_eol_type, Qunix))
 +      coding_system = AREF (eol_type, 0);
 +      else if (EQ (parent_eol_type, Qdos))
 +      coding_system = AREF (eol_type, 1);
 +      else if (EQ (parent_eol_type, Qmac))
 +      coding_system = AREF (eol_type, 2);
 +    }
 +  return coding_system;
  }
  
  /* Emacs has a mechanism to automatically detect a coding system if it
     o coding-category-iso-7-else
  
        The category for a coding system which has the same code range
 -      as ISO2022 of 7-bit environment but uses locking shift or
 +      as ISO2022 of 7-bit environemnt but uses locking shift or
        single shift functions.  Assigned the coding-system (Lisp
        symbol) `iso-2022-7bit-lock' by default.
  
     o coding-category-iso-8-else
  
        The category for a coding system which has the same code range
 -      as ISO2022 of 8-bit environment but uses locking shift or
 +      as ISO2022 of 8-bit environemnt but uses locking shift or
        single shift functions.  Assigned the coding-system (Lisp
        symbol) `iso-2022-8bit-ss2' by default.
  
        `no-conversion' by default.
  
     Each of them is a Lisp symbol and the value is an actual
 -   `coding-system' (this is also a Lisp symbol) assigned by a user.
 +   `coding-system's (this is also a Lisp symbol) assigned by a user.
     What Emacs does actually is to detect a category of coding system.
     Then, it uses a `coding-system' assigned to it.  If Emacs can't
 -   decide a single possible category, it selects a category of the
 +   decide only one possible category, it selects a category of the
     highest priority.  Priorities of categories are also specified by a
     user in a Lisp variable `coding-category-list'.
  
  */
  
 -static
 -int ascii_skip_code[256];
 -
 -/* Detect how a text of length SRC_BYTES pointed by SOURCE is encoded.
 -   If it detects possible coding systems, return an integer in which
 -   appropriate flag bits are set.  Flag bits are defined by macros
 -   CODING_CATEGORY_MASK_XXX in `coding.h'.  If PRIORITIES is non-NULL,
 -   it should point the table `coding_priorities'.  In that case, only
 -   the flag bit for a coding system of the highest priority is set in
 -   the returned value.  If MULTIBYTEP is nonzero, 8-bit codes of the
 -   range 0x80..0x9F are in multibyte form.
 -
 -   How many ASCII characters are at the head is returned as *SKIP.  */
 -
 -static int
 -detect_coding_mask (source, src_bytes, priorities, skip, multibytep)
 -     unsigned char *source;
 -     int src_bytes, *priorities, *skip;
 -     int multibytep;
 -{
 -  register unsigned char c;
 -  unsigned char *src = source, *src_end = source + src_bytes;
 -  unsigned int mask, utf16_examined_p, iso2022_examined_p;
 -  int i;
 -
 -  /* At first, skip all ASCII characters and control characters except
 -     for three ISO2022 specific control characters.  */
 -  ascii_skip_code[ISO_CODE_SO] = 0;
 -  ascii_skip_code[ISO_CODE_SI] = 0;
 -  ascii_skip_code[ISO_CODE_ESC] = 0;
 -
 - label_loop_detect_coding:
 -  while (src < src_end && ascii_skip_code[*src]) src++;
 -  *skip = src - source;
 -
 -  if (src >= src_end)
 -    /* We found nothing other than ASCII.  There's nothing to do.  */
 -    return 0;
 -
 -  c = *src;
 -  /* The text seems to be encoded in some multilingual coding system.
 -     Now, try to find in which coding system the text is encoded.  */
 -  if (c < 0x80)
 -    {
 -      /* i.e. (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO) */
 -      /* C is an ISO2022 specific control code of C0.  */
 -      mask = detect_coding_iso2022 (src, src_end, multibytep);
 -      if (mask == 0)
 -      {
 -        /* No valid ISO2022 code follows C.  Try again.  */
 -        src++;
 -        if (c == ISO_CODE_ESC)
 -          ascii_skip_code[ISO_CODE_ESC] = 1;
 -        else
 -          ascii_skip_code[ISO_CODE_SO] = ascii_skip_code[ISO_CODE_SI] = 1;
 -        goto label_loop_detect_coding;
 -      }
 -      if (priorities)
 -      {
 -        for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)
 -          {
 -            if (mask & priorities[i])
 -              return priorities[i];
 -          }
 -        return CODING_CATEGORY_MASK_RAW_TEXT;
 -      }
 -    }
 -  else
 -    {
 -      int try;
 -
 -      if (multibytep && c == LEADING_CODE_8_BIT_CONTROL)
 -      c = src[1] - 0x20;
 -
 -      if (c < 0xA0)
 -      {
 -        /* C is the first byte of SJIS character code,
 -           or a leading-code of Emacs' internal format (emacs-mule),
 -           or the first byte of UTF-16.  */
 -        try = (CODING_CATEGORY_MASK_SJIS
 -                | CODING_CATEGORY_MASK_EMACS_MULE
 -                | CODING_CATEGORY_MASK_UTF_16_BE
 -                | CODING_CATEGORY_MASK_UTF_16_LE);
 -
 -        /* Or, if C is a special latin extra code,
 -           or is an ISO2022 specific control code of C1 (SS2 or SS3),
 -           or is an ISO2022 control-sequence-introducer (CSI),
 -           we should also consider the possibility of ISO2022 codings.  */
 -        if ((VECTORP (Vlatin_extra_code_table)
 -             && !NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
 -            || (c == ISO_CODE_SS2 || c == ISO_CODE_SS3)
 -            || (c == ISO_CODE_CSI
 -                && (src < src_end
 -                    && (*src == ']'
 -                        || ((*src == '0' || *src == '1' || *src == '2')
 -                            && src + 1 < src_end
 -                            && src[1] == ']')))))
 -          try |= (CODING_CATEGORY_MASK_ISO_8_ELSE
 -                   | CODING_CATEGORY_MASK_ISO_8BIT);
 -      }
 -      else
 -      /* C is a character of ISO2022 in graphic plane right,
 -         or a SJIS's 1-byte character code (i.e. JISX0201),
 -         or the first byte of BIG5's 2-byte code,
 -         or the first byte of UTF-8/16.  */
 -      try = (CODING_CATEGORY_MASK_ISO_8_ELSE
 -              | CODING_CATEGORY_MASK_ISO_8BIT
 -              | CODING_CATEGORY_MASK_SJIS
 -              | CODING_CATEGORY_MASK_BIG5
 -              | CODING_CATEGORY_MASK_UTF_8
 -              | CODING_CATEGORY_MASK_UTF_16_BE
 -              | CODING_CATEGORY_MASK_UTF_16_LE);
 -
 -      /* Or, we may have to consider the possibility of CCL.  */
 -      if (coding_system_table[CODING_CATEGORY_IDX_CCL]
 -        && (coding_system_table[CODING_CATEGORY_IDX_CCL]
 -            ->spec.ccl.valid_codes)[c])
 -      try |= CODING_CATEGORY_MASK_CCL;
 -
 -      mask = 0;
 -      utf16_examined_p = iso2022_examined_p = 0;
 -      if (priorities)
 -      {
 -        for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)
 -          {
 -            if (!iso2022_examined_p
 -                && (priorities[i] & try & CODING_CATEGORY_MASK_ISO))
 -              {
 -                mask |= detect_coding_iso2022 (src, src_end, multibytep);
 -                iso2022_examined_p = 1;
 -              }
 -            else if (priorities[i] & try & CODING_CATEGORY_MASK_SJIS)
 -              mask |= detect_coding_sjis (src, src_end, multibytep);
 -            else if (priorities[i] & try & CODING_CATEGORY_MASK_UTF_8)
 -              mask |= detect_coding_utf_8 (src, src_end, multibytep);
 -            else if (!utf16_examined_p
 -                     && (priorities[i] & try &
 -                         CODING_CATEGORY_MASK_UTF_16_BE_LE))
 -              {
 -                mask |= detect_coding_utf_16 (src, src_end, multibytep);
 -                utf16_examined_p = 1;
 -              }
 -            else if (priorities[i] & try & CODING_CATEGORY_MASK_BIG5)
 -              mask |= detect_coding_big5 (src, src_end, multibytep);
 -            else if (priorities[i] & try & CODING_CATEGORY_MASK_EMACS_MULE)
 -              mask |= detect_coding_emacs_mule (src, src_end, multibytep);
 -            else if (priorities[i] & try & CODING_CATEGORY_MASK_CCL)
 -              mask |= detect_coding_ccl (src, src_end, multibytep);
 -            else if (priorities[i] & CODING_CATEGORY_MASK_RAW_TEXT)
 -              mask |= CODING_CATEGORY_MASK_RAW_TEXT;
 -            else if (priorities[i] & CODING_CATEGORY_MASK_BINARY)
 -              mask |= CODING_CATEGORY_MASK_BINARY;
 -            if (mask & priorities[i])
 -              return priorities[i];
 -          }
 -        return CODING_CATEGORY_MASK_RAW_TEXT;
 -      }
 -      if (try & CODING_CATEGORY_MASK_ISO)
 -      mask |= detect_coding_iso2022 (src, src_end, multibytep);
 -      if (try & CODING_CATEGORY_MASK_SJIS)
 -      mask |= detect_coding_sjis (src, src_end, multibytep);
 -      if (try & CODING_CATEGORY_MASK_BIG5)
 -      mask |= detect_coding_big5 (src, src_end, multibytep);
 -      if (try & CODING_CATEGORY_MASK_UTF_8)
 -      mask |= detect_coding_utf_8 (src, src_end, multibytep);
 -      if (try & CODING_CATEGORY_MASK_UTF_16_BE_LE)
 -      mask |= detect_coding_utf_16 (src, src_end, multibytep);
 -      if (try & CODING_CATEGORY_MASK_EMACS_MULE)
 -      mask |= detect_coding_emacs_mule (src, src_end, multibytep);
 -      if (try & CODING_CATEGORY_MASK_CCL)
 -      mask |= detect_coding_ccl (src, src_end, multibytep);
 -    }
 -  return (mask | CODING_CATEGORY_MASK_RAW_TEXT | CODING_CATEGORY_MASK_BINARY);
 -}
 -
 -/* Detect how a text of length SRC_BYTES pointed by SRC is encoded.
 -   The information of the detected coding system is set in CODING.  */
 -
 -void
 -detect_coding (coding, src, src_bytes)
 -     struct coding_system *coding;
 -     const unsigned char *src;
 -     int src_bytes;
 -{
 -  unsigned int idx;
 -  int skip, mask;
 -  Lisp_Object val;
 -
 -  val = Vcoding_category_list;
 -  mask = detect_coding_mask (src, src_bytes, coding_priorities, &skip,
 -                           coding->src_multibyte);
 -  coding->heading_ascii = skip;
 -
 -  if (!mask) return;
 -
 -  /* We found a single coding system of the highest priority in MASK.  */
 -  idx = 0;
 -  while (mask && ! (mask & 1)) mask >>= 1, idx++;
 -  if (! mask)
 -    idx = CODING_CATEGORY_IDX_RAW_TEXT;
 -
 -  val = SYMBOL_VALUE (XVECTOR (Vcoding_category_table)->contents[idx]);
 -
 -  if (coding->eol_type != CODING_EOL_UNDECIDED)
 -    {
 -      Lisp_Object tmp;
 -
 -      tmp = Fget (val, Qeol_type);
 -      if (VECTORP (tmp))
 -      val = XVECTOR (tmp)->contents[coding->eol_type];
 -    }
 -
 -  /* Setup this new coding system while preserving some slots.  */
 -  {
 -    int src_multibyte = coding->src_multibyte;
 -    int dst_multibyte = coding->dst_multibyte;
 -
 -    setup_coding_system (val, coding);
 -    coding->src_multibyte = src_multibyte;
 -    coding->dst_multibyte = dst_multibyte;
 -    coding->heading_ascii = skip;
 -  }
 -}
 +#define EOL_SEEN_NONE 0
 +#define EOL_SEEN_LF   1
 +#define EOL_SEEN_CR   2
 +#define EOL_SEEN_CRLF 4
  
  /* Detect how end-of-line of a text of length SRC_BYTES pointed by
 -   SOURCE is encoded.  Return one of CODING_EOL_LF, CODING_EOL_CRLF,
 -   CODING_EOL_CR, and CODING_EOL_UNDECIDED.
 +   SOURCE is encoded.  If CATEGORY is one of
 +   coding_category_utf_16_XXXX, assume that CR and LF are encoded by
 +   two-byte, else they are encoded by one-byte.
  
 -   How many non-eol characters are at the head is returned as *SKIP.  */
 +   Return one of EOL_SEEN_XXX.  */
  
  #define MAX_EOL_CHECK_COUNT 3
  
 -static int
 -detect_eol_type (source, src_bytes, skip)
 -     unsigned char *source;
 -     int src_bytes, *skip;
 -{
 -  unsigned char *src = source, *src_end = src + src_bytes;
 -  unsigned char c;
 -  int total = 0;              /* How many end-of-lines are found so far.  */
 -  int eol_type = CODING_EOL_UNDECIDED;
 -  int this_eol_type;
 -
 -  *skip = 0;
 -
 -  while (src < src_end && total < MAX_EOL_CHECK_COUNT)
 -    {
 -      c = *src++;
 -      if (c == '\n' || c == '\r')
 -      {
 -        if (*skip == 0)
 -          *skip = src - 1 - source;
 -        total++;
 -        if (c == '\n')
 -          this_eol_type = CODING_EOL_LF;
 -        else if (src >= src_end || *src != '\n')
 -          this_eol_type = CODING_EOL_CR;
 -        else
 -          this_eol_type = CODING_EOL_CRLF, src++;
 -
 -        if (eol_type == CODING_EOL_UNDECIDED)
 -          /* This is the first end-of-line.  */
 -          eol_type = this_eol_type;
 -        else if (eol_type != this_eol_type)
 -          {
 -            /* The found type is different from what found before.  */
 -            eol_type = CODING_EOL_INCONSISTENT;
 -            break;
 -          }
 -      }
 -    }
 -
 -  if (*skip == 0)
 -    *skip = src_end - source;
 -  return eol_type;
 -}
 -
 -/* Like detect_eol_type, but detect EOL type in 2-octet
 -   big-endian/little-endian format for coding systems utf-16-be and
 -   utf-16-le.  */
 -
 -static int
 -detect_eol_type_in_2_octet_form (source, src_bytes, skip, big_endian_p)
 -     unsigned char *source;
 -     int src_bytes, *skip, big_endian_p;
 -{
 -  unsigned char *src = source, *src_end = src + src_bytes;
 -  unsigned int c1, c2;
 -  int total = 0;              /* How many end-of-lines are found so far.  */
 -  int eol_type = CODING_EOL_UNDECIDED;
 -  int this_eol_type;
 -  int msb, lsb;
 -
 -  if (big_endian_p)
 -    msb = 0, lsb = 1;
 -  else
 -    msb = 1, lsb = 0;
 -
 -  *skip = 0;
 -
 -  while ((src + 1) < src_end && total < MAX_EOL_CHECK_COUNT)
 -    {
 -      c1 = (src[msb] << 8) | (src[lsb]);
 -      src += 2;
 -
 -      if (c1 == '\n' || c1 == '\r')
 -      {
 -        if (*skip == 0)
 -          *skip = src - 2 - source;
 -        total++;
 -        if (c1 == '\n')
 -          {
 -            this_eol_type = CODING_EOL_LF;
 -          }
 -        else
 -          {
 -            if ((src + 1) >= src_end)
 -              {
 -                this_eol_type = CODING_EOL_CR;
 -              }
 -            else
 -              {
 -                c2 = (src[msb] << 8) | (src[lsb]);
 -                if (c2 == '\n')
 -                  this_eol_type = CODING_EOL_CRLF, src += 2;
 -                else
 -                  this_eol_type = CODING_EOL_CR;
 -              }
 -          }
 -
 -        if (eol_type == CODING_EOL_UNDECIDED)
 -          /* This is the first end-of-line.  */
 -          eol_type = this_eol_type;
 -        else if (eol_type != this_eol_type)
 -          {
 -            /* The found type is different from what found before.  */
 -            eol_type = CODING_EOL_INCONSISTENT;
 -            break;
 -          }
 -      }
 -    }
 -
 -  if (*skip == 0)
 -    *skip = src_end - source;
 -  return eol_type;
 -}
 -
 -/* Detect how end-of-line of a text of length SRC_BYTES pointed by SRC
 -   is encoded.  If it detects an appropriate format of end-of-line, it
 -   sets the information in *CODING.  */
 -
 -void
 -detect_eol (coding, src, src_bytes)
 -     struct coding_system *coding;
 -     const unsigned char *src;
 -     int src_bytes;
 +static int
 +detect_eol (source, src_bytes, category)
 +     const unsigned char *source;
 +     EMACS_INT src_bytes;
 +     enum coding_category category;
  {
 -  Lisp_Object val;
 -  int skip;
 -  int eol_type;
 +  const unsigned char *src = source, *src_end = src + src_bytes;
 +  unsigned char c;
 +  int total  = 0;
 +  int eol_seen = EOL_SEEN_NONE;
  
 -  switch (coding->category_idx)
 +  if ((1 << category) & CATEGORY_MASK_UTF_16)
      {
 -    case CODING_CATEGORY_IDX_UTF_16_BE:
 -      eol_type = detect_eol_type_in_2_octet_form (src, src_bytes, &skip, 1);
 -      break;
 -    case CODING_CATEGORY_IDX_UTF_16_LE:
 -      eol_type = detect_eol_type_in_2_octet_form (src, src_bytes, &skip, 0);
 -      break;
 -    default:
 -      eol_type = detect_eol_type (src, src_bytes, &skip);
 -      break;
 -    }
 -
 -  if (coding->heading_ascii > skip)
 -    coding->heading_ascii = skip;
 -  else
 -    skip = coding->heading_ascii;
 +      int msb, lsb;
  
 -  if (eol_type == CODING_EOL_UNDECIDED)
 -    return;
 -  if (eol_type == CODING_EOL_INCONSISTENT)
 -    {
 -#if 0
 -      /* This code is suppressed until we find a better way to
 -       distinguish raw text file and binary file.  */
 +      msb = category == (coding_category_utf_16_le
 +                       | coding_category_utf_16_le_nosig);
 +      lsb = 1 - msb;
  
 -      /* If we have already detected that the coding is raw-text, the
 -       coding should actually be no-conversion.  */
 -      if (coding->type == coding_type_raw_text)
 +      while (src + 1 < src_end)
        {
 -        setup_coding_system (Qno_conversion, coding);
 -        return;
 +        c = src[lsb];
 +        if (src[msb] == 0 && (c == '\n' || c == '\r'))
 +          {
 +            int this_eol;
 +
 +            if (c == '\n')
 +              this_eol = EOL_SEEN_LF;
 +            else if (src + 3 >= src_end
 +                     || src[msb + 2] != 0
 +                     || src[lsb + 2] != '\n')
 +              this_eol = EOL_SEEN_CR;
 +            else
 +              this_eol = EOL_SEEN_CRLF;
 +
 +            if (eol_seen == EOL_SEEN_NONE)
 +              /* This is the first end-of-line.  */
 +              eol_seen = this_eol;
 +            else if (eol_seen != this_eol)
 +              {
 +                /* The found type is different from what found before.  */
 +                eol_seen = EOL_SEEN_LF;
 +                break;
 +              }
 +            if (++total == MAX_EOL_CHECK_COUNT)
 +              break;
 +          }
 +        src += 2;
        }
 -      /* Else, let's decode only text code anyway.  */
 -#endif /* 0 */
 -      eol_type = CODING_EOL_LF;
      }
 -
 -  val = Fget (coding->symbol, Qeol_type);
 -  if (VECTORP (val) && XVECTOR (val)->size == 3)
 +  else
      {
 -      int src_multibyte = coding->src_multibyte;
 -      int dst_multibyte = coding->dst_multibyte;
 -      struct composition_data *cmp_data = coding->cmp_data;
 -
 -      setup_coding_system (XVECTOR (val)->contents[eol_type], coding);
 -      coding->src_multibyte = src_multibyte;
 -      coding->dst_multibyte = dst_multibyte;
 -      coding->heading_ascii = skip;
 -      coding->cmp_data = cmp_data;
 -    }
 -}
 -
 -#define CONVERSION_BUFFER_EXTRA_ROOM 256
 -
 -#define DECODING_BUFFER_MAG(coding)                   \
 -  (coding->type == coding_type_iso2022                        \
 -   ? 3                                                        \
 -   : (coding->type == coding_type_ccl                 \
 -      ? coding->spec.ccl.decoder.buf_magnification    \
 -      : 2))
 +      while (src < src_end)
 +      {
 +        c = *src++;
 +        if (c == '\n' || c == '\r')
 +          {
 +            int this_eol;
  
 -/* Return maximum size (bytes) of a buffer enough for decoding
 -   SRC_BYTES of text encoded in CODING.  */
 +            if (c == '\n')
 +              this_eol = EOL_SEEN_LF;
 +            else if (src >= src_end || *src != '\n')
 +              this_eol = EOL_SEEN_CR;
 +            else
 +              this_eol = EOL_SEEN_CRLF, src++;
  
 -int
 -decoding_buffer_size (coding, src_bytes)
 -     struct coding_system *coding;
 -     int src_bytes;
 -{
 -  return (src_bytes * DECODING_BUFFER_MAG (coding)
 -        + CONVERSION_BUFFER_EXTRA_ROOM);
 +            if (eol_seen == EOL_SEEN_NONE)
 +              /* This is the first end-of-line.  */
 +              eol_seen = this_eol;
 +            else if (eol_seen != this_eol)
 +              {
 +                /* The found type is different from what found before.  */
 +                eol_seen = EOL_SEEN_LF;
 +                break;
 +              }
 +            if (++total == MAX_EOL_CHECK_COUNT)
 +              break;
 +          }
 +      }
 +    }
 +  return eol_seen;
  }
  
 -/* Return maximum size (bytes) of a buffer enough for encoding
 -   SRC_BYTES of text to CODING.  */
  
 -int
 -encoding_buffer_size (coding, src_bytes)
 +static Lisp_Object
 +adjust_coding_eol_type (coding, eol_seen)
       struct coding_system *coding;
 -     int src_bytes;
 +     int eol_seen;
  {
 -  int magnification;
 +  Lisp_Object eol_type;
  
 -  if (coding->type == coding_type_ccl)
 +  eol_type = CODING_ID_EOL_TYPE (coding->id);
 +  if (eol_seen & EOL_SEEN_LF)
      {
 -      magnification = coding->spec.ccl.encoder.buf_magnification;
 -      if (coding->eol_type == CODING_EOL_CRLF)
 -      magnification *= 2;
 +      coding->id = CODING_SYSTEM_ID (AREF (eol_type, 0));
 +      eol_type = Qunix;
      }
 -  else if (CODING_REQUIRE_ENCODING (coding))
 -    magnification = 3;
 -  else
 -    magnification = 1;
 -
 -  return (src_bytes * magnification + CONVERSION_BUFFER_EXTRA_ROOM);
 -}
 -
 -/* Working buffer for code conversion.  */
 -struct conversion_buffer
 -{
 -  int size;                   /* size of data.  */
 -  int on_stack;                       /* 1 if allocated by alloca.  */
 -  unsigned char *data;
 -};
 -
 -/* Allocate LEN bytes of memory for BUF (struct conversion_buffer).  */
 -#define allocate_conversion_buffer(buf, len)          \
 -  do {                                                        \
 -    if (len < MAX_ALLOCA)                             \
 -      {                                                       \
 -      buf.data = (unsigned char *) alloca (len);      \
 -      buf.on_stack = 1;                               \
 -      }                                                       \
 -    else                                              \
 -      {                                                       \
 -      buf.data = (unsigned char *) xmalloc (len);     \
 -      buf.on_stack = 0;                               \
 -      }                                                       \
 -    buf.size = len;                                   \
 -  } while (0)
 -
 -/* Double the allocated memory for *BUF.  */
 -static void
 -extend_conversion_buffer (buf)
 -     struct conversion_buffer *buf;
 -{
 -  if (buf->on_stack)
 +  else if (eol_seen & EOL_SEEN_CRLF)
      {
 -      unsigned char *save = buf->data;
 -      buf->data = (unsigned char *) xmalloc (buf->size * 2);
 -      bcopy (save, buf->data, buf->size);
 -      buf->on_stack = 0;
 +      coding->id = CODING_SYSTEM_ID (AREF (eol_type, 1));
 +      eol_type = Qdos;
      }
 -  else
 +  else if (eol_seen & EOL_SEEN_CR)
      {
 -      buf->data = (unsigned char *) xrealloc (buf->data, buf->size * 2);
 +      coding->id = CODING_SYSTEM_ID (AREF (eol_type, 2));
 +      eol_type = Qmac;
      }
 -  buf->size *= 2;
 +  return eol_type;
  }
  
 -/* Free the allocated memory for BUF if it is not on stack.  */
 -static void
 -free_conversion_buffer (buf)
 -     struct conversion_buffer *buf;
 -{
 -  if (!buf->on_stack)
 -    xfree (buf->data);
 -}
 +/* Detect how a text specified in CODING is encoded.  If a coding
 +   system is detected, update fields of CODING by the detected coding
 +   system.  */
  
 -int
 -ccl_coding_driver (coding, source, destination, src_bytes, dst_bytes, encodep)
 +void
 +detect_coding (coding)
       struct coding_system *coding;
 -     unsigned char *source, *destination;
 -     int src_bytes, dst_bytes, encodep;
  {
 -  struct ccl_program *ccl
 -    = encodep ? &coding->spec.ccl.encoder : &coding->spec.ccl.decoder;
 -  unsigned char *dst = destination;
 +  const unsigned char *src, *src_end;
  
 -  ccl->suppress_error = coding->suppress_error;
 -  ccl->last_block = coding->mode & CODING_MODE_LAST_BLOCK;
 -  if (encodep)
 -    {
 -      /* On encoding, EOL format is converted within ccl_driver.  For
 -       that, setup proper information in the structure CCL.  */
 -      ccl->eol_type = coding->eol_type;
 -      if (ccl->eol_type ==CODING_EOL_UNDECIDED)
 -      ccl->eol_type = CODING_EOL_LF;
 -      ccl->cr_consumed = coding->spec.ccl.cr_carryover;
 -      ccl->eight_bit_control = coding->dst_multibyte;
 -    }
 -  else
 -    ccl->eight_bit_control = 1;
 -  ccl->multibyte = coding->src_multibyte;
 -  if (coding->spec.ccl.eight_bit_carryover[0] != 0)
 -    {
 -      /* Move carryover bytes to DESTINATION.  */
 -      unsigned char *p = coding->spec.ccl.eight_bit_carryover;
 -      while (*p)
 -      *dst++ = *p++;
 -      coding->spec.ccl.eight_bit_carryover[0] = 0;
 -      if (dst_bytes)
 -      dst_bytes -= dst - destination;
 -    }
 +  coding->consumed = coding->consumed_char = 0;
 +  coding->produced = coding->produced_char = 0;
 +  coding_set_source (coding);
  
 -  coding->produced = (ccl_driver (ccl, source, dst, src_bytes, dst_bytes,
 -                                &(coding->consumed))
 -                    + dst - destination);
 +  src_end = coding->source + coding->src_bytes;
  
 -  if (encodep)
 -    {
 -      coding->produced_char = coding->produced;
 -      coding->spec.ccl.cr_carryover = ccl->cr_consumed;
 -    }
 -  else if (!ccl->eight_bit_control)
 -    {
 -      /* The produced bytes forms a valid multibyte sequence. */
 -      coding->produced_char
 -      = multibyte_chars_in_text (destination, coding->produced);
 -      coding->spec.ccl.eight_bit_carryover[0] = 0;
 -    }
 -  else
 +  /* If we have not yet decided the text encoding type, detect it
 +     now.  */
 +  if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qundecided))
      {
 -      /* On decoding, the destination should always multibyte.  But,
 -       CCL program might have been generated an invalid multibyte
 -       sequence.  Here we make such a sequence valid as
 -       multibyte.  */
 -      int bytes
 -      = dst_bytes ? dst_bytes : source + coding->consumed - destination;
 -
 -      if ((coding->consumed < src_bytes
 -         || !ccl->last_block)
 -        && coding->produced >= 1
 -        && destination[coding->produced - 1] >= 0x80)
 -      {
 -        /* We should not convert the tailing 8-bit codes to
 -           multibyte form even if they doesn't form a valid
 -           multibyte sequence.  They may form a valid sequence in
 -           the next call.  */
 -        int carryover = 0;
 -
 -        if (destination[coding->produced - 1] < 0xA0)
 -          carryover = 1;
 -        else if (coding->produced >= 2)
 +      int c, i;
 +      struct coding_detection_info detect_info;
 +
 +      detect_info.checked = detect_info.found = detect_info.rejected = 0;
 +      for (i = 0, src = coding->source; src < src_end; i++, src++)
 +      {
 +        c = *src;
 +        if (c & 0x80)
 +          break;
 +        if (c < 0x20
 +            && (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO)
 +            && ! inhibit_iso_escape_detection
 +            && ! detect_info.checked)
            {
 -            if (destination[coding->produced - 2] >= 0x80)
 +            coding->head_ascii = src - (coding->source + coding->consumed);
 +            if (detect_coding_iso_2022 (coding, &detect_info))
                {
 -                if (destination[coding->produced - 2] < 0xA0)
 -                  carryover = 2;
 -                else if (coding->produced >= 3
 -                         && destination[coding->produced - 3] >= 0x80
 -                         && destination[coding->produced - 3] < 0xA0)
 -                  carryover = 3;
 +                /* We have scanned the whole data.  */
 +                if (! (detect_info.rejected & CATEGORY_MASK_ISO_7_ELSE))
 +                  /* We didn't find an 8-bit code.  */
 +                  src = src_end;
 +                break;
                }
            }
 -        if (carryover > 0)
 -          {
 -            BCOPY_SHORT (destination + coding->produced - carryover,
 -                         coding->spec.ccl.eight_bit_carryover,
 -                         carryover);
 -            coding->spec.ccl.eight_bit_carryover[carryover] = 0;
 -            coding->produced -= carryover;
 -          }
        }
 -      coding->produced = str_as_multibyte (destination, bytes,
 -                                         coding->produced,
 -                                         &(coding->produced_char));
 -    }
 +      coding->head_ascii = src - (coding->source + coding->consumed);
 +
 +      if (coding->head_ascii < coding->src_bytes
 +        || detect_info.found)
 +      {
 +        enum coding_category category;
 +        struct coding_system *this;
  
 -  switch (ccl->status)
 +        if (coding->head_ascii == coding->src_bytes)
 +          /* As all bytes are 7-bit, we can ignore non-ISO-2022 codings.  */
 +          for (i = 0; i < coding_category_raw_text; i++)
 +            {
 +              category = coding_priorities[i];
 +              this = coding_categories + category;
 +              if (detect_info.found & (1 << category))
 +                break;
 +            }
 +        else
 +          for (i = 0; i < coding_category_raw_text; i++)
 +            {
 +              category = coding_priorities[i];
 +              this = coding_categories + category;
 +              if (this->id < 0)
 +                {
 +                  /* No coding system of this category is defined.  */
 +                  detect_info.rejected |= (1 << category);
 +                }
 +              else if (category >= coding_category_raw_text)
 +                continue;
 +              else if (detect_info.checked & (1 << category))
 +                {
 +                  if (detect_info.found & (1 << category))
 +                    break;
 +                }
 +              else if ((*(this->detector)) (coding, &detect_info)
 +                       && detect_info.found & (1 << category))
 +                {
 +                  if (category == coding_category_utf_16_auto)
 +                    {
 +                      if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
 +                        category = coding_category_utf_16_le;
 +                      else
 +                        category = coding_category_utf_16_be;
 +                    }
 +                  break;
 +                }
 +            }
 +        
 +        if (i < coding_category_raw_text)
 +          setup_coding_system (CODING_ID_NAME (this->id), coding);
 +        else if (detect_info.rejected == CATEGORY_MASK_ANY)
 +          setup_coding_system (Qraw_text, coding);
 +        else if (detect_info.rejected)
 +          for (i = 0; i < coding_category_raw_text; i++)
 +            if (! (detect_info.rejected & (1 << coding_priorities[i])))
 +              {
 +                this = coding_categories + coding_priorities[i];
 +                setup_coding_system (CODING_ID_NAME (this->id), coding);
 +                break;
 +              }
 +      }
 +    }
 +  else if (XINT (CODING_ATTR_CATEGORY (CODING_ID_ATTRS (coding->id)))
 +         == coding_category_utf_16_auto)
      {
 -    case CCL_STAT_SUSPEND_BY_SRC:
 -      coding->result = CODING_FINISH_INSUFFICIENT_SRC;
 -      break;
 -    case CCL_STAT_SUSPEND_BY_DST:
 -      coding->result = CODING_FINISH_INSUFFICIENT_DST;
 -      break;
 -    case CCL_STAT_QUIT:
 -    case CCL_STAT_INVALID_CMD:
 -      coding->result = CODING_FINISH_INTERRUPT;
 -      break;
 -    default:
 -      coding->result = CODING_FINISH_NORMAL;
 -      break;
 +      Lisp_Object coding_systems;
 +      struct coding_detection_info detect_info;
 +
 +      coding_systems
 +      = AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_16_bom);
 +      detect_info.found = detect_info.rejected = 0;
 +      if (CONSP (coding_systems)
 +        && detect_coding_utf_16 (coding, &detect_info))
 +      {
 +        if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
 +          setup_coding_system (XCAR (coding_systems), coding);
 +        else if (detect_info.found & CATEGORY_MASK_UTF_16_BE)
 +          setup_coding_system (XCDR (coding_systems), coding);
 +      }
      }
 -  return coding->result;
  }
  
 -/* Decode EOL format of the text at PTR of BYTES length destructively
 -   according to CODING->eol_type.  This is called after the CCL
 -   program produced a decoded text at PTR.  If we do CRLF->LF
 -   conversion, update CODING->produced and CODING->produced_char.  */
  
  static void
 -decode_eol_post_ccl (coding, ptr, bytes)
 +decode_eol (coding)
       struct coding_system *coding;
 -     unsigned char *ptr;
 -     int bytes;
  {
 -  Lisp_Object val, saved_coding_symbol;
 -  unsigned char *pend = ptr + bytes;
 -  int dummy;
 -
 -  /* Remember the current coding system symbol.  We set it back when
 -     an inconsistent EOL is found so that `last-coding-system-used' is
 -     set to the coding system that doesn't specify EOL conversion.  */
 -  saved_coding_symbol = coding->symbol;
 +  Lisp_Object eol_type;
 +  unsigned char *p, *pbeg, *pend;
 +  
 +  eol_type = CODING_ID_EOL_TYPE (coding->id);
 +  if (EQ (eol_type, Qunix))
 +    return;
  
 -  coding->spec.ccl.cr_carryover = 0;
 -  if (coding->eol_type == CODING_EOL_UNDECIDED)
 -    {
 -      /* Here, to avoid the call of setup_coding_system, we directly
 -       call detect_eol_type.  */
 -      coding->eol_type = detect_eol_type (ptr, bytes, &dummy);
 -      if (coding->eol_type == CODING_EOL_INCONSISTENT)
 -      coding->eol_type = CODING_EOL_LF;
 -      if (coding->eol_type != CODING_EOL_UNDECIDED)
 -      {
 -        val = Fget (coding->symbol, Qeol_type);
 -        if (VECTORP (val) && XVECTOR (val)->size == 3)
 -          coding->symbol = XVECTOR (val)->contents[coding->eol_type];
 -      }
 -      coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;
 -    }
 +  if (NILP (coding->dst_object))
 +    pbeg = coding->destination;
 +  else
 +    pbeg = BYTE_POS_ADDR (coding->dst_pos_byte);
 +  pend = pbeg + coding->produced;
  
 -  if (coding->eol_type == CODING_EOL_LF
 -      || coding->eol_type == CODING_EOL_UNDECIDED)
 -    {
 -      /* We have nothing to do.  */
 -      ptr = pend;
 -    }
 -  else if (coding->eol_type == CODING_EOL_CRLF)
 +  if (VECTORP (eol_type))
      {
 -      unsigned char *pstart = ptr, *p = ptr;
 +      int eol_seen = EOL_SEEN_NONE;
  
 -      if (! (coding->mode & CODING_MODE_LAST_BLOCK)
 -        && *(pend - 1) == '\r')
 -      {
 -        /* If the last character is CR, we can't handle it here
 -           because LF will be in the not-yet-decoded source text.
 -           Record that the CR is not yet processed.  */
 -        coding->spec.ccl.cr_carryover = 1;
 -        coding->produced--;
 -        coding->produced_char--;
 -        pend--;
 -      }
 -      while (ptr < pend)
 +      for (p = pbeg; p < pend; p++)
        {
 -        if (*ptr == '\r')
 +        if (*p == '\n')
 +          eol_seen |= EOL_SEEN_LF;
 +        else if (*p == '\r')
            {
 -            if (ptr + 1 < pend && *(ptr + 1) == '\n')
 -              {
 -                *p++ = '\n';
 -                ptr += 2;
 -              }
 -            else
 +            if (p + 1 < pend && *(p + 1) == '\n')
                {
 -                if (coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
 -                  goto undo_eol_conversion;
 -                *p++ = *ptr++;
 +                eol_seen |= EOL_SEEN_CRLF;
 +                p++;
                }
 -          }
 -        else if (*ptr == '\n'
 -                 && coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
 -          goto undo_eol_conversion;
 -        else
 -          *p++ = *ptr++;
 -        continue;
 -
 -      undo_eol_conversion:
 -        /* We have faced with inconsistent EOL format at PTR.
 -           Convert all LFs before PTR back to CRLFs.  */
 -        for (p--, ptr--; p >= pstart; p--)
 -          {
 -            if (*p == '\n')
 -              *ptr-- = '\n', *ptr-- = '\r';
              else
 -              *ptr-- = *p;
 -          }
 -        /*  If carryover is recorded, cancel it because we don't
 -            convert CRLF anymore.  */
 -        if (coding->spec.ccl.cr_carryover)
 -          {
 -            coding->spec.ccl.cr_carryover = 0;
 -            coding->produced++;
 -            coding->produced_char++;
 -            pend++;
 +              eol_seen |= EOL_SEEN_CR;
            }
 -        p = ptr = pend;
 -        coding->eol_type = CODING_EOL_LF;
 -        coding->symbol = saved_coding_symbol;
 -      }
 -      if (p < pend)
 -      {
 -        /* As each two-byte sequence CRLF was converted to LF, (PEND
 -           - P) is the number of deleted characters.  */
 -        coding->produced -= pend - p;
 -        coding->produced_char -= pend - p;
        }
 +      if (eol_seen != EOL_SEEN_NONE
 +        && eol_seen != EOL_SEEN_LF
 +        && eol_seen != EOL_SEEN_CRLF
 +        && eol_seen != EOL_SEEN_CR)
 +      eol_seen = EOL_SEEN_LF;
 +      if (eol_seen != EOL_SEEN_NONE)
 +      eol_type = adjust_coding_eol_type (coding, eol_seen);
 +    }
 +
 +  if (EQ (eol_type, Qmac))
 +    {
 +      for (p = pbeg; p < pend; p++)
 +      if (*p == '\r')
 +        *p = '\n';
      }
 -  else                        /* i.e. coding->eol_type == CODING_EOL_CR */
 +  else if (EQ (eol_type, Qdos))
      {
 -      unsigned char *p = ptr;
 +      int n = 0;
  
 -      for (; ptr < pend; ptr++)
 +      if (NILP (coding->dst_object))
 +      {
 +        /* Start deleting '\r' from the tail to minimize the memory
 +           movement.  */
 +        for (p = pend - 2; p >= pbeg; p--)
 +          if (*p == '\r')
 +            {
 +              safe_bcopy ((char *) (p + 1), (char *) p, pend-- - p - 1);
 +              n++;
 +            }
 +      }
 +      else
        {
 -        if (*ptr == '\r')
 -          *ptr = '\n';
 -        else if (*ptr == '\n'
 -                 && coding->mode & CODING_MODE_INHIBIT_INCONSISTENT_EOL)
 +        int pos_byte = coding->dst_pos_byte;
 +        int pos = coding->dst_pos;
 +        int pos_end = pos + coding->produced_char - 1;
 +
 +        while (pos < pos_end)
            {
 -            for (; p < ptr; p++)
 +            p = BYTE_POS_ADDR (pos_byte);
 +            if (*p == '\r' && p[1] == '\n')
                {
 -                if (*p == '\n')
 -                  *p = '\r';
 +                del_range_2 (pos, pos_byte, pos + 1, pos_byte + 1, 0);
 +                n++;
 +                pos_end--;
                }
 -            ptr = pend;
 -            coding->eol_type = CODING_EOL_LF;
 -            coding->symbol = saved_coding_symbol;
 +            pos++;
 +            pos_byte += BYTES_BY_CHAR_HEAD (*p);
            }
        }
 +      coding->produced -= n;
 +      coding->produced_char -= n;
      }
  }
  
 -/* See "GENERAL NOTES about `decode_coding_XXX ()' functions".  Before
 -   decoding, it may detect coding system and format of end-of-line if
 -   those are not yet decided.  The source should be unibyte, the
 -   result is multibyte if CODING->dst_multibyte is nonzero, else
 -   unibyte.  */
 -
 -int
 -decode_coding (coding, source, destination, src_bytes, dst_bytes)
 -     struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
 -{
 -  int extra = 0;
 -
 -  if (coding->type == coding_type_undecided)
 -    detect_coding (coding, source, src_bytes);
  
 -  if (coding->eol_type == CODING_EOL_UNDECIDED
 -      && coding->type != coding_type_ccl)
 -    {
 -      detect_eol (coding, source, src_bytes);
 -      /* We had better recover the original eol format if we
 -       encounter an inconsistent eol format while decoding.  */
 -      coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;
 -    }
 +/* Return a translation table (or list of them) from coding system
 +   attribute vector ATTRS for encoding (ENCODEP is nonzero) or
 +   decoding (ENCODEP is zero). */
  
 -  coding->produced = coding->produced_char = 0;
 -  coding->consumed = coding->consumed_char = 0;
 -  coding->errors = 0;
 -  coding->result = CODING_FINISH_NORMAL;
 +static Lisp_Object
 +get_translation_table (attrs, encodep, max_lookup)
 +     Lisp_Object attrs;
 +     int encodep, *max_lookup;
 +{
 +  Lisp_Object standard, translation_table;
 +  Lisp_Object val;
  
 -  switch (coding->type)
 +  if (encodep)
 +    translation_table = CODING_ATTR_ENCODE_TBL (attrs),
 +      standard = Vstandard_translation_table_for_encode;
 +  else
 +    translation_table = CODING_ATTR_DECODE_TBL (attrs),
 +      standard = Vstandard_translation_table_for_decode;
 +  if (NILP (translation_table))
 +    translation_table = standard;
 +  else
      {
 -    case coding_type_sjis:
 -      decode_coding_sjis_big5 (coding, source, destination,
 -                             src_bytes, dst_bytes, 1);
 -      break;
 -
 -    case coding_type_iso2022:
 -      decode_coding_iso2022 (coding, source, destination,
 -                           src_bytes, dst_bytes);
 -      break;
 -
 -    case coding_type_big5:
 -      decode_coding_sjis_big5 (coding, source, destination,
 -                             src_bytes, dst_bytes, 0);
 -      break;
 -
 -    case coding_type_emacs_mule:
 -      decode_coding_emacs_mule (coding, source, destination,
 -                              src_bytes, dst_bytes);
 -      break;
 -
 -    case coding_type_ccl:
 -      if (coding->spec.ccl.cr_carryover)
 +      if (SYMBOLP (translation_table))
 +      translation_table = Fget (translation_table, Qtranslation_table);
 +      else if (CONSP (translation_table))
        {
 -        /* Put the CR which was not processed by the previous call
 -           of decode_eol_post_ccl in DESTINATION.  It will be
 -           decoded together with the following LF by the call to
 -           decode_eol_post_ccl below.  */
 -        *destination = '\r';
 -        coding->produced++;
 -        coding->produced_char++;
 -        dst_bytes--;
 -        extra = coding->spec.ccl.cr_carryover;
 +        translation_table = Fcopy_sequence (translation_table);
 +        for (val = translation_table; CONSP (val); val = XCDR (val))
 +          if (SYMBOLP (XCAR (val)))
 +            XSETCAR (val, Fget (XCAR (val), Qtranslation_table));
        }
 -      ccl_coding_driver (coding, source, destination + extra,
 -                       src_bytes, dst_bytes, 0);
 -      if (coding->eol_type != CODING_EOL_LF)
 +      if (CHAR_TABLE_P (standard))
        {
 -        coding->produced += extra;
 -        coding->produced_char += extra;
 -        decode_eol_post_ccl (coding, destination, coding->produced);
 +        if (CONSP (translation_table))
 +          translation_table = nconc2 (translation_table,
 +                                      Fcons (standard, Qnil));
 +        else
 +          translation_table = Fcons (translation_table,
 +                                     Fcons (standard, Qnil));
        }
 -      break;
 -
 -    default:
 -      decode_eol (coding, source, destination, src_bytes, dst_bytes);
      }
  
 -  if (coding->result == CODING_FINISH_INSUFFICIENT_SRC
 -      && coding->mode & CODING_MODE_LAST_BLOCK
 -      && coding->consumed == src_bytes)
 -    coding->result = CODING_FINISH_NORMAL;
 -
 -  if (coding->mode & CODING_MODE_LAST_BLOCK
 -      && coding->result == CODING_FINISH_INSUFFICIENT_SRC)
 +  if (max_lookup)
      {
 -      const unsigned char *src = source + coding->consumed;
 -      unsigned char *dst = destination + coding->produced;
 -
 -      src_bytes -= coding->consumed;
 -      coding->errors++;
 -      if (COMPOSING_P (coding))
 -      DECODE_COMPOSITION_END ('1');
 -      while (src_bytes--)
 +      *max_lookup = 1;
 +      if (CHAR_TABLE_P (translation_table)
 +        && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (translation_table)) > 1)
        {
 -        int c = *src++;
 -        dst += CHAR_STRING (c, dst);
 -        coding->produced_char++;
 +        val = XCHAR_TABLE (translation_table)->extras[1];
 +        if (NATNUMP (val) && *max_lookup < XFASTINT (val))
 +          *max_lookup = XFASTINT (val);
        }
 -      coding->consumed = coding->consumed_char = src - source;
 -      coding->produced = dst - destination;
 -      coding->result = CODING_FINISH_NORMAL;
 -    }
 +      else if (CONSP (translation_table))
 +      {
 +        Lisp_Object tail, val;
  
 -  if (!coding->dst_multibyte)
 -    {
 -      coding->produced = str_as_unibyte (destination, coding->produced);
 -      coding->produced_char = coding->produced;
 +        for (tail = translation_table; CONSP (tail); tail = XCDR (tail))
 +          if (CHAR_TABLE_P (XCAR (tail))
 +              && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (XCAR (tail))) > 1)
 +            {
 +              val = XCHAR_TABLE (XCAR (tail))->extras[1];
 +              if (NATNUMP (val) && *max_lookup < XFASTINT (val))
 +                *max_lookup = XFASTINT (val);
 +            }
 +      }
      }
 -
 -  return coding->result;
 +  return translation_table;
  }
  
 -/* See "GENERAL NOTES about `encode_coding_XXX ()' functions".  The
 -   multibyteness of the source is CODING->src_multibyte, the
 -   multibyteness of the result is always unibyte.  */
 -
 -int
 -encode_coding (coding, source, destination, src_bytes, dst_bytes)
 -     struct coding_system *coding;
 -     const unsigned char *source;
 -     unsigned char *destination;
 -     int src_bytes, dst_bytes;
 -{
 -  coding->produced = coding->produced_char = 0;
 -  coding->consumed = coding->consumed_char = 0;
 -  coding->errors = 0;
 -  coding->result = CODING_FINISH_NORMAL;
 -  if (coding->eol_type == CODING_EOL_UNDECIDED)
 -    coding->eol_type = CODING_EOL_LF;
 -
 -  switch (coding->type)
 -    {
 -    case coding_type_sjis:
 -      encode_coding_sjis_big5 (coding, source, destination,
 -                             src_bytes, dst_bytes, 1);
 -      break;
 -
 -    case coding_type_iso2022:
 -      encode_coding_iso2022 (coding, source, destination,
 -                           src_bytes, dst_bytes);
 -      break;
 -
 -    case coding_type_big5:
 -      encode_coding_sjis_big5 (coding, source, destination,
 -                             src_bytes, dst_bytes, 0);
 -      break;
 -
 -    case coding_type_emacs_mule:
 -      encode_coding_emacs_mule (coding, source, destination,
 -                              src_bytes, dst_bytes);
 -      break;
 -
 -    case coding_type_ccl:
 -      ccl_coding_driver (coding, source, destination,
 -                       src_bytes, dst_bytes, 1);
 -      break;
 +#define LOOKUP_TRANSLATION_TABLE(table, c, trans)             \
 +  do {                                                                \
 +    trans = Qnil;                                             \
 +    if (CHAR_TABLE_P (table))                                 \
 +      {                                                               \
 +      trans = CHAR_TABLE_REF (table, c);                      \
 +      if (CHARACTERP (trans))                                 \
 +        c = XFASTINT (trans), trans = Qnil;                   \
 +      }                                                               \
 +    else if (CONSP (table))                                   \
 +      {                                                               \
 +      Lisp_Object tail;                                       \
 +                                                              \
 +      for (tail = table; CONSP (tail); tail = XCDR (tail))    \
 +        if (CHAR_TABLE_P (XCAR (tail)))                       \
 +          {                                                   \
 +            trans = CHAR_TABLE_REF (XCAR (tail), c);          \
 +            if (CHARACTERP (trans))                           \
 +              c = XFASTINT (trans), trans = Qnil;             \
 +            else if (! NILP (trans))                          \
 +              break;                                          \
 +          }                                                   \
 +      }                                                               \
 +  } while (0)
  
 -    default:
 -      encode_eol (coding, source, destination, src_bytes, dst_bytes);
 -    }
  
 -  if (coding->mode & CODING_MODE_LAST_BLOCK
 -      && coding->result == CODING_FINISH_INSUFFICIENT_SRC)
 +static Lisp_Object
 +get_translation (val, buf, buf_end, last_block, from_nchars, to_nchars)
 +     Lisp_Object val;
 +     int *buf, *buf_end;
 +     int last_block;
 +     int *from_nchars, *to_nchars;
 +{
 +  /* VAL is TO or (([FROM-CHAR ...] .  TO) ...) where TO is TO-CHAR or
 +     [TO-CHAR ...].  */
 +  if (CONSP (val))
      {
 -      const unsigned char *src = source + coding->consumed;
 -      unsigned char *dst = destination + coding->produced;
 +      Lisp_Object from, tail;
 +      int i, len;
  
 -      if (coding->type == coding_type_iso2022)
 -      ENCODE_RESET_PLANE_AND_REGISTER;
 -      if (COMPOSING_P (coding))
 -      *dst++ = ISO_CODE_ESC, *dst++ = '1';
 -      if (coding->consumed < src_bytes)
 +      for (tail = val; CONSP (tail); tail = XCDR (tail))
        {
 -        int len = src_bytes - coding->consumed;
 -
 -        BCOPY_SHORT (src, dst, len);
 -        if (coding->src_multibyte)
 -          len = str_as_unibyte (dst, len);
 -        dst += len;
 -        coding->consumed = src_bytes;
 +        val = XCAR (tail);
 +        from = XCAR (val);
 +        len = ASIZE (from);
 +        for (i = 0; i < len; i++)
 +          {
 +            if (buf + i == buf_end)
 +              {
 +                if (! last_block)
 +                  return Qt;
 +                break;
 +              }
 +            if (XINT (AREF (from, i)) != buf[i])
 +              break;
 +          }
 +        if (i == len)
 +          {
 +            val = XCDR (val);
 +            *from_nchars = len;
 +            break;
 +          }
        }
 -      coding->produced = coding->produced_char = dst - destination;
 -      coding->result = CODING_FINISH_NORMAL;
 +      if (! CONSP (tail))
 +      return Qnil;
      }
 -
 -  if (coding->result == CODING_FINISH_INSUFFICIENT_SRC
 -      && coding->consumed == src_bytes)
 -    coding->result = CODING_FINISH_NORMAL;
 -
 -  return coding->result;
 +  if (VECTORP (val))
 +    *buf = XINT (AREF (val, 0)), *to_nchars = ASIZE (val);
 +  else
 +    *buf = XINT (val);
 +  return val;
  }
  
 -/* Scan text in the region between *BEG and *END (byte positions),
 -   skip characters which we don't have to decode by coding system
 -   CODING at the head and tail, then set *BEG and *END to the region
 -   of the text we actually have to convert.  The caller should move
 -   the gap out of the region in advance if the region is from a
 -   buffer.
 -
 -   If STR is not NULL, *BEG and *END are indices into STR.  */
  
 -static void
 -shrink_decoding_region (beg, end, coding, str)
 -     int *beg, *end;
 +static int
 +produce_chars (coding, translation_table, last_block)
       struct coding_system *coding;
 -     unsigned char *str;
 -{
 -  unsigned char *begp_orig, *begp, *endp_orig, *endp, c;
 -  int eol_conversion;
 -  Lisp_Object translation_table;
 -
 -  if (coding->type == coding_type_ccl
 -      || coding->type == coding_type_undecided
 -      || coding->eol_type != CODING_EOL_LF
 -      || !NILP (coding->post_read_conversion)
 -      || coding->composing != COMPOSITION_DISABLED)
 -    {
 -      /* We can't skip any data.  */
 -      return;
 -    }
 -  if (coding->type == coding_type_no_conversion
 -      || coding->type == coding_type_raw_text
 -      || coding->type == coding_type_emacs_mule)
 -    {
 -      /* We need no conversion, but don't have to skip any data here.
 -         Decoding routine handles them effectively anyway.  */
 -      return;
 -    }
 +     Lisp_Object translation_table;
 +     int last_block;
 +{
 +  unsigned char *dst = coding->destination + coding->produced;
 +  unsigned char *dst_end = coding->destination + coding->dst_bytes;
 +  int produced;
 +  int produced_chars = 0;
 +  int carryover = 0;
  
 -  translation_table = coding->translation_table_for_decode;
 -  if (NILP (translation_table) && !NILP (Venable_character_translation))
 -    translation_table = Vstandard_translation_table_for_decode;
 -  if (CHAR_TABLE_P (translation_table))
 +  if (! coding->chars_at_source)
      {
 -      int i;
 -      for (i = 0; i < 128; i++)
 -      if (!NILP (CHAR_TABLE_REF (translation_table, i)))
 -        break;
 -      if (i < 128)
 -      /* Some ASCII character should be translated.  We give up
 -         shrinking.  */
 -      return;
 -    }
 +      /* Characters are in coding->charbuf.  */
 +      int *buf = coding->charbuf;
 +      int *buf_end = buf + coding->charbuf_used;
  
 -  if (coding->heading_ascii >= 0)
 -    /* Detection routine has already found how much we can skip at the
 -       head.  */
 -    *beg += coding->heading_ascii;
 +      if (BUFFERP (coding->src_object)
 +        && EQ (coding->src_object, coding->dst_object))
 +      dst_end = ((unsigned char *) coding->source) + coding->consumed;
  
 -  if (str)
 -    {
 -      begp_orig = begp = str + *beg;
 -      endp_orig = endp = str + *end;
 +      while (buf < buf_end)
 +      {
 +        int c = *buf, i;
 +
 +        if (c >= 0)
 +          {
 +            int from_nchars = 1, to_nchars = 1;
 +            Lisp_Object trans = Qnil;
 +
 +            LOOKUP_TRANSLATION_TABLE (translation_table, c, trans);
 +            if (! NILP (trans))
 +              {
 +                trans = get_translation (trans, buf, buf_end, last_block,
 +                                         &from_nchars, &to_nchars);
 +                if (EQ (trans, Qt))
 +                  break;
 +                c = *buf;
 +              }
 +
 +            if (dst + MAX_MULTIBYTE_LENGTH * to_nchars > dst_end)
 +              {
 +                dst = alloc_destination (coding,
 +                                         buf_end - buf
 +                                         + MAX_MULTIBYTE_LENGTH * to_nchars,
 +                                         dst);
 +                dst_end = coding->destination + coding->dst_bytes;
 +              }
 +
 +            for (i = 0; i < to_nchars; i++)
 +              {
 +                if (i > 0)
 +                  c = XINT (AREF (trans, i));
 +                if (coding->dst_multibyte
 +                    || ! CHAR_BYTE8_P (c))
 +                  CHAR_STRING_ADVANCE (c, dst);
 +                else
 +                  *dst++ = CHAR_TO_BYTE8 (c);
 +              }
 +            produced_chars += to_nchars;
 +            *buf++ = to_nchars;
 +            while (--from_nchars > 0)
 +              *buf++ = 0;
 +          }
 +        else
 +          /* This is an annotation datum.  (-C) is the length.  */
 +          buf += -c;
 +      }
 +      carryover = buf_end - buf;
      }
    else
      {
 -      begp_orig = begp = BYTE_POS_ADDR (*beg);
 -      endp_orig = endp = begp + *end - *beg;
 -    }
 +      const unsigned char *src = coding->source;
 +      const unsigned char *src_end = src + coding->src_bytes;
 +      Lisp_Object eol_type;
  
 -  eol_conversion = (coding->eol_type == CODING_EOL_CR
 -                  || coding->eol_type == CODING_EOL_CRLF);
 +      eol_type = CODING_ID_EOL_TYPE (coding->id);
  
 -  switch (coding->type)
 -    {
 -    case coding_type_sjis:
 -    case coding_type_big5:
 -      /* We can skip all ASCII characters at the head.  */
 -      if (coding->heading_ascii < 0)
 +      if (coding->src_multibyte != coding->dst_multibyte)
        {
 -        if (eol_conversion)
 -          while (begp < endp && *begp < 0x80 && *begp != '\r') begp++;
 -        else
 -          while (begp < endp && *begp < 0x80) begp++;
 -      }
 -      /* We can skip all ASCII characters at the tail except for the
 -       second byte of SJIS or BIG5 code.  */
 -      if (eol_conversion)
 -      while (begp < endp && endp[-1] < 0x80 && endp[-1] != '\r') endp--;
 -      else
 -      while (begp < endp && endp[-1] < 0x80) endp--;
 -      /* Do not consider LF as ascii if preceded by CR, since that
 -       confuses eol decoding. */
 -      if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')
 -      endp++;
 -      if (begp < endp && endp < endp_orig && endp[-1] >= 0x80)
 -      endp++;
 -      break;
 +        if (coding->src_multibyte)
 +          {
 +            int multibytep = 1;
 +            int consumed_chars;
  
 -    case coding_type_iso2022:
 -      if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, 0) != CHARSET_ASCII)
 -      /* We can't skip any data.  */
 -      break;
 -      if (coding->heading_ascii < 0)
 -      {
 -        /* We can skip all ASCII characters at the head except for a
 -           few control codes.  */
 -        while (begp < endp && (c = *begp) < 0x80
 -               && c != ISO_CODE_CR && c != ISO_CODE_SO
 -               && c != ISO_CODE_SI && c != ISO_CODE_ESC
 -               && (!eol_conversion || c != ISO_CODE_LF))
 -          begp++;
 -      }
 -      switch (coding->category_idx)
 -      {
 -      case CODING_CATEGORY_IDX_ISO_8_1:
 -      case CODING_CATEGORY_IDX_ISO_8_2:
 -        /* We can skip all ASCII characters at the tail.  */
 -        if (eol_conversion)
 -          while (begp < endp && (c = endp[-1]) < 0x80 && c != '\r') endp--;
 +            while (1)
 +              {
 +                const unsigned char *src_base = src;
 +                int c;
 +
 +                ONE_MORE_BYTE (c);
 +                if (c == '\r')
 +                  {
 +                    if (EQ (eol_type, Qdos))
 +                      {
 +                        if (src == src_end)
 +                          {
 +                            record_conversion_result
 +                              (coding, CODING_RESULT_INSUFFICIENT_SRC);
 +                            goto no_more_source;
 +                          }
 +                        if (*src == '\n')
 +                          c = *src++;
 +                      }
 +                    else if (EQ (eol_type, Qmac))
 +                      c = '\n';
 +                  }
 +                if (dst == dst_end)
 +                  {
 +                    coding->consumed = src - coding->source;
 +
 +                  if (EQ (coding->src_object, coding->dst_object))
 +                    dst_end = (unsigned char *) src;
 +                  if (dst == dst_end)
 +                    {
 +                      dst = alloc_destination (coding, src_end - src + 1,
 +                                               dst);
 +                      dst_end = coding->destination + coding->dst_bytes;
 +                      coding_set_source (coding);
 +                      src = coding->source + coding->consumed;
 +                      src_end = coding->source + coding->src_bytes;
 +                    }
 +                  }
 +                *dst++ = c;
 +                produced_chars++;
 +              }
 +          no_more_source:
 +            ;
 +          }
          else
 -          while (begp < endp && endp[-1] < 0x80) endp--;
 -        /* Do not consider LF as ascii if preceded by CR, since that
 -             confuses eol decoding. */
 -        if (begp < endp && endp < endp_orig && endp[-1] == '\r' && endp[0] == '\n')
 -          endp++;
 -        break;
 +          while (src < src_end)
 +            {
 +              int multibytep = 1;
 +              int c = *src++;
  
 -      case CODING_CATEGORY_IDX_ISO_7:
 -      case CODING_CATEGORY_IDX_ISO_7_TIGHT:
 -        {
 -          /* We can skip all characters at the tail except for 8-bit
 -             codes and ESC and the following 2-byte at the tail.  */
 -          unsigned char *eight_bit = NULL;
 +              if (c == '\r')
 +                {
 +                  if (EQ (eol_type, Qdos))
 +                    {
 +                      if (src < src_end
 +                          && *src == '\n')
 +                        c = *src++;
 +                    }
 +                  else if (EQ (eol_type, Qmac))
 +                    c = '\n';
 +                }
 +              if (dst >= dst_end - 1)
 +                {
 +                  coding->consumed = src - coding->source;
 +
 +                  if (EQ (coding->src_object, coding->dst_object))
 +                    dst_end = (unsigned char *) src;
 +                  if (dst >= dst_end - 1)
 +                    {
 +                      dst = alloc_destination (coding, src_end - src + 2,
 +                                               dst);
 +                      dst_end = coding->destination + coding->dst_bytes;
 +                      coding_set_source (coding);
 +                      src = coding->source + coding->consumed;
 +                      src_end = coding->source + coding->src_bytes;
 +                    }
 +                }
 +              EMIT_ONE_BYTE (c);
 +            }
 +      }
 +      else
 +      {
 +        if (!EQ (coding->src_object, coding->dst_object))
 +          {
 +            int require = coding->src_bytes - coding->dst_bytes;
  
 -          if (eol_conversion)
 -            while (begp < endp
 -                   && (c = endp[-1]) != ISO_CODE_ESC && c != '\r')
 +            if (require > 0)
                {
 -                if (!eight_bit && c & 0x80) eight_bit = endp;
 -                endp--;
 +                EMACS_INT offset = src - coding->source;
 +
 +                dst = alloc_destination (coding, require, dst);
 +                coding_set_source (coding);
 +                src = coding->source + offset;
 +                src_end = coding->source + coding->src_bytes;
                }
 -          else
 -            while (begp < endp
 -                   && (c = endp[-1]) != ISO_CODE_ESC)
 +          }
 +        produced_chars = coding->src_chars;
 +        while (src < src_end)
 +          {
 +            int c = *src++;
 +
 +            if (c == '\r')
                {
 -                if (!eight_bit && c & 0x80) eight_bit = endp;
 -                endp--;
 +                if (EQ (eol_type, Qdos))
 +                  {
 +                    if (src < src_end
 +                        && *src == '\n')
 +                      c = *src++;
 +                    produced_chars--;
 +                  }
 +                else if (EQ (eol_type, Qmac))
 +                  c = '\n';
                }
 -          /* Do not consider LF as ascii if preceded by CR, since that
 -             confuses eol decoding. */
 -          if (begp < endp && endp < endp_orig
 -              && endp[-1] == '\r' && endp[0] == '\n')
 -            endp++;
 -          if (begp < endp && endp[-1] == ISO_CODE_ESC)
 -            {
 -              if (endp + 1 < endp_orig && end[0] == '(' && end[1] == 'B')
 -                /* This is an ASCII designation sequence.  We can
 -                   surely skip the tail.  But, if we have
 -                   encountered an 8-bit code, skip only the codes
 -                   after that.  */
 -                endp = eight_bit ? eight_bit : endp + 2;
 -              else
 -                /* Hmmm, we can't skip the tail.  */
 -                endp = endp_orig;
 -            }
 -          else if (eight_bit)
 -            endp = eight_bit;
 -        }
 +            *dst++ = c;
 +          }
        }
 -      break;
 -
 -    default:
 -      abort ();
 +      coding->consumed = coding->src_bytes;
 +      coding->consumed_char = coding->src_chars;
      }
 -  *beg += begp - begp_orig;
 -  *end += endp - endp_orig;
 -  return;
 +
 +  produced = dst - (coding->destination + coding->produced);
 +  if (BUFFERP (coding->dst_object))
 +    insert_from_gap (produced_chars, produced);
 +  coding->produced += produced;
 +  coding->produced_char += produced_chars;
 +  return carryover;
  }
  
 -/* Like shrink_decoding_region but for encoding.  */
 +/* Compose text in CODING->object according to the annotation data at
 +   CHARBUF.  CHARBUF is an array:
 +     [ -LENGTH ANNOTATION_MASK FROM TO METHOD COMP_LEN [ COMPONENTS... ] ]
 + */
  
 -static void
 -shrink_encoding_region (beg, end, coding, str)
 -     int *beg, *end;
 +static INLINE void
 +produce_composition (coding, charbuf, pos)
       struct coding_system *coding;
 -     unsigned char *str;
 +     int *charbuf;
 +     EMACS_INT pos;
  {
 -  unsigned char *begp_orig, *begp, *endp_orig, *endp;
 -  int eol_conversion;
 -  Lisp_Object translation_table;
 +  int len;
 +  EMACS_INT to;
 +  enum composition_method method;
 +  Lisp_Object components;
  
 -  if (coding->type == coding_type_ccl
 -      || coding->eol_type == CODING_EOL_CRLF
 -      || coding->eol_type == CODING_EOL_CR
 -      || (coding->cmp_data && coding->cmp_data->used > 0))
 -    {
 -      /* We can't skip any data.  */
 -      return;
 -    }
 -  if (coding->type == coding_type_no_conversion
 -      || coding->type == coding_type_raw_text
 -      || coding->type == coding_type_emacs_mule
 -      || coding->type == coding_type_undecided)
 -    {
 -      /* We need no conversion, but don't have to skip any data here.
 -         Encoding routine handles them effectively anyway.  */
 -      return;
 -    }
 +  len = -charbuf[0];
 +  to = pos + charbuf[2];
 +  if (to <= pos)
 +    return;
 +  method = (enum composition_method) (charbuf[3]);
  
 -  translation_table = coding->translation_table_for_encode;
 -  if (NILP (translation_table) && !NILP (Venable_character_translation))
 -    translation_table = Vstandard_translation_table_for_encode;
 -  if (CHAR_TABLE_P (translation_table))
 +  if (method == COMPOSITION_RELATIVE)
 +    components = Qnil;
 +  else if (method >= COMPOSITION_WITH_RULE
 +         && method <= COMPOSITION_WITH_RULE_ALTCHARS)
      {
 +      Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];
        int i;
 -      for (i = 0; i < 128; i++)
 -      if (!NILP (CHAR_TABLE_REF (translation_table, i)))
 -        break;
 -      if (i < 128)
 -      /* Some ASCII character should be translated.  We give up
 -         shrinking.  */
 -      return;
 -    }
  
 -  if (str)
 -    {
 -      begp_orig = begp = str + *beg;
 -      endp_orig = endp = str + *end;
 +      len -= 4;
 +      charbuf += 4;
 +      for (i = 0; i < len; i++)
 +      {
 +        args[i] = make_number (charbuf[i]);
 +        if (charbuf[i] < 0)
 +          return;
 +      }
 +      components = (method == COMPOSITION_WITH_ALTCHARS
 +                  ? Fstring (len, args) : Fvector (len, args));
      }
    else
 -    {
 -      begp_orig = begp = BYTE_POS_ADDR (*beg);
 -      endp_orig = endp = begp + *end - *beg;
 -    }
 -
 -  eol_conversion = (coding->eol_type == CODING_EOL_CR
 -                  || coding->eol_type == CODING_EOL_CRLF);
 +    return;
 +  compose_text (pos, to, components, Qnil, coding->dst_object);
 +}
  
 -  /* Here, we don't have to check coding->pre_write_conversion because
 -     the caller is expected to have handled it already.  */
 -  switch (coding->type)
 -    {
 -    case coding_type_iso2022:
 -      if (CODING_SPEC_ISO_INITIAL_DESIGNATION (coding, 0) != CHARSET_ASCII)
 -      /* We can't skip any data.  */
 -      break;
 -      if (coding->flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL)
 -      {
 -        unsigned char *bol = begp;
 -        while (begp < endp && *begp < 0x80)
 -          {
 -            begp++;
 -            if (begp[-1] == '\n')
 -              bol = begp;
 -          }
 -        begp = bol;
 -        goto label_skip_tail;
 -      }
 -      /* fall down ... */
  
 -    case coding_type_sjis:
 -    case coding_type_big5:
 -      /* We can skip all ASCII characters at the head and tail.  */
 -      if (eol_conversion)
 -      while (begp < endp && *begp < 0x80 && *begp != '\n') begp++;
 -      else
 -      while (begp < endp && *begp < 0x80) begp++;
 -    label_skip_tail:
 -      if (eol_conversion)
 -      while (begp < endp && endp[-1] < 0x80 && endp[-1] != '\n') endp--;
 -      else
 -      while (begp < endp && *(endp - 1) < 0x80) endp--;
 -      break;
 +/* Put `charset' property on text in CODING->object according to
 +   the annotation data at CHARBUF.  CHARBUF is an array:
 +     [ -LENGTH ANNOTATION_MASK NCHARS CHARSET-ID ]
 + */
  
 -    default:
 -      abort ();
 -    }
 +static INLINE void
 +produce_charset (coding, charbuf, pos)
 +     struct coding_system *coding;
 +     int *charbuf;
 +     EMACS_INT pos;
 +{
 +  EMACS_INT from = pos - charbuf[2];
 +  struct charset *charset = CHARSET_FROM_ID (charbuf[3]);
  
 -  *beg += begp - begp_orig;
 -  *end += endp - endp_orig;
 -  return;
 +  Fput_text_property (make_number (from), make_number (pos),
 +                    Qcharset, CHARSET_NAME (charset),
 +                    coding->dst_object);
  }
  
 -/* As shrinking conversion region requires some overhead, we don't try
 -   shrinking if the length of conversion region is less than this
 -   value.  */
 -static int shrink_conversion_region_threshhold = 1024;
  
 -#define SHRINK_CONVERSION_REGION(beg, end, coding, str, encodep)      \
 +#define CHARBUF_SIZE 0x4000
 +
 +#define ALLOC_CONVERSION_WORK_AREA(coding)                            \
    do {                                                                        \
 -    if (*(end) - *(beg) > shrink_conversion_region_threshhold)                \
 +    int size = CHARBUF_SIZE;;                                         \
 +                                                                      \
 +    coding->charbuf = NULL;                                           \
 +    while (size > 1024)                                                       \
 +      {                                                                       \
 +      coding->charbuf = (int *) alloca (sizeof (int) * size);         \
 +      if (coding->charbuf)                                            \
 +        break;                                                        \
 +      size >>= 1;                                                     \
 +      }                                                                       \
 +    if (! coding->charbuf)                                            \
        {                                                                       \
 -        if (encodep) shrink_encoding_region (beg, end, coding, str);  \
 -        else shrink_decoding_region (beg, end, coding, str);          \
 +      record_conversion_result (coding, CODING_RESULT_INSUFFICIENT_MEM); \
 +      return coding->result;                                          \
        }                                                                       \
 +    coding->charbuf_size = size;                                      \
    } while (0)
  
 -/* ARG is (CODING BUFFER ...) where CODING is what to be set in
 -   Vlast_coding_system_used and the remaining elements are buffers to
 -   kill.  */
 -static Lisp_Object
 -code_convert_region_unwind (arg)
 -     Lisp_Object arg;
 -{
 -  struct gcpro gcpro1;
 -  GCPRO1 (arg);
 -
 -  inhibit_pre_post_conversion = 0;
 -  Vlast_coding_system_used = XCAR (arg);
 -  for (arg = XCDR (arg); ! NILP (arg); arg = XCDR (arg))
 -    Fkill_buffer (XCAR (arg));
 -
 -  UNGCPRO;
 -  return Qnil;
 -}
 -
 -/* Store information about all compositions in the range FROM and TO
 -   of OBJ in memory blocks pointed by CODING->cmp_data.  OBJ is a
 -   buffer or a string, defaults to the current buffer.  */
  
 -void
 -coding_save_composition (coding, from, to, obj)
 +static void
 +produce_annotation (coding, pos)
       struct coding_system *coding;
 -     int from, to;
 -     Lisp_Object obj;
 +     EMACS_INT pos;
  {
 -  Lisp_Object prop;
 -  int start, end;
 +  int *charbuf = coding->charbuf;
 +  int *charbuf_end = charbuf + coding->charbuf_used;
  
 -  if (coding->composing == COMPOSITION_DISABLED)
 -    return;
 -  if (!coding->cmp_data)
 -    coding_allocate_composition_data (coding, from);
 -  if (!find_composition (from, to, &start, &end, &prop, obj)
 -      || end > to)
 +  if (NILP (coding->dst_object))
      return;
 -  if (start < from
 -      && (!find_composition (end, to, &start, &end, &prop, obj)
 -        || end > to))
 -    return;
 -  coding->composing = COMPOSITION_NO;
 -  do
 +
 +  while (charbuf < charbuf_end)
      {
 -      if (COMPOSITION_VALID_P (start, end, prop))
 +      if (*charbuf >= 0)
 +      pos += *charbuf++;
 +      else
        {
 -        enum composition_method method = COMPOSITION_METHOD (prop);
 -        if (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH
 -            >= COMPOSITION_DATA_SIZE)
 -          coding_allocate_composition_data (coding, from);
 -        /* For relative composition, we remember start and end
 -             positions, for the other compositions, we also remember
 -             components.  */
 -        CODING_ADD_COMPOSITION_START (coding, start - from, method);
 -        if (method != COMPOSITION_RELATIVE)
 +        int len = -*charbuf;
 +        switch (charbuf[1])
            {
 -            /* We must store a*/
 -            Lisp_Object val, ch;
 -
 -            val = COMPOSITION_COMPONENTS (prop);
 -            if (CONSP (val))
 -              while (CONSP (val))
 -                {
 -                  ch = XCAR (val), val = XCDR (val);
 -                  CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (ch));
 -                }
 -            else if (VECTORP (val) || STRINGP (val))
 -              {
 -                int len = (VECTORP (val)
 -                           ? XVECTOR (val)->size : SCHARS (val));
 -                int i;
 -                for (i = 0; i < len; i++)
 -                  {
 -                    ch = (STRINGP (val)
 -                          ? Faref (val, make_number (i))
 -                          : XVECTOR (val)->contents[i]);
 -                    CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (ch));
 -                  }
 -              }
 -            else              /* INTEGERP (val) */
 -              CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (val));
 +          case CODING_ANNOTATE_COMPOSITION_MASK:
 +            produce_composition (coding, charbuf, pos);
 +            break;
 +          case CODING_ANNOTATE_CHARSET_MASK:
 +            produce_charset (coding, charbuf, pos);
 +            break;
 +          default:
 +            abort ();
            }
 -        CODING_ADD_COMPOSITION_END (coding, end - from);
 +        charbuf += len;
        }
 -      start = end;
      }
 -  while (start < to
 -       && find_composition (start, to, &start, &end, &prop, obj)
 -       && end <= to);
 -
 -  /* Make coding->cmp_data point to the first memory block.  */
 -  while (coding->cmp_data->prev)
 -    coding->cmp_data = coding->cmp_data->prev;
 -  coding->cmp_data_start = 0;
  }
  
 -/* Reflect the saved information about compositions to OBJ.
 -   CODING->cmp_data points to a memory block for the information.  OBJ
 -   is a buffer or a string, defaults to the current buffer.  */
 +/* Decode the data at CODING->src_object into CODING->dst_object.
 +   CODING->src_object is a buffer, a string, or nil.
 +   CODING->dst_object is a buffer.
  
 -void
 -coding_restore_composition (coding, obj)
 -     struct coding_system *coding;
 -     Lisp_Object obj;
 -{
 -  struct composition_data *cmp_data = coding->cmp_data;
 +   If CODING->src_object is a buffer, it must be the current buffer.
 +   In this case, if CODING->src_pos is positive, it is a position of
 +   the source text in the buffer, otherwise, the source text is in the
 +   gap area of the buffer, and CODING->src_pos specifies the offset of
 +   the text from GPT (which must be the same as PT).  If this is the
 +   same buffer as CODING->dst_object, CODING->src_pos must be
 +   negative.
  
 -  if (!cmp_data)
 -    return;
 +   If CODING->src_object is a string, CODING->src_pos is an index to
 +   that string.
  
 -  while (cmp_data->prev)
 -    cmp_data = cmp_data->prev;
 +   If CODING->src_object is nil, CODING->source must already point to
 +   the non-relocatable memory area.  In this case, CODING->src_pos is
 +   an offset from CODING->source.
  
 -  while (cmp_data)
 -    {
 -      int i;
 +   The decoded data is inserted at the current point of the buffer
 +   CODING->dst_object.
 +*/
  
 -      for (i = 0; i < cmp_data->used && cmp_data->data[i] > 0;
 -         i += cmp_data->data[i])
 -      {
 -        int *data = cmp_data->data + i;
 -        enum composition_method method = (enum composition_method) data[3];
 -        Lisp_Object components;
 +static int
 +decode_coding (coding)
 +     struct coding_system *coding;
 +{
 +  Lisp_Object attrs;
 +  Lisp_Object undo_list;
 +  Lisp_Object translation_table;
 +  int carryover;
 +  int i;
  
 -        if (data[0] < 0 || i + data[0] > cmp_data->used)
 -          /* Invalid composition data.  */
 -          break;
 +  if (BUFFERP (coding->src_object)
 +      && coding->src_pos > 0
 +      && coding->src_pos < GPT
 +      && coding->src_pos + coding->src_chars > GPT)
 +    move_gap_both (coding->src_pos, coding->src_pos_byte);
  
 -        if (method == COMPOSITION_RELATIVE)
 -          components = Qnil;
 -        else
 -          {
 -            int len = data[0] - 4, j;
 -            Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];
 -
 -            if (method == COMPOSITION_WITH_RULE_ALTCHARS
 -                && len % 2 == 0)
 -              len --;
 -            if (len < 1)
 -              /* Invalid composition data.  */
 -              break;
 -            for (j = 0; j < len; j++)
 -              args[j] = make_number (data[4 + j]);
 -            components = (method == COMPOSITION_WITH_ALTCHARS
 -                          ? Fstring (len, args)
 -                          : Fvector (len, args));
 -          }
 -        compose_text (data[1], data[2], components, Qnil, obj);
 -      }
 -      cmp_data = cmp_data->next;
 +  undo_list = Qt;
 +  if (BUFFERP (coding->dst_object))
 +    {
 +      if (current_buffer != XBUFFER (coding->dst_object))
 +      set_buffer_internal (XBUFFER (coding->dst_object));
 +      if (GPT != PT)
 +      move_gap_both (PT, PT_BYTE);
 +      undo_list = current_buffer->undo_list;
 +      current_buffer->undo_list = Qt;
      }
 -}
 -
 -/* Decode (if ENCODEP is zero) or encode (if ENCODEP is nonzero) the
 -   text from FROM to TO (byte positions are FROM_BYTE and TO_BYTE) by
 -   coding system CODING, and return the status code of code conversion
 -   (currently, this value has no meaning).
 -
 -   How many characters (and bytes) are converted to how many
 -   characters (and bytes) are recorded in members of the structure
 -   CODING.
  
 -   If REPLACE is nonzero, we do various things as if the original text
 -   is deleted and a new text is inserted.  See the comments in
 -   replace_range (insdel.c) to know what we are doing.
 -
 -   If REPLACE is zero, it is assumed that the source text is unibyte.
 -   Otherwise, it is assumed that the source text is multibyte.  */
 +  coding->consumed = coding->consumed_char = 0;
 +  coding->produced = coding->produced_char = 0;
 +  coding->chars_at_source = 0;
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->errors = 0;
  
 -int
 -code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
 -     int from, from_byte, to, to_byte, encodep, replace;
 -     struct coding_system *coding;
 -{
 -  int len = to - from, len_byte = to_byte - from_byte;
 -  int nchars_del = 0, nbytes_del = 0;
 -  int require, inserted, inserted_byte;
 -  int head_skip, tail_skip, total_skip = 0;
 -  Lisp_Object saved_coding_symbol;
 -  int first = 1;
 -  unsigned char *src, *dst;
 -  Lisp_Object deletion;
 -  int orig_point = PT, orig_len = len;
 -  int prev_Z;
 -  int multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
 +  ALLOC_CONVERSION_WORK_AREA (coding);
  
 -  deletion = Qnil;
 -  saved_coding_symbol = coding->symbol;
 +  attrs = CODING_ID_ATTRS (coding->id);
 +  translation_table = get_translation_table (attrs, 0, NULL);
  
 -  if (from < PT && PT < to)
 +  carryover = 0;
 +  do
      {
 -      TEMP_SET_PT_BOTH (from, from_byte);
 -      orig_point = from;
 +      EMACS_INT pos = coding->dst_pos + coding->produced_char;
 +
 +      coding_set_source (coding);
 +      coding->annotated = 0;
 +      coding->charbuf_used = carryover;
 +      (*(coding->decoder)) (coding);
 +      coding_set_destination (coding);
 +      carryover = produce_chars (coding, translation_table, 0);
 +      if (coding->annotated)
 +      produce_annotation (coding, pos);
 +      for (i = 0; i < carryover; i++)
 +      coding->charbuf[i]
 +        = coding->charbuf[coding->charbuf_used - carryover + i];
      }
 +  while (coding->consumed < coding->src_bytes
 +       && (coding->result == CODING_RESULT_SUCCESS
 +           || coding->result == CODING_RESULT_INVALID_SRC));
  
 -  if (replace)
 +  if (carryover > 0)
      {
 -      int saved_from = from;
 -      int saved_inhibit_modification_hooks;
 -
 -      prepare_to_modify_buffer (from, to, &from);
 -      if (saved_from != from)
 -      {
 -        to = from + len;
 -        from_byte = CHAR_TO_BYTE (from), to_byte = CHAR_TO_BYTE (to);
 -        len_byte = to_byte - from_byte;
 -      }
 -
 -      /* The code conversion routine can not preserve text properties
 -       for now.  So, we must remove all text properties in the
 -       region.  Here, we must suppress all modification hooks.  */
 -      saved_inhibit_modification_hooks = inhibit_modification_hooks;
 -      inhibit_modification_hooks = 1;
 -      Fset_text_properties (make_number (from), make_number (to), Qnil, Qnil);
 -      inhibit_modification_hooks = saved_inhibit_modification_hooks;
 +      coding_set_destination (coding);
 +      coding->charbuf_used = carryover;
 +      produce_chars (coding, translation_table, 1);
      }
  
 -  coding->heading_ascii = 0;
 -
 -  if (! encodep && CODING_REQUIRE_DETECTION (coding))
 +  coding->carryover_bytes = 0;
 +  if (coding->consumed < coding->src_bytes)
      {
 -      /* We must detect encoding of text and eol format.  */
 +      int nbytes = coding->src_bytes - coding->consumed;
 +      const unsigned char *src;
  
 -      if (from < GPT && to > GPT)
 -      move_gap_both (from, from_byte);
 -      if (coding->type == coding_type_undecided)
 +      coding_set_source (coding);
 +      coding_set_destination (coding);
 +      src = coding->source + coding->consumed;
 +
 +      if (coding->mode & CODING_MODE_LAST_BLOCK)
        {
 -        detect_coding (coding, BYTE_POS_ADDR (from_byte), len_byte);
 -        if (coding->type == coding_type_undecided)
 +        /* Flush out unprocessed data as binary chars.  We are sure
 +           that the number of data is less than the size of
 +           coding->charbuf.  */
 +        coding->charbuf_used = 0;
 +        while (nbytes-- > 0)
            {
 -            /* It seems that the text contains only ASCII, but we
 -               should not leave it undecided because the deeper
 -               decoding routine (decode_coding) tries to detect the
 -               encodings again in vain.  */
 -            coding->type = coding_type_emacs_mule;
 -            coding->category_idx = CODING_CATEGORY_IDX_EMACS_MULE;
 -            /* As emacs-mule decoder will handle composition, we
 -               need this setting to allocate coding->cmp_data
 -               later.  */
 -            coding->composing = COMPOSITION_NO;
 +            int c = *src++;
 +
 +            if (c & 0x80)
 +              c = BYTE8_TO_CHAR (c);
 +            coding->charbuf[coding->charbuf_used++] = c;
            }
 +        produce_chars (coding, Qnil, 1);
        }
 -      if (coding->eol_type == CODING_EOL_UNDECIDED
 -        && coding->type != coding_type_ccl)
 +      else
        {
 -        detect_eol (coding, BYTE_POS_ADDR (from_byte), len_byte);
 -        if (coding->eol_type == CODING_EOL_UNDECIDED)
 -          coding->eol_type = CODING_EOL_LF;
 -        /* We had better recover the original eol format if we
 -           encounter an inconsistent eol format while decoding.  */
 -        coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;
 +        /* Record unprocessed bytes in coding->carryover.  We are
 +           sure that the number of data is less than the size of
 +           coding->carryover.  */
 +        unsigned char *p = coding->carryover;
 +
 +        coding->carryover_bytes = nbytes;
 +        while (nbytes-- > 0)
 +          *p++ = *src++;
        }
 +      coding->consumed = coding->src_bytes;
      }
  
 -  /* Now we convert the text.  */
 -
 -  /* For encoding, we must process pre-write-conversion in advance.  */
 -  if (! inhibit_pre_post_conversion
 -      && encodep
 -      && SYMBOLP (coding->pre_write_conversion)
 -      && ! NILP (Ffboundp (coding->pre_write_conversion)))
 +  if (! EQ (CODING_ID_EOL_TYPE (coding->id), Qunix))
 +    decode_eol (coding);
 +  if (BUFFERP (coding->dst_object))
      {
 -      /* The function in pre-write-conversion may put a new text in a
 -         new buffer.  */
 -      struct buffer *prev = current_buffer;
 -      Lisp_Object new;
 +      current_buffer->undo_list = undo_list;
 +      record_insert (coding->dst_pos, coding->produced_char);
 +    }
 +  return coding->result;
 +}
  
 -      record_unwind_protect (code_convert_region_unwind,
 -                           Fcons (Vlast_coding_system_used, Qnil));
 -      /* We should not call any more pre-write/post-read-conversion
 -         functions while this pre-write-conversion is running.  */
 -      inhibit_pre_post_conversion = 1;
 -      call2 (coding->pre_write_conversion,
 -           make_number (from), make_number (to));
 -      inhibit_pre_post_conversion = 0;
 -      /* Discard the unwind protect.  */
 -      specpdl_ptr--;
  
 -      if (current_buffer != prev)
 -      {
 -        len = ZV - BEGV;
 -        new = Fcurrent_buffer ();
 -        set_buffer_internal_1 (prev);
 -        del_range_2 (from, from_byte, to, to_byte, 0);
 -        TEMP_SET_PT_BOTH (from, from_byte);
 -        insert_from_buffer (XBUFFER (new), 1, len, 0);
 -        Fkill_buffer (new);
 -        if (orig_point >= to)
 -          orig_point += len - orig_len;
 -        else if (orig_point > from)
 -          orig_point = from;
 -        orig_len = len;
 -        to = from + len;
 -        from_byte = CHAR_TO_BYTE (from);
 -        to_byte = CHAR_TO_BYTE (to);
 -        len_byte = to_byte - from_byte;
 -        TEMP_SET_PT_BOTH (from, from_byte);
 -      }
 -    }
 +/* Extract an annotation datum from a composition starting at POS and
 +   ending before LIMIT of CODING->src_object (buffer or string), store
 +   the data in BUF, set *STOP to a starting position of the next
 +   composition (if any) or to LIMIT, and return the address of the
 +   next element of BUF.
 +
 +   If such an annotation is not found, set *STOP to a starting
 +   position of a composition after POS (if any) or to LIMIT, and
 +   return BUF.  */
 +
 +static INLINE int *
 +handle_composition_annotation (pos, limit, coding, buf, stop)
 +     EMACS_INT pos, limit;
 +     struct coding_system *coding;
 +     int *buf;
 +     EMACS_INT *stop;
 +{
 +  EMACS_INT start, end;
 +  Lisp_Object prop;
  
 -  if (replace)
 +  if (! find_composition (pos, limit, &start, &end, &prop, coding->src_object)
 +      || end > limit)
 +    *stop = limit;
 +  else if (start > pos)
 +    *stop = start;
 +  else
      {
 -      if (! EQ (current_buffer->undo_list, Qt))
 -      deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
 -      else
 +      if (start == pos)
        {
 -        nchars_del = to - from;
 -        nbytes_del = to_byte - from_byte;
 +        /* We found a composition.  Store the corresponding
 +           annotation data in BUF.  */
 +        int *head = buf;
 +        enum composition_method method = COMPOSITION_METHOD (prop);
 +        int nchars = COMPOSITION_LENGTH (prop);
 +
 +        ADD_COMPOSITION_DATA (buf, nchars, method);
 +        if (method != COMPOSITION_RELATIVE)
 +          {
 +            Lisp_Object components;
 +            int len, i, i_byte;
 +
 +            components = COMPOSITION_COMPONENTS (prop);
 +            if (VECTORP (components))
 +              {
 +                len = XVECTOR (components)->size;
 +                for (i = 0; i < len; i++)
 +                  *buf++ = XINT (AREF (components, i));
 +              }
 +            else if (STRINGP (components))
 +              {
 +                len = SCHARS (components);
 +                i = i_byte = 0;
 +                while (i < len)
 +                  {
 +                    FETCH_STRING_CHAR_ADVANCE (*buf, components, i, i_byte);
 +                    buf++;
 +                  }
 +              }
 +            else if (INTEGERP (components))
 +              {
 +                len = 1;
 +                *buf++ = XINT (components);
 +              }
 +            else if (CONSP (components))
 +              {
 +                for (len = 0; CONSP (components);
 +                     len++, components = XCDR (components))
 +                  *buf++ = XINT (XCAR (components));
 +              }
 +            else
 +              abort ();
 +            *head -= len;
 +          }
        }
 -    }
  
 -  if (coding->composing != COMPOSITION_DISABLED)
 -    {
 -      if (encodep)
 -      coding_save_composition (coding, from, to, Fcurrent_buffer ());
 +      if (find_composition (end, limit, &start, &end, &prop,
 +                          coding->src_object)
 +        && end <= limit)
 +      *stop = start;
        else
 -      coding_allocate_composition_data (coding, from);
 +      *stop = limit;
      }
 +  return buf;
 +}
  
 -  /* Try to skip the heading and tailing ASCIIs.  We can't skip them
 -     if we must run CCL program or there are compositions to
 -     encode.  */
 -  if (coding->type != coding_type_ccl
 -      && (! coding->cmp_data || coding->cmp_data->used == 0))
 -    {
 -      int from_byte_orig = from_byte, to_byte_orig = to_byte;
  
 -      if (from < GPT && GPT < to)
 -      move_gap_both (from, from_byte);
 -      SHRINK_CONVERSION_REGION (&from_byte, &to_byte, coding, NULL, encodep);
 -      if (from_byte == to_byte
 -        && (encodep || NILP (coding->post_read_conversion))
 -        && ! CODING_REQUIRE_FLUSHING (coding))
 -      {
 -        coding->produced = len_byte;
 -        coding->produced_char = len;
 -        if (!replace)
 -          /* We must record and adjust for this new text now.  */
 -          adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);
 -        coding_free_composition_data (coding);
 -        return 0;
 -      }
 -
 -      head_skip = from_byte - from_byte_orig;
 -      tail_skip = to_byte_orig - to_byte;
 -      total_skip = head_skip + tail_skip;
 -      from += head_skip;
 -      to -= tail_skip;
 -      len -= total_skip; len_byte -= total_skip;
 -    }
 -
 -  /* For conversion, we must put the gap before the text in addition to
 -     making the gap larger for efficient decoding.  The required gap
 -     size starts from 2000 which is the magic number used in make_gap.
 -     But, after one batch of conversion, it will be incremented if we
 -     find that it is not enough .  */
 -  require = 2000;
 -
 -  if (GAP_SIZE  < require)
 -    make_gap (require - GAP_SIZE);
 -  move_gap_both (from, from_byte);
 -
 -  inserted = inserted_byte = 0;
 -
 -  GAP_SIZE += len_byte;
 -  ZV -= len;
 -  Z -= len;
 -  ZV_BYTE -= len_byte;
 -  Z_BYTE -= len_byte;
 -
 -  if (GPT - BEG < BEG_UNCHANGED)
 -    BEG_UNCHANGED = GPT - BEG;
 -  if (Z - GPT < END_UNCHANGED)
 -    END_UNCHANGED = Z - GPT;
 -
 -  if (!encodep && coding->src_multibyte)
 -    {
 -      /* Decoding routines expects that the source text is unibyte.
 -       We must convert 8-bit characters of multibyte form to
 -       unibyte.  */
 -      int len_byte_orig = len_byte;
 -      len_byte = str_as_unibyte (GAP_END_ADDR - len_byte, len_byte);
 -      if (len_byte < len_byte_orig)
 -      safe_bcopy (GAP_END_ADDR - len_byte_orig, GAP_END_ADDR - len_byte,
 -                  len_byte);
 -      coding->src_multibyte = 0;
 -    }
 -
 -  for (;;)
 -    {
 -      int result;
 -
 -      /* The buffer memory is now:
 -       +--------+converted-text+---------+-------original-text-------+---+
 -       |<-from->|<--inserted-->|---------|<--------len_byte--------->|---|
 -                |<---------------------- GAP ----------------------->|  */
 -      src = GAP_END_ADDR - len_byte;
 -      dst = GPT_ADDR + inserted_byte;
 -
 -      if (encodep)
 -      result = encode_coding (coding, src, dst, len_byte, 0);
 -      else
 -      {
 -        if (coding->composing != COMPOSITION_DISABLED)
 -          coding->cmp_data->char_offset = from + inserted;
 -        result = decode_coding (coding, src, dst, len_byte, 0);
 -      }
 +/* Extract an annotation datum from a text property `charset' at POS of
 +   CODING->src_object (buffer of string), store the data in BUF, set
 +   *STOP to the position where the value of `charset' property changes
 +   (limiting by LIMIT), and return the address of the next element of
 +   BUF.
  
 -      /* The buffer memory is now:
 -       +--------+-------converted-text----+--+------original-text----+---+
 -       |<-from->|<-inserted->|<-produced->|--|<-(len_byte-consumed)->|---|
 -                |<---------------------- GAP ----------------------->|  */
 +   If the property value is nil, set *STOP to the position where the
 +   property value is non-nil (limiting by LIMIT), and return BUF.  */
  
 -      inserted += coding->produced_char;
 -      inserted_byte += coding->produced;
 -      len_byte -= coding->consumed;
 +static INLINE int *
 +handle_charset_annotation (pos, limit, coding, buf, stop)
 +     EMACS_INT pos, limit;
 +     struct coding_system *coding;
 +     int *buf;
 +     EMACS_INT *stop;
 +{
 +  Lisp_Object val, next;
 +  int id;
  
 -      if (result == CODING_FINISH_INSUFFICIENT_CMP)
 -      {
 -        coding_allocate_composition_data (coding, from + inserted);
 -        continue;
 -      }
 +  val = Fget_text_property (make_number (pos), Qcharset, coding->src_object);
 +  if (! NILP (val) && CHARSETP (val))
 +    id = XINT (CHARSET_SYMBOL_ID (val));
 +  else
 +    id = -1;
 +  ADD_CHARSET_DATA (buf, 0, id);
 +  next = Fnext_single_property_change (make_number (pos), Qcharset,
 +                                     coding->src_object,
 +                                     make_number (limit));
 +  *stop = XINT (next);
 +  return buf;
 +}
  
 -      src += coding->consumed;
 -      dst += coding->produced;
  
 -      if (result == CODING_FINISH_NORMAL)
 -      {
 -        src += len_byte;
 -        break;
 -      }
 -      if (! encodep && result == CODING_FINISH_INCONSISTENT_EOL)
 -      {
 -        unsigned char *pend = dst, *p = pend - inserted_byte;
 -        Lisp_Object eol_type;
 +static void
 +consume_chars (coding, translation_table, max_lookup)
 +     struct coding_system *coding;
 +     Lisp_Object translation_table;
 +     int max_lookup;
 +{
 +  int *buf = coding->charbuf;
 +  int *buf_end = coding->charbuf + coding->charbuf_size;
 +  const unsigned char *src = coding->source + coding->consumed;
 +  const unsigned char *src_end = coding->source + coding->src_bytes;
 +  EMACS_INT pos = coding->src_pos + coding->consumed_char;
 +  EMACS_INT end_pos = coding->src_pos + coding->src_chars;
 +  int multibytep = coding->src_multibyte;
 +  Lisp_Object eol_type;
 +  int c;
 +  EMACS_INT stop, stop_composition, stop_charset;
 +  int *lookup_buf = NULL;
  
 -        /* Encode LFs back to the original eol format (CR or CRLF).  */
 -        if (coding->eol_type == CODING_EOL_CR)
 -          {
 -            while (p < pend) if (*p++ == '\n') p[-1] = '\r';
 -          }
 -        else
 -          {
 -            int count = 0;
 +  if (! NILP (translation_table))
 +    lookup_buf = alloca (sizeof (int) * max_lookup);
  
 -            while (p < pend) if (*p++ == '\n') count++;
 -            if (src - dst < count)
 -              {
 -                /* We don't have sufficient room for encoding LFs
 -                   back to CRLF.  We must record converted and
 -                   not-yet-converted text back to the buffer
 -                   content, enlarge the gap, then record them out of
 -                   the buffer contents again.  */
 -                int add = len_byte + inserted_byte;
 -
 -                GAP_SIZE -= add;
 -                ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
 -                GPT += inserted_byte; GPT_BYTE += inserted_byte;
 -                make_gap (count - GAP_SIZE);
 -                GAP_SIZE += add;
 -                ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
 -                GPT -= inserted_byte; GPT_BYTE -= inserted_byte;
 -                /* Don't forget to update SRC, DST, and PEND.  */
 -                src = GAP_END_ADDR - len_byte;
 -                dst = GPT_ADDR + inserted_byte;
 -                pend = dst;
 -              }
 -            inserted += count;
 -            inserted_byte += count;
 -            coding->produced += count;
 -            p = dst = pend + count;
 -            while (count)
 -              {
 -                *--p = *--pend;
 -                if (*p == '\n') count--, *--p = '\r';
 -              }
 -          }
 +  eol_type = CODING_ID_EOL_TYPE (coding->id);
 +  if (VECTORP (eol_type))
 +    eol_type = Qunix;
  
 -        /* Suppress eol-format conversion in the further conversion.  */
 -        coding->eol_type = CODING_EOL_LF;
 +  /* Note: composition handling is not yet implemented.  */
 +  coding->common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
 +
 +  if (NILP (coding->src_object))
 +    stop = stop_composition = stop_charset = end_pos;
 +  else
 +    {
 +      if (coding->common_flags & CODING_ANNOTATE_COMPOSITION_MASK)
 +      stop = stop_composition = pos;
 +      else
 +      stop = stop_composition = end_pos;
 +      if (coding->common_flags & CODING_ANNOTATE_CHARSET_MASK)
 +      stop = stop_charset = pos;
 +      else
 +      stop_charset = end_pos;
 +    }
  
 -        /* Set the coding system symbol to that for Unix-like EOL.  */
 -        eol_type = Fget (saved_coding_symbol, Qeol_type);
 -        if (VECTORP (eol_type)
 -            && XVECTOR (eol_type)->size == 3
 -            && SYMBOLP (XVECTOR (eol_type)->contents[CODING_EOL_LF]))
 -          coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF];
 -        else
 -          coding->symbol = saved_coding_symbol;
 +  /* Compensate for CRLF and conversion.  */
 +  buf_end -= 1 + MAX_ANNOTATION_LENGTH;
 +  while (buf < buf_end)
 +    {
 +      Lisp_Object trans;
  
 -        continue;
 -      }
 -      if (len_byte <= 0)
 +      if (pos == stop)
        {
 -        if (coding->type != coding_type_ccl
 -            || coding->mode & CODING_MODE_LAST_BLOCK)
 +        if (pos == end_pos)
            break;
 -        coding->mode |= CODING_MODE_LAST_BLOCK;
 -        continue;
 +        if (pos == stop_composition)
 +          buf = handle_composition_annotation (pos, end_pos, coding,
 +                                               buf, &stop_composition);
 +        if (pos == stop_charset)
 +          buf = handle_charset_annotation (pos, end_pos, coding,
 +                                           buf, &stop_charset);
 +        stop = (stop_composition < stop_charset
 +                ? stop_composition : stop_charset);
        }
 -      if (result == CODING_FINISH_INSUFFICIENT_SRC)
 -      {
 -        /* The source text ends in invalid codes.  Let's just
 -           make them valid buffer contents, and finish conversion.  */
 -        if (multibyte_p)
 -          {
 -            unsigned char *start = dst;
  
 -            inserted += len_byte;
 -            while (len_byte--)
 -              {
 -                int c = *src++;
 -                dst += CHAR_STRING (c, dst);
 -              }
 +      if (! multibytep)
 +      {
 +        EMACS_INT bytes;
  
 -            inserted_byte += dst - start;
 -          }
 +        if (coding->encoder == encode_coding_raw_text)
 +          c = *src++, pos++;
 +        else if ((bytes = MULTIBYTE_LENGTH (src, src_end)) > 0)
 +          c = STRING_CHAR_ADVANCE (src), pos += bytes;
          else
 -          {
 -            inserted += len_byte;
 -            inserted_byte += len_byte;
 -            while (len_byte--)
 -              *dst++ = *src++;
 -          }
 -        break;
 -      }
 -      if (result == CODING_FINISH_INTERRUPT)
 -      {
 -        /* The conversion procedure was interrupted by a user.  */
 -        break;
 -      }
 -      /* Now RESULT == CODING_FINISH_INSUFFICIENT_DST  */
 -      if (coding->consumed < 1)
 -      {
 -        /* It's quite strange to require more memory without
 -           consuming any bytes.  Perhaps CCL program bug.  */
 -        break;
 +          c = BYTE8_TO_CHAR (*src), src++, pos++;
        }
 -      if (first)
 +      else
 +      c = STRING_CHAR_ADVANCE (src), pos++;
 +      if ((c == '\r') && (coding->mode & CODING_MODE_SELECTIVE_DISPLAY))
 +      c = '\n';
 +      if (! EQ (eol_type, Qunix))
        {
 -        /* We have just done the first batch of conversion which was
 -           stopped because of insufficient gap.  Let's reconsider the
 -           required gap size (i.e. SRT - DST) now.
 -
 -           We have converted ORIG bytes (== coding->consumed) into
 -           NEW bytes (coding->produced).  To convert the remaining
 -           LEN bytes, we may need REQUIRE bytes of gap, where:
 -              REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG)
 -              REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG
 -           Here, we are sure that NEW >= ORIG.  */
 -
 -        if (coding->produced <= coding->consumed)
 -          {
 -            /* This happens because of CCL-based coding system with
 -               eol-type CRLF.  */
 -            require = 0;
 -          }
 -        else
 +        if (c == '\n')
            {
 -            float ratio = coding->produced - coding->consumed;
 -            ratio /= coding->consumed;
 -            require = len_byte * ratio;
 +            if (EQ (eol_type, Qdos))
 +              *buf++ = '\r';
 +            else
 +              c = '\r';
            }
 -        first = 0;
 -      }
 -      if ((src - dst) < (require + 2000))
 -      {
 -        /* See the comment above the previous call of make_gap.  */
 -        int add = len_byte + inserted_byte;
 -
 -        GAP_SIZE -= add;
 -        ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
 -        GPT += inserted_byte; GPT_BYTE += inserted_byte;
 -        make_gap (require + 2000);
 -        GAP_SIZE += add;
 -        ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
 -        GPT -= inserted_byte; GPT_BYTE -= inserted_byte;
        }
 -    }
 -  if (src - dst > 0) *dst = 0; /* Put an anchor.  */
  
 -  if (encodep && coding->dst_multibyte)
 -    {
 -      /* The output is unibyte.  We must convert 8-bit characters to
 -       multibyte form.  */
 -      if (inserted_byte * 2 > GAP_SIZE)
 +      trans = Qnil;
 +      LOOKUP_TRANSLATION_TABLE (translation_table, c, trans);
 +      if (NILP (trans))
 +      *buf++ = c;
 +      else
        {
 -        GAP_SIZE -= inserted_byte;
 -        ZV += inserted_byte; Z += inserted_byte;
 -        ZV_BYTE += inserted_byte; Z_BYTE += inserted_byte;
 -        GPT += inserted_byte; GPT_BYTE += inserted_byte;
 -        make_gap (inserted_byte - GAP_SIZE);
 -        GAP_SIZE += inserted_byte;
 -        ZV -= inserted_byte; Z -= inserted_byte;
 -        ZV_BYTE -= inserted_byte; Z_BYTE -= inserted_byte;
 -        GPT -= inserted_byte; GPT_BYTE -= inserted_byte;
 +        int from_nchars = 1, to_nchars = 1;
 +        int *lookup_buf_end;
 +        const unsigned char *p = src;
 +        int i;
 +
 +        lookup_buf[0] = c;
 +        for (i = 1; i < max_lookup && p < src_end; i++)
 +          lookup_buf[i] = STRING_CHAR_ADVANCE (p);
 +        lookup_buf_end = lookup_buf + i;
 +        trans = get_translation (trans, lookup_buf, lookup_buf_end, 1,
 +                                 &from_nchars, &to_nchars);
 +        if (EQ (trans, Qt)
 +            || buf + to_nchars > buf_end)
 +          break;
 +        *buf++ = *lookup_buf;
 +        for (i = 1; i < to_nchars; i++)
 +          *buf++ = XINT (AREF (trans, i));
 +        for (i = 1; i < from_nchars; i++, pos++)
 +          src += MULTIBYTE_LENGTH_NO_CHECK (src);
        }
 -      inserted_byte = str_to_multibyte (GPT_ADDR, GAP_SIZE, inserted_byte);
      }
  
 -  /* If we shrank the conversion area, adjust it now.  */
 -  if (total_skip > 0)
 -    {
 -      if (tail_skip > 0)
 -      safe_bcopy (GAP_END_ADDR, GPT_ADDR + inserted_byte, tail_skip);
 -      inserted += total_skip; inserted_byte += total_skip;
 -      GAP_SIZE += total_skip;
 -      GPT -= head_skip; GPT_BYTE -= head_skip;
 -      ZV -= total_skip; ZV_BYTE -= total_skip;
 -      Z -= total_skip; Z_BYTE -= total_skip;
 -      from -= head_skip; from_byte -= head_skip;
 -      to += tail_skip; to_byte += tail_skip;
 -    }
 +  coding->consumed = src - coding->source;
 +  coding->consumed_char = pos - coding->src_pos;
 +  coding->charbuf_used = buf - coding->charbuf;
 +  coding->chars_at_source = 0;
 +}
  
 -  prev_Z = Z;
 -  if (! EQ (current_buffer->undo_list, Qt))
 -    adjust_after_replace (from, from_byte, deletion, inserted, inserted_byte);
 -  else
 -    adjust_after_replace_noundo (from, from_byte, nchars_del, nbytes_del,
 -                               inserted, inserted_byte);
 -  inserted = Z - prev_Z;
  
 -  if (!encodep && coding->cmp_data && coding->cmp_data->used)
 -    coding_restore_composition (coding, Fcurrent_buffer ());
 -  coding_free_composition_data (coding);
 +/* Encode the text at CODING->src_object into CODING->dst_object.
 +   CODING->src_object is a buffer or a string.
 +   CODING->dst_object is a buffer or nil.
  
 -  if (! inhibit_pre_post_conversion
 -      && ! encodep && ! NILP (coding->post_read_conversion))
 -    {
 -      Lisp_Object val;
 -      Lisp_Object saved_coding_system;
 +   If CODING->src_object is a buffer, it must be the current buffer.
 +   In this case, if CODING->src_pos is positive, it is a position of
 +   the source text in the buffer, otherwise. the source text is in the
 +   gap area of the buffer, and coding->src_pos specifies the offset of
 +   the text from GPT (which must be the same as PT).  If this is the
 +   same buffer as CODING->dst_object, CODING->src_pos must be
 +   negative and CODING should not have `pre-write-conversion'.
  
 -      if (from != PT)
 -      TEMP_SET_PT_BOTH (from, from_byte);
 -      prev_Z = Z;
 -      record_unwind_protect (code_convert_region_unwind,
 -                           Fcons (Vlast_coding_system_used, Qnil));
 -      saved_coding_system = Vlast_coding_system_used;
 -      Vlast_coding_system_used = coding->symbol;
 -      /* We should not call any more pre-write/post-read-conversion
 -         functions while this post-read-conversion is running.  */
 -      inhibit_pre_post_conversion = 1;
 -      val = call1 (coding->post_read_conversion, make_number (inserted));
 -      inhibit_pre_post_conversion = 0;
 -      coding->symbol = Vlast_coding_system_used;
 -      Vlast_coding_system_used = saved_coding_system;
 -      /* Discard the unwind protect.  */
 -      specpdl_ptr--;
 -      CHECK_NUMBER (val);
 -      inserted += Z - prev_Z;
 -    }
 -
 -  if (orig_point >= from)
 -    {
 -      if (orig_point >= from + orig_len)
 -      orig_point += inserted - orig_len;
 -      else
 -      orig_point = from;
 -      TEMP_SET_PT (orig_point);
 -    }
 +   If CODING->src_object is a string, CODING should not have
 +   `pre-write-conversion'.
 +
 +   If CODING->dst_object is a buffer, the encoded data is inserted at
 +   the current point of that buffer.
 +
 +   If CODING->dst_object is nil, the encoded data is placed at the
 +   memory area specified by CODING->destination.  */
 +
 +static int
 +encode_coding (coding)
 +     struct coding_system *coding;
 +{
 +  Lisp_Object attrs;
 +  Lisp_Object translation_table;
 +  int max_lookup;
  
 -  if (replace)
 +  attrs = CODING_ID_ATTRS (coding->id);
 +  if (coding->encoder == encode_coding_raw_text)
 +    translation_table = Qnil, max_lookup = 0;
 +  else
 +    translation_table = get_translation_table (attrs, 1, &max_lookup);
 +
 +  if (BUFFERP (coding->dst_object))
      {
 -      signal_after_change (from, to - from, inserted);
 -      update_compositions (from, from + inserted, CHECK_BORDER);
 +      set_buffer_internal (XBUFFER (coding->dst_object));
 +      coding->dst_multibyte
 +      = ! NILP (current_buffer->enable_multibyte_characters);
      }
  
 -  {
 -    coding->consumed = to_byte - from_byte;
 -    coding->consumed_char = to - from;
 -    coding->produced = inserted_byte;
 -    coding->produced_char = inserted;
 -  }
 +  coding->consumed = coding->consumed_char = 0;
 +  coding->produced = coding->produced_char = 0;
 +  record_conversion_result (coding, CODING_RESULT_SUCCESS);
 +  coding->errors = 0;
  
 -  return 0;
 +  ALLOC_CONVERSION_WORK_AREA (coding);
 +
 +  do {
 +    coding_set_source (coding);
 +    consume_chars (coding, translation_table, max_lookup);
 +    coding_set_destination (coding);
 +    (*(coding->encoder)) (coding);
 +  } while (coding->consumed_char < coding->src_chars);
 +
 +  if (BUFFERP (coding->dst_object))
 +    insert_from_gap (coding->produced_char, coding->produced);
 +
 +  return (coding->result);
  }
  
 +
  /* Name (or base name) of work buffer for code conversion.  */
  static Lisp_Object Vcode_conversion_workbuf_name;
  
 -/* Set the current buffer to the working buffer prepared for
 -   code-conversion.  MULTIBYTE specifies the multibyteness of the
 -   buffer.  Return the buffer we set if it must be killed after use.
 -   Otherwise return Qnil.  */
 +/* A working buffer used by the top level conversion.  Once it is
 +   created, it is never destroyed.  It has the name
 +   Vcode_conversion_workbuf_name.  The other working buffers are
 +   destroyed after the use is finished, and their names are modified
 +   versions of Vcode_conversion_workbuf_name.  */
 +static Lisp_Object Vcode_conversion_reused_workbuf;
 +
 +/* 1 iff Vcode_conversion_reused_workbuf is already in use.  */
 +static int reused_workbuf_in_use;
 +
 +
 +/* Return a working buffer of code convesion.  MULTIBYTE specifies the
 +   multibyteness of returning buffer.  */
  
  static Lisp_Object
 -set_conversion_work_buffer (multibyte)
 +make_conversion_work_buffer (multibyte)
       int multibyte;
  {
 -  Lisp_Object buffer, buffer_to_kill;
 -  struct buffer *buf;
 +  Lisp_Object name, workbuf;
 +  struct buffer *current;
  
 -  buffer = Fget_buffer_create (Vcode_conversion_workbuf_name);
 -  buf = XBUFFER (buffer);
 -  if (buf == current_buffer)
 +  if (reused_workbuf_in_use++)
      {
 -      /* As we are already in the work buffer, we must generate a new
 -       buffer for the work.  */
 -      Lisp_Object name;
 -
        name = Fgenerate_new_buffer_name (Vcode_conversion_workbuf_name, Qnil);
 -      buffer = buffer_to_kill = Fget_buffer_create (name);
 -      buf = XBUFFER (buffer);
 +      workbuf = Fget_buffer_create (name);
      }
    else
 -    buffer_to_kill = Qnil;
 -
 -  delete_all_overlays (buf);
 -  buf->directory = current_buffer->directory;
 -  buf->read_only = Qnil;
 -  buf->filename = Qnil;
 -  buf->undo_list = Qt;
 -  eassert (buf->overlays_before == NULL);
 -  eassert (buf->overlays_after == NULL);
 -  set_buffer_internal (buf);
 -  if (BEG != BEGV || Z != ZV)
 -    Fwiden ();
 -  del_range_2 (BEG, BEG_BYTE, Z, Z_BYTE, 0);
 -  buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
 -  return buffer_to_kill;
 +    {
 +      name = Vcode_conversion_workbuf_name;
 +      workbuf = Fget_buffer_create (name);
 +      if (NILP (Vcode_conversion_reused_workbuf))
 +      Vcode_conversion_reused_workbuf = workbuf;
 +    }
 +  current = current_buffer;
 +  set_buffer_internal (XBUFFER (workbuf));
 +  Ferase_buffer ();      
 +  current_buffer->undo_list = Qt;
 +  current_buffer->enable_multibyte_characters = multibyte ? Qt : Qnil;
 +  set_buffer_internal (current);
 +  return workbuf;
 +}
 +
 +
 +static Lisp_Object
 +code_conversion_restore (arg)
 +     Lisp_Object arg;
 +{
 +  Lisp_Object current, workbuf;
 +  struct gcpro gcpro1;
 +
 +  GCPRO1 (arg);
 +  current = XCAR (arg);
 +  workbuf = XCDR (arg);
 +  if (! NILP (workbuf))
 +    {
 +      if (EQ (workbuf, Vcode_conversion_reused_workbuf))
 +      reused_workbuf_in_use = 0;
 +      else if (! NILP (Fbuffer_live_p (workbuf)))
 +      Fkill_buffer (workbuf);
 +    }
 +  set_buffer_internal (XBUFFER (current));
 +  UNGCPRO;
 +  return Qnil;
  }
  
  Lisp_Object
 -run_pre_post_conversion_on_str (str, coding, encodep)
 -     Lisp_Object str;
 +code_conversion_save (with_work_buf, multibyte)
 +     int with_work_buf, multibyte;
 +{
 +  Lisp_Object workbuf = Qnil;
 +
 +  if (with_work_buf)
 +    workbuf = make_conversion_work_buffer (multibyte);
 +  record_unwind_protect (code_conversion_restore,
 +                       Fcons (Fcurrent_buffer (), workbuf));
 +  return workbuf;
 +}
 +
 +int
 +decode_coding_gap (coding, chars, bytes)
       struct coding_system *coding;
 -     int encodep;
 +     EMACS_INT chars, bytes;
  {
 -  int count = SPECPDL_INDEX ();
 -  struct gcpro gcpro1, gcpro2;
 -  int multibyte = STRING_MULTIBYTE (str);
 -  Lisp_Object old_deactivate_mark;
 -  Lisp_Object buffer_to_kill;
 -  Lisp_Object unwind_arg;
 -
 -  record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
 -  /* It is not crucial to specbind this.  */
 -  old_deactivate_mark = Vdeactivate_mark;
 -  GCPRO2 (str, old_deactivate_mark);
 -
 -  /* We must insert the contents of STR as is without
 -     unibyte<->multibyte conversion.  For that, we adjust the
 -     multibyteness of the working buffer to that of STR.  */
 -  buffer_to_kill = set_conversion_work_buffer (multibyte);
 -  if (NILP (buffer_to_kill))
 -    unwind_arg = Fcons (Vlast_coding_system_used, Qnil);
 -  else
 -    unwind_arg = list2 (Vlast_coding_system_used, buffer_to_kill);
 -  record_unwind_protect (code_convert_region_unwind, unwind_arg);
 +  int count = specpdl_ptr - specpdl;
 +  Lisp_Object attrs;
 +
 +  code_conversion_save (0, 0);
 +
 +  coding->src_object = Fcurrent_buffer ();
 +  coding->src_chars = chars;
 +  coding->src_bytes = bytes;
 +  coding->src_pos = -chars;
 +  coding->src_pos_byte = -bytes;
 +  coding->src_multibyte = chars < bytes;
 +  coding->dst_object = coding->src_object;
 +  coding->dst_pos = PT;
 +  coding->dst_pos_byte = PT_BYTE;
 +  coding->dst_multibyte = ! NILP (current_buffer->enable_multibyte_characters);
  
 -  insert_from_string (str, 0, 0,
 -                    SCHARS (str), SBYTES (str), 0);
 -  UNGCPRO;
 -  inhibit_pre_post_conversion = 1;
 -  if (encodep)
 -    {
 -      struct buffer *prev = current_buffer;
 +  if (CODING_REQUIRE_DETECTION (coding))
 +    detect_coding (coding);
  
 -      call2 (coding->pre_write_conversion, make_number (BEG), make_number (Z));
 -      if (prev != current_buffer)
 -      /* We must kill the current buffer too.  */
 -      Fsetcdr (unwind_arg, Fcons (Fcurrent_buffer (), XCDR (unwind_arg)));
 -    }
 -  else
 +  coding->mode |= CODING_MODE_LAST_BLOCK;
 +  decode_coding (coding);
 +
 +  attrs = CODING_ID_ATTRS (coding->id);
 +  if (! NILP (CODING_ATTR_POST_READ (attrs)))
      {
 -      Vlast_coding_system_used = coding->symbol;
 -      TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
 -      call1 (coding->post_read_conversion, make_number (Z - BEG));
 -      coding->symbol = Vlast_coding_system_used;
 +      EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
 +      Lisp_Object val;
 +
 +      TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
 +      val = call1 (CODING_ATTR_POST_READ (attrs),
 +                 make_number (coding->produced_char));
 +      CHECK_NATNUM (val);
 +      coding->produced_char += Z - prev_Z;
 +      coding->produced += Z_BYTE - prev_Z_BYTE;
      }
 -  inhibit_pre_post_conversion = 0;
 -  Vdeactivate_mark = old_deactivate_mark;
 -  str = make_buffer_string (BEG, Z, 1);
 -  return unbind_to (count, str);
 +
 +  unbind_to (count, Qnil);
 +  return coding->result;
  }
  
 +int
 +encode_coding_gap (coding, chars, bytes)
 +     struct coding_system *coding;
 +     EMACS_INT chars, bytes;
 +{
 +  int count = specpdl_ptr - specpdl;
  
 -/* Run pre-write-conversion function of CODING on NCHARS/NBYTES
 -   text in *STR.  *SIZE is the allocated bytes for STR.  As it
 -   is intended that this function is called from encode_terminal_code,
 -   the pre-write-conversion function is run by safe_call and thus
 -   "Error during redisplay: ..." is logged when an error occurs.
 +  code_conversion_save (0, 0);
  
 -   Store the resulting text in *STR and set CODING->produced_char and
 -   CODING->produced to the number of characters and bytes
 -   respectively.  If the size of *STR is too small, enlarge it by
 -   xrealloc and update *STR and *SIZE.  */
 +  coding->src_object = Fcurrent_buffer ();
 +  coding->src_chars = chars;
 +  coding->src_bytes = bytes;
 +  coding->src_pos = -chars;
 +  coding->src_pos_byte = -bytes;
 +  coding->src_multibyte = chars < bytes;
 +  coding->dst_object = coding->src_object;
 +  coding->dst_pos = PT;
 +  coding->dst_pos_byte = PT_BYTE;
  
 -void
 -run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
 -     unsigned char **str;
 -     int *size, nchars, nbytes;
 -     struct coding_system *coding;
 -{
 -  struct gcpro gcpro1, gcpro2;
 -  struct buffer *cur = current_buffer;
 -  struct buffer *prev;
 -  Lisp_Object old_deactivate_mark, old_last_coding_system_used;
 -  Lisp_Object args[3];
 -  Lisp_Object buffer_to_kill;
 -
 -  /* It is not crucial to specbind this.  */
 -  old_deactivate_mark = Vdeactivate_mark;
 -  old_last_coding_system_used = Vlast_coding_system_used;
 -  GCPRO2 (old_deactivate_mark, old_last_coding_system_used);
 -
 -  /* We must insert the contents of STR as is without
 -     unibyte<->multibyte conversion.  For that, we adjust the
 -     multibyteness of the working buffer to that of STR.  */
 -  buffer_to_kill = set_conversion_work_buffer (coding->src_multibyte);
 -  insert_1_both (*str, nchars, nbytes, 0, 0, 0);
 -  UNGCPRO;
 -  inhibit_pre_post_conversion = 1;
 -  prev = current_buffer;
 -  args[0] = coding->pre_write_conversion;
 -  args[1] = make_number (BEG);
 -  args[2] = make_number (Z);
 -  safe_call (3, args);
 -  inhibit_pre_post_conversion = 0;
 -  Vdeactivate_mark = old_deactivate_mark;
 -  Vlast_coding_system_used = old_last_coding_system_used;
 -  coding->produced_char = Z - BEG;
 -  coding->produced = Z_BYTE - BEG_BYTE;
 -  if (coding->produced > *size)
 -    {
 -      *size = coding->produced;
 -      *str = xrealloc (*str, *size);
 -    }
 -  if (BEG < GPT && GPT < Z)
 -    move_gap (BEG);
 -  bcopy (BEG_ADDR, *str, coding->produced);
 -  coding->src_multibyte
 -    = ! NILP (current_buffer->enable_multibyte_characters);
 -  if (prev != current_buffer)
 -    Fkill_buffer (Fcurrent_buffer ());
 -  set_buffer_internal (cur);
 -  if (! NILP (buffer_to_kill))
 -    Fkill_buffer (buffer_to_kill);
 +  encode_coding (coding);
 +
 +  unbind_to (count, Qnil);
 +  return coding->result;
  }
  
  
 -Lisp_Object
 -decode_coding_string (str, coding, nocopy)
 -     Lisp_Object str;
 +/* Decode the text in the range FROM/FROM_BYTE and TO/TO_BYTE in
 +   SRC_OBJECT into DST_OBJECT by coding context CODING.
 +
 +   SRC_OBJECT is a buffer, a string, or Qnil.
 +
 +   If it is a buffer, the text is at point of the buffer.  FROM and TO
 +   are positions in the buffer.
 +
 +   If it is a string, the text is at the beginning of the string.
 +   FROM and TO are indices to the string.
 +
 +   If it is nil, the text is at coding->source.  FROM and TO are
 +   indices to coding->source.
 +
 +   DST_OBJECT is a buffer, Qt, or Qnil.
 +
 +   If it is a buffer, the decoded text is inserted at point of the
 +   buffer.  If the buffer is the same as SRC_OBJECT, the source text
 +   is deleted.
 +
 +   If it is Qt, a string is made from the decoded text, and
 +   set in CODING->dst_object.
 +
 +   If it is Qnil, the decoded text is stored at CODING->destination.
 +   The caller must allocate CODING->dst_bytes bytes at
 +   CODING->destination by xmalloc.  If the decoded text is longer than
 +   CODING->dst_bytes, CODING->destination is relocated by xrealloc.
 + */
 +
 +void
 +decode_coding_object (coding, src_object, from, from_byte, to, to_byte,
 +                    dst_object)
       struct coding_system *coding;
 -     int nocopy;
 +     Lisp_Object src_object;
 +     EMACS_INT from, from_byte, to, to_byte;
 +     Lisp_Object dst_object;
  {
 -  int len;
 -  struct conversion_buffer buf;
 -  int from, to_byte;
 -  Lisp_Object saved_coding_symbol;
 -  int result;
 -  int require_decoding;
 -  int shrinked_bytes = 0;
 -  Lisp_Object newstr;
 -  int consumed, consumed_char, produced, produced_char;
 -
 -  from = 0;
 -  to_byte = SBYTES (str);
 -
 -  saved_coding_symbol = coding->symbol;
 -  coding->src_multibyte = STRING_MULTIBYTE (str);
 -  coding->dst_multibyte = 1;
 -  coding->heading_ascii = 0;
 +  int count = specpdl_ptr - specpdl;
 +  unsigned char *destination;
 +  EMACS_INT dst_bytes;
 +  EMACS_INT chars = to - from;
 +  EMACS_INT bytes = to_byte - from_byte;
 +  Lisp_Object attrs;
 +  Lisp_Object buffer;
 +  int saved_pt = -1, saved_pt_byte;
  
 -  if (CODING_REQUIRE_DETECTION (coding))
 +  buffer = Fcurrent_buffer ();
 +
 +  if (NILP (dst_object))
 +    {
 +      destination = coding->destination;
 +      dst_bytes = coding->dst_bytes;
 +    }
 +
 +  coding->src_object = src_object;
 +  coding->src_chars = chars;
 +  coding->src_bytes = bytes;
 +  coding->src_multibyte = chars < bytes;
 +
 +  if (STRINGP (src_object))
 +    {
 +      coding->src_pos = from;
 +      coding->src_pos_byte = from_byte;
 +    }
 +  else if (BUFFERP (src_object))
      {
 -      /* See the comments in code_convert_region.  */
 -      if (coding->type == coding_type_undecided)
 +      set_buffer_internal (XBUFFER (src_object));
 +      if (from != GPT)
 +      move_gap_both (from, from_byte);
 +      if (EQ (src_object, dst_object))
        {
 -        detect_coding (coding, SDATA (str), to_byte);
 -        if (coding->type == coding_type_undecided)
 -          {
 -            coding->type = coding_type_emacs_mule;
 -            coding->category_idx = CODING_CATEGORY_IDX_EMACS_MULE;
 -            /* As emacs-mule decoder will handle composition, we
 -               need this setting to allocate coding->cmp_data
 -               later.  */
 -            coding->composing = COMPOSITION_NO;
 -          }
 +        saved_pt = PT, saved_pt_byte = PT_BYTE;
 +        TEMP_SET_PT_BOTH (from, from_byte);
 +        del_range_both (from, from_byte, to, to_byte, 1);
 +        coding->src_pos = -chars;
 +        coding->src_pos_byte = -bytes;
        }
 -      if (coding->eol_type == CODING_EOL_UNDECIDED
 -        && coding->type != coding_type_ccl)
 +      else
        {
 -        saved_coding_symbol = coding->symbol;
 -        detect_eol (coding, SDATA (str), to_byte);
 -        if (coding->eol_type == CODING_EOL_UNDECIDED)
 -          coding->eol_type = CODING_EOL_LF;
 -        /* We had better recover the original eol format if we
 -           encounter an inconsistent eol format while decoding.  */
 -        coding->mode |= CODING_MODE_INHIBIT_INCONSISTENT_EOL;
 +        coding->src_pos = from;
 +        coding->src_pos_byte = from_byte;
        }
      }
  
 -  if (coding->type == coding_type_no_conversion
 -      || coding->type == coding_type_raw_text)
 -    coding->dst_multibyte = 0;
 -
 -  require_decoding = CODING_REQUIRE_DECODING (coding);
 +  if (CODING_REQUIRE_DETECTION (coding))
 +    detect_coding (coding);
 +  attrs = CODING_ID_ATTRS (coding->id);
  
 -  if (STRING_MULTIBYTE (str))
 +  if (EQ (dst_object, Qt)
 +      || (! NILP (CODING_ATTR_POST_READ (attrs))
 +        && NILP (dst_object)))
      {
 -      /* Decoding routines expect the source text to be unibyte.  */
 -      str = Fstring_as_unibyte (str);
 -      to_byte = SBYTES (str);
 -      nocopy = 1;
 -      coding->src_multibyte = 0;
 +      coding->dst_object = code_conversion_save (1, 1);
 +      coding->dst_pos = BEG;
 +      coding->dst_pos_byte = BEG_BYTE;
 +      coding->dst_multibyte = 1;
      }
 -
 -  /* Try to skip the heading and tailing ASCIIs.  */
 -  if (require_decoding && coding->type != coding_type_ccl)
 +  else if (BUFFERP (dst_object))
      {
 -      SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),
 -                              0);
 -      if (from == to_byte)
 -      require_decoding = 0;
 -      shrinked_bytes = from + (SBYTES (str) - to_byte);
 +      code_conversion_save (0, 0);
 +      coding->dst_object = dst_object;
 +      coding->dst_pos = BUF_PT (XBUFFER (dst_object));
 +      coding->dst_pos_byte = BUF_PT_BYTE (XBUFFER (dst_object));
 +      coding->dst_multibyte
 +      = ! NILP (XBUFFER (dst_object)->enable_multibyte_characters);
      }
 -
 -  if (!require_decoding
 -      && !(SYMBOLP (coding->post_read_conversion)
 -         && !NILP (Ffboundp (coding->post_read_conversion))))
 +  else
      {
 -      coding->consumed = SBYTES (str);
 -      coding->consumed_char = SCHARS (str);
 -      if (coding->dst_multibyte)
 -      {
 -        str = Fstring_as_multibyte (str);
 -        nocopy = 1;
 -      }
 -      coding->produced = SBYTES (str);
 -      coding->produced_char = SCHARS (str);
 -      return (nocopy ? str : Fcopy_sequence (str));
 +      code_conversion_save (0, 0);
 +      coding->dst_object = Qnil;
 +      coding->dst_multibyte = 1;
      }
  
 -  if (coding->composing != COMPOSITION_DISABLED)
 -    coding_allocate_composition_data (coding, from);
 -  len = decoding_buffer_size (coding, to_byte - from);
 -  allocate_conversion_buffer (buf, len);
 +  decode_coding (coding);
  
 -  consumed = consumed_char = produced = produced_char = 0;
 -  while (1)
 +  if (BUFFERP (coding->dst_object))
 +    set_buffer_internal (XBUFFER (coding->dst_object));
 +
 +  if (! NILP (CODING_ATTR_POST_READ (attrs)))
      {
 -      result = decode_coding (coding, SDATA (str) + from + consumed,
 -                            buf.data + produced, to_byte - from - consumed,
 -                            buf.size - produced);
 -      consumed += coding->consumed;
 -      consumed_char += coding->consumed_char;
 -      produced += coding->produced;
 -      produced_char += coding->produced_char;
 -      if (result == CODING_FINISH_NORMAL
 -        || result == CODING_FINISH_INTERRUPT
 -        || (result == CODING_FINISH_INSUFFICIENT_SRC
 -            && coding->consumed == 0))
 -      break;
 -      if (result == CODING_FINISH_INSUFFICIENT_CMP)
 -      coding_allocate_composition_data (coding, from + produced_char);
 -      else if (result == CODING_FINISH_INSUFFICIENT_DST)
 -      extend_conversion_buffer (&buf);
 -      else if (result == CODING_FINISH_INCONSISTENT_EOL)
 -      {
 -        Lisp_Object eol_type;
 +      struct gcpro gcpro1, gcpro2;
 +      EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
 +      Lisp_Object val;
  
 -        /* Recover the original EOL format.  */
 -        if (coding->eol_type == CODING_EOL_CR)
 -          {
 -            unsigned char *p;
 -            for (p = buf.data; p < buf.data + produced; p++)
 -              if (*p == '\n') *p = '\r';
 -          }
 -        else if (coding->eol_type == CODING_EOL_CRLF)
 +      TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
 +      GCPRO2 (coding->src_object, coding->dst_object);
 +      val = safe_call1 (CODING_ATTR_POST_READ (attrs),
 +                      make_number (coding->produced_char));
 +      UNGCPRO;
 +      CHECK_NATNUM (val);
 +      coding->produced_char += Z - prev_Z;
 +      coding->produced += Z_BYTE - prev_Z_BYTE;
 +    }
 +
 +  if (EQ (dst_object, Qt))
 +    {
 +      coding->dst_object = Fbuffer_string ();
 +    }
 +  else if (NILP (dst_object) && BUFFERP (coding->dst_object))
 +    {
 +      set_buffer_internal (XBUFFER (coding->dst_object));
 +      if (dst_bytes < coding->produced)
 +      {
 +        destination
 +          = (unsigned char *) xrealloc (destination, coding->produced);
 +        if (! destination)
            {
 -            int num_eol = 0;
 -            unsigned char *p0, *p1;
 -            for (p0 = buf.data, p1 = p0 + produced; p0 < p1; p0++)
 -              if (*p0 == '\n') num_eol++;
 -            if (produced + num_eol >= buf.size)
 -              extend_conversion_buffer (&buf);
 -            for (p0 = buf.data + produced, p1 = p0 + num_eol; p0 > buf.data;)
 -              {
 -                *--p1 = *--p0;
 -                if (*p0 == '\n') *--p1 = '\r';
 -              }
 -            produced += num_eol;
 -            produced_char += num_eol;
 +            record_conversion_result (coding,
 +                                      CODING_RESULT_INSUFFICIENT_DST);
 +            unbind_to (count, Qnil);
 +            return;
            }
 -        /* Suppress eol-format conversion in the further conversion.  */
 -        coding->eol_type = CODING_EOL_LF;
 -
 -        /* Set the coding system symbol to that for Unix-like EOL.  */
 -        eol_type = Fget (saved_coding_symbol, Qeol_type);
 -        if (VECTORP (eol_type)
 -            && XVECTOR (eol_type)->size == 3
 -            && SYMBOLP (XVECTOR (eol_type)->contents[CODING_EOL_LF]))
 -          coding->symbol = XVECTOR (eol_type)->contents[CODING_EOL_LF];
 -        else
 -          coding->symbol = saved_coding_symbol;
 -
 -
 +        if (BEGV < GPT && GPT < BEGV + coding->produced_char)
 +          move_gap_both (BEGV, BEGV_BYTE);
 +        bcopy (BEGV_ADDR, destination, coding->produced);
 +        coding->destination = destination;
        }
      }
  
 -  coding->consumed = consumed;
 -  coding->consumed_char = consumed_char;
 -  coding->produced = produced;
 -  coding->produced_char = produced_char;
 +  if (saved_pt >= 0)
 +    {
 +      /* This is the case of:
 +       (BUFFERP (src_object) && EQ (src_object, dst_object))
 +       As we have moved PT while replacing the original buffer
 +       contents, we must recover it now.  */
 +      set_buffer_internal (XBUFFER (src_object));
 +      if (saved_pt < from)
 +      TEMP_SET_PT_BOTH (saved_pt, saved_pt_byte);
 +      else if (saved_pt < from + chars)
 +      TEMP_SET_PT_BOTH (from, from_byte);
 +      else if (! NILP (current_buffer->enable_multibyte_characters))
 +      TEMP_SET_PT_BOTH (saved_pt + (coding->produced_char - chars),
 +                        saved_pt_byte + (coding->produced - bytes));
 +      else
 +      TEMP_SET_PT_BOTH (saved_pt + (coding->produced - bytes),
 +                        saved_pt_byte + (coding->produced - bytes));
 +    }
  
 -  if (coding->dst_multibyte)
 -    newstr = make_uninit_multibyte_string (produced_char + shrinked_bytes,
 -                                         produced + shrinked_bytes);
 -  else
 -    newstr = make_uninit_string (produced + shrinked_bytes);
 -  if (from > 0)
 -    STRING_COPYIN (newstr, 0, SDATA (str), from);
 -  STRING_COPYIN (newstr, from, buf.data, produced);
 -  if (shrinked_bytes > from)
 -    STRING_COPYIN (newstr, from + produced,
 -                 SDATA (str) + to_byte,
 -                 shrinked_bytes - from);
 -  free_conversion_buffer (&buf);
 -
 -  coding->consumed += shrinked_bytes;
 -  coding->consumed_char += shrinked_bytes;
 -  coding->produced += shrinked_bytes;
 -  coding->produced_char += shrinked_bytes;
 -
 -  if (coding->cmp_data && coding->cmp_data->used)
 -    coding_restore_composition (coding, newstr);
 -  coding_free_composition_data (coding);
 -
 -  if (SYMBOLP (coding->post_read_conversion)
 -      && !NILP (Ffboundp (coding->post_read_conversion)))
 -    newstr = run_pre_post_conversion_on_str (newstr, coding, 0);
 -
 -  return newstr;
 +  unbind_to (count, coding->dst_object);
  }
  
 -Lisp_Object
 -encode_coding_string (str, coding, nocopy)
 -     Lisp_Object str;
 +
 +void
 +encode_coding_object (coding, src_object, from, from_byte, to, to_byte,
 +                    dst_object)
       struct coding_system *coding;
 -     int nocopy;
 +     Lisp_Object src_object;
 +     EMACS_INT from, from_byte, to, to_byte;
 +     Lisp_Object dst_object;
  {
 -  int len;
 -  struct conversion_buffer buf;
 -  int from, to, to_byte;
 -  int result;
 -  int shrinked_bytes = 0;
 -  Lisp_Object newstr;
 -  int consumed, consumed_char, produced, produced_char;
 -
 -  if (SYMBOLP (coding->pre_write_conversion)
 -      && !NILP (Ffboundp (coding->pre_write_conversion)))
 -    {
 -      str = run_pre_post_conversion_on_str (str, coding, 1);
 -      /* As STR is just newly generated, we don't have to copy it
 -       anymore.  */
 -      nocopy = 1;
 -    }
 +  int count = specpdl_ptr - specpdl;
 +  EMACS_INT chars = to - from;
 +  EMACS_INT bytes = to_byte - from_byte;
 +  Lisp_Object attrs;
 +  Lisp_Object buffer;
 +  int saved_pt = -1, saved_pt_byte;
 +  int kill_src_buffer = 0;
 +
 +  buffer = Fcurrent_buffer ();
 +
 +  coding->src_object = src_object;
 +  coding->src_chars = chars;
 +  coding->src_bytes = bytes;
 +  coding->src_multibyte = chars < bytes;
 +
 +  attrs = CODING_ID_ATTRS (coding->id);
 +
 +  if (! NILP (CODING_ATTR_PRE_WRITE (attrs)))
 +    {
 +      coding->src_object = code_conversion_save (1, coding->src_multibyte);
 +      set_buffer_internal (XBUFFER (coding->src_object));
 +      if (STRINGP (src_object))
 +      insert_from_string (src_object, from, from_byte, chars, bytes, 0);
 +      else if (BUFFERP (src_object))
 +      insert_from_buffer (XBUFFER (src_object), from, chars, 0);
 +      else
 +      insert_1_both (coding->source + from, chars, bytes, 0, 0, 0);
  
 -  from = 0;
 -  to = SCHARS (str);
 -  to_byte = SBYTES (str);
 +      if (EQ (src_object, dst_object))
 +      {
 +        set_buffer_internal (XBUFFER (src_object));
 +        saved_pt = PT, saved_pt_byte = PT_BYTE;
 +        del_range_both (from, from_byte, to, to_byte, 1);
 +        set_buffer_internal (XBUFFER (coding->src_object));
 +      }
  
 -  /* Encoding routines determine the multibyteness of the source text
 -     by coding->src_multibyte.  */
 -  coding->src_multibyte = SCHARS (str) < SBYTES (str);
 -  coding->dst_multibyte = 0;
 -  if (! CODING_REQUIRE_ENCODING (coding))
 -    goto no_need_of_encoding;
 +      {
 +      Lisp_Object args[3];
  
 -  if (coding->composing != COMPOSITION_DISABLED)
 -    coding_save_composition (coding, from, to, str);
 +      args[0] = CODING_ATTR_PRE_WRITE (attrs);
 +      args[1] = make_number (BEG);
 +      args[2] = make_number (Z);
 +      safe_call (3, args);
 +      }
 +      if (XBUFFER (coding->src_object) != current_buffer)
 +      kill_src_buffer = 1;
 +      coding->src_object = Fcurrent_buffer ();
 +      if (BEG != GPT)
 +      move_gap_both (BEG, BEG_BYTE);
 +      coding->src_chars = Z - BEG;
 +      coding->src_bytes = Z_BYTE - BEG_BYTE;
 +      coding->src_pos = BEG;
 +      coding->src_pos_byte = BEG_BYTE;
 +      coding->src_multibyte = Z < Z_BYTE;
 +    }
 +  else if (STRINGP (src_object))
 +    {
 +      code_conversion_save (0, 0);
 +      coding->src_pos = from;
 +      coding->src_pos_byte = from_byte;
 +    }
 +  else if (BUFFERP (src_object))
 +    {
 +      code_conversion_save (0, 0);
 +      set_buffer_internal (XBUFFER (src_object));
 +      if (EQ (src_object, dst_object))
 +      {
 +        saved_pt = PT, saved_pt_byte = PT_BYTE;
 +        coding->src_object = del_range_1 (from, to, 1, 1);
 +        coding->src_pos = 0;
 +        coding->src_pos_byte = 0;
 +      }
 +      else
 +      {
 +        if (from < GPT && to >= GPT)
 +          move_gap_both (from, from_byte);
 +        coding->src_pos = from;
 +        coding->src_pos_byte = from_byte;
 +      }
 +    }
 +  else
 +    code_conversion_save (0, 0);
  
 -  /* Try to skip the heading and tailing ASCIIs.  We can't skip them
 -     if we must run CCL program or there are compositions to
 -     encode.  */
 -  coding->heading_ascii = 0;
 -  if (coding->type != coding_type_ccl
 -      && (! coding->cmp_data || coding->cmp_data->used == 0))
 +  if (BUFFERP (dst_object))
      {
 -      SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),
 -                              1);
 -      if (from == to_byte)
 +      coding->dst_object = dst_object;
 +      if (EQ (src_object, dst_object))
 +      {
 +        coding->dst_pos = from;
 +        coding->dst_pos_byte = from_byte;
 +      }
 +      else
        {
 -        coding_free_composition_data (coding);
 -        goto no_need_of_encoding;
 +        coding->dst_pos = BUF_PT (XBUFFER (dst_object));
 +        coding->dst_pos_byte = BUF_PT_BYTE (XBUFFER (dst_object));
        }
 -      shrinked_bytes = from + (SBYTES (str) - to_byte);
 +      coding->dst_multibyte
 +      = ! NILP (XBUFFER (dst_object)->enable_multibyte_characters);
 +    }
 +  else if (EQ (dst_object, Qt))
 +    {
 +      coding->dst_object = Qnil;
 +      coding->dst_bytes = coding->src_chars;
 +      if (coding->dst_bytes == 0)
 +      coding->dst_bytes = 1;
 +      coding->destination = (unsigned char *) xmalloc (coding->dst_bytes);
 +      coding->dst_multibyte = 0;
 +    }
 +  else
 +    {
 +      coding->dst_object = Qnil;
 +      coding->dst_multibyte = 0;
      }
  
 -  len = encoding_buffer_size (coding, to_byte - from);
 -  allocate_conversion_buffer (buf, len);
 +  encode_coding (coding);
  
 -  consumed = consumed_char = produced = produced_char = 0;
 -  while (1)
 +  if (EQ (dst_object, Qt))
      {
 -      result = encode_coding (coding, SDATA (str) + from + consumed,
 -                            buf.data + produced, to_byte - from - consumed,
 -                            buf.size - produced);
 -      consumed += coding->consumed;
 -      consumed_char += coding->consumed_char;
 -      produced += coding->produced;
 -      produced_char += coding->produced_char;
 -      if (result == CODING_FINISH_NORMAL
 -        || result == CODING_FINISH_INTERRUPT
 -        || (result == CODING_FINISH_INSUFFICIENT_SRC
 -            && coding->consumed == 0))
 -      break;
 -      /* Now result should be CODING_FINISH_INSUFFICIENT_DST.  */
 -      extend_conversion_buffer (&buf);
 -    }
 -
 -  coding->consumed = consumed;
 -  coding->consumed_char = consumed_char;
 -  coding->produced = produced;
 -  coding->produced_char = produced_char;
 -
 -  newstr = make_uninit_string (produced + shrinked_bytes);
 -  if (from > 0)
 -    STRING_COPYIN (newstr, 0, SDATA (str), from);
 -  STRING_COPYIN (newstr, from, buf.data, produced);
 -  if (shrinked_bytes > from)
 -    STRING_COPYIN (newstr, from + produced,
 -                 SDATA (str) + to_byte,
 -                 shrinked_bytes - from);
 -
 -  free_conversion_buffer (&buf);
 -  coding_free_composition_data (coding);
 -
 -  return newstr;
 -
 - no_need_of_encoding:
 -  coding->consumed = SBYTES (str);
 -  coding->consumed_char = SCHARS (str);
 -  if (STRING_MULTIBYTE (str))
 -    {
 -      if (nocopy)
 -      /* We are sure that STR doesn't contain a multibyte
 -         character.  */
 -      STRING_SET_UNIBYTE (str);
 +      if (BUFFERP (coding->dst_object))
 +      coding->dst_object = Fbuffer_string ();
        else
        {
 -        str = Fstring_as_unibyte (str);
 -        nocopy = 1;
 +        coding->dst_object
 +          = make_unibyte_string ((char *) coding->destination,
 +                                 coding->produced);
 +        xfree (coding->destination);
        }
      }
 -  coding->produced = SBYTES (str);
 -  coding->produced_char = SCHARS (str);
 -  return (nocopy ? str : Fcopy_sequence (str));
 +
 +  if (saved_pt >= 0)
 +    {
 +      /* This is the case of:
 +       (BUFFERP (src_object) && EQ (src_object, dst_object))
 +       As we have moved PT while replacing the original buffer
 +       contents, we must recover it now.  */
 +      set_buffer_internal (XBUFFER (src_object));
 +      if (saved_pt < from)
 +      TEMP_SET_PT_BOTH (saved_pt, saved_pt_byte);
 +      else if (saved_pt < from + chars)
 +      TEMP_SET_PT_BOTH (from, from_byte);
 +      else if (! NILP (current_buffer->enable_multibyte_characters))
 +      TEMP_SET_PT_BOTH (saved_pt + (coding->produced_char - chars),
 +                        saved_pt_byte + (coding->produced - bytes));
 +      else
 +      TEMP_SET_PT_BOTH (saved_pt + (coding->produced - bytes),
 +                        saved_pt_byte + (coding->produced - bytes));
 +    }
 +
 +  if (kill_src_buffer)
 +    Fkill_buffer (coding->src_object);
 +  unbind_to (count, Qnil);
 +}
 +
 +
 +Lisp_Object
 +preferred_coding_system ()
 +{
 +  int id = coding_categories[coding_priorities[0]].id;
 +
 +  return CODING_ID_NAME (id);
  }
  
  \f
  
  DEFUN ("coding-system-p", Fcoding_system_p, Scoding_system_p, 1, 1, 0,
         doc: /* Return t if OBJECT is nil or a coding-system.
 -See the documentation of `make-coding-system' for information
 +See the documentation of `define-coding-system' for information
  about coding-system objects.  */)
       (obj)
       Lisp_Object obj;
  {
 -  if (NILP (obj))
 +  if (NILP (obj)
 +      || CODING_SYSTEM_ID (obj) >= 0)
      return Qt;
 -  if (!SYMBOLP (obj))
 +  if (! SYMBOLP (obj)
 +      || NILP (Fget (obj, Qcoding_system_define_form)))
      return Qnil;
 -  if (! NILP (Fget (obj, Qcoding_system_define_form)))
 -    return Qt;
 -  /* Get coding-spec vector for OBJ.  */
 -  obj = Fget (obj, Qcoding_system);
 -  return ((VECTORP (obj) && XVECTOR (obj)->size == 5)
 -        ? Qt : Qnil);
 +  return Qt;
  }
  
  DEFUN ("read-non-nil-coding-system", Fread_non_nil_coding_system,
@@@ -7198,7 -6564,7 +7198,7 @@@ If the user enters null input, return s
  {
    Lisp_Object val;
    if (SYMBOLP (default_coding_system))
 -    default_coding_system = SYMBOL_NAME (default_coding_system);
 +    XSETSTRING (default_coding_system, XPNTR (SYMBOL_NAME (default_coding_system)));
    val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
                          Qt, Qnil, Qcoding_system_history,
                          default_coding_system, Qnil);
@@@ -7209,9 -6575,9 +7209,9 @@@ DEFUN ("check-coding-system", Fcheck_co
         1, 1, 0,
         doc: /* Check validity of CODING-SYSTEM.
  If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.
 -It is valid if it is nil or a symbol with a non-nil `coding-system' property.
 -The value of this property should be a vector of length 5.  */)
 -     (coding_system)
 +It is valid if it is nil or a symbol defined as a coding system by the
 +function `define-coding-system'.  */)
 +  (coding_system)
       Lisp_Object coding_system;
  {
    Lisp_Object define_form;
      return coding_system;
    xsignal1 (Qcoding_system_error, coding_system);
  }
 +
  \f
 +/* Detect how the bytes at SRC of length SRC_BYTES are encoded.  If
 +   HIGHEST is nonzero, return the coding system of the highest
 +   priority among the detected coding systems.  Otherwize return a
 +   list of detected coding systems sorted by their priorities.  If
 +   MULTIBYTEP is nonzero, it is assumed that the bytes are in correct
 +   multibyte form but contains only ASCII and eight-bit chars.
 +   Otherwise, the bytes are raw bytes.
 +
 +   CODING-SYSTEM controls the detection as below:
 +
 +   If it is nil, detect both text-format and eol-format.  If the
 +   text-format part of CODING-SYSTEM is already specified
 +   (e.g. `iso-latin-1'), detect only eol-format.  If the eol-format
 +   part of CODING-SYSTEM is already specified (e.g. `undecided-unix'),
 +   detect only text-format.  */
 +
  Lisp_Object
 -detect_coding_system (src, src_bytes, highest, multibytep)
 +detect_coding_system (src, src_chars, src_bytes, highest, multibytep,
 +                    coding_system)
       const unsigned char *src;
 -     int src_bytes, highest;
 +     int src_chars, src_bytes, highest;
       int multibytep;
 +     Lisp_Object coding_system;
  {
 -  int coding_mask, eol_type;
 -  Lisp_Object val, tmp;
 -  int dummy;
 +  const unsigned char *src_end = src + src_bytes;
 +  Lisp_Object attrs, eol_type;
 +  Lisp_Object val;
 +  struct coding_system coding;
 +  int id;
 +  struct coding_detection_info detect_info;
 +  enum coding_category base_category;
 +
 +  if (NILP (coding_system))
 +    coding_system = Qundecided;
 +  setup_coding_system (coding_system, &coding);
 +  attrs = CODING_ID_ATTRS (coding.id);
 +  eol_type = CODING_ID_EOL_TYPE (coding.id);
 +  coding_system = CODING_ATTR_BASE_NAME (attrs);
 +
 +  coding.source = src;
 +  coding.src_chars = src_chars;
 +  coding.src_bytes = src_bytes;
 +  coding.src_multibyte = multibytep;
 +  coding.consumed = 0;
 +  coding.mode |= CODING_MODE_LAST_BLOCK;
  
 -  coding_mask = detect_coding_mask (src, src_bytes, NULL, &dummy, multibytep);
 -  eol_type  = detect_eol_type (src, src_bytes, &dummy);
 -  if (eol_type == CODING_EOL_INCONSISTENT)
 -    eol_type = CODING_EOL_UNDECIDED;
 +  detect_info.checked = detect_info.found = detect_info.rejected = 0;
  
 -  if (!coding_mask)
 +  /* At first, detect text-format if necessary.  */
 +  base_category = XINT (CODING_ATTR_CATEGORY (attrs));
 +  if (base_category == coding_category_undecided)
      {
 -      val = Qundecided;
 -      if (eol_type != CODING_EOL_UNDECIDED)
 +      enum coding_category category;
 +      struct coding_system *this;
 +      int c, i;
 +
 +      /* Skip all ASCII bytes except for a few ISO2022 controls.  */
 +      for (i = 0; src < src_end; i++, src++)
 +      {
 +        c = *src;
 +        if (c & 0x80)
 +          break;
 +        if (c < 0x20
 +            && (c == ISO_CODE_ESC || c == ISO_CODE_SI || c == ISO_CODE_SO)
 +            && ! inhibit_iso_escape_detection)
 +          {
 +            coding.head_ascii = src - coding.source;
 +            if (detect_coding_iso_2022 (&coding, &detect_info))
 +              {
 +                /* We have scanned the whole data.  */
 +                if (! (detect_info.rejected & CATEGORY_MASK_ISO_7_ELSE))
 +                  /* We didn't find an 8-bit code.  */
 +                  src = src_end;
 +                break;
 +              }
 +          }
 +      }
 +      coding.head_ascii = src - coding.source;
 +
 +      if (src < src_end
 +        || detect_info.found)
 +      {
 +        if (src == src_end)
 +          /* As all bytes are 7-bit, we can ignore non-ISO-2022 codings.  */
 +          for (i = 0; i < coding_category_raw_text; i++)
 +            {
 +              category = coding_priorities[i];
 +              this = coding_categories + category;
 +              if (detect_info.found & (1 << category))
 +                break;
 +            }
 +        else
 +          for (i = 0; i < coding_category_raw_text; i++)
 +            {
 +              category = coding_priorities[i];
 +              this = coding_categories + category;
 +
 +              if (this->id < 0)
 +                {
 +                  /* No coding system of this category is defined.  */
 +                  detect_info.rejected |= (1 << category);
 +                }
 +              else if (category >= coding_category_raw_text)
 +                continue;
 +              else if (detect_info.checked & (1 << category))
 +                {
 +                  if (highest
 +                      && (detect_info.found & (1 << category)))
 +                    break;
 +                }
 +              else
 +                {
 +                  if ((*(this->detector)) (&coding, &detect_info)
 +                      && highest
 +                      && (detect_info.found & (1 << category)))
 +                    {
 +                      if (category == coding_category_utf_16_auto)
 +                        {
 +                          if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
 +                            category = coding_category_utf_16_le;
 +                          else
 +                            category = coding_category_utf_16_be;
 +                        }
 +                      break;
 +                    }
 +                }
 +            }
 +      }
 +
 +      if (detect_info.rejected == CATEGORY_MASK_ANY)
 +      {
 +        detect_info.found = CATEGORY_MASK_RAW_TEXT;
 +        id = coding_categories[coding_category_raw_text].id;
 +        val = Fcons (make_number (id), Qnil);
 +      }
 +      else if (! detect_info.rejected && ! detect_info.found)
 +      {
 +        detect_info.found = CATEGORY_MASK_ANY;
 +        id = coding_categories[coding_category_undecided].id;
 +        val = Fcons (make_number (id), Qnil);
 +      }
 +      else if (highest)
 +      {
 +        if (detect_info.found)
 +          {
 +            detect_info.found = 1 << category;
 +            val = Fcons (make_number (this->id), Qnil);
 +          }
 +        else
 +          for (i = 0; i < coding_category_raw_text; i++)
 +            if (! (detect_info.rejected & (1 << coding_priorities[i])))
 +              {
 +                detect_info.found = 1 << coding_priorities[i];
 +                id = coding_categories[coding_priorities[i]].id;
 +                val = Fcons (make_number (id), Qnil);
 +                break;
 +              }
 +      }
 +      else
        {
 -        Lisp_Object val2;
 -        val2 = Fget (Qundecided, Qeol_type);
 -        if (VECTORP (val2))
 -          val = XVECTOR (val2)->contents[eol_type];
 +        int mask = detect_info.rejected | detect_info.found;
 +        int found = 0;
 +        val = Qnil;
 +
 +        for (i = coding_category_raw_text - 1; i >= 0; i--)
 +          {
 +            category = coding_priorities[i];
 +            if (! (mask & (1 << category)))
 +              {
 +                found |= 1 << category;
 +                id = coding_categories[category].id;
 +                if (id >= 0)
 +                  val = Fcons (make_number (id), val);
 +              }
 +          }
 +        for (i = coding_category_raw_text - 1; i >= 0; i--)
 +          {
 +            category = coding_priorities[i];
 +            if (detect_info.found & (1 << category))
 +              {
 +                id = coding_categories[category].id;
 +                val = Fcons (make_number (id), val);
 +              }
 +          }
 +        detect_info.found |= found;
        }
 -      return (highest ? val : Fcons (val, Qnil));
      }
 -
 -  /* At first, gather possible coding systems in VAL.  */
 -  val = Qnil;
 -  for (tmp = Vcoding_category_list; CONSP (tmp); tmp = XCDR (tmp))
 +  else if (base_category == coding_category_utf_16_auto)
      {
 -      Lisp_Object category_val, category_index;
 -
 -      category_index = Fget (XCAR (tmp), Qcoding_category_index);
 -      category_val = Fsymbol_value (XCAR (tmp));
 -      if (!NILP (category_val)
 -        && NATNUMP (category_index)
 -        && (coding_mask & (1 << XFASTINT (category_index))))
 +      if (detect_coding_utf_16 (&coding, &detect_info))
        {
 -        val = Fcons (category_val, val);
 -        if (highest)
 -          break;
 +        struct coding_system *this;
 +
 +        if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
 +          this = coding_categories + coding_category_utf_16_le;
 +        else if (detect_info.found & CATEGORY_MASK_UTF_16_BE)
 +          this = coding_categories + coding_category_utf_16_be;
 +        else if (detect_info.rejected & CATEGORY_MASK_UTF_16_LE_NOSIG)
 +          this = coding_categories + coding_category_utf_16_be_nosig;
 +        else
 +          this = coding_categories + coding_category_utf_16_le_nosig;
 +        val = Fcons (make_number (this->id), Qnil);
        }
      }
 -  if (!highest)
 -    val = Fnreverse (val);
 -
 -  /* Then, replace the elements with subsidiary coding systems.  */
 -  for (tmp = val; CONSP (tmp); tmp = XCDR (tmp))
 +  else
      {
 -      if (eol_type != CODING_EOL_UNDECIDED
 -        && eol_type != CODING_EOL_INCONSISTENT)
 -      {
 -        Lisp_Object eol;
 -        eol = Fget (XCAR (tmp), Qeol_type);
 -        if (VECTORP (eol))
 -          XSETCAR (tmp, XVECTOR (eol)->contents[eol_type]);
 -      }
 +      detect_info.found = 1 << XINT (CODING_ATTR_CATEGORY (attrs));
 +      val = Fcons (make_number (coding.id), Qnil);
      }
 +
 +  /* Then, detect eol-format if necessary.  */
 +  {
 +    int normal_eol = -1, utf_16_be_eol = -1, utf_16_le_eol;
 +    Lisp_Object tail;
 +
 +    if (VECTORP (eol_type))
 +      {
 +      if (detect_info.found & ~CATEGORY_MASK_UTF_16)
 +        normal_eol = detect_eol (coding.source, src_bytes,
 +                                 coding_category_raw_text);
 +      if (detect_info.found & (CATEGORY_MASK_UTF_16_BE
 +                               | CATEGORY_MASK_UTF_16_BE_NOSIG))
 +        utf_16_be_eol = detect_eol (coding.source, src_bytes,
 +                                    coding_category_utf_16_be);
 +      if (detect_info.found & (CATEGORY_MASK_UTF_16_LE
 +                               | CATEGORY_MASK_UTF_16_LE_NOSIG))
 +        utf_16_le_eol = detect_eol (coding.source, src_bytes,
 +                                    coding_category_utf_16_le);
 +      }
 +    else
 +      {
 +      if (EQ (eol_type, Qunix))
 +        normal_eol = utf_16_be_eol = utf_16_le_eol = EOL_SEEN_LF;
 +      else if (EQ (eol_type, Qdos))
 +        normal_eol = utf_16_be_eol = utf_16_le_eol = EOL_SEEN_CRLF;
 +      else
 +        normal_eol = utf_16_be_eol = utf_16_le_eol = EOL_SEEN_CR;
 +      }
 +
 +    for (tail = val; CONSP (tail); tail = XCDR (tail))
 +      {
 +      enum coding_category category;
 +      int this_eol;
 +
 +      id = XINT (XCAR (tail));
 +      attrs = CODING_ID_ATTRS (id);
 +      category = XINT (CODING_ATTR_CATEGORY (attrs));
 +      eol_type = CODING_ID_EOL_TYPE (id);
 +      if (VECTORP (eol_type))
 +        {
 +          if (category == coding_category_utf_16_be
 +              || category == coding_category_utf_16_be_nosig)
 +            this_eol = utf_16_be_eol;
 +          else if (category == coding_category_utf_16_le
 +                   || category == coding_category_utf_16_le_nosig)
 +            this_eol = utf_16_le_eol;
 +          else
 +            this_eol = normal_eol;
 +
 +          if (this_eol == EOL_SEEN_LF)
 +            XSETCAR (tail, AREF (eol_type, 0));
 +          else if (this_eol == EOL_SEEN_CRLF)
 +            XSETCAR (tail, AREF (eol_type, 1));
 +          else if (this_eol == EOL_SEEN_CR)
 +            XSETCAR (tail, AREF (eol_type, 2));
 +          else
 +            XSETCAR (tail, CODING_ID_NAME (id));
 +        }
 +      else
 +        XSETCAR (tail, CODING_ID_NAME (id));
 +      }
 +  }
 +
    return (highest ? XCAR (val) : val);
  }
  
 +
  DEFUN ("detect-coding-region", Fdetect_coding_region, Sdetect_coding_region,
         2, 3, 0,
 -       doc: /* Detect how the byte sequence in the region is encoded.
 -Return a list of possible coding systems used on decoding a byte
 -sequence containing the bytes in the region between START and END when
 -the coding system `undecided' is specified.  The list is ordered by
 -priority decided in the current language environment.
 +       doc: /* Detect coding system of the text in the region between START and END.
 +Return a list of possible coding systems ordered by priority.
  
  If only ASCII characters are found (except for such ISO-2022 control
  characters ISO-2022 as ESC), it returns a list of single element
@@@ -7522,6 -6676,7 +7522,6 @@@ highest priority.  */
  {
    int from, to;
    int from_byte, to_byte;
 -  int include_anchor_byte = 0;
  
    CHECK_NUMBER_COERCE_MARKER (start);
    CHECK_NUMBER_COERCE_MARKER (end);
  
    if (from < GPT && to >= GPT)
      move_gap_both (to, to_byte);
 -  /* If we an anchor byte `\0' follows the region, we include it in
 -     the detecting source.  Then code detectors can handle the tailing
 -     byte sequence more accurately.
  
 -     Fix me: This is not a perfect solution.  It is better that we
 -     add one more argument, say LAST_BLOCK, to all detect_coding_XXX.
 -  */
 -  if (to == Z || (to == GPT && GAP_SIZE > 0))
 -    include_anchor_byte = 1;
    return detect_coding_system (BYTE_POS_ADDR (from_byte),
 -                             to_byte - from_byte + include_anchor_byte,
 +                             to - from, to_byte - from_byte,
                               !NILP (highest),
                               !NILP (current_buffer
 -                                    ->enable_multibyte_characters));
 +                                    ->enable_multibyte_characters),
 +                             Qnil);
  }
  
  DEFUN ("detect-coding-string", Fdetect_coding_string, Sdetect_coding_string,
         1, 2, 0,
 -       doc: /* Detect how the byte sequence in STRING is encoded.
 -Return a list of possible coding systems used on decoding a byte
 -sequence containing the bytes in STRING when the coding system
 -`undecided' is specified.  The list is ordered by priority decided in
 -the current language environment.
 +       doc: /* Detect coding system of the text in STRING.
 +Return a list of possible coding systems ordered by priority.
  
  If only ASCII characters are found (except for such ISO-2022 control
  characters ISO-2022 as ESC), it returns a list of single element
@@@ -7560,157 -6725,288 +7560,157 @@@ highest priority.  */
    CHECK_STRING (string);
  
    return detect_coding_system (SDATA (string),
 -                             /* "+ 1" is to include the anchor byte
 -                                `\0'.  With this, code detectors can
 -                                handle the tailing bytes more
 -                                accurately.  */
 -                             SBYTES (string) + 1,
 -                             !NILP (highest),
 -                             STRING_MULTIBYTE (string));
 +                             SCHARS (string), SBYTES (string),
 +                             !NILP (highest), STRING_MULTIBYTE (string),
 +                             Qnil);
  }
  
 -/*  Subroutine for Ffind_coding_systems_region_internal.
 -
 -    Return a list of coding systems that safely encode the multibyte
 -    text between P and PEND.  SAFE_CODINGS, if non-nil, is an alist of
 -    possible coding systems.  If it is nil, it means that we have not
 -    yet found any coding systems.
 -
 -    WORK_TABLE a char-table of which element is set to t once the
 -    element is looked up.
  
 -    If a non-ASCII single byte char is found, set
 -    *single_byte_char_found to 1.  */
 -
 -static Lisp_Object
 -find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)
 -     unsigned char *p, *pend;
 -     Lisp_Object safe_codings, work_table;
 -     int *single_byte_char_found;
 +static INLINE int
 +char_encodable_p (c, attrs)
 +     int c;
 +     Lisp_Object attrs;
  {
 -  int c, len;
 -  Lisp_Object val, ch;
 -  Lisp_Object prev, tail;
 +  Lisp_Object tail;
 +  struct charset *charset;
 +  Lisp_Object translation_table;
  
 -  if (NILP (safe_codings))
 -    goto done_safe_codings;
 -  while (p < pend)
 +  translation_table = CODING_ATTR_TRANS_TBL (attrs);
 +  if (! NILP (translation_table))
 +    c = translate_char (translation_table, c);
 +  for (tail = CODING_ATTR_CHARSET_LIST (attrs);
 +       CONSP (tail); tail = XCDR (tail))
      {
 -      c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
 -      p += len;
 -      if (ASCII_BYTE_P (c))
 -      /* We can ignore ASCII characters here.  */
 -      continue;
 -      if (SINGLE_BYTE_CHAR_P (c))
 -      *single_byte_char_found = 1;
 -      /* Check the safe coding systems for C.  */
 -      ch = make_number (c);
 -      val = Faref (work_table, ch);
 -      if (EQ (val, Qt))
 -      /* This element was already checked.  Ignore it.  */
 -      continue;
 -      /* Remember that we checked this element.  */
 -      Faset (work_table, ch, Qt);
 -
 -      for (prev = tail = safe_codings; CONSP (tail); tail = XCDR (tail))
 -      {
 -        Lisp_Object elt, translation_table, hash_table, accept_latin_extra;
 -        int encodable;
 -
 -        elt = XCAR (tail);
 -        if (CONSP (XCDR (elt)))
 -          {
 -            /* This entry has this format now:
 -               ( CODING SAFE-CHARS TRANSLATION-TABLE HASH-TABLE
 -                        ACCEPT-LATIN-EXTRA ) */
 -            val = XCDR (elt);
 -            encodable = ! NILP (Faref (XCAR (val), ch));
 -            if (! encodable)
 -              {
 -                val = XCDR (val);
 -                translation_table = XCAR (val);
 -                hash_table = XCAR (XCDR (val));
 -                accept_latin_extra = XCAR (XCDR (XCDR (val)));
 -              }
 -          }
 -        else
 -          {
 -            /* This entry has this format now: ( CODING . SAFE-CHARS) */
 -            encodable = ! NILP (Faref (XCDR (elt), ch));
 -            if (! encodable)
 -              {
 -                /* Transform the format to:
 -                   ( CODING SAFE-CHARS TRANSLATION-TABLE HASH-TABLE
 -                     ACCEPT-LATIN-EXTRA )  */
 -                val = Fget (XCAR (elt), Qcoding_system);
 -                translation_table
 -                  = Fplist_get (AREF (val, 3),
 -                                Qtranslation_table_for_encode);
 -                if (SYMBOLP (translation_table))
 -                  translation_table = Fget (translation_table,
 -                                            Qtranslation_table);
 -                hash_table
 -                  = (CHAR_TABLE_P (translation_table)
 -                     ? XCHAR_TABLE (translation_table)->extras[1]
 -                     : Qnil);
 -                accept_latin_extra
 -                  = ((EQ (AREF (val, 0), make_number (2))
 -                      && VECTORP (AREF (val, 4)))
 -                     ? AREF (AREF (val, 4), 16)
 -                     : Qnil);
 -                XSETCAR (tail, list5 (XCAR (elt), XCDR (elt),
 -                                      translation_table, hash_table,
 -                                      accept_latin_extra));
 -              }
 -          }
 -
 -        if (! encodable
 -            && ((CHAR_TABLE_P (translation_table)
 -                 && ! NILP (Faref (translation_table, ch)))
 -                || (HASH_TABLE_P (hash_table)
 -                    && ! NILP (Fgethash (ch, hash_table, Qnil)))
 -                || (SINGLE_BYTE_CHAR_P (c)
 -                    && ! NILP (accept_latin_extra)
 -                    && VECTORP (Vlatin_extra_code_table)
 -                    && ! NILP (AREF (Vlatin_extra_code_table, c)))))
 -          encodable = 1;
 -        if (encodable)
 -          prev = tail;
 -        else
 -          {
 -            /* Exclude this coding system from SAFE_CODINGS.  */
 -            if (EQ (tail, safe_codings))
 -              {
 -                safe_codings = XCDR (safe_codings);
 -                if (NILP (safe_codings))
 -                  goto done_safe_codings;
 -              }
 -            else
 -              XSETCDR (prev, XCDR (tail));
 -          }
 -      }
 +      charset = CHARSET_FROM_ID (XINT (XCAR (tail)));
 +      if (CHAR_CHARSET_P (c, charset))
 +      break;
      }
 -
 - done_safe_codings:
 -  /* If the above loop was terminated before P reaches PEND, it means
 -     SAFE_CODINGS was set to nil.  If we have not yet found an
 -     non-ASCII single-byte char, check it now.  */
 -  if (! *single_byte_char_found)
 -    while (p < pend)
 -      {
 -      c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
 -      p += len;
 -      if (! ASCII_BYTE_P (c)
 -          && SINGLE_BYTE_CHAR_P (c))
 -        {
 -          *single_byte_char_found = 1;
 -          break;
 -        }
 -      }
 -  return safe_codings;
 +  return (! NILP (tail));
  }
  
 +
 +/* Return a list of coding systems that safely encode the text between
 +   START and END.  If EXCLUDE is non-nil, it is a list of coding
 +   systems not to check.  The returned list doesn't contain any such
 +   coding systems.  In any case, if the text contains only ASCII or is
 +   unibyte, return t.  */
 +
  DEFUN ("find-coding-systems-region-internal",
         Ffind_coding_systems_region_internal,
 -       Sfind_coding_systems_region_internal, 2, 2, 0,
 +       Sfind_coding_systems_region_internal, 2, 3, 0,
         doc: /* Internal use only.  */)
 -     (start, end)
 -     Lisp_Object start, end;
 +     (start, end, exclude)
 +     Lisp_Object start, end, exclude;
  {
 -  Lisp_Object work_table, safe_codings;
 -  int non_ascii_p = 0;
 -  int single_byte_char_found = 0;
 -  const unsigned char *p1, *p1end, *p2, *p2end, *p;
 +  Lisp_Object coding_attrs_list, safe_codings;
 +  EMACS_INT start_byte, end_byte;
 +  const unsigned char *p, *pbeg, *pend;
 +  int c;
 +  Lisp_Object tail, elt;
  
    if (STRINGP (start))
      {
 -      if (!STRING_MULTIBYTE (start))
 +      if (!STRING_MULTIBYTE (start)
 +        || SCHARS (start) == SBYTES (start))
        return Qt;
 -      p1 = SDATA (start), p1end = p1 + SBYTES (start);
 -      p2 = p2end = p1end;
 -      if (SCHARS (start) != SBYTES (start))
 -      non_ascii_p = 1;
 +      start_byte = 0;
 +      end_byte = SBYTES (start);
      }
    else
      {
 -      int from, to, stop;
 -
        CHECK_NUMBER_COERCE_MARKER (start);
        CHECK_NUMBER_COERCE_MARKER (end);
        if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end))
        args_out_of_range (start, end);
        if (NILP (current_buffer->enable_multibyte_characters))
        return Qt;
 -      from = CHAR_TO_BYTE (XINT (start));
 -      to = CHAR_TO_BYTE (XINT (end));
 -      stop = from < GPT_BYTE && GPT_BYTE < to ? GPT_BYTE : to;
 -      p1 = BYTE_POS_ADDR (from), p1end = p1 + (stop - from);
 -      if (stop == to)
 -      p2 = p2end = p1end;
 -      else
 -      p2 = BYTE_POS_ADDR (stop), p2end = p2 + (to - stop);
 -      if (XINT (end) - XINT (start) != to - from)
 -      non_ascii_p = 1;
 -    }
 +      start_byte = CHAR_TO_BYTE (XINT (start));
 +      end_byte = CHAR_TO_BYTE (XINT (end));
 +      if (XINT (end) - XINT (start) == end_byte - start_byte)
 +      return Qt;
  
 -  if (!non_ascii_p)
 -    {
 -      /* We are sure that the text contains no multibyte character.
 -       Check if it contains eight-bit-graphic.  */
 -      p = p1;
 -      for (p = p1; p < p1end && ASCII_BYTE_P (*p); p++);
 -      if (p == p1end)
 +      if (XINT (start) < GPT && XINT (end) > GPT)
        {
 -        for (p = p2; p < p2end && ASCII_BYTE_P (*p); p++);
 -        if (p == p2end)
 -          return Qt;
 +        if ((GPT - XINT (start)) < (XINT (end) - GPT))
 +          move_gap_both (XINT (start), start_byte);
 +        else
 +          move_gap_both (XINT (end), end_byte);
        }
      }
  
 -  /* The text contains non-ASCII characters.  */
 +  coding_attrs_list = Qnil;
 +  for (tail = Vcoding_system_list; CONSP (tail); tail = XCDR (tail))
 +    if (NILP (exclude)
 +      || NILP (Fmemq (XCAR (tail), exclude)))
 +      {
 +      Lisp_Object attrs;
  
 -  work_table = Fmake_char_table (Qchar_coding_system, Qnil);
 -  safe_codings = Fcopy_sequence (XCDR (Vcoding_system_safe_chars));
 +      attrs = AREF (CODING_SYSTEM_SPEC (XCAR (tail)), 0);
 +      if (EQ (XCAR (tail), CODING_ATTR_BASE_NAME (attrs))
 +          && ! EQ (CODING_ATTR_TYPE (attrs), Qundecided))
 +        {
 +          ASET (attrs, coding_attr_trans_tbl,
 +                get_translation_table (attrs, 1, NULL));
 +          coding_attrs_list = Fcons (attrs, coding_attrs_list);
 +        }
 +      }
  
 -  safe_codings = find_safe_codings (p1, p1end, safe_codings, work_table,
 -                                  &single_byte_char_found);
 -  if (p2 < p2end)
 -    safe_codings = find_safe_codings (p2, p2end, safe_codings, work_table,
 -                                    &single_byte_char_found);
 -  if (EQ (safe_codings, XCDR (Vcoding_system_safe_chars)))
 -    safe_codings = Qt;
 +  if (STRINGP (start))
 +    p = pbeg = SDATA (start);
    else
 -    {
 -      /* Turn safe_codings to a list of coding systems... */
 -      Lisp_Object val;
 -
 -      if (single_byte_char_found)
 -      /* ... and append these for eight-bit chars.  */
 -      val = Fcons (Qraw_text,
 -                   Fcons (Qemacs_mule, Fcons (Qno_conversion, Qnil)));
 -      else
 -      /* ... and append generic coding systems.  */
 -      val = Fcopy_sequence (XCAR (Vcoding_system_safe_chars));
 -
 -      for (; CONSP (safe_codings); safe_codings = XCDR (safe_codings))
 -      val = Fcons (XCAR (XCAR (safe_codings)), val);
 -      safe_codings = val;
 -    }
 -
 -  return safe_codings;
 -}
 -
 -
 -/* Search from position POS for such characters that are unencodable
 -   accoding to SAFE_CHARS, and return a list of their positions.  P
 -   points where in the memory the character at POS exists.  Limit the
 -   search at PEND or when Nth unencodable characters are found.
 +    p = pbeg = BYTE_POS_ADDR (start_byte);
 +  pend = p + (end_byte - start_byte);
  
 -   If SAFE_CHARS is a char table, an element for an unencodable
 -   character is nil.
 +  while (p < pend && ASCII_BYTE_P (*p)) p++;
 +  while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--;
  
 -   If SAFE_CHARS is nil, all non-ASCII characters are unencodable.
 -
 -   Otherwise, SAFE_CHARS is t, and only eight-bit-contrl and
 -   eight-bit-graphic characters are unencodable.  */
 -
 -static Lisp_Object
 -unencodable_char_position (safe_chars, pos, p, pend, n)
 -     Lisp_Object safe_chars;
 -     int pos;
 -     unsigned char *p, *pend;
 -     int n;
 -{
 -  Lisp_Object pos_list;
 -
 -  pos_list = Qnil;
    while (p < pend)
      {
 -      int len;
 -      int c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len);
 -
 -      if (c >= 128
 -        && (CHAR_TABLE_P (safe_chars)
 -            ? NILP (CHAR_TABLE_REF (safe_chars, c))
 -            : (NILP (safe_chars) || c < 256)))
 +      if (ASCII_BYTE_P (*p))
 +      p++;
 +      else
        {
 -        pos_list = Fcons (make_number (pos), pos_list);
 -        if (--n <= 0)
 -          break;
 +        c = STRING_CHAR_ADVANCE (p);
 +
 +        charset_map_loaded = 0;
 +        for (tail = coding_attrs_list; CONSP (tail);)
 +          {
 +            elt = XCAR (tail);
 +            if (NILP (elt))
 +              tail = XCDR (tail);
 +            else if (char_encodable_p (c, elt))
 +              tail = XCDR (tail);
 +            else if (CONSP (XCDR (tail)))
 +              {
 +                XSETCAR (tail, XCAR (XCDR (tail)));
 +                XSETCDR (tail, XCDR (XCDR (tail)));
 +              }
 +            else
 +              {
 +                XSETCAR (tail, Qnil);
 +                tail = XCDR (tail);
 +              }
 +          }
 +        if (charset_map_loaded)
 +          {
 +            EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
 +
 +            if (STRINGP (start))
 +              pbeg = SDATA (start);
 +            else
 +              pbeg = BYTE_POS_ADDR (start_byte);
 +            p = pbeg + p_offset;
 +            pend = pbeg + pend_offset;
 +          }
        }
 -      pos++;
 -      p += len;
      }
 -  return Fnreverse (pos_list);
 +
 +  safe_codings = list2 (Qraw_text, Qno_conversion);
 +  for (tail = coding_attrs_list; CONSP (tail); tail = XCDR (tail))
 +    if (! NILP (XCAR (tail)))
 +      safe_codings = Fcons (CODING_ATTR_BASE_NAME (XCAR (tail)), safe_codings);
 +
 +  return safe_codings;
  }
  
  
@@@ -7732,36 -7028,24 +7732,36 @@@ to the string.  */
       Lisp_Object start, end, coding_system, count, string;
  {
    int n;
 -  Lisp_Object safe_chars;
    struct coding_system coding;
 +  Lisp_Object attrs, charset_list, translation_table;
    Lisp_Object positions;
    int from, to;
 -  unsigned char *p, *pend;
 +  const unsigned char *p, *stop, *pend;
 +  int ascii_compatible;
 +
 +  setup_coding_system (Fcheck_coding_system (coding_system), &coding);
 +  attrs = CODING_ID_ATTRS (coding.id);
 +  if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
 +    return Qnil;
 +  ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
 +  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
 +  translation_table = get_translation_table (attrs, 1, NULL);
  
    if (NILP (string))
      {
        validate_region (&start, &end);
        from = XINT (start);
        to = XINT (end);
 -      if (NILP (current_buffer->enable_multibyte_characters))
 +      if (NILP (current_buffer->enable_multibyte_characters)
 +        || (ascii_compatible
 +            && (to - from) == (CHAR_TO_BYTE (to) - (CHAR_TO_BYTE (from)))))
        return Qnil;
        p = CHAR_POS_ADDR (from);
 -      if (to == GPT)
 -      pend = GPT_ADDR;
 +      pend = CHAR_POS_ADDR (to);
 +      if (from < GPT && to >= GPT)
 +      stop = GPT_ADDR;
        else
 -      pend = CHAR_POS_ADDR (to);
 +      stop = pend;
      }
    else
      {
        if (! STRING_MULTIBYTE (string))
        return Qnil;
        p = SDATA (string) + string_char_to_byte (string, from);
 -      pend = SDATA (string) + string_char_to_byte (string, to);
 +      stop = pend = SDATA (string) + string_char_to_byte (string, to);
 +      if (ascii_compatible && (to - from) == (pend - p))
 +      return Qnil;
      }
  
 -  setup_coding_system (Fcheck_coding_system (coding_system), &coding);
 -
    if (NILP (count))
      n = 1;
    else
        n = XINT (count);
      }
  
 -  if (coding.type == coding_type_no_conversion
 -      || coding.type == coding_type_raw_text)
 -    return Qnil;
 +  positions = Qnil;
 +  while (1)
 +    {
 +      int c;
  
 -  if (coding.type == coding_type_undecided)
 -    safe_chars = Qnil;
 -  else
 -    safe_chars = coding_safe_chars (coding_system);
 +      if (ascii_compatible)
 +      while (p < stop && ASCII_BYTE_P (*p))
 +        p++, from++;
 +      if (p >= stop)
 +      {
 +        if (p >= pend)
 +          break;
 +        stop = pend;
 +        p = GAP_END_ADDR;
 +      }
 +
 +      c = STRING_CHAR_ADVANCE (p);
 +      if (! (ASCII_CHAR_P (c) && ascii_compatible)
 +        && ! char_charset (translate_char (translation_table, c),
 +                           charset_list, NULL))
 +      {
 +        positions = Fcons (make_number (from), positions);
 +        n--;
 +        if (n == 0)
 +          break;
 +      }
 +
 +      from++;
 +    }
 +
 +  return (NILP (count) ? Fcar (positions) : Fnreverse (positions));
 +}
 +
 +
 +DEFUN ("check-coding-systems-region", Fcheck_coding_systems_region,
 +       Scheck_coding_systems_region, 3, 3, 0,
 +       doc: /* Check if the region is encodable by coding systems.
 +
 +START and END are buffer positions specifying the region.
 +CODING-SYSTEM-LIST is a list of coding systems to check.
 +
 +The value is an alist ((CODING-SYSTEM POS0 POS1 ...) ...), where
 +CODING-SYSTEM is a member of CODING-SYSTEM-LIst and can't encode the
 +whole region, POS0, POS1, ... are buffer positions where non-encodable
 +characters are found.
 +
 +If all coding systems in CODING-SYSTEM-LIST can encode the region, the
 +value is nil.
 +
 +START may be a string.  In that case, check if the string is
 +encodable, and the value contains indices to the string instead of
 +buffer positions.  END is ignored.  */)
 +     (start, end, coding_system_list)
 +     Lisp_Object start, end, coding_system_list;
 +{
 +  Lisp_Object list;
 +  EMACS_INT start_byte, end_byte;
 +  int pos;
 +  const unsigned char *p, *pbeg, *pend;
 +  int c;
 +  Lisp_Object tail, elt, attrs;
  
 -  if (STRINGP (string)
 -      || from >= GPT || to <= GPT)
 -    positions = unencodable_char_position (safe_chars, from, p, pend, n);
 +  if (STRINGP (start))
 +    {
 +      if (!STRING_MULTIBYTE (start)
 +        && SCHARS (start) != SBYTES (start))
 +      return Qnil;
 +      start_byte = 0;
 +      end_byte = SBYTES (start);
 +      pos = 0;
 +    }
    else
      {
 -      Lisp_Object args[2];
 +      CHECK_NUMBER_COERCE_MARKER (start);
 +      CHECK_NUMBER_COERCE_MARKER (end);
 +      if (XINT (start) < BEG || XINT (end) > Z || XINT (start) > XINT (end))
 +      args_out_of_range (start, end);
 +      if (NILP (current_buffer->enable_multibyte_characters))
 +      return Qnil;
 +      start_byte = CHAR_TO_BYTE (XINT (start));
 +      end_byte = CHAR_TO_BYTE (XINT (end));
 +      if (XINT (end) - XINT (start) == end_byte - start_byte)
 +      return Qt;
 +
 +      if (XINT (start) < GPT && XINT (end) > GPT)
 +      {
 +        if ((GPT - XINT (start)) < (XINT (end) - GPT))
 +          move_gap_both (XINT (start), start_byte);
 +        else
 +          move_gap_both (XINT (end), end_byte);
 +      }
 +      pos = XINT (start);
 +    }
 +
 +  list = Qnil;
 +  for (tail = coding_system_list; CONSP (tail); tail = XCDR (tail))
 +    {
 +      elt = XCAR (tail);
 +      attrs = AREF (CODING_SYSTEM_SPEC (elt), 0);
 +      ASET (attrs, coding_attr_trans_tbl,
 +          get_translation_table (attrs, 1, NULL));
 +      list = Fcons (Fcons (elt, Fcons (attrs, Qnil)), list);
 +    }
 +
 +  if (STRINGP (start))
 +    p = pbeg = SDATA (start);
 +  else
 +    p = pbeg = BYTE_POS_ADDR (start_byte);
 +  pend = p + (end_byte - start_byte);
  
 -      args[0] = unencodable_char_position (safe_chars, from, p, GPT_ADDR, n);
 -      n -= XINT (Flength (args[0]));
 -      if (n <= 0)
 -      positions = args[0];
 +  while (p < pend && ASCII_BYTE_P (*p)) p++, pos++;
 +  while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--;
 +
 +  while (p < pend)
 +    {
 +      if (ASCII_BYTE_P (*p))
 +      p++;
        else
        {
 -        args[1] = unencodable_char_position (safe_chars, GPT, GAP_END_ADDR,
 -                                             pend, n);
 -        positions = Fappend (2, args);
 +        c = STRING_CHAR_ADVANCE (p);
 +
 +        charset_map_loaded = 0;
 +        for (tail = list; CONSP (tail); tail = XCDR (tail))
 +          {
 +            elt = XCDR (XCAR (tail));
 +            if (! char_encodable_p (c, XCAR (elt)))
 +              XSETCDR (elt, Fcons (make_number (pos), XCDR (elt)));
 +          }
 +        if (charset_map_loaded)
 +          {
 +            EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
 +
 +            if (STRINGP (start))
 +              pbeg = SDATA (start);
 +            else
 +              pbeg = BYTE_POS_ADDR (start_byte);
 +            p = pbeg + p_offset;
 +            pend = pbeg + pend_offset;
 +          }
        }
 +      pos++;
 +    }
 +
 +  tail = list;
 +  list = Qnil;
 +  for (; CONSP (tail); tail = XCDR (tail))
 +    {
 +      elt = XCAR (tail);
 +      if (CONSP (XCDR (XCDR (elt))))
 +      list = Fcons (Fcons (XCAR (elt), Fnreverse (XCDR (XCDR (elt)))),
 +                    list);
      }
  
 -  return  (NILP (count) ? Fcar (positions) : positions);
 +  return list;
  }
  
  
  Lisp_Object
 -code_convert_region1 (start, end, coding_system, encodep)
 -     Lisp_Object start, end, coding_system;
 -     int encodep;
 +code_convert_region (start, end, coding_system, dst_object, encodep, norecord)
 +     Lisp_Object start, end, coding_system, dst_object;
 +     int encodep, norecord;
  {
    struct coding_system coding;
 -  int from, to;
 +  EMACS_INT from, from_byte, to, to_byte;
 +  Lisp_Object src_object;
  
    CHECK_NUMBER_COERCE_MARKER (start);
    CHECK_NUMBER_COERCE_MARKER (end);
 -  CHECK_SYMBOL (coding_system);
 +  if (NILP (coding_system))
 +    coding_system = Qno_conversion;
 +  else
 +    CHECK_CODING_SYSTEM (coding_system);
 +  src_object = Fcurrent_buffer ();
 +  if (NILP (dst_object))
 +    dst_object = src_object;
 +  else if (! EQ (dst_object, Qt))
 +    CHECK_BUFFER (dst_object);
  
    validate_region (&start, &end);
    from = XFASTINT (start);
 +  from_byte = CHAR_TO_BYTE (from);
    to = XFASTINT (end);
 +  to_byte = CHAR_TO_BYTE (to);
  
 -  if (NILP (coding_system))
 -    return make_number (to - from);
 -
 -  if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
 -    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));
 -
 +  setup_coding_system (coding_system, &coding);
    coding.mode |= CODING_MODE_LAST_BLOCK;
 -  coding.src_multibyte = coding.dst_multibyte
 -    = !NILP (current_buffer->enable_multibyte_characters);
 -  code_convert_region (from, CHAR_TO_BYTE (from), to, CHAR_TO_BYTE (to),
 -                     &coding, encodep, 1);
 -  Vlast_coding_system_used = coding.symbol;
 -  return make_number (coding.produced_char);
 +
 +  if (encodep)
 +    encode_coding_object (&coding, src_object, from, from_byte, to, to_byte,
 +                        dst_object);
 +  else
 +    decode_coding_object (&coding, src_object, from, from_byte, to, to_byte,
 +                        dst_object);
 +  if (! norecord)
 +    Vlast_coding_system_used = CODING_ID_NAME (coding.id);
 +
 +  return (BUFFERP (dst_object)
 +        ? make_number (coding.produced_char)
 +        : coding.dst_object);
  }
  
 +
  DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region,
 -       3, 3, "r\nzCoding system: ",
 +       3, 4, "r\nzCoding system: ",
         doc: /* Decode the current region from the specified coding system.
 -When called from a program, takes three arguments:
 -START, END, and CODING-SYSTEM.  START and END are buffer positions.
 +When called from a program, takes four arguments:
 +      START, END, CODING-SYSTEM, and DESTINATION.
 +START and END are buffer positions.
 +
 +Optional 4th arguments DESTINATION specifies where the decoded text goes.
 +If nil, the region between START and END is replace by the decoded text.
 +If buffer, the decoded text is inserted in the buffer.
 +If t, the decoded text is returned.
 +
  This function sets `last-coding-system-used' to the precise coding system
  used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
  not fully specified.)
  It returns the length of the decoded text.  */)
 -     (start, end, coding_system)
 -     Lisp_Object start, end, coding_system;
 +     (start, end, coding_system, destination)
 +     Lisp_Object start, end, coding_system, destination;
  {
 -  return code_convert_region1 (start, end, coding_system, 0);
 +  return code_convert_region (start, end, coding_system, destination, 0, 0);
  }
  
  DEFUN ("encode-coding-region", Fencode_coding_region, Sencode_coding_region,
 -       3, 3, "r\nzCoding system: ",
 -       doc: /* Encode the current region into the specified coding system.
 +       3, 4, "r\nzCoding system: ",
 +       doc: /* Encode the current region by specified coding system.
  When called from a program, takes three arguments:
  START, END, and CODING-SYSTEM.  START and END are buffer positions.
 +
 +Optional 4th arguments DESTINATION specifies where the encoded text goes.
 +If nil, the region between START and END is replace by the encoded text.
 +If buffer, the encoded text is inserted in the buffer.
 +If t, the encoded text is returned.
 +
  This function sets `last-coding-system-used' to the precise coding system
  used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
  not fully specified.)
  It returns the length of the encoded text.  */)
 -     (start, end, coding_system)
 -     Lisp_Object start, end, coding_system;
 +  (start, end, coding_system, destination)
 +     Lisp_Object start, end, coding_system, destination;
  {
 -  return code_convert_region1 (start, end, coding_system, 1);
 +  return code_convert_region (start, end, coding_system, destination, 1, 0);
  }
  
  Lisp_Object
 -code_convert_string1 (string, coding_system, nocopy, encodep)
 -     Lisp_Object string, coding_system, nocopy;
 -     int encodep;
 +code_convert_string (string, coding_system, dst_object,
 +                   encodep, nocopy, norecord)
 +     Lisp_Object string, coding_system, dst_object;
 +     int encodep, nocopy, norecord;
  {
    struct coding_system coding;
 +  EMACS_INT chars, bytes;
  
    CHECK_STRING (string);
 -  CHECK_SYMBOL (coding_system);
 -
    if (NILP (coding_system))
 -    return (NILP (nocopy) ? Fcopy_sequence (string) : string);
 +    {
 +      if (! norecord)
 +      Vlast_coding_system_used = Qno_conversion;
 +      if (NILP (dst_object))
 +      return (nocopy ? Fcopy_sequence (string) : string);
 +    }
  
 -  if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
 -    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));
 +  if (NILP (coding_system))
 +    coding_system = Qno_conversion;
 +  else
 +    CHECK_CODING_SYSTEM (coding_system);
 +  if (NILP (dst_object))
 +    dst_object = Qt;
 +  else if (! EQ (dst_object, Qt))
 +    CHECK_BUFFER (dst_object);
  
 +  setup_coding_system (coding_system, &coding);
    coding.mode |= CODING_MODE_LAST_BLOCK;
 -  string = (encodep
 -          ? encode_coding_string (string, &coding, !NILP (nocopy))
 -          : decode_coding_string (string, &coding, !NILP (nocopy)));
 -  Vlast_coding_system_used = coding.symbol;
 -
 -  return string;
 -}
 +  chars = SCHARS (string);
 +  bytes = SBYTES (string);
 +  if (encodep)
 +    encode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object);
 +  else
 +    decode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object);
 +  if (! norecord)
 +    Vlast_coding_system_used = CODING_ID_NAME (coding.id);
  
 -DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string,
 -       2, 3, 0,
 -       doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result.
 -Optional arg NOCOPY non-nil means it is OK to return STRING itself
 -if the decoding operation is trivial.
 -This function sets `last-coding-system-used' to the precise coding system
 -used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
 -not fully specified.)  */)
 -     (string, coding_system, nocopy)
 -     Lisp_Object string, coding_system, nocopy;
 -{
 -  return code_convert_string1 (string, coding_system, nocopy, 0);
 +  return (BUFFERP (dst_object)
 +        ? make_number (coding.produced_char)
 +        : coding.dst_object);
  }
  
 -DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string,
 -       2, 3, 0,
 -       doc: /* Encode STRING to CODING-SYSTEM, and return the result.
 -Optional arg NOCOPY non-nil means it is OK to return STRING itself
 -if the encoding operation is trivial.
 -This function sets `last-coding-system-used' to the precise coding system
 -used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
 -not fully specified.)  */)
 -     (string, coding_system, nocopy)
 -     Lisp_Object string, coding_system, nocopy;
 -{
 -  return code_convert_string1 (string, coding_system, nocopy, 1);
 -}
  
  /* Encode or decode STRING according to CODING_SYSTEM.
     Do not set Vlast_coding_system_used.
@@@ -8089,52 -7230,23 +8089,52 @@@ code_convert_string_norecord (string, c
       Lisp_Object string, coding_system;
       int encodep;
  {
 -  struct coding_system coding;
 +  return code_convert_string (string, coding_system, Qt, encodep, 0, 1);
 +}
 +
 +
 +DEFUN ("decode-coding-string", Fdecode_coding_string, Sdecode_coding_string,
 +       2, 4, 0,
 +       doc: /* Decode STRING which is encoded in CODING-SYSTEM, and return the result.
 +
 +Optional third arg NOCOPY non-nil means it is OK to return STRING itself
 +if the decoding operation is trivial.
 +
 +Optional fourth arg BUFFER non-nil meant that the decoded text is
 +inserted in BUFFER instead of returned as a string.  In this case,
 +the return value is BUFFER.
 +
 +This function sets `last-coding-system-used' to the precise coding system
 +used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
 +not fully specified.  */)
 +  (string, coding_system, nocopy, buffer)
 +     Lisp_Object string, coding_system, nocopy, buffer;
 +{
 +  return code_convert_string (string, coding_system, buffer,
 +                            0, ! NILP (nocopy), 0);
 +}
  
 -  CHECK_STRING (string);
 -  CHECK_SYMBOL (coding_system);
 +DEFUN ("encode-coding-string", Fencode_coding_string, Sencode_coding_string,
 +       2, 4, 0,
 +       doc: /* Encode STRING to CODING-SYSTEM, and return the result.
  
 -  if (NILP (coding_system))
 -    return string;
 +Optional third arg NOCOPY non-nil means it is OK to return STRING
 +itself if the encoding operation is trivial.
  
 -  if (setup_coding_system (Fcheck_coding_system (coding_system), &coding) < 0)
 -    error ("Invalid coding system: %s", SDATA (SYMBOL_NAME (coding_system)));
 +Optional fourth arg BUFFER non-nil meant that the encoded text is
 +inserted in BUFFER instead of returned as a string.  In this case,
 +the return value is BUFFER.
  
 -  coding.composing = COMPOSITION_DISABLED;
 -  coding.mode |= CODING_MODE_LAST_BLOCK;
 -  return (encodep
 -        ? encode_coding_string (string, &coding, 1)
 -        : decode_coding_string (string, &coding, 1));
 +This function sets `last-coding-system-used' to the precise coding system
 +used (which may be different from CODING-SYSTEM if CODING-SYSTEM is
 +not fully specified.)  */)
 +     (string, coding_system, nocopy, buffer)
 +     Lisp_Object string, coding_system, nocopy, buffer;
 +{
 +  return code_convert_string (string, coding_system, buffer,
 +                            1, ! NILP (nocopy), 1);
  }
 +
  \f
  DEFUN ("decode-sjis-char", Fdecode_sjis_char, Sdecode_sjis_char, 1, 1, 0,
         doc: /* Decode a Japanese character which has CODE in shift_jis encoding.
@@@ -8142,75 -7254,60 +8142,75 @@@ Return the corresponding character.  */
       (code)
       Lisp_Object code;
  {
 -  unsigned char c1, c2, s1, s2;
 -  Lisp_Object val;
 +  Lisp_Object spec, attrs, val;
 +  struct charset *charset_roman, *charset_kanji, *charset_kana, *charset;
 +  int c;
 +
 +  CHECK_NATNUM (code);
 +  c = XFASTINT (code);
 +  CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);
 +  attrs = AREF (spec, 0);
 +
 +  if (ASCII_BYTE_P (c)
 +      && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
 +    return code;
  
 -  CHECK_NUMBER (code);
 -  s1 = (XFASTINT (code)) >> 8, s2 = (XFASTINT (code)) & 0xFF;
 -  if (s1 == 0)
 +  val = CODING_ATTR_CHARSET_LIST (attrs);
 +  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val)));
 +
 +  if (c <= 0x7F)
 +    charset = charset_roman;
 +  else if (c >= 0xA0 && c < 0xDF)
      {
 -      if (s2 < 0x80)
 -      XSETFASTINT (val, s2);
 -      else if (s2 >= 0xA0 || s2 <= 0xDF)
 -      XSETFASTINT (val, MAKE_CHAR (charset_katakana_jisx0201, s2, 0));
 -      else
 -      error ("Invalid Shift JIS code: %x", XFASTINT (code));
 +      charset = charset_kana;
 +      c -= 0x80;
      }
    else
      {
 -      if ((s1 < 0x80 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF)
 -        || (s2 < 0x40 || s2 == 0x7F || s2 > 0xFC))
 -      error ("Invalid Shift JIS code: %x", XFASTINT (code));
 -      DECODE_SJIS (s1, s2, c1, c2);
 -      XSETFASTINT (val, MAKE_CHAR (charset_jisx0208, c1, c2));
 +      int s1 = c >> 8, s2 = c & 0xFF;
 +
 +      if (s1 < 0x81 || (s1 > 0x9F && s1 < 0xE0) || s1 > 0xEF
 +        || s2 < 0x40 || s2 == 0x7F || s2 > 0xFC)
 +      error ("Invalid code: %d", code);
 +      SJIS_TO_JIS (c);
 +      charset = charset_kanji;
      }
 -  return val;
 +  c = DECODE_CHAR (charset, c);
 +  if (c < 0)
 +    error ("Invalid code: %d", code);
 +  return make_number (c);
  }
  
 +
  DEFUN ("encode-sjis-char", Fencode_sjis_char, Sencode_sjis_char, 1, 1, 0,
         doc: /* Encode a Japanese character CH to shift_jis encoding.
  Return the corresponding code in SJIS.  */)
       (ch)
 -     Lisp_Object ch;
 +    Lisp_Object ch;
  {
 -  int charset, c1, c2, s1, s2;
 -  Lisp_Object val;
 +  Lisp_Object spec, attrs, charset_list;
 +  int c;
 +  struct charset *charset;
 +  unsigned code;
  
 -  CHECK_NUMBER (ch);
 -  SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);
 -  if (charset == CHARSET_ASCII)
 -    {
 -      val = ch;
 -    }
 -  else if (charset == charset_jisx0208
 -         && c1 > 0x20 && c1 < 0x7F && c2 > 0x20 && c2 < 0x7F)
 -    {
 -      ENCODE_SJIS (c1, c2, s1, s2);
 -      XSETFASTINT (val, (s1 << 8) | s2);
 -    }
 -  else if (charset == charset_katakana_jisx0201
 -         && c1 > 0x20 && c2 < 0xE0)
 -    {
 -      XSETFASTINT (val, c1 | 0x80);
 -    }
 -  else
 -    error ("Can't encode to shift_jis: %d", XFASTINT (ch));
 -  return val;
 +  CHECK_CHARACTER (ch);
 +  c = XFASTINT (ch);
 +  CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);
 +  attrs = AREF (spec, 0);
 +
 +  if (ASCII_CHAR_P (c)
 +      && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
 +    return ch;
 +
 +  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
 +  charset = char_charset (c, charset_list, &code);
 +  if (code == CHARSET_INVALID_CODE (charset))
 +    error ("Can't encode by shift_jis encoding: %d", c);
 +  JIS_TO_SJIS (code);
 +
 +  return make_number (code);
  }
  
  DEFUN ("decode-big5-char", Fdecode_big5_char, Sdecode_big5_char, 1, 1, 0,
@@@ -8219,37 -7316,27 +8219,37 @@@ Return the corresponding character.  */
       (code)
       Lisp_Object code;
  {
 -  int charset;
 -  unsigned char b1, b2, c1, c2;
 -  Lisp_Object val;
 +  Lisp_Object spec, attrs, val;
 +  struct charset *charset_roman, *charset_big5, *charset;
 +  int c;
  
 -  CHECK_NUMBER (code);
 -  b1 = (XFASTINT (code)) >> 8, b2 = (XFASTINT (code)) & 0xFF;
 -  if (b1 == 0)
 -    {
 -      if (b2 >= 0x80)
 -      error ("Invalid BIG5 code: %x", XFASTINT (code));
 -      val = code;
 -    }
 +  CHECK_NATNUM (code);
 +  c = XFASTINT (code);
 +  CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);
 +  attrs = AREF (spec, 0);
 +
 +  if (ASCII_BYTE_P (c)
 +      && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
 +    return code;
 +
 +  val = CODING_ATTR_CHARSET_LIST (attrs);
 +  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
 +  charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
 +
 +  if (c <= 0x7F)
 +    charset = charset_roman;
    else
      {
 -      if ((b1 < 0xA1 || b1 > 0xFE)
 -        || (b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE))
 -      error ("Invalid BIG5 code: %x", XFASTINT (code));
 -      DECODE_BIG5 (b1, b2, charset, c1, c2);
 -      XSETFASTINT (val, MAKE_CHAR (charset, c1, c2));
 +      int b1 = c >> 8, b2 = c & 0x7F;
 +      if (b1 < 0xA1 || b1 > 0xFE
 +        || b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE)
 +      error ("Invalid code: %d", code);
 +      charset = charset_big5;
      }
 -  return val;
 +  c = DECODE_CHAR (charset, (unsigned )c);
 +  if (c < 0)
 +    error ("Invalid code: %d", code);
 +  return make_number (c);
  }
  
  DEFUN ("encode-big5-char", Fencode_big5_char, Sencode_big5_char, 1, 1, 0,
@@@ -8258,50 -7345,48 +8258,50 @@@ Return the corresponding character cod
       (ch)
       Lisp_Object ch;
  {
 -  int charset, c1, c2, b1, b2;
 -  Lisp_Object val;
 -
 -  CHECK_NUMBER (ch);
 -  SPLIT_CHAR (XFASTINT (ch), charset, c1, c2);
 -  if (charset == CHARSET_ASCII)
 -    {
 -      val = ch;
 -    }
 -  else if ((charset == charset_big5_1
 -          && (XFASTINT (ch) >= 0x250a1 && XFASTINT (ch) <= 0x271ec))
 -         || (charset == charset_big5_2
 -             && XFASTINT (ch) >= 0x290a1 && XFASTINT (ch) <= 0x2bdb2))
 -    {
 -      ENCODE_BIG5 (charset, c1, c2, b1, b2);
 -      XSETFASTINT (val, (b1 << 8) | b2);
 -    }
 -  else
 -    error ("Can't encode to Big5: %d", XFASTINT (ch));
 -  return val;
 +  Lisp_Object spec, attrs, charset_list;
 +  struct charset *charset;
 +  int c;
 +  unsigned code;
 +
 +  CHECK_CHARACTER (ch);
 +  c = XFASTINT (ch);
 +  CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);
 +  attrs = AREF (spec, 0);
 +  if (ASCII_CHAR_P (c)
 +      && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
 +    return ch;
 +
 +  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
 +  charset = char_charset (c, charset_list, &code);
 +  if (code == CHARSET_INVALID_CODE (charset))
 +    error ("Can't encode by Big5 encoding: %d", c);
 +
 +  return make_number (code);
  }
 +
  \f
 -DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_internal,
 +DEFUN ("set-terminal-coding-system-internal",
 +       Fset_terminal_coding_system_internal,
         Sset_terminal_coding_system_internal, 1, 1, 0,
         doc: /* Internal use only.  */)
       (coding_system)
       Lisp_Object coding_system;
  {
    CHECK_SYMBOL (coding_system);
 -  setup_coding_system (Fcheck_coding_system (coding_system), &terminal_coding);
 +  setup_coding_system (Fcheck_coding_system (coding_system),
 +                      &terminal_coding);
 +
    /* We had better not send unsafe characters to terminal.  */
 -  terminal_coding.mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;
 -  /* Character composition should be disabled.  */
 -  terminal_coding.composing = COMPOSITION_DISABLED;
 -  /* Error notification should be suppressed.  */
 -  terminal_coding.suppress_error = 1;
 +  terminal_coding.mode |= CODING_MODE_SAFE_ENCODING;
 +  /* Characer composition should be disabled.  */
 +  terminal_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
    terminal_coding.src_multibyte = 1;
    terminal_coding.dst_multibyte = 0;
    return Qnil;
  }
  
 -DEFUN ("set-safe-terminal-coding-system-internal", Fset_safe_terminal_coding_system_internal,
 +DEFUN ("set-safe-terminal-coding-system-internal",
 +       Fset_safe_terminal_coding_system_internal,
         Sset_safe_terminal_coding_system_internal, 1, 1, 0,
         doc: /* Internal use only.  */)
       (coding_system)
    CHECK_SYMBOL (coding_system);
    setup_coding_system (Fcheck_coding_system (coding_system),
                       &safe_terminal_coding);
 -  /* Character composition should be disabled.  */
 -  safe_terminal_coding.composing = COMPOSITION_DISABLED;
 -  /* Error notification should be suppressed.  */
 -  safe_terminal_coding.suppress_error = 1;
 +  /* Characer composition should be disabled.  */
 +  safe_terminal_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
    safe_terminal_coding.src_multibyte = 1;
    safe_terminal_coding.dst_multibyte = 0;
    return Qnil;
  }
  
 -DEFUN ("terminal-coding-system", Fterminal_coding_system,
 -       Sterminal_coding_system, 0, 0, 0,
 +DEFUN ("terminal-coding-system",
 +       Fterminal_coding_system, Sterminal_coding_system, 0, 0, 0,
         doc: /* Return coding system specified for terminal output.  */)
       ()
  {
 -  return terminal_coding.symbol;
 +  Lisp_Object coding_system;
 +
 +  coding_system = CODING_ID_NAME (terminal_coding.id);
 +  /* For backward compatibility, return nil if it is `undecided'. */
 +  return (! EQ (coding_system, Qundecided) ? coding_system : Qnil);
  }
  
 -DEFUN ("set-keyboard-coding-system-internal", Fset_keyboard_coding_system_internal,
 +DEFUN ("set-keyboard-coding-system-internal",
 +       Fset_keyboard_coding_system_internal,
         Sset_keyboard_coding_system_internal, 1, 1, 0,
         doc: /* Internal use only.  */)
       (coding_system)
       Lisp_Object coding_system;
  {
    CHECK_SYMBOL (coding_system);
 -  setup_coding_system (Fcheck_coding_system (coding_system), &keyboard_coding);
 -  /* Character composition should be disabled.  */
 -  keyboard_coding.composing = COMPOSITION_DISABLED;
 +  setup_coding_system (Fcheck_coding_system (coding_system),
 +                     &keyboard_coding);
 +  /* Characer composition should be disabled.  */
 +  keyboard_coding.common_flags &= ~CODING_ANNOTATE_COMPOSITION_MASK;
    return Qnil;
  }
  
 -DEFUN ("keyboard-coding-system", Fkeyboard_coding_system,
 -       Skeyboard_coding_system, 0, 0, 0,
 +DEFUN ("keyboard-coding-system",
 +       Fkeyboard_coding_system, Skeyboard_coding_system, 0, 0, 0,
         doc: /* Return coding system specified for decoding keyboard input.  */)
       ()
  {
 -  return keyboard_coding.symbol;
 +  return CODING_ID_NAME (keyboard_coding.id);
  }
  
  \f
@@@ -8366,896 -7447,205 +8366,896 @@@ The first argument OPERATION specifies 
    For process I/O, `call-process', `call-process-region', or `start-process'.
    For network I/O, `open-network-stream'.
  
 -The remaining arguments should be the same arguments that were passed
 -to the primitive.  Depending on which primitive, one of those arguments
 -is selected as the TARGET.  For example, if OPERATION does file I/O,
 -whichever argument specifies the file name is TARGET.
 +The remaining arguments should be the same arguments that were passed
 +to the primitive.  Depending on which primitive, one of those arguments
 +is selected as the TARGET.  For example, if OPERATION does file I/O,
 +whichever argument specifies the file name is TARGET.
 +
 +TARGET has a meaning which depends on OPERATION:
 +  For file I/O, TARGET is a file name (except for the special case below).
 +  For process I/O, TARGET is a process name.
 +  For network I/O, TARGET is a service name or a port number
 +
 +This function looks up what specified for TARGET in,
 +`file-coding-system-alist', `process-coding-system-alist',
 +or `network-coding-system-alist' depending on OPERATION.
 +They may specify a coding system, a cons of coding systems,
 +or a function symbol to call.
 +In the last case, we call the function with one argument,
 +which is a list of all the arguments given to this function.
 +
 +If OPERATION is `insert-file-contents', the argument corresponding to
 +TARGET may be a cons (FILENAME . BUFFER).  In that case, FILENAME is a
 +file name to look up, and BUFFER is a buffer that contains the file's
 +contents (not yet decoded).  If `file-coding-system-alist' specifies a
 +function to call for FILENAME, that function should examine the
 +contents of BUFFER instead of reading the file.
 +
 +usage: (find-operation-coding-system OPERATION ARGUMENTS ...)  */)
 +     (nargs, args)
 +     int nargs;
 +     Lisp_Object *args;
 +{
 +  Lisp_Object operation, target_idx, target, val;
 +  register Lisp_Object chain;
 +
 +  if (nargs < 2)
 +    error ("Too few arguments");
 +  operation = args[0];
 +  if (!SYMBOLP (operation)
 +      || !INTEGERP (target_idx = Fget (operation, Qtarget_idx)))
 +    error ("Invalid first arguement");
 +  if (nargs < 1 + XINT (target_idx))
 +    error ("Too few arguments for operation: %s",
 +         SDATA (SYMBOL_NAME (operation)));
 +  target = args[XINT (target_idx) + 1];
 +  if (!(STRINGP (target)
 +      || (EQ (operation, Qinsert_file_contents) && CONSP (target)
 +          && STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))
 +      || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
 +    error ("Invalid %dth argument", XINT (target_idx) + 1);
 +  if (CONSP (target))
 +    target = XCAR (target);
 +
 +  chain = ((EQ (operation, Qinsert_file_contents)
 +          || EQ (operation, Qwrite_region))
 +         ? Vfile_coding_system_alist
 +         : (EQ (operation, Qopen_network_stream)
 +            ? Vnetwork_coding_system_alist
 +            : Vprocess_coding_system_alist));
 +  if (NILP (chain))
 +    return Qnil;
 +
 +  for (; CONSP (chain); chain = XCDR (chain))
 +    {
 +      Lisp_Object elt;
 +
 +      elt = XCAR (chain);
 +      if (CONSP (elt)
 +        && ((STRINGP (target)
 +             && STRINGP (XCAR (elt))
 +             && fast_string_match (XCAR (elt), target) >= 0)
 +            || (INTEGERP (target) && EQ (target, XCAR (elt)))))
 +      {
 +        val = XCDR (elt);
 +        /* Here, if VAL is both a valid coding system and a valid
 +             function symbol, we return VAL as a coding system.  */
 +        if (CONSP (val))
 +          return val;
 +        if (! SYMBOLP (val))
 +          return Qnil;
 +        if (! NILP (Fcoding_system_p (val)))
 +          return Fcons (val, val);
 +        if (! NILP (Ffboundp (val)))
 +          {
 +            /* We use call1 rather than safe_call1
 +               so as to get bug reports about functions called here
 +               which don't handle the current interface.  */
 +            val = call1 (val, Flist (nargs, args));
 +            if (CONSP (val))
 +              return val;
 +            if (SYMBOLP (val) && ! NILP (Fcoding_system_p (val)))
 +              return Fcons (val, val);
 +          }
 +        return Qnil;
 +      }
 +    }
 +  return Qnil;
 +}
 +
 +DEFUN ("set-coding-system-priority", Fset_coding_system_priority,
 +       Sset_coding_system_priority, 0, MANY, 0,
 +       doc: /* Assign higher priority to the coding systems given as arguments.
 +If multiple coding systems belongs to the same category,
 +all but the first one are ignored.
 +
 +usage: (set-coding-system-priority ...)  */)
 +     (nargs, args)
 +     int nargs;
 +     Lisp_Object *args;
 +{
 +  int i, j;
 +  int changed[coding_category_max];
 +  enum coding_category priorities[coding_category_max];
 +
 +  bzero (changed, sizeof changed);
 +
 +  for (i = j = 0; i < nargs; i++)
 +    {
 +      enum coding_category category;
 +      Lisp_Object spec, attrs;
 +
 +      CHECK_CODING_SYSTEM_GET_SPEC (args[i], spec);
 +      attrs = AREF (spec, 0);
 +      category = XINT (CODING_ATTR_CATEGORY (attrs));
 +      if (changed[category])
 +      /* Ignore this coding system because a coding system of the
 +         same category already had a higher priority.  */
 +      continue;
 +      changed[category] = 1;
 +      priorities[j++] = category;
 +      if (coding_categories[category].id >= 0
 +        && ! EQ (args[i], CODING_ID_NAME (coding_categories[category].id)))
 +      setup_coding_system (args[i], &coding_categories[category]);
 +      Fset (AREF (Vcoding_category_table, category), args[i]);
 +    }
 +
 +  /* Now we have decided top J priorities.  Reflect the order of the
 +     original priorities to the remaining priorities.  */
 +
 +  for (i = j, j = 0; i < coding_category_max; i++, j++)
 +    {
 +      while (j < coding_category_max
 +           && changed[coding_priorities[j]])
 +      j++;
 +      if (j == coding_category_max)
 +      abort ();
 +      priorities[i] = coding_priorities[j];
 +    }
 +
 +  bcopy (priorities, coding_priorities, sizeof priorities);
 +
 +  /* Update `coding-category-list'.  */
 +  Vcoding_category_list = Qnil;
 +  for (i = coding_category_max - 1; i >= 0; i--)
 +    Vcoding_category_list
 +      = Fcons (AREF (Vcoding_category_table, priorities[i]),
 +             Vcoding_category_list);
 +
 +  return Qnil;
 +}
 +
 +DEFUN ("coding-system-priority-list", Fcoding_system_priority_list,
 +       Scoding_system_priority_list, 0, 1, 0,
 +       doc: /* Return a list of coding systems ordered by their priorities.
 +HIGHESTP non-nil means just return the highest priority one.  */)
 +     (highestp)
 +     Lisp_Object highestp;
 +{
 +  int i;
 +  Lisp_Object val;
 +
 +  for (i = 0, val = Qnil; i < coding_category_max; i++)
 +    {
 +      enum coding_category category = coding_priorities[i];
 +      int id = coding_categories[category].id;
 +      Lisp_Object attrs;
 +
 +      if (id < 0)
 +      continue;
 +      attrs = CODING_ID_ATTRS (id);
 +      if (! NILP (highestp))
 +      return CODING_ATTR_BASE_NAME (attrs);
 +      val = Fcons (CODING_ATTR_BASE_NAME (attrs), val);
 +    }
 +  return Fnreverse (val);
 +}
 +
 +static char *suffixes[] = { "-unix", "-dos", "-mac" };
 +
 +static Lisp_Object
 +make_subsidiaries (base)
 +     Lisp_Object base;
 +{
 +  Lisp_Object subsidiaries;
 +  int base_name_len = SBYTES (SYMBOL_NAME (base));
 +  char *buf = (char *) alloca (base_name_len + 6);
 +  int i;
 +
 +  bcopy (SDATA (SYMBOL_NAME (base)), buf, base_name_len);
 +  subsidiaries = Fmake_vector (make_number (3), Qnil);
 +  for (i = 0; i < 3; i++)
 +    {
 +      bcopy (suffixes[i], buf + base_name_len, strlen (suffixes[i]) + 1);
 +      ASET (subsidiaries, i, intern (buf));
 +    }
 +  return subsidiaries;
 +}
 +
 +
 +DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal,
 +       Sdefine_coding_system_internal, coding_arg_max, MANY, 0,
 +       doc: /* For internal use only.
 +usage: (define-coding-system-internal ...)  */)
 +     (nargs, args)
 +     int nargs;
 +     Lisp_Object *args;
 +{
 +  Lisp_Object name;
 +  Lisp_Object spec_vec;               /* [ ATTRS ALIASE EOL_TYPE ] */
 +  Lisp_Object attrs;          /* Vector of attributes.  */
 +  Lisp_Object eol_type;
 +  Lisp_Object aliases;
 +  Lisp_Object coding_type, charset_list, safe_charsets;
 +  enum coding_category category;
 +  Lisp_Object tail, val;
 +  int max_charset_id = 0;
 +  int i;
 +
 +  if (nargs < coding_arg_max)
 +    goto short_args;
 +
 +  attrs = Fmake_vector (make_number (coding_attr_last_index), Qnil);
 +
 +  name = args[coding_arg_name];
 +  CHECK_SYMBOL (name);
 +  CODING_ATTR_BASE_NAME (attrs) = name;
 +
 +  val = args[coding_arg_mnemonic];
 +  if (! STRINGP (val))
 +    CHECK_CHARACTER (val);
 +  CODING_ATTR_MNEMONIC (attrs) = val;
 +
 +  coding_type = args[coding_arg_coding_type];
 +  CHECK_SYMBOL (coding_type);
 +  CODING_ATTR_TYPE (attrs) = coding_type;
 +
 +  charset_list = args[coding_arg_charset_list];
 +  if (SYMBOLP (charset_list))
 +    {
 +      if (EQ (charset_list, Qiso_2022))
 +      {
 +        if (! EQ (coding_type, Qiso_2022))
 +          error ("Invalid charset-list");
 +        charset_list = Viso_2022_charset_list;
 +      }
 +      else if (EQ (charset_list, Qemacs_mule))
 +      {
 +        if (! EQ (coding_type, Qemacs_mule))
 +          error ("Invalid charset-list");
 +        charset_list = Vemacs_mule_charset_list;
 +      }
 +      for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
 +      if (max_charset_id < XFASTINT (XCAR (tail)))
 +        max_charset_id = XFASTINT (XCAR (tail));
 +    }
 +  else
 +    {
 +      charset_list = Fcopy_sequence (charset_list);
 +      for (tail = charset_list; !NILP (tail); tail = Fcdr (tail))
 +      {
 +        struct charset *charset;
 +
 +        val = Fcar (tail);
 +        CHECK_CHARSET_GET_CHARSET (val, charset);
 +        if (EQ (coding_type, Qiso_2022)
 +            ? CHARSET_ISO_FINAL (charset) < 0
 +            : EQ (coding_type, Qemacs_mule)
 +            ? CHARSET_EMACS_MULE_ID (charset) < 0
 +            : 0)
 +          error ("Can't handle charset `%s'",
 +                 SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 +
 +        XSETCAR (tail, make_number (charset->id));
 +        if (max_charset_id < charset->id)
 +          max_charset_id = charset->id;
 +      }
 +    }
 +  CODING_ATTR_CHARSET_LIST (attrs) = charset_list;
 +
 +  safe_charsets = Fmake_string (make_number (max_charset_id + 1),
 +                              make_number (255));
 +  for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
 +    SSET (safe_charsets, XFASTINT (XCAR (tail)), 0);
 +  CODING_ATTR_SAFE_CHARSETS (attrs) = safe_charsets;
 +
 +  CODING_ATTR_ASCII_COMPAT (attrs) = args[coding_arg_ascii_compatible_p];
 +
 +  val = args[coding_arg_decode_translation_table];
 +  if (! CHAR_TABLE_P (val) && ! CONSP (val))
 +    CHECK_SYMBOL (val);
 +  CODING_ATTR_DECODE_TBL (attrs) = val;
 +
 +  val = args[coding_arg_encode_translation_table];
 +  if (! CHAR_TABLE_P (val) && ! CONSP (val))
 +    CHECK_SYMBOL (val);
 +  CODING_ATTR_ENCODE_TBL (attrs) = val;
 +
 +  val = args[coding_arg_post_read_conversion];
 +  CHECK_SYMBOL (val);
 +  CODING_ATTR_POST_READ (attrs) = val;
 +
 +  val = args[coding_arg_pre_write_conversion];
 +  CHECK_SYMBOL (val);
 +  CODING_ATTR_PRE_WRITE (attrs) = val;
 +
 +  val = args[coding_arg_default_char];
 +  if (NILP (val))
 +    CODING_ATTR_DEFAULT_CHAR (attrs) = make_number (' ');
 +  else
 +    {
 +      CHECK_CHARACTER (val);
 +      CODING_ATTR_DEFAULT_CHAR (attrs) = val;
 +    }
 +
 +  val = args[coding_arg_for_unibyte];
 +  CODING_ATTR_FOR_UNIBYTE (attrs) = NILP (val) ? Qnil : Qt;
 +
 +  val = args[coding_arg_plist];
 +  CHECK_LIST (val);
 +  CODING_ATTR_PLIST (attrs) = val;
 +
 +  if (EQ (coding_type, Qcharset))
 +    {
 +      /* Generate a lisp vector of 256 elements.  Each element is nil,
 +       integer, or a list of charset IDs.
 +
 +       If Nth element is nil, the byte code N is invalid in this
 +       coding system.
 +
 +       If Nth element is a number NUM, N is the first byte of a
 +       charset whose ID is NUM.
 +
 +       If Nth element is a list of charset IDs, N is the first byte
 +       of one of them.  The list is sorted by dimensions of the
 +       charsets.  A charset of smaller dimension comes firtst. */
 +      val = Fmake_vector (make_number (256), Qnil);
 +
 +      for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
 +      {
 +        struct charset *charset = CHARSET_FROM_ID (XFASTINT (XCAR (tail)));
 +        int dim = CHARSET_DIMENSION (charset);
 +        int idx = (dim - 1) * 4;
 +
 +        if (CHARSET_ASCII_COMPATIBLE_P (charset))
 +          CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 +
 +        for (i = charset->code_space[idx];
 +             i <= charset->code_space[idx + 1]; i++)
 +          {
 +            Lisp_Object tmp, tmp2;
 +            int dim2;
 +
 +            tmp = AREF (val, i);
 +            if (NILP (tmp))
 +              tmp = XCAR (tail);
 +            else if (NUMBERP (tmp))
 +              {
 +                dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp)));
 +                if (dim < dim2)
 +                  tmp = Fcons (XCAR (tail), Fcons (tmp, Qnil));
 +                else
 +                  tmp = Fcons (tmp, Fcons (XCAR (tail), Qnil));
 +              }
 +            else
 +              {
 +                for (tmp2 = tmp; CONSP (tmp2); tmp2 = XCDR (tmp2))
 +                  {
 +                    dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (XCAR (tmp2))));
 +                    if (dim < dim2)
 +                      break;
 +                  }
 +                if (NILP (tmp2))
 +                  tmp = nconc2 (tmp, Fcons (XCAR (tail), Qnil));
 +                else
 +                  {
 +                    XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2)));
 +                    XSETCAR (tmp2, XCAR (tail));
 +                  }
 +              }
 +            ASET (val, i, tmp);
 +          }
 +      }
 +      ASET (attrs, coding_attr_charset_valids, val);
 +      category = coding_category_charset;
 +    }
 +  else if (EQ (coding_type, Qccl))
 +    {
 +      Lisp_Object valids;
 +
 +      if (nargs < coding_arg_ccl_max)
 +      goto short_args;
  
 -TARGET has a meaning which depends on OPERATION:
 -  For file I/O, TARGET is a file name (except for the special case below).
 -  For process I/O, TARGET is a process name.
 -  For network I/O, TARGET is a service name or a port number
 +      val = args[coding_arg_ccl_decoder];
 +      CHECK_CCL_PROGRAM (val);
 +      if (VECTORP (val))
 +      val = Fcopy_sequence (val);
 +      ASET (attrs, coding_attr_ccl_decoder, val);
  
 -This function looks up what specified for TARGET in,
 -`file-coding-system-alist', `process-coding-system-alist',
 -or `network-coding-system-alist' depending on OPERATION.
 -They may specify a coding system, a cons of coding systems,
 -or a function symbol to call.
 -In the last case, we call the function with one argument,
 -which is a list of all the arguments given to this function.
 +      val = args[coding_arg_ccl_encoder];
 +      CHECK_CCL_PROGRAM (val);
 +      if (VECTORP (val))
 +      val = Fcopy_sequence (val);
 +      ASET (attrs, coding_attr_ccl_encoder, val);
  
 -If OPERATION is `insert-file-contents', the argument corresponding to
 -TARGET may be a cons (FILENAME . BUFFER).  In that case, FILENAME is a
 -file name to look up, and BUFFER is a buffer that contains the file's
 -contents (not yet decoded).  If `file-coding-system-alist' specifies a
 -function to call for FILENAME, that function should examine the
 -contents of BUFFER instead of reading the file.
 +      val = args[coding_arg_ccl_valids];
 +      valids = Fmake_string (make_number (256), make_number (0));
 +      for (tail = val; !NILP (tail); tail = Fcdr (tail))
 +      {
 +        int from, to;
  
 -usage: (find-operation-coding-system OPERATION ARGUMENTS ...)  */)
 -     (nargs, args)
 -     int nargs;
 -     Lisp_Object *args;
 -{
 -  Lisp_Object operation, target_idx, target, val;
 -  register Lisp_Object chain;
 +        val = Fcar (tail);
 +        if (INTEGERP (val))
 +          {
 +            from = to = XINT (val);
 +            if (from < 0 || from > 255)
 +              args_out_of_range_3 (val, make_number (0), make_number (255));
 +          }
 +        else
 +          {
 +            CHECK_CONS (val);
 +            CHECK_NATNUM_CAR (val);
 +            CHECK_NATNUM_CDR (val);
 +            from = XINT (XCAR (val));
 +            if (from > 255)
 +              args_out_of_range_3 (XCAR (val),
 +                                   make_number (0), make_number (255));
 +            to = XINT (XCDR (val));
 +            if (to < from || to > 255)
 +              args_out_of_range_3 (XCDR (val),
 +                                   XCAR (val), make_number (255));
 +          }
 +        for (i = from; i <= to; i++)
 +          SSET (valids, i, 1);
 +      }
 +      ASET (attrs, coding_attr_ccl_valids, valids);
  
 -  if (nargs < 2)
 -    error ("Too few arguments");
 -  operation = args[0];
 -  if (!SYMBOLP (operation)
 -      || !INTEGERP (target_idx = Fget (operation, Qtarget_idx)))
 -    error ("Invalid first argument");
 -  if (nargs < 1 + XINT (target_idx))
 -    error ("Too few arguments for operation: %s",
 -         SDATA (SYMBOL_NAME (operation)));
 -  /* For write-region, if the 6th argument (i.e. VISIT, the 5th
 -     argument to write-region) is string, it must be treated as a
 -     target file name.  */
 -  if (EQ (operation, Qwrite_region)
 -      && nargs > 5
 -      && STRINGP (args[5]))
 -    target_idx = make_number (4);
 -  target = args[XINT (target_idx) + 1];
 -  if (!(STRINGP (target)
 -      || (EQ (operation, Qinsert_file_contents) && CONSP (target)
 -          && STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))
 -      || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
 -    error ("Invalid argument %d", XINT (target_idx) + 1);
 -  if (CONSP (target))
 -    target = XCAR (target);
 +      category = coding_category_ccl;
 +    }
 +  else if (EQ (coding_type, Qutf_16))
 +    {
 +      Lisp_Object bom, endian;
  
 -  chain = ((EQ (operation, Qinsert_file_contents)
 -          || EQ (operation, Qwrite_region))
 -         ? Vfile_coding_system_alist
 -         : (EQ (operation, Qopen_network_stream)
 -            ? Vnetwork_coding_system_alist
 -            : Vprocess_coding_system_alist));
 -  if (NILP (chain))
 -    return Qnil;
 +      CODING_ATTR_ASCII_COMPAT (attrs) = Qnil;
  
 -  for (; CONSP (chain); chain = XCDR (chain))
 -    {
 -      Lisp_Object elt;
 -      elt = XCAR (chain);
 +      if (nargs < coding_arg_utf16_max)
 +      goto short_args;
  
 -      if (CONSP (elt)
 -        && ((STRINGP (target)
 -             && STRINGP (XCAR (elt))
 -             && fast_string_match (XCAR (elt), target) >= 0)
 -            || (INTEGERP (target) && EQ (target, XCAR (elt)))))
 +      bom = args[coding_arg_utf16_bom];
 +      if (! NILP (bom) && ! EQ (bom, Qt))
        {
 -        val = XCDR (elt);
 -        /* Here, if VAL is both a valid coding system and a valid
 -             function symbol, we return VAL as a coding system.  */
 -        if (CONSP (val))
 -          return val;
 -        if (! SYMBOLP (val))
 -          return Qnil;
 -        if (! NILP (Fcoding_system_p (val)))
 -          return Fcons (val, val);
 -        if (! NILP (Ffboundp (val)))
 +        CHECK_CONS (bom);
 +        val = XCAR (bom);
 +        CHECK_CODING_SYSTEM (val);
 +        val = XCDR (bom);
 +        CHECK_CODING_SYSTEM (val);
 +      }
 +      ASET (attrs, coding_attr_utf_16_bom, bom);
 +
 +      endian = args[coding_arg_utf16_endian];
 +      CHECK_SYMBOL (endian);
 +      if (NILP (endian))
 +      endian = Qbig;
 +      else if (! EQ (endian, Qbig) && ! EQ (endian, Qlittle))
 +      error ("Invalid endian: %s", SDATA (SYMBOL_NAME (endian)));
 +      ASET (attrs, coding_attr_utf_16_endian, endian);
 +
 +      category = (CONSP (bom)
 +                ? coding_category_utf_16_auto
 +                : NILP (bom)
 +                ? (EQ (endian, Qbig)
 +                   ? coding_category_utf_16_be_nosig
 +                   : coding_category_utf_16_le_nosig)
 +                : (EQ (endian, Qbig)
 +                   ? coding_category_utf_16_be
 +                   : coding_category_utf_16_le));
 +    }
 +  else if (EQ (coding_type, Qiso_2022))
 +    {
 +      Lisp_Object initial, reg_usage, request, flags;
 +      int i;
 +
 +      if (nargs < coding_arg_iso2022_max)
 +      goto short_args;
 +
 +      initial = Fcopy_sequence (args[coding_arg_iso2022_initial]);
 +      CHECK_VECTOR (initial);
 +      for (i = 0; i < 4; i++)
 +      {
 +        val = Faref (initial, make_number (i));
 +        if (! NILP (val))
            {
 -            /* We use call1 rather than safe_call1
 -               so as to get bug reports about functions called here
 -               which don't handle the current interface.  */
 -            val = call1 (val, Flist (nargs, args));
 -            if (CONSP (val))
 -              return val;
 -            if (SYMBOLP (val) && ! NILP (Fcoding_system_p (val)))
 -              return Fcons (val, val);
 +            struct charset *charset;
 +
 +            CHECK_CHARSET_GET_CHARSET (val, charset);
 +            ASET (initial, i, make_number (CHARSET_ID (charset)));
 +            if (i == 0 && CHARSET_ASCII_COMPATIBLE_P (charset))
 +              CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
            }
 -        return Qnil;
 +        else
 +          ASET (initial, i, make_number (-1));
        }
 -    }
 -  return Qnil;
 -}
  
 -DEFUN ("update-coding-systems-internal",  Fupdate_coding_systems_internal,
 -       Supdate_coding_systems_internal, 0, 0, 0,
 -       doc: /* Update internal database for ISO2022 and CCL based coding systems.
 -When values of any coding categories are changed, you must
 -call this function.  */)
 -     ()
 -{
 -  int i;
 +      reg_usage = args[coding_arg_iso2022_reg_usage];
 +      CHECK_CONS (reg_usage);
 +      CHECK_NUMBER_CAR (reg_usage);
 +      CHECK_NUMBER_CDR (reg_usage);
 +
 +      request = Fcopy_sequence (args[coding_arg_iso2022_request]);
 +      for (tail = request; ! NILP (tail); tail = Fcdr (tail))
 +      {
 +        int id;
 +        Lisp_Object tmp;
 +
 +        val = Fcar (tail);
 +        CHECK_CONS (val);
 +        tmp = XCAR (val);
 +        CHECK_CHARSET_GET_ID (tmp, id);
 +        CHECK_NATNUM_CDR (val);
 +        if (XINT (XCDR (val)) >= 4)
 +          error ("Invalid graphic register number: %d", XINT (XCDR (val)));
 +        XSETCAR (val, make_number (id));
 +      }
  
 -  for (i = CODING_CATEGORY_IDX_EMACS_MULE; i < CODING_CATEGORY_IDX_MAX; i++)
 +      flags = args[coding_arg_iso2022_flags];
 +      CHECK_NATNUM (flags);
 +      i = XINT (flags);
 +      if (EQ (args[coding_arg_charset_list], Qiso_2022))
 +      flags = make_number (i | CODING_ISO_FLAG_FULL_SUPPORT);
 +
 +      ASET (attrs, coding_attr_iso_initial, initial);
 +      ASET (attrs, coding_attr_iso_usage, reg_usage);
 +      ASET (attrs, coding_attr_iso_request, request);
 +      ASET (attrs, coding_attr_iso_flags, flags);
 +      setup_iso_safe_charsets (attrs);
 +
 +      if (i & CODING_ISO_FLAG_SEVEN_BITS)
 +      category = ((i & (CODING_ISO_FLAG_LOCKING_SHIFT
 +                        | CODING_ISO_FLAG_SINGLE_SHIFT))
 +                  ? coding_category_iso_7_else
 +                  : EQ (args[coding_arg_charset_list], Qiso_2022)
 +                  ? coding_category_iso_7
 +                  : coding_category_iso_7_tight);
 +      else
 +      {
 +        int id = XINT (AREF (initial, 1));
 +
 +        category = (((i & CODING_ISO_FLAG_LOCKING_SHIFT)
 +                     || EQ (args[coding_arg_charset_list], Qiso_2022)
 +                     || id < 0)
 +                    ? coding_category_iso_8_else
 +                    : (CHARSET_DIMENSION (CHARSET_FROM_ID (id)) == 1)
 +                    ? coding_category_iso_8_1
 +                    : coding_category_iso_8_2);
 +      }
 +      if (category != coding_category_iso_8_1
 +        && category != coding_category_iso_8_2)
 +      CODING_ATTR_ASCII_COMPAT (attrs) = Qnil;
 +    }
 +  else if (EQ (coding_type, Qemacs_mule))
      {
 -      Lisp_Object val;
 +      if (EQ (args[coding_arg_charset_list], Qemacs_mule))
 +      ASET (attrs, coding_attr_emacs_mule_full, Qt);
 +      CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 +      category = coding_category_emacs_mule;
 +    }
 +  else if (EQ (coding_type, Qshift_jis))
 +    {
 +
 +      struct charset *charset;
  
 -      val = SYMBOL_VALUE (XVECTOR (Vcoding_category_table)->contents[i]);
 -      if (!NILP (val))
 +      if (XINT (Flength (charset_list)) != 3
 +        && XINT (Flength (charset_list)) != 4)
 +      error ("There should be three or four charsets");
 +
 +      charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
 +      if (CHARSET_DIMENSION (charset) != 1)
 +      error ("Dimension of charset %s is not one",
 +             SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 +      if (CHARSET_ASCII_COMPATIBLE_P (charset))
 +      CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 +
 +      charset_list = XCDR (charset_list);
 +      charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
 +      if (CHARSET_DIMENSION (charset) != 1)
 +      error ("Dimension of charset %s is not one",
 +             SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 +
 +      charset_list = XCDR (charset_list);
 +      charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
 +      if (CHARSET_DIMENSION (charset) != 2)
 +      error ("Dimension of charset %s is not two",
 +             SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 +
 +      charset_list = XCDR (charset_list);
 +      if (! NILP (charset_list))
        {
 -        if (! coding_system_table[i])
 -          coding_system_table[i] = ((struct coding_system *)
 -                                    xmalloc (sizeof (struct coding_system)));
 -        setup_coding_system (val, coding_system_table[i]);
 +        charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
 +        if (CHARSET_DIMENSION (charset) != 2)
 +          error ("Dimension of charset %s is not two",
 +                 SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
        }
 -      else if (coding_system_table[i])
 +
 +      category = coding_category_sjis;
 +      Vsjis_coding_system = name;
 +    }
 +  else if (EQ (coding_type, Qbig5))
 +    {
 +      struct charset *charset;
 +
 +      if (XINT (Flength (charset_list)) != 2)
 +      error ("There should be just two charsets");
 +
 +      charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
 +      if (CHARSET_DIMENSION (charset) != 1)
 +      error ("Dimension of charset %s is not one",
 +             SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 +      if (CHARSET_ASCII_COMPATIBLE_P (charset))
 +      CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 +
 +      charset_list = XCDR (charset_list);
 +      charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
 +      if (CHARSET_DIMENSION (charset) != 2)
 +      error ("Dimension of charset %s is not two",
 +             SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
 +
 +      category = coding_category_big5;
 +      Vbig5_coding_system = name;
 +    }
 +  else if (EQ (coding_type, Qraw_text))
 +    {
 +      category = coding_category_raw_text;
 +      CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 +    }
 +  else if (EQ (coding_type, Qutf_8))
 +    {
 +      category = coding_category_utf_8;
 +      CODING_ATTR_ASCII_COMPAT (attrs) = Qt;
 +    }
 +  else if (EQ (coding_type, Qundecided))
 +    category = coding_category_undecided;
 +  else
 +    error ("Invalid coding system type: %s",
 +         SDATA (SYMBOL_NAME (coding_type)));
 +
 +  CODING_ATTR_CATEGORY (attrs) = make_number (category);
 +  CODING_ATTR_PLIST (attrs)
 +    = Fcons (QCcategory, Fcons (AREF (Vcoding_category_table, category),
 +                              CODING_ATTR_PLIST (attrs)));
 +  CODING_ATTR_PLIST (attrs)
 +    = Fcons (QCascii_compatible_p, 
 +           Fcons (CODING_ATTR_ASCII_COMPAT (attrs),
 +                  CODING_ATTR_PLIST (attrs)));
 +
 +  eol_type = args[coding_arg_eol_type];
 +  if (! NILP (eol_type)
 +      && ! EQ (eol_type, Qunix)
 +      && ! EQ (eol_type, Qdos)
 +      && ! EQ (eol_type, Qmac))
 +    error ("Invalid eol-type");
 +
 +  aliases = Fcons (name, Qnil);
 +
 +  if (NILP (eol_type))
 +    {
 +      eol_type = make_subsidiaries (name);
 +      for (i = 0; i < 3; i++)
        {
 -        xfree (coding_system_table[i]);
 -        coding_system_table[i] = NULL;
 +        Lisp_Object this_spec, this_name, this_aliases, this_eol_type;
 +
 +        this_name = AREF (eol_type, i);
 +        this_aliases = Fcons (this_name, Qnil);
 +        this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac);
 +        this_spec = Fmake_vector (make_number (3), attrs);
 +        ASET (this_spec, 1, this_aliases);
 +        ASET (this_spec, 2, this_eol_type);
 +        Fputhash (this_name, this_spec, Vcoding_system_hash_table);
 +        Vcoding_system_list = Fcons (this_name, Vcoding_system_list);
 +        val = Fassoc (Fsymbol_name (this_name), Vcoding_system_alist);
 +        if (NILP (val))
 +          Vcoding_system_alist
 +            = Fcons (Fcons (Fsymbol_name (this_name), Qnil),
 +                     Vcoding_system_alist);
        }
      }
  
 +  spec_vec = Fmake_vector (make_number (3), attrs);
 +  ASET (spec_vec, 1, aliases);
 +  ASET (spec_vec, 2, eol_type);
 +
 +  Fputhash (name, spec_vec, Vcoding_system_hash_table);
 +  Vcoding_system_list = Fcons (name, Vcoding_system_list);
 +  val = Fassoc (Fsymbol_name (name), Vcoding_system_alist);
 +  if (NILP (val))
 +    Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (name), Qnil),
 +                                Vcoding_system_alist);
 +
 +  {
 +    int id = coding_categories[category].id;
 +
 +    if (id < 0 || EQ (name, CODING_ID_NAME (id)))
 +      setup_coding_system (name, &coding_categories[category]);
 +  }
 +
    return Qnil;
 +
 + short_args:
 +  return Fsignal (Qwrong_number_of_arguments,
 +                Fcons (intern ("define-coding-system-internal"),
 +                       make_number (nargs)));
  }
  
 -DEFUN ("set-coding-priority-internal", Fset_coding_priority_internal,
 -       Sset_coding_priority_internal, 0, 0, 0,
 -       doc: /* Update internal database for the current value of `coding-category-list'.
 -This function is internal use only.  */)
 -     ()
 +
 +DEFUN ("coding-system-put", Fcoding_system_put, Scoding_system_put,
 +       3, 3, 0,
 +       doc: /* Change value in CODING-SYSTEM's property list PROP to VAL.  */)
 +  (coding_system, prop, val)
 +     Lisp_Object coding_system, prop, val;
  {
 -  int i = 0, idx;
 -  Lisp_Object val;
 +  Lisp_Object spec, attrs;
 +
 +  CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
 +  attrs = AREF (spec, 0);
 +  if (EQ (prop, QCmnemonic))
 +    {
 +      if (! STRINGP (val))
 +      CHECK_CHARACTER (val);
 +      CODING_ATTR_MNEMONIC (attrs) = val;
 +    }
 +  else if (EQ (prop, QCdefalut_char))
 +    {
 +      if (NILP (val))
 +      val = make_number (' ');
 +      else
 +      CHECK_CHARACTER (val);
 +      CODING_ATTR_DEFAULT_CHAR (attrs) = val;
 +    }
 +  else if (EQ (prop, QCdecode_translation_table))
 +    {
 +      if (! CHAR_TABLE_P (val) && ! CONSP (val))
 +      CHECK_SYMBOL (val);
 +      CODING_ATTR_DECODE_TBL (attrs) = val;
 +    }
 +  else if (EQ (prop, QCencode_translation_table))
 +    {
 +      if (! CHAR_TABLE_P (val) && ! CONSP (val))
 +      CHECK_SYMBOL (val);
 +      CODING_ATTR_ENCODE_TBL (attrs) = val;
 +    }
 +  else if (EQ (prop, QCpost_read_conversion))
 +    {
 +      CHECK_SYMBOL (val);
 +      CODING_ATTR_POST_READ (attrs) = val;
 +    }
 +  else if (EQ (prop, QCpre_write_conversion))
 +    {
 +      CHECK_SYMBOL (val);
 +      CODING_ATTR_PRE_WRITE (attrs) = val;
 +    }
 +  else if (EQ (prop, QCascii_compatible_p))
 +    {
 +      CODING_ATTR_ASCII_COMPAT (attrs) = val;
 +    }
 +
 +  CODING_ATTR_PLIST (attrs)
 +    = Fplist_put (CODING_ATTR_PLIST (attrs), prop, val);
 +  return val;
 +}
  
 -  val = Vcoding_category_list;
  
 -  while (CONSP (val) && i < CODING_CATEGORY_IDX_MAX)
 +DEFUN ("define-coding-system-alias", Fdefine_coding_system_alias,
 +       Sdefine_coding_system_alias, 2, 2, 0,
 +       doc: /* Define ALIAS as an alias for CODING-SYSTEM.  */)
 +     (alias, coding_system)
 +     Lisp_Object alias, coding_system;
 +{
 +  Lisp_Object spec, aliases, eol_type, val;
 +
 +  CHECK_SYMBOL (alias);
 +  CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
 +  aliases = AREF (spec, 1);
 +  /* ALISES should be a list of length more than zero, and the first
 +     element is a base coding system.  Append ALIAS at the tail of the
 +     list.  */
 +  while (!NILP (XCDR (aliases)))
 +    aliases = XCDR (aliases);
 +  XSETCDR (aliases, Fcons (alias, Qnil));
 +
 +  eol_type = AREF (spec, 2);
 +  if (VECTORP (eol_type))
      {
 -      if (! SYMBOLP (XCAR (val)))
 -      break;
 -      idx = XFASTINT (Fget (XCAR (val), Qcoding_category_index));
 -      if (idx >= CODING_CATEGORY_IDX_MAX)
 -      break;
 -      coding_priorities[i++] = (1 << idx);
 -      val = XCDR (val);
 +      Lisp_Object subsidiaries;
 +      int i;
 +
 +      subsidiaries = make_subsidiaries (alias);
 +      for (i = 0; i < 3; i++)
 +      Fdefine_coding_system_alias (AREF (subsidiaries, i),
 +                                   AREF (eol_type, i));
      }
 -  /* If coding-category-list is valid and contains all coding
 -     categories, `i' should be CODING_CATEGORY_IDX_MAX now.  If not,
 -     the following code saves Emacs from crashing.  */
 -  while (i < CODING_CATEGORY_IDX_MAX)
 -    coding_priorities[i++] = CODING_CATEGORY_MASK_RAW_TEXT;
 +
 +  Fputhash (alias, spec, Vcoding_system_hash_table);
 +  Vcoding_system_list = Fcons (alias, Vcoding_system_list);
 +  val = Fassoc (Fsymbol_name (alias), Vcoding_system_alist);
 +  if (NILP (val))
 +    Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (alias), Qnil),
 +                                Vcoding_system_alist);
  
    return Qnil;
  }
  
 -DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal,
 -       Sdefine_coding_system_internal, 1, 1, 0,
 -       doc: /* Register CODING-SYSTEM as a base coding system.
 -This function is internal use only.  */)
 +DEFUN ("coding-system-base", Fcoding_system_base, Scoding_system_base,
 +       1, 1, 0,
 +       doc: /* Return the base of CODING-SYSTEM.
 +Any alias or subsidiary coding system is not a base coding system.  */)
 +  (coding_system)
 +     Lisp_Object coding_system;
 +{
 +  Lisp_Object spec, attrs;
 +
 +  if (NILP (coding_system))
 +    return (Qno_conversion);
 +  CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
 +  attrs = AREF (spec, 0);
 +  return CODING_ATTR_BASE_NAME (attrs);
 +}
 +
 +DEFUN ("coding-system-plist", Fcoding_system_plist, Scoding_system_plist,
 +       1, 1, 0,
 +       doc: "Return the property list of CODING-SYSTEM.")
 +     (coding_system)
 +     Lisp_Object coding_system;
 +{
 +  Lisp_Object spec, attrs;
 +
 +  if (NILP (coding_system))
 +    coding_system = Qno_conversion;
 +  CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
 +  attrs = AREF (spec, 0);
 +  return CODING_ATTR_PLIST (attrs);
 +}
 +
 +
 +DEFUN ("coding-system-aliases", Fcoding_system_aliases, Scoding_system_aliases,
 +       1, 1, 0,
 +       doc: /* Return the list of aliases of CODING-SYSTEM.  */)
       (coding_system)
       Lisp_Object coding_system;
  {
 -  Lisp_Object safe_chars, slot;
 +  Lisp_Object spec;
  
 -  if (NILP (Fcheck_coding_system (coding_system)))
 -    xsignal1 (Qcoding_system_error, coding_system);
 +  if (NILP (coding_system))
 +    coding_system = Qno_conversion;
 +  CHECK_CODING_SYSTEM_GET_SPEC (coding_system, spec);
 +  return AREF (spec, 1);
 +}
  
 -  safe_chars = coding_safe_chars (coding_system);
 -  if (! EQ (safe_chars, Qt) && ! CHAR_TABLE_P (safe_chars))
 -    error ("No valid safe-chars property for %s",
 -         SDATA (SYMBOL_NAME (coding_system)));
 +DEFUN ("coding-system-eol-type", Fcoding_system_eol_type,
 +       Scoding_system_eol_type, 1, 1, 0,
 +       doc: /* Return eol-type of CODING-SYSTEM.
 +An eol-type is integer 0, 1, 2, or a vector of coding systems.
  
 -  if (EQ (safe_chars, Qt))
 -    {
 -      if (NILP (Fmemq (coding_system, XCAR (Vcoding_system_safe_chars))))
 -      XSETCAR (Vcoding_system_safe_chars,
 -               Fcons (coding_system, XCAR (Vcoding_system_safe_chars)));
 -    }
 -  else
 -    {
 -      slot = Fassq (coding_system, XCDR (Vcoding_system_safe_chars));
 -      if (NILP (slot))
 -      XSETCDR (Vcoding_system_safe_chars,
 -               nconc2 (XCDR (Vcoding_system_safe_chars),
 -                       Fcons (Fcons (coding_system, safe_chars), Qnil)));
 -      else
 -      XSETCDR (slot, safe_chars);
 -    }
 -  return Qnil;
 +Integer values 0, 1, and 2 indicate a format of end-of-line; LF, CRLF,
 +and CR respectively.
 +
 +A vector value indicates that a format of end-of-line should be
 +detected automatically.  Nth element of the vector is the subsidiary
 +coding system whose eol-type is N.  */)
 +     (coding_system)
 +     Lisp_Object coding_system;
 +{
 +  Lisp_Object spec, eol_type;
 +  int n;
 +
 +  if (NILP (coding_system))
 +    coding_system = Qno_conversion;
 +  if (! CODING_SYSTEM_P (coding_system))
 +    return Qnil;
 +  spec = CODING_SYSTEM_SPEC (coding_system);
 +  eol_type = AREF (spec, 2);
 +  if (VECTORP (eol_type))
 +    return Fcopy_sequence (eol_type);
 +  n = EQ (eol_type, Qunix) ? 0 : EQ (eol_type, Qdos) ? 1 : 2;
 +  return make_number (n);
  }
  
  #endif /* emacs */
@@@ -9268,11 -7658,20 +9268,11 @@@ init_coding_once (
  {
    int i;
  
 -  /* Emacs' internal format specific initialize routine.  */
 -  for (i = 0; i <= 0x20; i++)
 -    emacs_code_class[i] = EMACS_control_code;
 -  emacs_code_class[0x0A] = EMACS_linefeed_code;
 -  emacs_code_class[0x0D] = EMACS_carriage_return_code;
 -  for (i = 0x21 ; i < 0x7F; i++)
 -    emacs_code_class[i] = EMACS_ascii_code;
 -  emacs_code_class[0x7F] = EMACS_control_code;
 -  for (i = 0x80; i < 0xFF; i++)
 -    emacs_code_class[i] = EMACS_invalid_code;
 -  emacs_code_class[LEADING_CODE_PRIVATE_11] = EMACS_leading_code_3;
 -  emacs_code_class[LEADING_CODE_PRIVATE_12] = EMACS_leading_code_3;
 -  emacs_code_class[LEADING_CODE_PRIVATE_21] = EMACS_leading_code_4;
 -  emacs_code_class[LEADING_CODE_PRIVATE_22] = EMACS_leading_code_4;
 +  for (i = 0; i < coding_category_max; i++)
 +    {
 +      coding_categories[i].id = -1;
 +      coding_priorities[i] = i;
 +    }
  
    /* ISO2022 specific initialize routine.  */
    for (i = 0; i < 0x20; i++)
      iso_code_class[i] = ISO_graphic_plane_1;
    iso_code_class[0x20] = iso_code_class[0x7F] = ISO_0x20_or_0x7F;
    iso_code_class[0xA0] = iso_code_class[0xFF] = ISO_0xA0_or_0xFF;
 -  iso_code_class[ISO_CODE_CR] = ISO_carriage_return;
    iso_code_class[ISO_CODE_SO] = ISO_shift_out;
    iso_code_class[ISO_CODE_SI] = ISO_shift_in;
    iso_code_class[ISO_CODE_SS2_7] = ISO_single_shift_2_7;
    iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3;
    iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer;
  
 -  setup_coding_system (Qnil, &keyboard_coding);
 -  setup_coding_system (Qnil, &terminal_coding);
 -  setup_coding_system (Qnil, &safe_terminal_coding);
 -  setup_coding_system (Qnil, &default_buffer_file_coding);
 -
 -  bzero (coding_system_table, sizeof coding_system_table);
 -
 -  bzero (ascii_skip_code, sizeof ascii_skip_code);
 -  for (i = 0; i < 128; i++)
 -    ascii_skip_code[i] = 1;
 -
 -#if defined (MSDOS) || defined (WINDOWSNT)
 -  system_eol_type = CODING_EOL_CRLF;
 -#else
 -  system_eol_type = CODING_EOL_LF;
 -#endif
 -
 -  inhibit_pre_post_conversion = 0;
 +  for (i = 0; i < 256; i++)
 +    {
 +      emacs_mule_bytes[i] = 1;
 +    }
 +  emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_11] = 3;
 +  emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_12] = 3;
 +  emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_21] = 4;
 +  emacs_mule_bytes[EMACS_MULE_LEADING_CODE_PRIVATE_22] = 4;
  }
  
  #ifdef emacs
  void
  syms_of_coding ()
  {
 +  staticpro (&Vcoding_system_hash_table);
 +  {
 +    Lisp_Object args[2];
 +    args[0] = QCtest;
 +    args[1] = Qeq;
 +    Vcoding_system_hash_table = Fmake_hash_table (2, args);
 +  }
 +
 +  staticpro (&Vsjis_coding_system);
 +  Vsjis_coding_system = Qnil;
 +
 +  staticpro (&Vbig5_coding_system);
 +  Vbig5_coding_system = Qnil;
 +
 +  staticpro (&Vcode_conversion_reused_workbuf);
 +  Vcode_conversion_reused_workbuf = Qnil;
 +
    staticpro (&Vcode_conversion_workbuf_name);
    Vcode_conversion_workbuf_name = build_string (" *code-conversion-work*");
  
 -  Qtarget_idx = intern ("target-idx");
 -  staticpro (&Qtarget_idx);
 +  reused_workbuf_in_use = 0;
  
 -  Qcoding_system_history = intern ("coding-system-history");
 -  staticpro (&Qcoding_system_history);
 +  DEFSYM (Qcharset, "charset");
 +  DEFSYM (Qtarget_idx, "target-idx");
 +  DEFSYM (Qcoding_system_history, "coding-system-history");
    Fset (Qcoding_system_history, Qnil);
  
    /* Target FILENAME is the first argument.  */
    /* Target FILENAME is the third argument.  */
    Fput (Qwrite_region, Qtarget_idx, make_number (2));
  
 -  Qcall_process = intern ("call-process");
 -  staticpro (&Qcall_process);
 +  DEFSYM (Qcall_process, "call-process");
    /* Target PROGRAM is the first argument.  */
    Fput (Qcall_process, Qtarget_idx, make_number (0));
  
 -  Qcall_process_region = intern ("call-process-region");
 -  staticpro (&Qcall_process_region);
 +  DEFSYM (Qcall_process_region, "call-process-region");
    /* Target PROGRAM is the third argument.  */
    Fput (Qcall_process_region, Qtarget_idx, make_number (2));
  
 -  Qstart_process = intern ("start-process");
 -  staticpro (&Qstart_process);
 +  DEFSYM (Qstart_process, "start-process");
    /* Target PROGRAM is the third argument.  */
    Fput (Qstart_process, Qtarget_idx, make_number (2));
  
 -  Qopen_network_stream = intern ("open-network-stream");
 -  staticpro (&Qopen_network_stream);
 +  DEFSYM (Qopen_network_stream, "open-network-stream");
    /* Target SERVICE is the fourth argument.  */
    Fput (Qopen_network_stream, Qtarget_idx, make_number (3));
  
 -  Qcoding_system = intern ("coding-system");
 -  staticpro (&Qcoding_system);
 +  DEFSYM (Qcoding_system, "coding-system");
 +  DEFSYM (Qcoding_aliases, "coding-aliases");
  
 -  Qeol_type = intern ("eol-type");
 -  staticpro (&Qeol_type);
 +  DEFSYM (Qeol_type, "eol-type");
 +  DEFSYM (Qunix, "unix");
 +  DEFSYM (Qdos, "dos");
  
 -  Qbuffer_file_coding_system = intern ("buffer-file-coding-system");
 -  staticpro (&Qbuffer_file_coding_system);
 +  DEFSYM (Qbuffer_file_coding_system, "buffer-file-coding-system");
 +  DEFSYM (Qpost_read_conversion, "post-read-conversion");
 +  DEFSYM (Qpre_write_conversion, "pre-write-conversion");
 +  DEFSYM (Qdefault_char, "default-char");
 +  DEFSYM (Qundecided, "undecided");
 +  DEFSYM (Qno_conversion, "no-conversion");
 +  DEFSYM (Qraw_text, "raw-text");
  
 -  Qpost_read_conversion = intern ("post-read-conversion");
 -  staticpro (&Qpost_read_conversion);
 +  DEFSYM (Qiso_2022, "iso-2022");
  
 -  Qpre_write_conversion = intern ("pre-write-conversion");
 -  staticpro (&Qpre_write_conversion);
 +  DEFSYM (Qutf_8, "utf-8");
 +  DEFSYM (Qutf_8_emacs, "utf-8-emacs");
  
 -  Qno_conversion = intern ("no-conversion");
 -  staticpro (&Qno_conversion);
 +  DEFSYM (Qutf_16, "utf-16");
 +  DEFSYM (Qbig, "big");
 +  DEFSYM (Qlittle, "little");
  
 -  Qundecided = intern ("undecided");
 -  staticpro (&Qundecided);
 +  DEFSYM (Qshift_jis, "shift-jis");
 +  DEFSYM (Qbig5, "big5");
  
 -  Qcoding_system_p = intern ("coding-system-p");
 -  staticpro (&Qcoding_system_p);
 -
 -  Qcoding_system_error = intern ("coding-system-error");
 -  staticpro (&Qcoding_system_error);
 +  DEFSYM (Qcoding_system_p, "coding-system-p");
  
 +  DEFSYM (Qcoding_system_error, "coding-system-error");
    Fput (Qcoding_system_error, Qerror_conditions,
        Fcons (Qcoding_system_error, Fcons (Qerror, Qnil)));
    Fput (Qcoding_system_error, Qerror_message,
        build_string ("Invalid coding system"));
  
 -  Qcoding_category = intern ("coding-category");
 -  staticpro (&Qcoding_category);
 -  Qcoding_category_index = intern ("coding-category-index");
 -  staticpro (&Qcoding_category_index);
 -
 -  Vcoding_category_table
 -    = Fmake_vector (make_number (CODING_CATEGORY_IDX_MAX), Qnil);
 -  staticpro (&Vcoding_category_table);
 -  {
 -    int i;
 -    for (i = 0; i < CODING_CATEGORY_IDX_MAX; i++)
 -      {
 -      XVECTOR (Vcoding_category_table)->contents[i]
 -        = intern (coding_category_name[i]);
 -      Fput (XVECTOR (Vcoding_category_table)->contents[i],
 -            Qcoding_category_index, make_number (i));
 -      }
 -  }
 -
 -  Vcoding_system_safe_chars = Fcons (Qnil, Qnil);
 -  staticpro (&Vcoding_system_safe_chars);
 -
 -  Qtranslation_table = intern ("translation-table");
 -  staticpro (&Qtranslation_table);
 -  Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2));
 -
 -  Qtranslation_table_id = intern ("translation-table-id");
 -  staticpro (&Qtranslation_table_id);
 -
 -  Qtranslation_table_for_decode = intern ("translation-table-for-decode");
 -  staticpro (&Qtranslation_table_for_decode);
 -
 -  Qtranslation_table_for_encode = intern ("translation-table-for-encode");
 -  staticpro (&Qtranslation_table_for_encode);
 -
 -  Qsafe_chars = intern ("safe-chars");
 -  staticpro (&Qsafe_chars);
 -
 -  Qchar_coding_system = intern ("char-coding-system");
 -  staticpro (&Qchar_coding_system);
 -
    /* Intern this now in case it isn't already done.
       Setting this variable twice is harmless.
       But don't staticpro it here--that is done in alloc.c.  */
    Qchar_table_extra_slots = intern ("char-table-extra-slots");
 -  Fput (Qsafe_chars, Qchar_table_extra_slots, make_number (0));
 -  Fput (Qchar_coding_system, Qchar_table_extra_slots, make_number (0));
  
 -  Qvalid_codes = intern ("valid-codes");
 -  staticpro (&Qvalid_codes);
 -
 -  Qascii_incompatible = intern ("ascii-incompatible");
 -  staticpro (&Qascii_incompatible);
 +  DEFSYM (Qtranslation_table, "translation-table");
 +  Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2));
 +  DEFSYM (Qtranslation_table_id, "translation-table-id");
 +  DEFSYM (Qtranslation_table_for_decode, "translation-table-for-decode");
 +  DEFSYM (Qtranslation_table_for_encode, "translation-table-for-encode");
  
 -  Qemacs_mule = intern ("emacs-mule");
 -  staticpro (&Qemacs_mule);
 +  DEFSYM (Qvalid_codes, "valid-codes");
  
 -  Qraw_text = intern ("raw-text");
 -  staticpro (&Qraw_text);
 +  DEFSYM (Qemacs_mule, "emacs-mule");
  
 -  Qutf_8 = intern ("utf-8");
 -  staticpro (&Qutf_8);
 +  DEFSYM (QCcategory, ":category");
 +  DEFSYM (QCmnemonic, ":mnemonic");
 +  DEFSYM (QCdefalut_char, ":default-char");
 +  DEFSYM (QCdecode_translation_table, ":decode-translation-table");
 +  DEFSYM (QCencode_translation_table, ":encode-translation-table");
 +  DEFSYM (QCpost_read_conversion, ":post-read-conversion");
 +  DEFSYM (QCpre_write_conversion, ":pre-write-conversion");
 +  DEFSYM (QCascii_compatible_p, ":ascii-compatible-p");
  
 -  Qcoding_system_define_form = intern ("coding-system-define-form");
 -  staticpro (&Qcoding_system_define_form);
 +  Vcoding_category_table
 +    = Fmake_vector (make_number (coding_category_max), Qnil);
 +  staticpro (&Vcoding_category_table);
 +  /* Followings are target of code detection.  */
 +  ASET (Vcoding_category_table, coding_category_iso_7,
 +      intern ("coding-category-iso-7"));
 +  ASET (Vcoding_category_table, coding_category_iso_7_tight,
 +      intern ("coding-category-iso-7-tight"));
 +  ASET (Vcoding_category_table, coding_category_iso_8_1,
 +      intern ("coding-category-iso-8-1"));
 +  ASET (Vcoding_category_table, coding_category_iso_8_2,
 +      intern ("coding-category-iso-8-2"));
 +  ASET (Vcoding_category_table, coding_category_iso_7_else,
 +      intern ("coding-category-iso-7-else"));
 +  ASET (Vcoding_category_table, coding_category_iso_8_else,
 +      intern ("coding-category-iso-8-else"));
 +  ASET (Vcoding_category_table, coding_category_utf_8,
 +      intern ("coding-category-utf-8"));
 +  ASET (Vcoding_category_table, coding_category_utf_16_be,
 +      intern ("coding-category-utf-16-be"));
 +  ASET (Vcoding_category_table, coding_category_utf_16_auto,
 +      intern ("coding-category-utf-16-auto"));
 +  ASET (Vcoding_category_table, coding_category_utf_16_le,
 +      intern ("coding-category-utf-16-le"));
 +  ASET (Vcoding_category_table, coding_category_utf_16_be_nosig,
 +      intern ("coding-category-utf-16-be-nosig"));
 +  ASET (Vcoding_category_table, coding_category_utf_16_le_nosig,
 +      intern ("coding-category-utf-16-le-nosig"));
 +  ASET (Vcoding_category_table, coding_category_charset,
 +      intern ("coding-category-charset"));
 +  ASET (Vcoding_category_table, coding_category_sjis,
 +      intern ("coding-category-sjis"));
 +  ASET (Vcoding_category_table, coding_category_big5,
 +      intern ("coding-category-big5"));
 +  ASET (Vcoding_category_table, coding_category_ccl,
 +      intern ("coding-category-ccl"));
 +  ASET (Vcoding_category_table, coding_category_emacs_mule,
 +      intern ("coding-category-emacs-mule"));
 +  /* Followings are NOT target of code detection.  */
 +  ASET (Vcoding_category_table, coding_category_raw_text,
 +      intern ("coding-category-raw-text"));
 +  ASET (Vcoding_category_table, coding_category_undecided,
 +      intern ("coding-category-undecided"));
 +
 +  DEFSYM (Qinsufficient_source, "insufficient-source");
 +  DEFSYM (Qinconsistent_eol, "inconsistent-eol");
 +  DEFSYM (Qinvalid_source, "invalid-source");
 +  DEFSYM (Qinterrupted, "interrupted");
 +  DEFSYM (Qinsufficient_memory, "insufficient-memory");
 +  DEFSYM (Qcoding_system_define_form, "coding-system-define-form");
  
    defsubr (&Scoding_system_p);
    defsubr (&Sread_coding_system);
    defsubr (&Sdetect_coding_string);
    defsubr (&Sfind_coding_systems_region_internal);
    defsubr (&Sunencodable_char_position);
 +  defsubr (&Scheck_coding_systems_region);
    defsubr (&Sdecode_coding_region);
    defsubr (&Sencode_coding_region);
    defsubr (&Sdecode_coding_string);
    defsubr (&Sset_keyboard_coding_system_internal);
    defsubr (&Skeyboard_coding_system);
    defsubr (&Sfind_operation_coding_system);
 -  defsubr (&Supdate_coding_systems_internal);
 -  defsubr (&Sset_coding_priority_internal);
 +  defsubr (&Sset_coding_system_priority);
    defsubr (&Sdefine_coding_system_internal);
 +  defsubr (&Sdefine_coding_system_alias);
 +  defsubr (&Scoding_system_put);
 +  defsubr (&Scoding_system_base);
 +  defsubr (&Scoding_system_plist);
 +  defsubr (&Scoding_system_aliases);
 +  defsubr (&Scoding_system_eol_type);
 +  defsubr (&Scoding_system_priority_list);
  
    DEFVAR_LISP ("coding-system-list", &Vcoding_system_list,
               doc: /* List of coding systems.
  
  Do not alter the value of this variable manually.  This variable should be
 -updated by the functions `make-coding-system' and
 +updated by the functions `define-coding-system' and
  `define-coding-system-alias'.  */);
    Vcoding_system_list = Qnil;
  
@@@ -9530,7 -7908,7 +9530,7 @@@ Don't modify this variable directly, bu
      int i;
  
      Vcoding_category_list = Qnil;
 -    for (i = CODING_CATEGORY_IDX_MAX - 1; i >= 0; i--)
 +    for (i = coding_category_max - 1; i >= 0; i--)
        Vcoding_category_list
        = Fcons (XVECTOR (Vcoding_category_table)->contents[i],
                 Vcoding_category_list);
@@@ -9560,44 -7938,25 +9560,44 @@@ the value of `buffer-file-coding-system
    Vcoding_system_for_write = Qnil;
  
    DEFVAR_LISP ("last-coding-system-used", &Vlast_coding_system_used,
 -             doc: /* Coding system used in the latest file or process I/O.
 -Also set by `encode-coding-region', `decode-coding-region',
 -`encode-coding-string' and `decode-coding-string'.  */);
 +             doc: /*
 +Coding system used in the latest file or process I/O.  */);
    Vlast_coding_system_used = Qnil;
  
 +  DEFVAR_LISP ("last-code-conversion-error", &Vlast_code_conversion_error,
 +             doc: /*
 +Error status of the last code conversion.
 +
 +When an error was detected in the last code conversion, this variable
 +is set to one of the following symbols.
 +  `insufficient-source'
 +  `inconsistent-eol'
 +  `invalid-source'
 +  `interrupted'
 +  `insufficient-memory'
 +When no error was detected, the value doesn't change.  So, to check
 +the error status of a code conversion by this variable, you must
 +explicitly set this variable to nil before performing code
 +conversion.  */);
 +  Vlast_code_conversion_error = Qnil;
 +
    DEFVAR_BOOL ("inhibit-eol-conversion", &inhibit_eol_conversion,
 -             doc: /* *Non-nil means always inhibit code conversion of end-of-line format.
 +             doc: /*
 +*Non-nil means always inhibit code conversion of end-of-line format.
  See info node `Coding Systems' and info node `Text and Binary' concerning
  such conversion.  */);
    inhibit_eol_conversion = 0;
  
    DEFVAR_BOOL ("inherit-process-coding-system", &inherit_process_coding_system,
 -             doc: /* Non-nil means process buffer inherits coding system of process output.
 +             doc: /*
 +Non-nil means process buffer inherits coding system of process output.
  Bind it to t if the process output is to be treated as if it were a file
  read from some filesystem.  */);
    inherit_process_coding_system = 0;
  
    DEFVAR_LISP ("file-coding-system-alist", &Vfile_coding_system_alist,
 -             doc: /* Alist to decide a coding system to use for a file I/O operation.
 +             doc: /*
 +Alist to decide a coding system to use for a file I/O operation.
  The format is ((PATTERN . VAL) ...),
  where PATTERN is a regular expression matching a file name,
  VAL is a coding system, a cons of coding systems, or a function symbol.
@@@ -9606,16 -7965,16 +9606,16 @@@ the file contents
  If VAL is a cons of coding systems, the car part is used for decoding,
  and the cdr part is used for encoding.
  If VAL is a function symbol, the function must return a coding system
 -or a cons of coding systems which are used as above.  The function is
 -called with an argument that is a list of the arguments with which
 -`find-operation-coding-system' was called.
 +or a cons of coding systems which are used as above.  The function gets
 +the arguments with which `find-operation-coding-systems' was called.
  
  See also the function `find-operation-coding-system'
  and the variable `auto-coding-alist'.  */);
    Vfile_coding_system_alist = Qnil;
  
    DEFVAR_LISP ("process-coding-system-alist", &Vprocess_coding_system_alist,
 -    doc: /* Alist to decide a coding system to use for a process I/O operation.
 +             doc: /*
 +Alist to decide a coding system to use for a process I/O operation.
  The format is ((PATTERN . VAL) ...),
  where PATTERN is a regular expression matching a program name,
  VAL is a coding system, a cons of coding systems, or a function symbol.
@@@ -9630,8 -7989,7 +9630,8 @@@ See also the function `find-operation-c
    Vprocess_coding_system_alist = Qnil;
  
    DEFVAR_LISP ("network-coding-system-alist", &Vnetwork_coding_system_alist,
 -    doc: /* Alist to decide a coding system to use for a network I/O operation.
 +             doc: /*
 +Alist to decide a coding system to use for a network I/O operation.
  The format is ((PATTERN . VAL) ...),
  where PATTERN is a regular expression matching a network service name
  or is a port number to connect to,
@@@ -9653,28 -8011,23 +9653,28 @@@ Also used for decoding keyboard input o
  
    /* The eol mnemonics are reset in startup.el system-dependently.  */
    DEFVAR_LISP ("eol-mnemonic-unix", &eol_mnemonic_unix,
 -             doc: /* *String displayed in mode line for UNIX-like (LF) end-of-line format.  */);
 +             doc: /*
 +*String displayed in mode line for UNIX-like (LF) end-of-line format.  */);
    eol_mnemonic_unix = build_string (":");
  
    DEFVAR_LISP ("eol-mnemonic-dos", &eol_mnemonic_dos,
 -             doc: /* *String displayed in mode line for DOS-like (CRLF) end-of-line format.  */);
 +             doc: /*
 +*String displayed in mode line for DOS-like (CRLF) end-of-line format.  */);
    eol_mnemonic_dos = build_string ("\\");
  
    DEFVAR_LISP ("eol-mnemonic-mac", &eol_mnemonic_mac,
 -             doc: /* *String displayed in mode line for MAC-like (CR) end-of-line format.  */);
 +             doc: /*
 +*String displayed in mode line for MAC-like (CR) end-of-line format.  */);
    eol_mnemonic_mac = build_string ("/");
  
    DEFVAR_LISP ("eol-mnemonic-undecided", &eol_mnemonic_undecided,
 -             doc: /* *String displayed in mode line when end-of-line format is not yet determined.  */);
 +             doc: /*
 +*String displayed in mode line when end-of-line format is not yet determined.  */);
    eol_mnemonic_undecided = build_string (":");
  
    DEFVAR_LISP ("enable-character-translation", &Venable_character_translation,
 -             doc: /* *Non-nil enables character translation while encoding and decoding.  */);
 +             doc: /*
 +*Non-nil enables character translation while encoding and decoding.  */);
    Venable_character_translation = Qt;
  
    DEFVAR_LISP ("standard-translation-table-for-decode",
               doc: /* Table for translating characters while encoding.  */);
    Vstandard_translation_table_for_encode = Qnil;
  
 -  DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_alist,
 +  DEFVAR_LISP ("charset-revision-table", &Vcharset_revision_table,
               doc: /* Alist of charsets vs revision numbers.
  While encoding, if a charset (car part of an element) is found,
 -designate it with the escape sequence identifying revision (cdr part of the element).  */);
 -  Vcharset_revision_alist = Qnil;
 +designate it with the escape sequence identifying revision (cdr part
 +of the element).  */);
 +  Vcharset_revision_table = Qnil;
  
    DEFVAR_LISP ("default-process-coding-system",
               &Vdefault_process_coding_system,
@@@ -9702,8 -8054,7 +9702,8 @@@ the cdr part is used for encoding a tex
    Vdefault_process_coding_system = Qnil;
  
    DEFVAR_LISP ("latin-extra-code-table", &Vlatin_extra_code_table,
 -             doc: /* Table of extra Latin codes in the range 128..159 (inclusive).
 +             doc: /*
 +Table of extra Latin codes in the range 128..159 (inclusive).
  This is a vector of length 256.
  If Nth element is non-nil, the existence of code N in a file
  \(or output of subprocess) doesn't prevent it to be detected as
@@@ -9715,8 -8066,7 +9715,8 @@@ Only 128th through 159th elements has 
  
    DEFVAR_LISP ("select-safe-coding-system-function",
               &Vselect_safe_coding_system_function,
 -             doc: /* Function to call to select safe coding system for encoding a text.
 +             doc: /*
 +Function to call to select safe coding system for encoding a text.
  
  If set, this function is called to force a user to select a proper
  coding system which can encode the text in the case that a default
@@@ -9736,8 -8086,7 +9736,8 @@@ called even if `coding-system-for-write
  
    DEFVAR_BOOL ("inhibit-iso-escape-detection",
               &inhibit_iso_escape_detection,
 -             doc: /* If non-nil, Emacs ignores ISO2022's escape sequence on code detection.
 +             doc: /*
 +If non-nil, Emacs ignores ISO2022's escape sequence on code detection.
  
  By default, on reading a file, Emacs tries to detect how the text is
  encoded.  This code detection is sensitive to escape sequences.  If
@@@ -9767,68 -8116,6 +9767,68 @@@ escape sequence (e.g `latin-1') on read
  This is applied to the result of input methods, not their input.  See also
  `keyboard-translate-table'.  */);
      Vtranslation_table_for_input = Qnil;
 +
 +  {
 +    Lisp_Object args[coding_arg_max];
 +    Lisp_Object plist[16];
 +    int i;
 +
 +    for (i = 0; i < coding_arg_max; i++)
 +      args[i] = Qnil;
 +
 +    plist[0] = intern (":name");
 +    plist[1] = args[coding_arg_name] = Qno_conversion;
 +    plist[2] = intern (":mnemonic");
 +    plist[3] = args[coding_arg_mnemonic] = make_number ('=');
 +    plist[4] = intern (":coding-type");
 +    plist[5] = args[coding_arg_coding_type] = Qraw_text;
 +    plist[6] = intern (":ascii-compatible-p");
 +    plist[7] = args[coding_arg_ascii_compatible_p] = Qt;
 +    plist[8] = intern (":default-char");
 +    plist[9] = args[coding_arg_default_char] = make_number (0);
 +    plist[10] = intern (":for-unibyte");
 +    plist[11] = args[coding_arg_for_unibyte] = Qt;
 +    plist[12] = intern (":docstring");
 +    plist[13] = build_string ("Do no conversion.\n\
 +\n\
 +When you visit a file with this coding, the file is read into a\n\
 +unibyte buffer as is, thus each byte of a file is treated as a\n\
 +character.");
 +    plist[14] = intern (":eol-type");
 +    plist[15] = args[coding_arg_eol_type] = Qunix;
 +    args[coding_arg_plist] = Flist (16, plist);
 +    Fdefine_coding_system_internal (coding_arg_max, args);
 +
 +    plist[1] = args[coding_arg_name] = Qundecided;
 +    plist[3] = args[coding_arg_mnemonic] = make_number ('-');
 +    plist[5] = args[coding_arg_coding_type] = Qundecided;
 +    /* This is already set.
 +       plist[7] = args[coding_arg_ascii_compatible_p] = Qt; */
 +    plist[8] = intern (":charset-list");
 +    plist[9] = args[coding_arg_charset_list] = Fcons (Qascii, Qnil);
 +    plist[11] = args[coding_arg_for_unibyte] = Qnil;
 +    plist[13] = build_string ("No conversion on encoding, automatic conversion on decoding.");
 +    plist[15] = args[coding_arg_eol_type] = Qnil;
 +    args[coding_arg_plist] = Flist (16, plist);
 +    Fdefine_coding_system_internal (coding_arg_max, args);
 +  }
 +
 +  setup_coding_system (Qno_conversion, &keyboard_coding);
 +  setup_coding_system (Qundecided, &terminal_coding);
 +  setup_coding_system (Qno_conversion, &safe_terminal_coding);
 +
 +  {
 +    int i;
 +
 +    for (i = 0; i < coding_category_max; i++)
 +      Fset (AREF (Vcoding_category_table, i), Qno_conversion);
 +  }
 +#if defined (MSDOS) || defined (WINDOWSNT)
 +  system_eol_type = Qdos;
 +#else
 +  system_eol_type = Qunix;
 +#endif
 +  staticpro (&system_eol_type);
  }
  
  char *
diff --combined src/coding.h
index 0f8d2b0ed7bc0785818f041153056010d7e1232b,b4e2668622992d6bfec36c8db0f41490e0f9e137..f33e8335752d3245a5a92372cfa0eb3135e8d7a3
@@@ -1,13 -1,10 +1,13 @@@
  /* Header for coding system handler.
-    Copyright (C) 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+    Copyright (C) 2001, 2002, 2003, 2004, 2005,
+                  2006, 2007  Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -29,253 -26,306 +29,253 @@@ Boston, MA 02110-1301, USA.  *
  #ifndef EMACS_CODING_H
  #define EMACS_CODING_H
  
 -#include "ccl.h"
 +/* Index to arguments of Fdefine_coding_system_internal.  */
  
 -/*** EMACS' INTERNAL FORMAT (emacs-mule) section ***/
 +enum define_coding_system_arg_index
 +  {
 +    coding_arg_name,
 +    coding_arg_mnemonic,
 +    coding_arg_coding_type,
 +    coding_arg_charset_list,
 +    coding_arg_ascii_compatible_p,
 +    coding_arg_decode_translation_table,
 +    coding_arg_encode_translation_table,
 +    coding_arg_post_read_conversion,
 +    coding_arg_pre_write_conversion,
 +    coding_arg_default_char,
 +    coding_arg_for_unibyte,
 +    coding_arg_plist,
 +    coding_arg_eol_type,
 +    coding_arg_max
 +  };
  
 -/* All code (1-byte) of Emacs' internal format is classified into one
 -   of the followings.  See also `charset.h'.  */
 -enum emacs_code_class_type
 +enum define_coding_iso2022_arg_index
    {
 -    EMACS_control_code,               /* Control codes in the range
 -                                 0x00..0x1F and 0x7F except for the
 -                                 following two codes.  */
 -    EMACS_linefeed_code,      /* 0x0A (linefeed) to denote
 -                                 end-of-line.  */
 -    EMACS_carriage_return_code,       /* 0x0D (carriage-return) to be used
 -                                 in selective display mode.  */
 -    EMACS_ascii_code,         /* ASCII characters.  */
 -    EMACS_leading_code_2,     /* Base leading code of official
 -                                 TYPE9N character.  */
 -    EMACS_leading_code_3,     /* Base leading code of private TYPE9N
 -                                 or official TYPE9Nx9N character.  */
 -    EMACS_leading_code_4,     /* Base leading code of private
 -                                 TYPE9Nx9N character.  */
 -    EMACS_invalid_code                /* Invalid code, i.e. a base leading
 -                                 code not yet assigned to any
 -                                 charset, or a code of the range
 -                                 0xA0..0xFF.  */
 +    coding_arg_iso2022_initial = coding_arg_max,
 +    coding_arg_iso2022_reg_usage,
 +    coding_arg_iso2022_request,
 +    coding_arg_iso2022_flags,
 +    coding_arg_iso2022_max
    };
  
 -extern enum emacs_code_class_type emacs_code_class[256];
 -
 -/*** ISO2022 section ***/
 -
 -/* Macros to define code of control characters for ISO2022's functions.  */
 -                      /* code */      /* function */
 -#define ISO_CODE_LF   0x0A            /* line-feed */
 -#define ISO_CODE_CR   0x0D            /* carriage-return */
 -#define ISO_CODE_SO   0x0E            /* shift-out */
 -#define ISO_CODE_SI   0x0F            /* shift-in */
 -#define ISO_CODE_SS2_7        0x19            /* single-shift-2 for 7-bit code */
 -#define ISO_CODE_ESC  0x1B            /* escape */
 -#define ISO_CODE_SS2  0x8E            /* single-shift-2 */
 -#define ISO_CODE_SS3  0x8F            /* single-shift-3 */
 -#define ISO_CODE_CSI  0x9B            /* control-sequence-introduce */
 -
 -/* All code (1-byte) of ISO2022 is classified into one of the
 -   followings.  */
 -enum iso_code_class_type
 +enum define_coding_utf16_arg_index
    {
 -    ISO_control_0,            /* Control codes in the range
 -                                 0x00..0x1F and 0x7F, except for the
 -                                 following 5 codes.  */
 -    ISO_carriage_return,      /* ISO_CODE_CR (0x0D) */
 -    ISO_shift_out,            /* ISO_CODE_SO (0x0E) */
 -    ISO_shift_in,             /* ISO_CODE_SI (0x0F) */
 -    ISO_single_shift_2_7,     /* ISO_CODE_SS2_7 (0x19) */
 -    ISO_escape,                       /* ISO_CODE_SO (0x1B) */
 -    ISO_control_1,            /* Control codes in the range
 -                                 0x80..0x9F, except for the
 -                                 following 3 codes.  */
 -    ISO_single_shift_2,               /* ISO_CODE_SS2 (0x8E) */
 -    ISO_single_shift_3,               /* ISO_CODE_SS3 (0x8F) */
 -    ISO_control_sequence_introducer, /* ISO_CODE_CSI (0x9B) */
 -    ISO_0x20_or_0x7F,         /* Codes of the values 0x20 or 0x7F.  */
 -    ISO_graphic_plane_0,      /* Graphic codes in the range 0x21..0x7E.  */
 -    ISO_0xA0_or_0xFF,         /* Codes of the values 0xA0 or 0xFF.  */
 -    ISO_graphic_plane_1               /* Graphic codes in the range 0xA1..0xFE.  */
 +    coding_arg_utf16_bom = coding_arg_max,
 +    coding_arg_utf16_endian,
 +    coding_arg_utf16_max
    };
  
 -/** The macros CODING_FLAG_ISO_XXX defines a flag bit of the `flags'
 -  element in the structure `coding_system'.  This information is used
 -  while encoding a text to ISO2022.  **/
 +enum define_coding_ccl_arg_index
 +  {
 +    coding_arg_ccl_decoder = coding_arg_max,
 +    coding_arg_ccl_encoder,
 +    coding_arg_ccl_valids,
 +    coding_arg_ccl_max
 +  };
  
 -/* If set, produce short-form designation sequence (e.g. ESC $ A)
 -   instead of long-form sequence (e.g. ESC $ ( A).  */
 -#define CODING_FLAG_ISO_SHORT_FORM    0x0001
 +/* Hash table for all coding systems.  Keys are coding system symbols
 +   and values are spec vectors of the corresponding coding system.  A
 +   spec vector has the form [ ATTRS ALIASES EOL-TYPE ].  ATTRS is a
 +   vector of attribute of the coding system.  ALIASES is a list of
 +   aliases (symbols) of the coding system.  EOL-TYPE is `unix', `dos',
 +   `mac' or a vector of coding systems (symbols).  */
  
 -/* If set, reset graphic planes and registers at end-of-line to the
 -   initial state.  */
 -#define CODING_FLAG_ISO_RESET_AT_EOL  0x0002
 +extern Lisp_Object Vcoding_system_hash_table;
  
 -/* If set, reset graphic planes and registers before any control
 -   characters to the initial state.  */
 -#define CODING_FLAG_ISO_RESET_AT_CNTL 0x0004
  
 -/* If set, encode by 7-bit environment.  */
 -#define CODING_FLAG_ISO_SEVEN_BITS    0x0008
 +/* Enumeration of coding system type.  */
  
 -/* If set, use locking-shift function.  */
 -#define CODING_FLAG_ISO_LOCKING_SHIFT 0x0010
 +enum coding_system_type
 +  {
 +    coding_type_charset,
 +    coding_type_utf_8,
 +    coding_type_utf_16,
 +    coding_type_iso_2022,
 +    coding_type_emacs_mule,
 +    coding_type_sjis,
 +    coding_type_ccl,
 +    coding_type_raw_text,
 +    coding_type_undecided,
 +    coding_type_max
 +  };
  
 -/* If set, use single-shift function.  Overwrite
 -   CODING_FLAG_ISO_LOCKING_SHIFT.  */
 -#define CODING_FLAG_ISO_SINGLE_SHIFT  0x0020
  
 -/* If set, designate JISX0201-Roman instead of ASCII.  */
 -#define CODING_FLAG_ISO_USE_ROMAN     0x0040
 +/* Enumeration of end-of-line format type.  */
  
 -/* If set, designate JISX0208-1978 instead of JISX0208-1983.  */
 -#define CODING_FLAG_ISO_USE_OLDJIS    0x0080
 +enum end_of_line_type
 +  {
 +    eol_lf,           /* Line-feed only, same as Emacs' internal
 +                         format.  */
 +    eol_crlf,         /* Sequence of carriage-return and
 +                         line-feed.  */
 +    eol_cr,           /* Carriage-return only.  */
 +    eol_any,          /* Accept any of above.  Produce line-feed
 +                         only.  */
 +    eol_undecided,    /* This value is used to denote that the
 +                         eol-type is not yet undecided.  */
 +    eol_type_max
 +  };
  
 -/* If set, do not produce ISO6429's direction specifying sequence.  */
 -#define CODING_FLAG_ISO_NO_DIRECTION  0x0100
 +/* Enumeration of index to an attribute vector of a coding system.  */
  
 -/* If set, assume designation states are reset at beginning of line on
 -   output.  */
 -#define CODING_FLAG_ISO_INIT_AT_BOL   0x0200
 +enum coding_attr_index
 +  {
 +    coding_attr_base_name,
 +    coding_attr_docstring,
 +    coding_attr_mnemonic,
 +    coding_attr_type,
 +    coding_attr_charset_list,
 +    coding_attr_ascii_compat,
 +    coding_attr_decode_tbl,
 +    coding_attr_encode_tbl,
 +    coding_attr_trans_tbl,
 +    coding_attr_post_read,
 +    coding_attr_pre_write,
 +    coding_attr_default_char,
 +    coding_attr_for_unibyte,
 +    coding_attr_plist,
 +
 +    coding_attr_category,
 +    coding_attr_safe_charsets,
 +
 +    /* The followings are extra attributes for each type.  */
 +    coding_attr_charset_valids,
 +
 +    coding_attr_ccl_decoder,
 +    coding_attr_ccl_encoder,
 +    coding_attr_ccl_valids,
 +
 +    coding_attr_iso_initial,
 +    coding_attr_iso_usage,
 +    coding_attr_iso_request,
 +    coding_attr_iso_flags,
 +
 +    coding_attr_utf_16_bom,
 +    coding_attr_utf_16_endian,
 +
 +    coding_attr_emacs_mule_full,
 +
 +    coding_attr_last_index
 +  };
  
 -/* If set, designation sequence should be placed at beginning of line
 -   on output.  */
 -#define CODING_FLAG_ISO_DESIGNATE_AT_BOL 0x0400
  
 -/* If set, do not encode unsafe characters on output.  */
 -#define CODING_FLAG_ISO_SAFE          0x0800
 +/* Macros to access an element of an attribute vector.  */
  
 -/* If set, extra latin codes (128..159) are accepted as a valid code
 -   on input.  */
 -#define CODING_FLAG_ISO_LATIN_EXTRA   0x1000
 +#define CODING_ATTR_BASE_NAME(attrs)  AREF (attrs, coding_attr_base_name)
 +#define CODING_ATTR_TYPE(attrs)               AREF (attrs, coding_attr_type)
 +#define CODING_ATTR_CHARSET_LIST(attrs)       AREF (attrs, coding_attr_charset_list)
 +#define CODING_ATTR_MNEMONIC(attrs)   AREF (attrs, coding_attr_mnemonic)
 +#define CODING_ATTR_DOCSTRING(attrs)  AREF (attrs, coding_attr_docstring)
 +#define CODING_ATTR_ASCII_COMPAT(attrs)       AREF (attrs, coding_attr_ascii_compat)
 +#define CODING_ATTR_DECODE_TBL(attrs) AREF (attrs, coding_attr_decode_tbl)
 +#define CODING_ATTR_ENCODE_TBL(attrs) AREF (attrs, coding_attr_encode_tbl)
 +#define CODING_ATTR_TRANS_TBL(attrs)  AREF (attrs, coding_attr_trans_tbl)
 +#define CODING_ATTR_POST_READ(attrs)  AREF (attrs, coding_attr_post_read)
 +#define CODING_ATTR_PRE_WRITE(attrs)  AREF (attrs, coding_attr_pre_write)
 +#define CODING_ATTR_DEFAULT_CHAR(attrs)       AREF (attrs, coding_attr_default_char)
 +#define CODING_ATTR_FOR_UNIBYTE(attrs)        AREF (attrs, coding_attr_for_unibyte)
 +#define CODING_ATTR_FLUSHING(attrs)   AREF (attrs, coding_attr_flushing)
 +#define CODING_ATTR_PLIST(attrs)      AREF (attrs, coding_attr_plist)
 +#define CODING_ATTR_CATEGORY(attrs)   AREF (attrs, coding_attr_category)
 +#define CODING_ATTR_SAFE_CHARSETS(attrs)AREF (attrs, coding_attr_safe_charsets)
  
 -/* If set, use designation escape sequence.  */
 -#define CODING_FLAG_ISO_DESIGNATION   0x10000
  
 -/* A character to be produced on output if encoding of the original
 -   character is inhibitted by CODING_MODE_INHIBIT_UNENCODABLE_CHAR.
 -   It must be an ASCII character.  */
 -#define CODING_REPLACEMENT_CHARACTER '?'
 +/* Return the name of a coding system specified by ID.  */
 +#define CODING_ID_NAME(id) \
 +  (HASH_KEY (XHASH_TABLE (Vcoding_system_hash_table), id))
  
 -/* Structure of the field `spec.iso2022' in the structure `coding_system'.  */
 -struct iso2022_spec
 -{
 -  /* The current graphic register invoked to each graphic plane.  */
 -  int current_invocation[2];
 +/* Return the attribute vector of a coding system specified by ID.  */
  
 -  /* The current charset designated to each graphic register.  */
 -  int current_designation[4];
 +#define CODING_ID_ATTRS(id)   \
 +  (AREF (HASH_VALUE (XHASH_TABLE (Vcoding_system_hash_table), id), 0))
  
 -  /* A charset initially designated to each graphic register.  */
 -  int initial_designation[4];
 +/* Return the list of aliases of a coding system specified by ID.  */
  
 -  /* If not -1, it is a graphic register specified in an invalid
 -     designation sequence.  */
 -  int last_invalid_designation_register;
 +#define CODING_ID_ALIASES(id) \
 +  (AREF (HASH_VALUE (XHASH_TABLE (Vcoding_system_hash_table), id), 1))
  
 -  /* A graphic register to which each charset should be designated.  */
 -  unsigned char requested_designation[MAX_CHARSET + 1];
 +/* Return the eol-type of a coding system specified by ID.  */
  
 -  /* A revision number to be specified for each charset on encoding.
 -     The value 255 means no revision number for the corresponding
 -     charset.  */
 -  unsigned char charset_revision_number[MAX_CHARSET + 1];
 +#define CODING_ID_EOL_TYPE(id)        \
 +  (AREF (HASH_VALUE (XHASH_TABLE (Vcoding_system_hash_table), id), 2))
  
 -  /* Set to 1 temporarily only when graphic register 2 or 3 is invoked
 -     by single-shift while encoding.  */
 -  int single_shifting;
  
 -  /* Set to 1 temporarily only when processing at beginning of line.  */
 -  int bol;
 -};
 +/* Return the spec vector of CODING_SYSTEM_SYMBOL.  */
 +
 +#define CODING_SYSTEM_SPEC(coding_system_symbol)      \
 +  (Fgethash (coding_system_symbol, Vcoding_system_hash_table, Qnil))
 +
 +
 +/* Return the ID of CODING_SYSTEM_SYMBOL.  */
 +
 +#define CODING_SYSTEM_ID(coding_system_symbol)                        \
 +  hash_lookup (XHASH_TABLE (Vcoding_system_hash_table),               \
 +             coding_system_symbol, NULL)
 +
 +/* Return 1 iff CODING_SYSTEM_SYMBOL is a coding system.  */
 +
 +#define CODING_SYSTEM_P(coding_system_symbol)         \
 +  (CODING_SYSTEM_ID (coding_system_symbol) >= 0               \
 +   || (! NILP (coding_system_symbol)                  \
 +       && ! NILP (Fcoding_system_p (coding_system_symbol))))
 +
 +/* Check if X is a coding system or not.  */
 +
 +#define CHECK_CODING_SYSTEM(x)                                \
 +  do {                                                        \
 +    if (CODING_SYSTEM_ID (x) < 0                      \
 +      && NILP (Fcheck_coding_system (x)))             \
 +      wrong_type_argument (Qcoding_system_p, (x));    \
 +  } while (0)
 +
 +
 +/* Check if X is a coding system or not.  If it is, set SEPC to the
 +   spec vector of the coding system.  */
 +
 +#define CHECK_CODING_SYSTEM_GET_SPEC(x, spec)         \
 +  do {                                                        \
 +    spec = CODING_SYSTEM_SPEC (x);                    \
 +    if (NILP (spec))                                  \
 +      {                                                       \
 +      Fcheck_coding_system (x);                       \
 +      spec = CODING_SYSTEM_SPEC (x);                  \
 +      }                                                       \
 +    if (NILP (spec))                                  \
 +      x = wrong_type_argument (Qcoding_system_p, (x));        \
 +  } while (0)
 +
 +
 +/* Check if X is a coding system or not.  If it is, set ID to the
 +   ID of the coding system.  */
 +
 +#define CHECK_CODING_SYSTEM_GET_ID(x, id)                     \
 +  do                                                          \
 +    {                                                         \
 +      id = CODING_SYSTEM_ID (x);                              \
 +      if (id < 0)                                             \
 +      {                                                       \
 +        Fcheck_coding_system (x);                             \
 +        id = CODING_SYSTEM_ID (x);                            \
 +      }                                                       \
 +      if (id < 0)                                             \
 +      x = wrong_type_argument (Qcoding_system_p, (x));        \
 +    } while (0)
  
 -/* Macros to access each field in the structure `spec.iso2022'.  */
 -#define CODING_SPEC_ISO_INVOCATION(coding, plane) \
 -  (coding)->spec.iso2022.current_invocation[plane]
 -#define CODING_SPEC_ISO_DESIGNATION(coding, reg) \
 -  (coding)->spec.iso2022.current_designation[reg]
 -#define CODING_SPEC_ISO_INITIAL_DESIGNATION(coding, reg) \
 -  (coding)->spec.iso2022.initial_designation[reg]
 -#define CODING_SPEC_ISO_REQUESTED_DESIGNATION(coding, charset) \
 -  (coding)->spec.iso2022.requested_designation[charset]
 -#define CODING_SPEC_ISO_REVISION_NUMBER(coding, charset) \
 -  (coding)->spec.iso2022.charset_revision_number[charset]
 -#define CODING_SPEC_ISO_SINGLE_SHIFTING(coding) \
 -  (coding)->spec.iso2022.single_shifting
 -#define CODING_SPEC_ISO_BOL(coding) \
 -  (coding)->spec.iso2022.bol
 -
 -/* A value which may appear in
 -   coding->spec.iso2022.requested_designation indicating that the
 -   corresponding charset does not request any graphic register to be
 -   designated.  */
 -#define CODING_SPEC_ISO_NO_REQUESTED_DESIGNATION 4
 -
 -/* Return a charset which is currently designated to the graphic plane
 -   PLANE in the coding-system CODING.  */
 -#define CODING_SPEC_ISO_PLANE_CHARSET(coding, plane)  \
 -  ((CODING_SPEC_ISO_INVOCATION (coding, plane) < 0)   \
 -   ? -1                                                       \
 -   : CODING_SPEC_ISO_DESIGNATION (coding,             \
 -                                CODING_SPEC_ISO_INVOCATION (coding, plane)))
 -
 -/*** BIG5 section ***/
 -
 -/* Macros to denote each type of BIG5 coding system.  */
 -#define CODING_FLAG_BIG5_HKU  0x00 /* BIG5-HKU is one of variants of
 -                                      BIG5 developed by Hong Kong
 -                                      University.  */
 -#define CODING_FLAG_BIG5_ETEN 0x01 /* BIG5_ETen is one of variants
 -                                      of BIG5 developed by the
 -                                      company ETen in Taiwan.  */
  
  /*** GENERAL section ***/
  
 -/* Types of coding system.  */
 -enum coding_type
 +/* Enumeration of result code of code conversion.  */
 +enum coding_result_code
    {
 -    coding_type_no_conversion,        /* A coding system which requires no
 -                                 conversion for reading and writing
 -                                 including end-of-line format.  */
 -    coding_type_emacs_mule,   /* A coding system used in Emacs'
 -                                 buffer and string.  Requires no
 -                                 conversion for reading and writing
 -                                 except for end-of-line format.  */
 -    coding_type_undecided,    /* A coding system which requires
 -                                 automatic detection of a real
 -                                 coding system.  */
 -    coding_type_sjis,         /* SJIS coding system for Japanese.  */
 -    coding_type_iso2022,      /* Any coding system of ISO2022
 -                                 variants.  */
 -    coding_type_big5,         /* BIG5 coding system for Chinese.  */
 -    coding_type_ccl,          /* The coding system of which decoder
 -                                 and encoder are written in CCL.  */
 -    coding_type_raw_text      /* A coding system for a text
 -                                 containing random 8-bit code which
 -                                 does not require code conversion
 -                                 except for end-of-line format. */
 +    CODING_RESULT_SUCCESS,
 +    CODING_RESULT_INSUFFICIENT_SRC,
 +    CODING_RESULT_INSUFFICIENT_DST,
 +    CODING_RESULT_INCONSISTENT_EOL,
 +    CODING_RESULT_INVALID_SRC,
 +    CODING_RESULT_INTERRUPT,
 +    CODING_RESULT_INSUFFICIENT_MEM
    };
  
 -/* Formats of end-of-line.  */
 -#define CODING_EOL_LF 0       /* Line-feed only, same as Emacs'
 -                                 internal format.  */
 -#define CODING_EOL_CRLF       1       /* Sequence of carriage-return and
 -                                 line-feed.  */
 -#define CODING_EOL_CR 2       /* Carriage-return only.  */
 -#define CODING_EOL_UNDECIDED 3        /* This value is used to denote the
 -                                 eol-type is not yet decided.  */
 -#define CODING_EOL_INCONSISTENT 4 /* This value is used to denote the
 -                                   eol-type is not consistent
 -                                   through the file.  */
 -
 -/* 1 iff composing.  */
 -#define COMPOSING_P(coding) ((int) coding->composing > (int) COMPOSITION_NO)
 -
 -#define COMPOSITION_DATA_SIZE 4080
 -#define COMPOSITION_DATA_MAX_BUNCH_LENGTH (4 + MAX_COMPOSITION_COMPONENTS*2)
 -
 -/* Data structure to hold information about compositions of text that
 -   is being decoded or encode.  ISO 2022 base code conversion routines
 -   handle special ESC sequences for composition specification.  But,
 -   they can't get/put such information directly from/to a buffer in
 -   the deepest place.  So, they store or retrieve the information
 -   through this structure.
 -
 -   The encoder stores the information in this structure when it meets
 -   ESC sequences for composition while encoding codes, then, after all
 -   text codes are encoded, puts `composition' properties on the text
 -   by referring to the structure.
 -
 -   The decoder at first stores the information of a text to be
 -   decoded, then, while decoding codes, generates ESC sequences for
 -   composition at proper places by referring to the structure.  */
 -
 -struct composition_data
 -{
 -  /* The character position of the first character to be encoded or
 -     decoded.  START and END (see below) are relative to this
 -     position.  */
 -  int char_offset;
 -
 -  /* The composition data.  These elements are repeated for each
 -     composition:
 -      LENGTH START END METHOD [ COMPONENT ... ]
 -     where,
 -        LENGTH is the number of elements for this composition.
 -
 -      START and END are starting and ending character positions of
 -      the composition relative to `char_offset'.
 -
 -      METHOD is one of `enum composing_status' specifying the way of
 -      composition.
 -
 -      COMPONENT is a character or an encoded composition rule.  */
 -  int data[COMPOSITION_DATA_SIZE];
 -
 -  /* The number of elements in `data' currently used.  */
 -  int used;
 -
 -  /* Pointers to the previous and next structures.  When `data' is
 -     filled up, another structure is allocated and linked in `next'.
 -     The new structure has backward link to this structure in `prev'.
 -     The number of chained structures depends on how many compositions
 -     the text being encoded or decoded contains.  */
 -  struct composition_data *prev, *next;
 -};
 -
 -/* Macros used for the member `result' of the struct
 -   coding_system.  */
 -#define CODING_FINISH_NORMAL          0
 -#define CODING_FINISH_INSUFFICIENT_SRC        1
 -#define CODING_FINISH_INSUFFICIENT_DST        2
 -#define CODING_FINISH_INCONSISTENT_EOL        3
 -#define CODING_FINISH_INSUFFICIENT_CMP        4
 -#define CODING_FINISH_INTERRUPT               5
  
  /* Macros used for the member `mode' of the struct coding_system.  */
  
  #define CODING_MODE_INHIBIT_INCONSISTENT_EOL  0x01
  
  /* If set, the decoding/encoding routines treat the current data as
 -   the last block of the whole text to be converted, and do
 +   the last block of the whole text to be converted, and do the
     appropriate finishing job.  */
  #define CODING_MODE_LAST_BLOCK                        0x02
  
     enables selective display.  */
  #define CODING_MODE_SELECTIVE_DISPLAY         0x04
  
 -/* If set, replace unencodabae characters by `?' on encoding.  */
 -#define CODING_MODE_INHIBIT_UNENCODABLE_CHAR  0x08
 -
  /* This flag is used by the decoding/encoding routines on the fly.  If
     set, it means that right-to-left text is being processed.  */
 -#define CODING_MODE_DIRECTION                 0x10
 +#define CODING_MODE_DIRECTION                 0x08
  
 -struct coding_system
 +#define CODING_MODE_FIXED_DESTINATION         0x10
 +
 +/* If set, it means that the encoding routines produces some safe
 +   ASCII characters (usually '?') for unsupported characters.  */
 +#define CODING_MODE_SAFE_ENCODING             0x20
 +
 +/* Structure of the field `spec.iso_2022' in the structure
 +   `coding_system'.  */
 +struct iso_2022_spec
  {
 -  /* Type of the coding system.  */
 -  enum coding_type type;
 +  /* Bit-wise-or of CODING_ISO_FLAG_XXX.  */
 +  unsigned flags;
  
 -  /* Type of end-of-line format (LF, CRLF, or CR) of the coding system.  */
 -  int eol_type;
 +  /* The current graphic register invoked to each graphic plane.  */
 +  int current_invocation[2];
  
 -  /* Flag bits of the coding system.  The meaning of each bit is common
 -     to all types of coding systems.  */
 -  unsigned int common_flags;
 +  /* The current charset designated to each graphic register.  The
 +     value -1 means that not charset is designated, -2 means that
 +     there was an invalid designation previously.  */
 +  int current_designation[4];
  
 -  /* Flag bits of the coding system.  The meaning of each bit depends
 -     on the type of the coding system.  */
 -  unsigned int flags;
 +  /* Set to 1 temporarily only when graphic register 2 or 3 is invoked
 +     by single-shift while encoding.  */
 +  int single_shifting;
  
 -  /* Mode bits of the coding system.  See the comments of the macros
 -     CODING_MODE_XXX.  */
 -  unsigned int mode;
 +  /* Set to 1 temporarily only when processing at beginning of line.  */
 +  int bol;
 +};
 +
 +struct ccl_spec;
 +
 +enum utf_16_bom_type
 +  {
 +    utf_16_detect_bom,
 +    utf_16_without_bom,
 +    utf_16_with_bom
 +  };
 +
 +enum utf_16_endian_type
 +  {
 +    utf_16_big_endian,
 +    utf_16_little_endian
 +  };
 +
 +struct utf_16_spec
 +{
 +  enum utf_16_bom_type bom;
 +  enum utf_16_endian_type endian;
 +  int surrogate;
 +};
  
 -  /* The current status of composition handling.  */
 -  int composing;
 +struct coding_detection_info
 +{
 +  /* Values of these members are bitwise-OR of CATEGORY_MASK_XXXs.  */
 +  /* Which categories are already checked.  */
 +  int checked;
 +  /* Which categories are strongly found.  */
 +  int found;
 +  /* Which categories are rejected.  */
 +  int rejected;
 +};
  
 -  /* 1 iff the next character is a composition rule.  */
 -  int composition_rule_follows;
  
 -  /* Information of compositions are stored here on decoding and set
 -     in advance on encoding.  */
 -  struct composition_data *cmp_data;
 +struct coding_system
 +{
 +  /* ID number of the coding system.  This is an index to
 +     Vcoding_system_hash_table.  This value is set by
 +     setup_coding_system.  At the early stage of building time, this
 +     value is -1 in the array coding_categories to indicate that no
 +     coding-system of that category is yet defined.  */
 +  int id;
  
 -  /* Index to cmp_data->data for the first element for the current
 -     composition.  */
 -  int cmp_data_start;
 +  /* Flag bits of the coding system.  The meaning of each bit is common
 +     to all types of coding systems.  */
 +  int common_flags;
  
 -  /* Index to cmp_data->data for the current element for the current
 -     composition.  */
 -  int cmp_data_index;
 +  /* Mode bits of the coding system.  See the comments of the macros
 +     CODING_MODE_XXX.  */
 +  unsigned int mode;
  
    /* Detailed information specific to each type of coding system.  */
 -  union spec
 +  union
      {
 -      struct iso2022_spec iso2022;
 -      struct ccl_spec ccl;    /* Defined in ccl.h.  */
 +      struct iso_2022_spec iso_2022;
 +      struct ccl_spec *ccl;   /* Defined in ccl.h.  */
 +      struct utf_16_spec utf_16;
 +      int emacs_mule_full_support;
      } spec;
  
 -  /* Index number of coding category of the coding system.  */
 -  int category_idx;
 +  int max_charset_id;
 +  char *safe_charsets;
  
 -  /* The following two members specify how characters 128..159 are
 -     represented in source and destination text respectively.  1 means
 -     they are represented by 2-byte sequence, 0 means they are
 -     represented by 1-byte as is (see the comment in charset.h).  */
 +  /* The following two members specify how binary 8-bit code 128..255
 +     are represented in source and destination text respectively.  1
 +     means they are represented by 2-byte sequence, 0 means they are
 +     represented by 1-byte as is (see the comment in character.h).  */
    unsigned src_multibyte : 1;
    unsigned dst_multibyte : 1;
  
       -1 in setup_coding_system, and updated by detect_coding.  So,
       when this is equal to the byte length of the text being
       converted, we can skip the actual conversion process.  */
 -  int heading_ascii;
 +  int head_ascii;
  
    /* The following members are set by encoding/decoding routine.  */
 -  int produced, produced_char, consumed, consumed_char;
 +  EMACS_INT produced, produced_char, consumed, consumed_char;
  
    /* Number of error source data found in a decoding routine.  */
    int errors;
  
 -  /* Finish status of code conversion.  It should be one of macros
 -     CODING_FINISH_XXXX.  */
 -  int result;
 +  /* Store the positions of error source data. */
 +  EMACS_INT *error_positions;
  
 -  /* If nonzero, suppress error notification.  */
 -  int suppress_error;
 +  /* Finish status of code conversion.  */
 +  enum coding_result_code result;
  
 -  /* The following members are all Lisp symbols.  We don't have to
 -     protect them from GC because the current garbage collection
 -     doesn't relocate Lisp symbols.  But, when it is changed, we must
 -     find a way to protect them.  */
 +  EMACS_INT src_pos, src_pos_byte, src_chars, src_bytes;
 +  Lisp_Object src_object;
 +  const unsigned char *source;
  
 -  /* Backward pointer to the Lisp symbol of the coding system.  */
 -  Lisp_Object symbol;
 +  EMACS_INT dst_pos, dst_pos_byte, dst_bytes;
 +  Lisp_Object dst_object;
 +  unsigned char *destination;
  
 -  /* Lisp function (symbol) to be called after decoding to do
 -     additional conversion, or nil.  */
 -  Lisp_Object post_read_conversion;
 +  /* Set to 1 iff the source of conversion is not in the member
 +     `charbuf', but at `src_object'.  */
 +  int chars_at_source;
  
 -  /* Lisp function (symbol) to be called before encoding to do
 -     additional conversion, or nil.  */
 -  Lisp_Object pre_write_conversion;
 +  /* If an element is non-negative, it is a character code.
  
 -  /* Character translation tables to look up, or nil.  */
 -  Lisp_Object translation_table_for_decode;
 -  Lisp_Object translation_table_for_encode;
 -};
 +     If it is in the range -128..-1, it is a 8-bit character code
 +     minus 256.
 +
 +     If it is less than -128, it specifies the start of an annotation
 +     chunk.  The length of the chunk is -128 minus the value of the
 +     element.  The following elements are OFFSET, ANNOTATION-TYPE, and
 +     a sequence of actual data for the annotation.  OFFSET is a
 +     character position offset from dst_pos or src_pos,
 +     ANNOTATION-TYPE specfies the meaning of the annotation and how to
 +     handle the following data..  */
 +  int *charbuf;
 +  int charbuf_size, charbuf_used;
 +
 +  /* Set to 1 if charbuf contains an annotation.  */
 +  int annotated;
 +
 +  unsigned char carryover[64];
 +  int carryover_bytes;
 +
 +  int default_char;
  
 -/* Mask bits for (struct coding_system *)->common_flags.  */
 -#define CODING_REQUIRE_FLUSHING_MASK  0x01
 -#define CODING_REQUIRE_DECODING_MASK  0x02
 -#define CODING_REQUIRE_ENCODING_MASK  0x04
 -#define CODING_REQUIRE_DETECTION_MASK 0x08
 -#define CODING_ASCII_INCOMPATIBLE_MASK        0x10
 +  int (*detector) P_ ((struct coding_system *,
 +                     struct coding_detection_info *));
 +  void (*decoder) P_ ((struct coding_system *));
 +  int (*encoder) P_ ((struct coding_system *));
 +};
  
 -/* Return 1 if the coding system CODING requires specific code to be
 +/* Meanings of bits in the member `common_flags' of the structure
 +   coding_system.  The lowest 8 bits are reserved for various kind of
 +   annotations (currently two of them are used).  */
 +#define CODING_ANNOTATION_MASK                        0x00FF
 +#define CODING_ANNOTATE_COMPOSITION_MASK      0x0001
 +#define CODING_ANNOTATE_DIRECTION_MASK                0x0002
 +#define CODING_ANNOTATE_CHARSET_MASK          0x0003
 +#define CODING_FOR_UNIBYTE_MASK                       0x0100
 +#define CODING_REQUIRE_FLUSHING_MASK          0x0200
 +#define CODING_REQUIRE_DECODING_MASK          0x0400
 +#define CODING_REQUIRE_ENCODING_MASK          0x0800
 +#define CODING_REQUIRE_DETECTION_MASK         0x1000
 +#define CODING_RESET_AT_BOL_MASK              0x2000
 +
 +/* Return 1 if the coding context CODING requires annotaion
 +   handling.  */
 +#define CODING_REQUIRE_ANNOTATION(coding) \
 +  ((coding)->common_flags & CODING_ANNOTATION_MASK)
 +
 +/* Return 1 if the coding context CODING prefers decoding into unibyte.  */
 +#define CODING_FOR_UNIBYTE(coding) \
 +  ((coding)->common_flags & CODING_FOR_UNIBYTE_MASK)
 +
 +/* Return 1 if the coding context CODING requires specific code to be
     attached at the tail of converted text.  */
  #define CODING_REQUIRE_FLUSHING(coding) \
    ((coding)->common_flags & CODING_REQUIRE_FLUSHING_MASK)
  
 -/* Return 1 if the coding system CODING requires code conversion on
 +/* Return 1 if the coding context CODING requires code conversion on
     decoding.  */
  #define CODING_REQUIRE_DECODING(coding)       \
    ((coding)->dst_multibyte            \
     || (coding)->common_flags & CODING_REQUIRE_DECODING_MASK)
  
 -/* Return 1 if the coding system CODING requires code conversion on
 +
 +/* Return 1 if the coding context CODING requires code conversion on
     encoding.
     The non-multibyte part of the condition is to support encoding of
     unibyte strings/buffers generated by string-as-unibyte or
     (set-buffer-multibyte nil) from multibyte strings/buffers.  */
 -#define CODING_REQUIRE_ENCODING(coding)       \
 -  ((coding)->src_multibyte            \
 -   || (coding)->common_flags & CODING_REQUIRE_ENCODING_MASK)
 +#define CODING_REQUIRE_ENCODING(coding)                               \
 +  ((coding)->src_multibyte                                    \
 +   || (coding)->common_flags & CODING_REQUIRE_ENCODING_MASK   \
 +   || (coding)->mode & CODING_MODE_SELECTIVE_DISPLAY)
  
 -/* Return 1 if the coding system CODING requires some kind of code
 +
 +/* Return 1 if the coding context CODING requires some kind of code
     detection.  */
  #define CODING_REQUIRE_DETECTION(coding) \
    ((coding)->common_flags & CODING_REQUIRE_DETECTION_MASK)
  
 -/* Return 1 if the coding system CODING requires code conversion on
 +/* Return 1 if the coding context CODING requires code conversion on
     decoding or some kind of code detection.  */
  #define CODING_MAY_REQUIRE_DECODING(coding)   \
    (CODING_REQUIRE_DECODING (coding)           \
     || CODING_REQUIRE_DETECTION (coding))
  
 -/* Index for each coding category in `coding_category_table' */
 -#define CODING_CATEGORY_IDX_EMACS_MULE        0
 -#define CODING_CATEGORY_IDX_SJIS      1
 -#define CODING_CATEGORY_IDX_ISO_7     2
 -#define CODING_CATEGORY_IDX_ISO_7_TIGHT       3
 -#define CODING_CATEGORY_IDX_ISO_8_1   4
 -#define CODING_CATEGORY_IDX_ISO_8_2   5
 -#define CODING_CATEGORY_IDX_ISO_7_ELSE        6
 -#define CODING_CATEGORY_IDX_ISO_8_ELSE        7
 -#define CODING_CATEGORY_IDX_CCL               8
 -#define CODING_CATEGORY_IDX_BIG5      9
 -#define CODING_CATEGORY_IDX_UTF_8       10
 -#define CODING_CATEGORY_IDX_UTF_16_BE   11
 -#define CODING_CATEGORY_IDX_UTF_16_LE   12
 -#define CODING_CATEGORY_IDX_RAW_TEXT  13
 -#define CODING_CATEGORY_IDX_BINARY    14
 -#define CODING_CATEGORY_IDX_MAX               15
 -
 -/* Definitions of flag bits returned by the function
 -   detect_coding_mask ().  */
 -#define CODING_CATEGORY_MASK_EMACS_MULE       (1 << CODING_CATEGORY_IDX_EMACS_MULE)
 -#define CODING_CATEGORY_MASK_SJIS     (1 << CODING_CATEGORY_IDX_SJIS)
 -#define CODING_CATEGORY_MASK_ISO_7    (1 << CODING_CATEGORY_IDX_ISO_7)
 -#define CODING_CATEGORY_MASK_ISO_7_TIGHT (1 << CODING_CATEGORY_IDX_ISO_7_TIGHT)
 -#define CODING_CATEGORY_MASK_ISO_8_1  (1 << CODING_CATEGORY_IDX_ISO_8_1)
 -#define CODING_CATEGORY_MASK_ISO_8_2  (1 << CODING_CATEGORY_IDX_ISO_8_2)
 -#define CODING_CATEGORY_MASK_ISO_7_ELSE       (1 << CODING_CATEGORY_IDX_ISO_7_ELSE)
 -#define CODING_CATEGORY_MASK_ISO_8_ELSE       (1 << CODING_CATEGORY_IDX_ISO_8_ELSE)
 -#define CODING_CATEGORY_MASK_CCL      (1 << CODING_CATEGORY_IDX_CCL)
 -#define CODING_CATEGORY_MASK_BIG5     (1 << CODING_CATEGORY_IDX_BIG5)
 -#define CODING_CATEGORY_MASK_UTF_8      (1 << CODING_CATEGORY_IDX_UTF_8)
 -#define CODING_CATEGORY_MASK_UTF_16_BE  (1 << CODING_CATEGORY_IDX_UTF_16_BE)
 -#define CODING_CATEGORY_MASK_UTF_16_LE  (1 << CODING_CATEGORY_IDX_UTF_16_LE)
 -#define CODING_CATEGORY_MASK_RAW_TEXT (1 << CODING_CATEGORY_IDX_RAW_TEXT)
 -#define CODING_CATEGORY_MASK_BINARY   (1 << CODING_CATEGORY_IDX_BINARY)
 -
 -/* This value is returned if detect_coding_mask () find nothing other
 -   than ASCII characters.  */
 -#define CODING_CATEGORY_MASK_ANY      \
 -  (  CODING_CATEGORY_MASK_EMACS_MULE  \
 -   | CODING_CATEGORY_MASK_SJIS                \
 -   | CODING_CATEGORY_MASK_ISO_7               \
 -   | CODING_CATEGORY_MASK_ISO_7_TIGHT         \
 -   | CODING_CATEGORY_MASK_ISO_8_1     \
 -   | CODING_CATEGORY_MASK_ISO_8_2     \
 -   | CODING_CATEGORY_MASK_ISO_7_ELSE  \
 -   | CODING_CATEGORY_MASK_ISO_8_ELSE  \
 -   | CODING_CATEGORY_MASK_CCL         \
 -   | CODING_CATEGORY_MASK_BIG5                \
 -   | CODING_CATEGORY_MASK_UTF_8               \
 -   | CODING_CATEGORY_MASK_UTF_16_BE   \
 -   | CODING_CATEGORY_MASK_UTF_16_LE)
 -
 -#define CODING_CATEGORY_MASK_ISO_7BIT \
 -  (CODING_CATEGORY_MASK_ISO_7 | CODING_CATEGORY_MASK_ISO_7_TIGHT)
 -
 -#define CODING_CATEGORY_MASK_ISO_8BIT \
 -  (CODING_CATEGORY_MASK_ISO_8_1 | CODING_CATEGORY_MASK_ISO_8_2)
 -
 -#define CODING_CATEGORY_MASK_ISO_SHIFT \
 -  (CODING_CATEGORY_MASK_ISO_7_ELSE | CODING_CATEGORY_MASK_ISO_8_ELSE)
 -
 -#define CODING_CATEGORY_MASK_ISO      \
 -  (  CODING_CATEGORY_MASK_ISO_7BIT    \
 -   | CODING_CATEGORY_MASK_ISO_SHIFT   \
 -   | CODING_CATEGORY_MASK_ISO_8BIT)
 -
 -#define CODING_CATEGORY_MASK_UTF_16_BE_LE \
 -   (CODING_CATEGORY_MASK_UTF_16_BE | CODING_CATEGORY_MASK_UTF_16_LE)
 -
  /* Macros to decode or encode a character of JISX0208 in SJIS.  S1 and
     S2 are the 1st and 2nd position-codes of JISX0208 in SJIS coding
     system.  C1 and C2 are the 1st and 2nd position codes of Emacs'
     internal format.  */
  
 -#define DECODE_SJIS(s1, s2, c1, c2)                   \
 -  do {                                                        \
 -    if (s2 >= 0x9F)                                   \
 -      c1 = s1 * 2 - (s1 >= 0xE0 ? 0x160 : 0xE0),      \
 -      c2 = s2 - 0x7E;                                 \
 -    else                                              \
 -      c1 = s1 * 2 - ((s1 >= 0xE0) ? 0x161 : 0xE1),    \
 -      c2 = s2 - ((s2 >= 0x7F) ? 0x20 : 0x1F);         \
 +#define SJIS_TO_JIS(code)                             \
 +  do {                                                        \
 +    int s1, s2, j1, j2;                                       \
 +                                                      \
 +    s1 = (code) >> 8, s2 = (code) & 0xFF;             \
 +                                                      \
 +    if (s2 >= 0x9F)                                   \
 +      (j1 = s1 * 2 - (s1 >= 0xE0 ? 0x160 : 0xE0),     \
 +       j2 = s2 - 0x7E);                                       \
 +    else                                              \
 +      (j1 = s1 * 2 - ((s1 >= 0xE0) ? 0x161 : 0xE1),   \
 +       j2 = s2 - ((s2 >= 0x7F) ? 0x20 : 0x1F));               \
 +    (code) = (j1 << 8) | j2;                          \
 +  } while (0)
 +
 +#define SJIS_TO_JIS2(code)                            \
 +  do {                                                        \
 +    int s1, s2, j1, j2;                                       \
 +                                                      \
 +    s1 = (code) >> 8, s2 = (code) & 0xFF;             \
 +                                                      \
 +    if (s2 >= 0x9F)                                   \
 +      {                                                       \
 +      j1 = (s1 == 0xF0 ? 0x28                         \
 +            : s1 == 0xF1 ? 0x24                       \
 +            : s1 == 0xF2 ? 0x2C                       \
 +            : s1 == 0xF3 ? 0x2E                       \
 +            : 0x6E + (s1 - 0xF4) * 2);                \
 +      j2 = s2 - 0x7E;                                 \
 +      }                                                       \
 +    else                                              \
 +      {                                                       \
 +      j1 = (s1 <= 0xF2 ? 0x21 + (s1 - 0xF0) * 2       \
 +            : s1 <= 0xF4 ? 0x2D + (s1 - 0xF3) * 2     \
 +            : 0x6F + (s1 - 0xF5) * 2);                \
 +      j2 = s2 - ((s2 >= 0x7F ? 0x20 : 0x1F));         \
 +      }                                                       \
 +    (code) = (j1 << 8) | j2;                          \
 +  } while (0)
 +
 +
 +#define JIS_TO_SJIS(code)                             \
 +  do {                                                        \
 +    int s1, s2, j1, j2;                                       \
 +                                                      \
 +    j1 = (code) >> 8, j2 = (code) & 0xFF;             \
 +    if (j1 & 1)                                               \
 +      (s1 = j1 / 2 + ((j1 < 0x5F) ? 0x71 : 0xB1),     \
 +       s2 = j2 + ((j2 >= 0x60) ? 0x20 : 0x1F));               \
 +    else                                              \
 +      (s1 = j1 / 2 + ((j1 < 0x5F) ? 0x70 : 0xB0),     \
 +       s2 = j2 + 0x7E);                                       \
 +    (code) = (s1 << 8) | s2;                          \
    } while (0)
  
 -#define ENCODE_SJIS(c1, c2, s1, s2)                   \
 +#define JIS_TO_SJIS2(code)                            \
    do {                                                        \
 -    if (c1 & 1)                                               \
 -      s1 = c1 / 2 + ((c1 < 0x5F) ? 0x71 : 0xB1),      \
 -      s2 = c2 + ((c2 >= 0x60) ? 0x20 : 0x1F);         \
 +    int s1, s2, j1, j2;                                       \
 +                                                      \
 +    j1 = (code) >> 8, j2 = (code) & 0xFF;             \
 +    if (j1 & 1)                                               \
 +      {                                                       \
 +      s1 = (j1 <= 0x25 ? 0xF0 + (j1 - 0x21) / 2       \
 +            : j1 <= 0x27 ? 0xF3 + (j1 - 0x2D) / 2     \
 +            : 0xF5 + (j1 - 0x6F) / 2);                \
 +      s2 = j2 + ((j2 >= 0x60) ? 0x20 : 0x1F);         \
 +      }                                                       \
      else                                              \
 -      s1 = c1 / 2 + ((c1 < 0x5F) ? 0x70 : 0xB0),      \
 -      s2 = c2 + 0x7E;                                 \
 +      {                                                       \
 +      s1 = (j1 == 0x28 ? 0xF0                         \
 +            : j1 == 0x24 ? 0xF1                       \
 +            : j1 == 0x2C ? 0xF2                       \
 +            : j1 == 0x2E ? 0xF3                       \
 +            : 0xF4 + (j1 - 0x6E) / 2);                \
 +      s2 = j2 + 0x7E;                                 \
 +      }                                                       \
 +    (code) = (s1 << 8) | s2;                          \
    } while (0)
  
  /* Encode the file name NAME using the specified coding system
        ? code_convert_string_norecord (name, Vdefault_file_name_coding_system, 1) \
        : name))
  
 +
  /* Decode the file name NAME using the specified coding system
     for file names, if any.  */
  #define DECODE_FILE(name)                                                \
        ? code_convert_string_norecord (name, Vdefault_file_name_coding_system, 0) \
        : name))
  
 +
  /* Encode the string STR using the specified coding system
     for system functions, if any.  */
  #define ENCODE_SYSTEM(str)                                               \
     ? code_convert_string_norecord (str, Vlocale_coding_system, 0)        \
     : str)
  
 +/* Used by the gtk menu code.  Note that this encodes utf-8, not
 +   utf-8-emacs, so it's not a no-op.  */
  #define ENCODE_UTF_8(str) code_convert_string_norecord (str, Qutf_8, 1)
  
  /* Extern declarations.  */
 -extern int decode_coding P_ ((struct coding_system *, const unsigned char *,
 -                            unsigned char *, int, int));
 -extern int encode_coding P_ ((struct coding_system *, const unsigned char *,
 -                            unsigned char *, int, int));
 -extern void coding_save_composition P_ ((struct coding_system *, int, int,
 -                                       Lisp_Object));
 -extern void coding_free_composition_data P_ ((struct coding_system *));
 -extern void coding_adjust_composition_offset P_ ((struct coding_system *,
 -                                                int));
 -extern void coding_allocate_composition_data P_ ((struct coding_system *,
 -                                                int));
 -extern void coding_restore_composition P_ ((struct coding_system *,
 -                                          Lisp_Object));
 -extern int code_convert_region P_ ((int, int, int, int, struct coding_system *,
 -                                  int, int));
 -extern Lisp_Object run_pre_post_conversion_on_str P_ ((Lisp_Object,
 -                                                     struct coding_system *,
 -                                                     int));
 -extern void run_pre_write_conversin_on_c_str P_ ((unsigned char **, int *,
 -                                                int, int,
 -                                                struct coding_system *));
 -
 +extern Lisp_Object code_conversion_save P_ ((int, int));
  extern int decoding_buffer_size P_ ((struct coding_system *, int));
  extern int encoding_buffer_size P_ ((struct coding_system *, int));
 -extern void detect_coding P_ ((struct coding_system *, const unsigned char *,
 -                             int));
 -extern void detect_eol P_ ((struct coding_system *, const unsigned char *,
 -                          int));
 -extern int setup_coding_system P_ ((Lisp_Object, struct coding_system *));
 -extern Lisp_Object code_convert_string P_ ((Lisp_Object,
 -                                          struct coding_system *, int, int));
 -extern Lisp_Object code_convert_string1 P_ ((Lisp_Object, Lisp_Object,
 -                                           Lisp_Object, int));
 +extern void setup_coding_system P_ ((Lisp_Object, struct coding_system *));
 +extern Lisp_Object coding_charset_list P_ ((struct coding_system *));
 +extern void detect_coding P_ ((struct coding_system *));
 +extern Lisp_Object code_convert_region P_ ((Lisp_Object, Lisp_Object,
 +                                          Lisp_Object, Lisp_Object,
 +                                          int, int));
 +extern Lisp_Object code_convert_string P_ ((Lisp_Object, Lisp_Object,
 +                                          Lisp_Object, int, int, int));
  extern Lisp_Object code_convert_string_norecord P_ ((Lisp_Object, Lisp_Object,
                                                     int));
 -extern void setup_raw_text_coding_system P_ ((struct coding_system *));
 -extern Lisp_Object encode_coding_string P_ ((Lisp_Object,
 -                                           struct coding_system *, int));
 -extern Lisp_Object decode_coding_string P_ ((Lisp_Object,
 -                                           struct coding_system *, int));
 +extern Lisp_Object raw_text_coding_system P_ ((Lisp_Object));
 +extern Lisp_Object coding_inherit_eol_type P_ ((Lisp_Object, Lisp_Object));
 +
 +extern int decode_coding_gap P_ ((struct coding_system *,
 +                                EMACS_INT, EMACS_INT));
 +extern int encode_coding_gap P_ ((struct coding_system *,
 +                                EMACS_INT, EMACS_INT));
 +extern void decode_coding_object P_ ((struct coding_system *,
 +                                    Lisp_Object, EMACS_INT, EMACS_INT,
 +                                    EMACS_INT, EMACS_INT, Lisp_Object));
 +extern void encode_coding_object P_ ((struct coding_system *,
 +                                    Lisp_Object, EMACS_INT, EMACS_INT,
 +                                    EMACS_INT, EMACS_INT, Lisp_Object));
 +
 +/* Macros for backward compatibility.  */
 +
 +#define decode_coding_region(coding, from, to)                \
 +  decode_coding_object (coding, Fcurrent_buffer (),   \
 +                      from, CHAR_TO_BYTE (from),      \
 +                      to, CHAR_TO_BYTE (to), Fcurrent_buffer ())
 +
 +
 +#define encode_coding_region(coding, from, to)                \
 +  encode_coding_object (coding, Fcurrent_buffer (),   \
 +                      from, CHAR_TO_BYTE (from),      \
 +                      to, CHAR_TO_BYTE (to), Fcurrent_buffer ())
 +
 +
 +#define decode_coding_string(coding, string, nocopy)                  \
 +  decode_coding_object (coding, string, 0, 0, XSTRING (string)->size, \
 +                      STRING_BYTES (XSTRING (string)), Qt)
 +
 +#define encode_coding_string(coding, string, nocopy)                  \
 +  (encode_coding_object (coding, string, 0, 0, XSTRING (string)->size,        \
 +                       STRING_BYTES (XSTRING (string)), Qt),          \
 +   (coding)->dst_object)
 +
 +
 +#define decode_coding_c_string(coding, src, bytes, dst_object)                \
 +  do {                                                                        \
 +    (coding)->source = (src);                                         \
 +    (coding)->src_chars = (coding)->src_bytes = (bytes);              \
 +    decode_coding_object ((coding), Qnil, 0, 0, (bytes), (bytes),     \
 +                        (dst_object));                                \
 +  } while (0)
 +
 +
 +extern Lisp_Object preferred_coding_system P_ (());
 +
 +
 +extern Lisp_Object Qutf_8, Qutf_8_emacs;
 +
  extern Lisp_Object Qcoding_system, Qeol_type, Qcoding_category_index;
 -extern Lisp_Object Qraw_text, Qemacs_mule;
 +extern Lisp_Object Qcoding_system_p;
 +extern Lisp_Object Qraw_text, Qemacs_mule, Qno_conversion, Qundecided;
 +extern Lisp_Object Qiso_2022;
  extern Lisp_Object Qbuffer_file_coding_system;
 -extern Lisp_Object Vcoding_category_list;
 -extern Lisp_Object Qutf_8;
 +
 +extern Lisp_Object Qunix, Qdos, Qmac;
  
  extern Lisp_Object Qtranslation_table;
  extern Lisp_Object Qtranslation_table_id;
@@@ -721,6 -672,9 +721,6 @@@ extern Lisp_Object eol_mnemonic_unix, e
  /* Mnemonic string to indicate type of end-of-line is not yet decided.  */
  extern Lisp_Object eol_mnemonic_undecided;
  
 -/* Format of end-of-line decided by system.  */
 -extern int system_eol_type;
 -
  #ifdef emacs
  extern Lisp_Object Qfile_coding_system;
  extern Lisp_Object Qcall_process, Qcall_process_region;
@@@ -756,10 -710,13 +756,10 @@@ extern struct coding_system safe_termin
     function `set-keyboard-coding-system'.  */
  extern struct coding_system keyboard_coding;
  
 -/* Default coding system to be used to write a file.  */
 -extern struct coding_system default_buffer_file_coding;
 -
  /* Default coding systems used for process I/O.  */
  extern Lisp_Object Vdefault_process_coding_system;
  
 -/* Function to call to force a user to force select a proper coding
 +/* Function to call to force a user to force select a propert coding
     system.  */
  extern Lisp_Object Vselect_safe_coding_system_function;
  
@@@ -779,9 -736,6 +779,9 @@@ extern Lisp_Object Vdefault_file_name_c
  /* Error signaled when there's a problem with detecting coding system */
  extern Lisp_Object Qcoding_system_error;
  
 +extern char emacs_mule_bytes[256];
 +extern int emacs_mule_string_char P_ ((unsigned char *));
 +
  #endif /* EMACS_CODING_H */
  
  /* arch-tag: 2bc3b4fa-6870-4f64-8135-b962b2d290e4
diff --combined src/composite.c
index 1ccd3af25156b4a1ea2840aaf74d8c514b651c00,3e0606e9007d5d8bd6f396d56548a832397f264d..d44acf24722c51b0fc4e881f08d2c5dda64d19ca
@@@ -1,12 -1,9 +1,12 @@@
  /* Composite sequence support.
     Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
-    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+                  2006, 2007 Free Software Foundation, Inc.
+    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003, 2006
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -28,7 -25,7 +28,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <config.h>
  #include "lisp.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "intervals.h"
  
  /* Emacs uses special text property `composition' to support character
@@@ -150,17 -147,19 +150,17 @@@ Lisp_Object composition_hash_table
  /* Function to call to adjust composition.  */
  Lisp_Object Vcompose_chars_after_function;
  
 -/* Char-table of patterns and functions to make a composition.  */
 -Lisp_Object Vcomposition_function_table;
 -Lisp_Object Qcomposition_function_table;
 +Lisp_Object Qauto_composed;
 +Lisp_Object Vauto_composition_function;
 +Lisp_Object Qauto_composition_function;
 +
 +EXFUN (Fremove_list_of_text_properties, 4);
  
  /* Temporary variable used in macros COMPOSITION_XXX.  */
  Lisp_Object composition_temp;
 -\f
 -/* Return how many columns C will occupy on the screen.  It always
 -   returns 1 for control characters and 8-bit characters because those
 -   are just ignored in a composition.  */
 -#define CHAR_WIDTH(c) \
 -  (SINGLE_BYTE_CHAR_P (c) ? 1 : CHARSET_WIDTH (CHAR_CHARSET (c)))
  
 +extern int enable_font_backend;
 +\f
  /* Return COMPOSITION-ID of a composition at buffer position
     CHARPOS/BYTEPOS and length NCHARS.  The `composition' property of
     the sequence is PROP.  STRING, if non-nil, is a string that
@@@ -275,22 -274,6 +275,22 @@@ get_composition_id (charpos, bytepos, n
    /* Check if the contents of COMPONENTS are valid if COMPONENTS is a
       vector or a list.  It should be a sequence of:
        char1 rule1 char2 rule2 char3 ...    ruleN charN+1  */
 +
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend
 +      && VECTORP (components)
 +      && ASIZE (components) >= 2
 +      && VECTORP (AREF (components, 0)))
 +    {
 +      /* COMPONENTS is a glyph-string.  */
 +      int len = ASIZE (key);
 +
 +      for (i = 1; i < len; i++)
 +      if (! VECTORP (AREF (key, i)))
 +        goto invalid_composition;
 +    }
 +  else
 +#endif  /* USE_FONT_BACKEND */
    if (VECTORP (components) || CONSP (components))
      {
        int len = XVECTOR (key)->size;
                 : ((INTEGERP (components) || STRINGP (components))
                    ? COMPOSITION_WITH_ALTCHARS
                    : COMPOSITION_WITH_RULE_ALTCHARS));
 +#ifdef USE_FONT_BACKEND
 +  if (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS
 +      && VECTORP (components)
 +      && ! INTEGERP (AREF (components, 0)))
 +    cmp->method = COMPOSITION_WITH_GLYPH_STRING;
 +#endif  /* USE_FONT_BACKEND */
    cmp->hash_index = hash_index;
    glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS
               ? (XVECTOR (key)->size + 1) / 2
    cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2);
    cmp->font = NULL;
  
 +#ifdef USE_FONT_BACKEND
 +  if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
 +    {
 +      cmp->width = 1;         /* Should be fixed later.  */
 +      cmp->glyph_len--;
 +    }
 +  else
 +#endif        /* USE_FONT_BACKEND */
    /* Calculate the width of overall glyphs of the composition.  */
    if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
      {
        float leftmost = 0.0, rightmost;
  
        ch = XINT (key_contents[0]);
 -      rightmost = CHAR_WIDTH (ch);
 +      rightmost = ch != '\t' ? CHAR_WIDTH (ch) : 1;
  
        for (i = 1; i < glyph_len; i += 2)
        {
 -        int rule, gref, nref;
 +        int rule, gref, nref, xoff, yoff;
          int this_width;
          float this_left;
  
          rule = XINT (key_contents[i]);
          ch = XINT (key_contents[i + 1]);
 -        this_width = CHAR_WIDTH (ch);
 +        this_width = ch != '\t' ? CHAR_WIDTH (ch) : 1;
  
          /* A composition rule is specified by an integer value
             that encodes global and new reference points (GREF and
                |       |
                6---7---8 -- descent
          */
 -        COMPOSITION_DECODE_RULE (rule, gref, nref);
 +        COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
          this_left = (leftmost
                       + (gref % 3) * (rightmost - leftmost) / 2.0
                       - (nref % 3) * this_width / 2.0);
  
  int
  find_composition (pos, limit, start, end, prop, object)
 -     int pos, limit, *start, *end;
 +     int pos, limit;
 +     EMACS_INT *start, *end;
       Lisp_Object *prop, object;
  {
    Lisp_Object val;
@@@ -483,7 -451,7 +483,7 @@@ run_composition_function (from, to, pro
       Lisp_Object prop;
  {
    Lisp_Object func;
 -  int start, end;
 +  EMACS_INT start, end;
  
    func = COMPOSITION_MODIFICATION_FUNC (prop);
    /* If an invalid composition precedes or follows, try to make them
      to = end;
    if (!NILP (Ffboundp (func)))
      call2 (func, make_number (from), make_number (to));
 -  else if (!NILP (Ffboundp (Vcompose_chars_after_function)))
 -    call3 (Vcompose_chars_after_function,
 -         make_number (from), make_number (to), Qnil);
  }
  
  /* Make invalid compositions adjacent to or inside FROM and TO valid.
     CHECK_MASK is bitwise `or' of mask bits defined by macros
     CHECK_XXX (see the comment in composite.h).
  
 +   It also resets the text-property `auto-composed' to a proper region
 +   so that automatic character composition works correctly later while
 +   displaying the region.
 +
     This function is called when a buffer text is changed.  If the
     change is deletion, FROM == TO.  Otherwise, FROM < TO.  */
  
  void
  update_compositions (from, to, check_mask)
 -     int from, to, check_mask;
 +     EMACS_INT from, to;
 +     int check_mask;
  {
    Lisp_Object prop;
 -  int start, end;
 +  EMACS_INT start, end;
 +  /* The beginning and end of the region to set the property
 +     `auto-composed' to nil.  */
 +  EMACS_INT min_pos = from, max_pos = to;
  
    if (inhibit_modification_hooks)
      return;
        if (from > BEGV
          && find_composition (from - 1, -1, &start, &end, &prop, Qnil))
        {
 +        min_pos = start;
 +        if (end > to)
 +          max_pos = end;
          if (from < end)
            Fput_text_property (make_number (from), make_number (end),
                                Qcomposition,
        }
        else if (from < ZV
               && find_composition (from, -1, &start, &from, &prop, Qnil))
 -      run_composition_function (start, from, prop);
 +      {
 +        if (from > to)
 +          max_pos = from;
 +        run_composition_function (start, from, prop);
 +      }
      }
  
    if (check_mask & CHECK_INSIDE)
             To avoid it, in such a case, we change the property of
             the former to the copy of it.  */
          if (to < end)
 -          Fput_text_property (make_number (start), make_number (to),
 -                              Qcomposition,
 -                              Fcons (XCAR (prop), XCDR (prop)), Qnil);
 +          {
 +            Fput_text_property (make_number (start), make_number (to),
 +                                Qcomposition,
 +                                Fcons (XCAR (prop), XCDR (prop)), Qnil);
 +            max_pos = end;
 +          }
          run_composition_function (start, end, prop);
        }
        else if (to < ZV
               && find_composition (to, -1, &start, &end, &prop, Qnil))
 -      run_composition_function (start, end, prop);
 +      {
 +        run_composition_function (start, end, prop);
 +        max_pos = end;
 +      }
 +    }
 +  if (min_pos < max_pos)
 +    {
 +      int count = SPECPDL_INDEX ();
 +
 +      specbind (Qinhibit_read_only, Qt);
 +      specbind (Qinhibit_modification_hooks, Qt);
 +      specbind (Qinhibit_point_motion_hooks, Qt);
 +      Fremove_list_of_text_properties (make_number (min_pos),
 +                                     make_number (max_pos),
 +                                     Fcons (Qauto_composed, Qnil), Qnil);
 +      unbind_to (count, Qnil);
      }
  }
  
@@@ -652,6 -590,7 +652,6 @@@ compose_text (start, end, components, m
    Fput_text_property  (make_number (start), make_number (end),
                       Qcomposition, prop, string);
  }
 -
  \f
  /* Emacs Lisp APIs.  */
  
@@@ -709,7 -648,7 +709,7 @@@ See `find-composition' for more detail
       Lisp_Object pos, limit, string, detail_p;
  {
    Lisp_Object prop, tail;
 -  int start, end;
 +  EMACS_INT start, end;
    int id;
  
    CHECK_NUMBER_COERCE_MARKER (pos);
@@@ -788,12 -727,12 +788,12 @@@ syms_of_composite (
  
      args[0] = QCtest;
      args[1] = Qequal;
 +    args[2] = QCweakness;
      /* We used to make the hash table weak so that unreferenced
         compostions can be garbage-collected.  But, usually once
         created compositions are repeatedly used in an Emacs session,
         and thus it's not worth to save memory in such a way.  So, we
         make the table not weak.  */
 -    args[2] = QCweakness;
      args[3] = Qnil;
      args[4] = QCsize;
      args[5] = make_number (311);
@@@ -819,24 -758,29 +819,24 @@@ valid
  The default value is the function `compose-chars-after'.  */);
    Vcompose_chars_after_function = intern ("compose-chars-after");
  
 -  Qcomposition_function_table = intern ("composition-function-table");
 -  staticpro (&Qcomposition_function_table);
 -
 -  /* Intern this now in case it isn't already done.
 -     Setting this variable twice is harmless.
 -     But don't staticpro it here--that is done in alloc.c.  */
 -  Qchar_table_extra_slots = intern ("char-table-extra-slots");
 +  Qauto_composed = intern ("auto-composed");
 +  staticpro (&Qauto_composed);
  
 -  Fput (Qcomposition_function_table, Qchar_table_extra_slots, make_number (0));
 +  Qauto_composition_function = intern ("auto-composition-function");
 +  staticpro (&Qauto_composition_function);
  
 -  DEFVAR_LISP ("composition-function-table", &Vcomposition_function_table,
 -             doc: /* Char table of patterns and functions to make a composition.
 +  DEFVAR_LISP ("auto-composition-function", &Vauto_composition_function,
 +             doc: /* Function to call to compose characters automatically.
 +The function is called from the display routine with two arguments,
 +POS and STRING.
  
 -Each element is nil or an alist of PATTERNs vs FUNCs, where PATTERNs
 -are regular expressions and FUNCs are functions.  FUNC is responsible
 -for composing text matching the corresponding PATTERN.  FUNC is called
 -with three arguments FROM, TO, and PATTERN.  See the function
 -`compose-chars-after' for more detail.
 +If STRING is nil, the function must compose characters following POS
 +in the current buffer.
  
 -This table is looked up by the first character of a composition when
 -the composition gets invalid after a change in a buffer.  */);
 -  Vcomposition_function_table
 -    = Fmake_char_table (Qcomposition_function_table, Qnil);
 +Otherwise, STRING is a string, and POS is an index to the string.  In
 +this case, the function must compose characters following POS in
 +the string.  */);
 +  Vauto_composition_function = Qnil;
  
    defsubr (&Scompose_region_internal);
    defsubr (&Scompose_string_internal);
diff --combined src/composite.h
index 6e600e7a29b6c805fac91edf08274e765544795d,8ff6416990f46ea6f921ebc143ade8046b66d692..5106fcc990f153c5aa89807ad8de3d3b42e8bae8
@@@ -1,12 -1,9 +1,12 @@@
  /* Header for composite sequence handler.
     Copyright (C) 2001, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
-    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+                  2006, 2007 Free Software Foundation, Inc.
+    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003, 2006
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -28,24 -25,22 +28,24 @@@ Boston, MA 02110-1301, USA.  *
  #ifndef EMACS_COMPOSITE_H
  #define EMACS_COMPOSITE_H
  
 -/* Methods to display a sequence of components a composition.  */
 +/* Methods to display a sequence of components of a composition.  */
  enum composition_method {
 -  /* The first two are actually not methods, but used in code
 -     conversion to specify the current composing status.  */
 -  COMPOSITION_DISABLED,               /* Never handle composition data */
 -  COMPOSITION_NO,             /* Not processing composition data */
    /* Compose relatively without alternate characters.  */
    COMPOSITION_RELATIVE,
 -  /* Compose by specified composition rule.  This is not used in Emacs
 -     21 but we need it to decode files saved in the older versions of
 -     Emacs.  */
 +  /* Compose by specified composition rules.  This is not used in
 +     Emacs 21 but we need it to decode files saved in the older
 +     versions of Emacs.  */
    COMPOSITION_WITH_RULE,
    /* Compose relatively with alternate characters.  */
    COMPOSITION_WITH_ALTCHARS,
 -  /* Compose by specified composition rule with alternate characters.  */
 -  COMPOSITION_WITH_RULE_ALTCHARS
 +  /* Compose by specified composition rules with alternate characters.  */
 +  COMPOSITION_WITH_RULE_ALTCHARS,
 +#ifdef USE_FONT_BACKEND
 +  /* Compose by specified lispy glyph-string.  */
 +  COMPOSITION_WITH_GLYPH_STRING,
 +#endif  /* USE_FONT_BACKEND */
 +  /* This is not a method.  */
 +  COMPOSITION_NO
  };
  
  /* Maximum number of compoments a single composition can have.  */
@@@ -133,19 -128,13 +133,19 @@@ extern Lisp_Object composition_temp
        ->contents[(n) * 2 - 1])
  
  /* Decode encoded composition rule RULE_CODE into GREF (global
 -   reference point code) and NREF (new reference point code).  Don't
 -   check RULE_CODE, always set GREF and NREF to valid values.  */
 -#define COMPOSITION_DECODE_RULE(rule_code, gref, nref)        \
 -  do {                                                        \
 -    gref = (rule_code) / 12;                          \
 -    if (gref > 12) gref = 11;                         \
 -    nref = (rule_code) % 12;                          \
 +   reference point code), NREF (new reference point code), XOFF
 +   (horizontal offset) YOFF (vertical offset).  Don't check RULE_CODE,
 +   always set GREF and NREF to valid values.  By side effect,
 +   RULE_CODE is modified.  */
 +
 +#define COMPOSITION_DECODE_RULE(rule_code, gref, nref, xoff, yoff)    \
 +  do {                                                                        \
 +    xoff = (rule_code) >> 16;                                         \
 +    yoff = ((rule_code) >> 8) & 0xFF;                                 \
 +    rule_code &= 0xFF;                                                        \
 +    gref = (rule_code) / 12;                                          \
 +    if (gref > 12) gref = 11;                                         \
 +    nref = (rule_code) % 12;                                          \
    } while (0)
  
  /* Return encoded composition rule for the pair of global reference
@@@ -172,8 -161,6 +172,8 @@@ struct composition 
    /* Width, ascent, and descent pixels of the composition.  */
    short pixel_width, ascent, descent;
  
 +  short lbearing, rbearing;
 +
    /* How many columns the overall glyphs occupy on the screen.  This
       gives an approximate value for column calculation in
       Fcurrent_column, and etc.  */
@@@ -213,14 -200,11 +213,14 @@@ extern int n_compositions
  
  extern Lisp_Object Qcomposition;
  extern Lisp_Object composition_hash_table;
 +extern Lisp_Object Qauto_composed;
 +extern Lisp_Object Vauto_composition_function;
 +extern Lisp_Object Qauto_composition_function;
  
  extern int get_composition_id P_ ((int, int, int, Lisp_Object, Lisp_Object));
 -extern int find_composition P_ ((int, int, int *, int *, Lisp_Object *,
 +extern int find_composition P_ ((int, int, EMACS_INT *, EMACS_INT *, Lisp_Object *,
                                 Lisp_Object));
 -extern void update_compositions P_ ((int, int, int));
 +extern void update_compositions P_ ((EMACS_INT, EMACS_INT, int));
  extern void make_composition_value_copy P_ ((Lisp_Object));
  extern void compose_region P_ ((int, int, Lisp_Object, Lisp_Object,
                                Lisp_Object));
diff --combined src/config.in
index 8ee525a611b55125fc4bff876110cf7378a1e43f,cf22a72cf979d363a0c15ff755f2e6ad1506310a..7c94952463b887227e988c2b40f288b524fe795a
@@@ -1,7 -1,7 +1,7 @@@
  /* src/config.in.  Generated from configure.in by autoheader.  */
  
  /* GNU Emacs site configuration template file.
-    Copyright (C) 1988, 1993, 1994, 1999, 2000, 2001, 2002, 2004, 2005, 2006
+    Copyright (C) 1988, 1993, 1994, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
               Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
@@@ -156,9 -156,6 +156,9 @@@ Boston, MA 02110-1301, USA.  *
  /* Define to 1 if you have the `fpathconf' function. */
  #undef HAVE_FPATHCONF
  
 +/* Define to 1 if you have freetype and fontconfig libraries. */
 +#undef HAVE_FREETYPE
 +
  /* Define to 1 if you have the `frexp' function. */
  #undef HAVE_FREXP
  
  /* Define to 1 if you have the `ncurses' library (-lncurses). */
  #undef HAVE_LIBNCURSES
  
 +/* Define to 1 if you have libotf library. */
 +#undef HAVE_LIBOTF
 +
  /* Define to 1 if you have the <libpng/png.h> header file. */
  #undef HAVE_LIBPNG_PNG_H
  
  /* Define to 1 if you're using XFree386. */
  #undef HAVE_XFREE386
  
 +/* Define to 1 if you have the Xft library. */
 +#undef HAVE_XFT
 +
  /* Define to 1 if XIM is available */
  #undef HAVE_XIM
  
  /* Define to the unexec source file name. */
  #undef UNEXEC_SRC
  
 +/* Define to 1 if we should use font-backend. */
 +#undef USE_FONT_BACKEND
 +
  /* Define to 1 if we should use toolkit scroll bars. */
  #undef USE_TOOLKIT_SCROLL_BARS
  
diff --combined src/data.c
index 120a92d66d79305b4f843891933720345db6b4e3,49e1570c4c26948d83d68272e16cca0652231ab2..af166329f816841b007d3e62c52381176e4b70e3
@@@ -1,6 -1,6 +1,6 @@@
  /* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
     Copyright (C) 1985, 1986, 1988, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
-                  2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -25,7 -25,7 +25,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <stdio.h>
  #include "lisp.h"
  #include "puresize.h"
 -#include "charset.h"
 +#include "character.h"
  #include "buffer.h"
  #include "keyboard.h"
  #include "frame.h"
@@@ -439,7 -439,7 +439,7 @@@ DEFUN ("char-or-string-p", Fchar_or_str
       (object)
       register Lisp_Object object;
  {
 -  if (INTEGERP (object) || STRINGP (object))
 +  if (CHARACTERP (object) || STRINGP (object))
      return Qt;
    return Qnil;
  }
@@@ -1957,8 -1957,96 +1957,8 @@@ or a byte-code object.  IDX starts at 0
      }
    else if (CHAR_TABLE_P (array))
      {
 -      Lisp_Object val;
 -
 -      val = Qnil;
 -
 -      if (idxval < 0)
 -      args_out_of_range (array, idx);
 -      if (idxval < CHAR_TABLE_ORDINARY_SLOTS)
 -      {
 -        if (! SINGLE_BYTE_CHAR_P (idxval))
 -          args_out_of_range (array, idx);
 -        /* For ASCII and 8-bit European characters, the element is
 -             stored in the top table.  */
 -        val = XCHAR_TABLE (array)->contents[idxval];
 -        if (NILP (val))
 -          {
 -            int default_slot
 -              = (idxval < 0x80 ? CHAR_TABLE_DEFAULT_SLOT_ASCII
 -                 : idxval < 0xA0 ? CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL
 -                 : CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC);
 -            val = XCHAR_TABLE (array)->contents[default_slot];
 -          }
 -        if (NILP (val))
 -          val = XCHAR_TABLE (array)->defalt;
 -        while (NILP (val))    /* Follow parents until we find some value.  */
 -          {
 -            array = XCHAR_TABLE (array)->parent;
 -            if (NILP (array))
 -              return Qnil;
 -            val = XCHAR_TABLE (array)->contents[idxval];
 -            if (NILP (val))
 -              val = XCHAR_TABLE (array)->defalt;
 -          }
 -        return val;
 -      }
 -      else
 -      {
 -        int code[4], i;
 -        Lisp_Object sub_table;
 -        Lisp_Object current_default;
 -
 -        SPLIT_CHAR (idxval, code[0], code[1], code[2]);
 -        if (code[1] < 32) code[1] = -1;
 -        else if (code[2] < 32) code[2] = -1;
 -
 -        /* Here, the possible range of CODE[0] (== charset ID) is
 -          128..MAX_CHARSET.  Since the top level char table contains
 -          data for multibyte characters after 256th element, we must
 -          increment CODE[0] by 128 to get a correct index.  */
 -        code[0] += 128;
 -        code[3] = -1;         /* anchor */
 -
 -      try_parent_char_table:
 -        current_default = XCHAR_TABLE (array)->defalt;
 -        sub_table = array;
 -        for (i = 0; code[i] >= 0; i++)
 -          {
 -            val = XCHAR_TABLE (sub_table)->contents[code[i]];
 -            if (SUB_CHAR_TABLE_P (val))
 -              {
 -                sub_table = val;
 -                if (! NILP (XCHAR_TABLE (sub_table)->defalt))
 -                  current_default = XCHAR_TABLE (sub_table)->defalt;
 -              }
 -            else
 -              {
 -                if (NILP (val))
 -                  val = current_default;
 -                if (NILP (val))
 -                  {
 -                    array = XCHAR_TABLE (array)->parent;
 -                    if (!NILP (array))
 -                      goto try_parent_char_table;
 -                  }
 -                return val;
 -              }
 -          }
 -        /* Reaching here means IDXVAL is a generic character in
 -           which each character or a group has independent value.
 -           Essentially it's nonsense to get a value for such a
 -           generic character, but for backward compatibility, we try
 -           the default value and parent.  */
 -        val = current_default;
 -        if (NILP (val))
 -          {
 -            array = XCHAR_TABLE (array)->parent;
 -            if (!NILP (array))
 -              goto try_parent_char_table;
 -          }
 -        return val;
 -      }
 +      CHECK_CHARACTER (idx);
 +      return CHAR_TABLE_REF (array, idxval);
      }
    else
      {
@@@ -2014,8 -2102,45 +2014,8 @@@ bool-vector.  IDX starts at 0.  */
      }
    else if (CHAR_TABLE_P (array))
      {
 -      if (idxval < 0)
 -      args_out_of_range (array, idx);
 -      if (idxval < CHAR_TABLE_ORDINARY_SLOTS)
 -      {
 -        if (! SINGLE_BYTE_CHAR_P (idxval))
 -          args_out_of_range (array, idx);
 -        XCHAR_TABLE (array)->contents[idxval] = newelt;
 -      }
 -      else
 -      {
 -        int code[4], i;
 -        Lisp_Object val;
 -
 -        SPLIT_CHAR (idxval, code[0], code[1], code[2]);
 -        if (code[1] < 32) code[1] = -1;
 -        else if (code[2] < 32) code[2] = -1;
 -
 -        /* See the comment of the corresponding part in Faref.  */
 -        code[0] += 128;
 -        code[3] = -1;         /* anchor */
 -        for (i = 0; code[i + 1] >= 0; i++)
 -          {
 -            val = XCHAR_TABLE (array)->contents[code[i]];
 -            if (SUB_CHAR_TABLE_P (val))
 -              array = val;
 -            else
 -              {
 -                Lisp_Object temp;
 -
 -                /* VAL is a leaf.  Create a sub char table with the
 -                   initial value VAL and look into it.  */
 -
 -                temp = make_sub_char_table (val);
 -                XCHAR_TABLE (array)->contents[code[i]] = temp;
 -                array = temp;
 -              }
 -          }
 -        XCHAR_TABLE (array)->contents[code[i]] = newelt;
 -      }
 +      CHECK_CHARACTER (idx);
 +      CHAR_TABLE_SET (array, idxval, newelt);
      }
    else if (STRING_MULTIBYTE (array))
      {
  
        if (idxval < 0 || idxval >= SCHARS (array))
        args_out_of_range (array, idx);
 -      CHECK_NUMBER (newelt);
 +      CHECK_CHARACTER (newelt);
  
        nbytes = SBYTES (array);
  
        args_out_of_range (array, idx);
        CHECK_NUMBER (newelt);
  
 -      if (XINT (newelt) < 0 || SINGLE_BYTE_CHAR_P (XINT (newelt)))
 -      SSET (array, idxval, XINT (newelt));
 -      else
 -      {
 -        /* We must relocate the string data while converting it to
 -           multibyte.  */
 -        int idxval_byte, prev_bytes, new_bytes;
 -        unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;
 -        unsigned char *origstr = SDATA (array), *str;
 -        int nchars, nbytes;
 -        USE_SAFE_ALLOCA;
 -
 -        nchars = SCHARS (array);
 -        nbytes = idxval_byte = count_size_as_multibyte (origstr, idxval);
 -        nbytes += count_size_as_multibyte (origstr + idxval,
 -                                           nchars - idxval);
 -        SAFE_ALLOCA (str, unsigned char *, nbytes);
 -        copy_text (SDATA (array), str, nchars, 0, 1);
 -        PARSE_MULTIBYTE_SEQ (str + idxval_byte, nbytes - idxval_byte,
 -                             prev_bytes);
 -        new_bytes = CHAR_STRING (XINT (newelt), p0);
 -        allocate_string_data (XSTRING (array), nchars,
 -                              nbytes + new_bytes - prev_bytes);
 -        bcopy (str, SDATA (array), idxval_byte);
 -        p1 = SDATA (array) + idxval_byte;
 -        while (new_bytes--)
 -          *p1++ = *p0++;
 -        bcopy (str + idxval_byte + prev_bytes, p1,
 -               nbytes - (idxval_byte + prev_bytes));
 -        SAFE_FREE ();
 -        clear_string_char_byte_cache ();
 -      }
 +      if (XINT (newelt) >= 0 && ! SINGLE_BYTE_CHAR_P (XINT (newelt)))
 +      args_out_of_range (array, newelt);
 +      SSET (array, idxval, XINT (newelt));
      }
  
    return newelt;
diff --combined src/dired.c
index 3283d38eb4b95ad35e061f6eeb4f3df6bc93c2f9,c542f8019db1996721234695c0cf555d93c54a94..27f9f953eb648d513fc9b5a8849c0ac54841f37f
@@@ -1,6 -1,6 +1,6 @@@
  /* Lisp functions for making directory listings.
     Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2002, 2003,
-                  2004, 2005, 2006 Free Software Foundation, Inc.
+                  2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -96,7 -96,6 +96,7 @@@ extern struct direct *readdir ()
  #include "systime.h"
  #include "buffer.h"
  #include "commands.h"
 +#include "character.h"
  #include "charset.h"
  #include "coding.h"
  #include "regex.h"
@@@ -931,6 -930,7 +931,7 @@@ Elements of the attribute list are
    char modes[10];
    Lisp_Object handler;
    struct gcpro gcpro1;
+   EMACS_INT uid, gid, ino;
  
    filename = Fexpand_file_name (filename, Qnil);
  
  #endif
      }
    values[1] = make_number (s.st_nlink);
+   /* When make_fixnum_or_float is called below with types that are
+      shorter than an int (e.g., `short'), GCC whines about comparison
+      being always false due to limited range of data type.  Fix by
+      copying s.st_uid and s.st_gid into int variables.  */
+   uid = s.st_uid;
+   gid = s.st_gid;
    if (NILP (id_format) || EQ (id_format, Qinteger))
      {
-       values[2] = make_number (s.st_uid);
-       values[3] = make_number (s.st_gid);
+       values[2] = make_fixnum_or_float (uid);
+       values[3] = make_fixnum_or_float (gid);
      }
    else
      {
        BLOCK_INPUT;
-       pw = (struct passwd *) getpwuid (s.st_uid);
-       values[2] = (pw ? build_string (pw->pw_name) : make_number (s.st_uid));
-       gr = (struct group *) getgrgid (s.st_gid);
-       values[3] = (gr ? build_string (gr->gr_name) : make_number (s.st_gid));
+       pw = (struct passwd *) getpwuid (uid);
+       values[2] = (pw ? build_string (pw->pw_name)
+                   : make_fixnum_or_float (uid));
+       gr = (struct group *) getgrgid (gid);
+       values[3] = (gr ? build_string (gr->gr_name)
+                   : make_fixnum_or_float (gid));
        UNBLOCK_INPUT;
      }
    values[4] = make_time (s.st_atime);
    if (! NILP (dirname))
      encoded = ENCODE_FILE (dirname);
    if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0)
-     values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
+     values[9] = (sdir.st_gid != gid) ? Qt : Qnil;
    else                                        /* if we can't tell, assume worst */
      values[9] = Qt;
  #else                                 /* file gid will be egid */
-   values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
+   values[9] = (gid != getegid ()) ? Qt : Qnil;
  #endif        /* BSD4_2 (or BSD4_3) */
-   if (FIXNUM_OVERFLOW_P (s.st_ino))
+   /* Shut up GCC warnings in FIXNUM_OVERFLOW_P below.  */
+   ino = s.st_ino;
+   if (FIXNUM_OVERFLOW_P (ino))
      /* To allow inode numbers larger than VALBITS, separate the bottom
         16 bits.  */
-     values[10] = Fcons (make_number (s.st_ino >> 16),
-                       make_number (s.st_ino & 0xffff));
+     values[10] = Fcons (make_number (ino >> 16),
+                       make_number (ino & 0xffff));
    else
      /* But keep the most common cases as integers.  */
-     values[10] = make_number (s.st_ino);
+     values[10] = make_number (ino);
  
    /* Likewise for device.  */
    if (FIXNUM_OVERFLOW_P (s.st_dev))
diff --combined src/dispextern.h
index 5eb7ee11dea323865710e7d67a646030340bb778,2dd0d91b111e0401034acb7eb0ae4d62807129de..e2ad4b73e5aa443f8883d49945071a65828560a4
@@@ -1,6 -1,6 +1,6 @@@
  /* Interface definitions for display code.
     Copyright (C) 1985, 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
-                  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -1220,11 -1220,6 +1220,11 @@@ struct glyph_strin
       *clip_tail, not including their overhangs.  */
    struct glyph_string *clip_head, *clip_tail;
  
 +#ifdef USE_FONT_BACKEND
 +  /* The current clipping area.  */
 +  int clip_x, clip_y, clip_width, clip_height;
 +#endif        /* USE_FONT_BACKEND */
 +
    struct glyph_string *next, *prev;
  };
  
@@@ -1396,7 -1391,6 +1396,7 @@@ enum lface_attribute_inde
    LFACE_FONT_INDEX,
    LFACE_INHERIT_INDEX,
    LFACE_AVGWIDTH_INDEX,
 +  LFACE_FONTSET_INDEX,
    LFACE_VECTOR_SIZE
  };
  
@@@ -1481,12 -1475,10 +1481,12 @@@ struct fac
       reallocated.  */
    int font_info_id;
  
 -  /* Fontset ID if this face uses a fontset, or -1.  This is only >= 0
 -     if the face was realized for a composition sequence.
 -     Otherwise, a specific font is loaded from the set of fonts
 -     specified by the fontset given by the family attribute of the face.  */
 +#ifdef USE_FONT_BACKEND
 +  struct font_info *font_info;
 +#endif        /* USE_FONT_BACKEND */
 +
 +  /* Fontset ID if for this face's fontset.  Non-ASCII faces derived
 +     from the same ASCII face have the same fontset.  */
    int fontset;
  
    /* Pixmap width and height.  */
    /* The hash value of this face.  */
    unsigned hash;
  
 -  /* The charset for which this face was realized if it was realized
 -     for use in multibyte text.  If fontset >= 0, this is the charset
 -     of the first character of the composition sequence.  A value of
 -     charset < 0 means the face was realized for use in unibyte text
 -     where the idea of Emacs charsets isn't applicable.  */
 -  int charset;
 -
    /* Non-zero if text in this face should be underlined, overlined,
       strike-through or have a box drawn around it.  */
    unsigned underline_p : 1;
    /* Next and previous face in hash collision list of face cache.  */
    struct face *next, *prev;
  
 -  /* If this face is for ASCII characters, this points this face
 -     itself.  Otherwise, this points a face for ASCII characters.  */
 +  /* If this face is an ASCII face, this points to this face itself.
 +     Otherwise, this points to an ASCII face that has the same
 +     attributes except the font.  */
    struct face *ascii_face;
 +
 +#ifdef USE_FONT_BACKEND
 +  /* Extra member that a font-driver uses privately.  */
 +  void *extra;
 +#endif        /* USE_FONT_BACKEND */
  };
  
  
@@@ -1659,7 -1652,7 +1659,7 @@@ struct face_cach
  /* Non-zero if FACE is suitable for displaying character CHAR.  */
  
  #define FACE_SUITABLE_FOR_CHAR_P(FACE, CHAR)  \
 -  (SINGLE_BYTE_CHAR_P (CHAR)                  \
 +  (ASCII_CHAR_P (CHAR)                                \
     ? (FACE) == (FACE)->ascii_face             \
     : face_suitable_for_char_p ((FACE), (CHAR)))
  
     with id ID but is suitable for displaying character CHAR.
     This macro is only meaningful for multibyte character CHAR.  */
  
 -#define FACE_FOR_CHAR(F, FACE, CHAR)  \
 -  (SINGLE_BYTE_CHAR_P (CHAR)          \
 -   ? (FACE)->ascii_face->id           \
 -   : face_for_char ((F), (FACE), (CHAR)))
 +#define FACE_FOR_CHAR(F, FACE, CHAR, POS, OBJECT)     \
 +  (ASCII_CHAR_P (CHAR)                                        \
 +   ? (FACE)->ascii_face->id                           \
 +   : face_for_char ((F), (FACE), (CHAR), (POS), (OBJECT)))
  
  #else /* not HAVE_WINDOW_SYSTEM */
  
  #define FACE_SUITABLE_FOR_CHAR_P(FACE, CHAR) 1
 -#define FACE_FOR_CHAR(F, FACE, CHAR) ((FACE)->id)
 +#define FACE_FOR_CHAR(F, FACE, CHAR, POS, OBJECT) ((FACE)->id)
  
  #endif /* not HAVE_WINDOW_SYSTEM */
  
@@@ -1793,7 -1786,6 +1793,7 @@@ enum display_element_typ
  
  enum prop_idx
  {
 +  AUTO_COMPOSED_PROP_IDX,
    FONTIFIED_PROP_IDX,
    FACE_PROP_IDX,
    INVISIBLE_PROP_IDX,
@@@ -2335,9 -2327,7 +2335,9 @@@ struct redisplay_interfac
     the two-byte form of C.  Encoding is returned in *CHAR2B.  If
     TWO_BYTE_P is non-null, return non-zero there if font is two-byte.  */
    int (*encode_char) P_ ((int c, XChar2b *char2b,
 -                        struct font_info *font_into, int *two_byte_p));
 +                        struct font_info *font_into,
 +                        struct charset *charset,
 +                        int *two_byte_p));
  
  /* Compute left and right overhang of glyph string S.
     A NULL pointer if platform does not support this. */
@@@ -2845,17 -2835,15 +2845,17 @@@ void clear_face_cache P_ ((int))
  unsigned long load_color P_ ((struct frame *, struct face *, Lisp_Object,
                              enum lface_attribute_index));
  void unload_color P_ ((struct frame *, unsigned long));
 -int face_font_available_p P_ ((struct frame *, Lisp_Object));
 +char *choose_face_font P_ ((struct frame *, Lisp_Object *, Lisp_Object,
 +                          int *));
  int ascii_face_of_lisp_face P_ ((struct frame *, int));
  void prepare_face_for_display P_ ((struct frame *, struct face *));
  int xstricmp P_ ((const unsigned char *, const unsigned char *));
 -int lookup_face P_ ((struct frame *, Lisp_Object *, int, struct face *));
 -int lookup_named_face P_ ((struct frame *, Lisp_Object, int, int));
 +int lookup_face P_ ((struct frame *, Lisp_Object *));
 +int lookup_non_ascii_face P_ ((struct frame *, int, struct face *));
 +int lookup_named_face P_ ((struct frame *, Lisp_Object, int));
  int smaller_face P_ ((struct frame *, int, int));
  int face_with_height P_ ((struct frame *, int, int));
 -int lookup_derived_face P_ ((struct frame *, Lisp_Object, int, int, int));
 +int lookup_derived_face P_ ((struct frame *, Lisp_Object, int, int));
  void init_frame_faces P_ ((struct frame *));
  void free_frame_faces P_ ((struct frame *));
  void recompute_basic_faces P_ ((struct frame *));
@@@ -2866,12 -2854,10 +2866,12 @@@ int face_at_string_position P_ ((struc
  int merge_faces P_ ((struct frame *, Lisp_Object, int, int));
  int compute_char_face P_ ((struct frame *, int, Lisp_Object));
  void free_all_realized_faces P_ ((Lisp_Object));
 +void free_realized_face P_ ((struct frame *, struct face *));
  extern Lisp_Object Qforeground_color, Qbackground_color;
  extern Lisp_Object Qframe_set_background_mode;
  extern char unspecified_fg[], unspecified_bg[];
 -void free_realized_multibyte_face P_ ((struct frame *, int));
 +extern Lisp_Object split_font_name_into_vector P_ ((Lisp_Object));
 +extern Lisp_Object build_font_name_from_vector P_ ((Lisp_Object));
  
  /* Defined in xfns.c  */
  
diff --combined src/dispnew.c
index e554eb1cd7e04a81e62398be0e2e2d8c892b839b,172f07c663a4727dfd381669e8f943d2a654049c..ccda3eca550f688b1477113a7ab04c8fe98ed668
@@@ -1,7 -1,7 +1,7 @@@
  /* Updating of data structures for redisplay.
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                   1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                  2004, 2005, 2006 Free Software Foundation, Inc.
+                  2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -37,7 -37,7 +37,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "dispextern.h"
  #include "cm.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "keyboard.h"
  #include "frame.h"
  #include "window.h"
@@@ -4391,12 -4391,12 +4391,12 @@@ update_text_area (w, vpos
        || desired_row->phys_height != current_row->phys_height
        || desired_row->visible_height != current_row->visible_height
        || current_row->overlapped_p
- #if 0
-       /* This causes excessive flickering when mouse is moved across
-        the mode line.  Luckily everything seems to work just fine
-        without doing this.  KFS 2006-09-17.  */
-       || current_row->mouse_face_p
- #endif
+       /* This next line is necessary for correctly redrawing
+        mouse-face areas after scrolling and other operations.
+        However, it causes excessive flickering when mouse is moved
+        across the mode line.  Luckily, turning it off for the mode
+        line doesn't seem to hurt anything. -- cyd.  */
+       || (current_row->mouse_face_p && !current_row->mode_line_p)
        || current_row->x != desired_row->x)
      {
        rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
diff --combined src/disptab.h
index 0d7a03c43ba4b7912ad22121fbe9f8e04494878a,e20f3e27631607bb2ea1c25191feb6662a7ec26e..513150902ad01bb91f411927d5b5ea3082586b59
@@@ -1,6 -1,6 +1,6 @@@
  /* Things for GLYPHS and glyph tables.
-    Copyright (C) 1993, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+    Copyright (C) 1993, 2001, 2002, 2003, 2004, 2005,
+                  2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -36,14 -36,8 +36,14 @@@ Boston, MA 02110-1301, USA.  *
  
  extern Lisp_Object disp_char_vector P_ ((struct Lisp_Char_Table *, int));
  
 -#define DISP_CHAR_VECTOR(dp, c) \
 -  (SINGLE_BYTE_CHAR_P(c) ? (dp)->contents[c] : disp_char_vector ((dp), (c)))
 +#define DISP_CHAR_VECTOR(dp, c)                               \
 +  (ASCII_CHAR_P(c)                                    \
 +   ? (NILP ((dp)->ascii)                              \
 +      ? (dp)->defalt                                  \
 +      : (SUB_CHAR_TABLE_P ((dp)->ascii)                       \
 +       ? XSUB_CHAR_TABLE ((dp)->ascii)->contents[c]   \
 +       : (dp)->ascii))                                \
 +   : disp_char_vector ((dp), (c)))
  
  /* Defined in window.c.  */
  extern struct Lisp_Char_Table *window_display_table P_ ((struct window *));
diff --combined src/doc.c
index ecb0197b3ca52bcebc867461d9eeb9f8d45a09b5,be52f8aa07e2010d500185cc034d09036214db29..df3ca94af1e09d79a4ac5acc84ea10eb859fe1cb
+++ b/src/doc.c
@@@ -1,6 -1,6 +1,6 @@@
  /* Record indices of function doc strings stored in a file.
     Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -41,7 -41,7 +41,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "lisp.h"
  #include "buffer.h"
  #include "keyboard.h"
 -#include "charset.h"
 +#include "character.h"
  #include "keymap.h"
  
  #ifdef HAVE_INDEX
diff --combined src/doprnt.c
index 6e71e261788c3127eb60fc263194d13882300986,326fb5743e2f57966b34c43729b27e79ec99f8e6..d3c8557c251e408ec1922ba21b9238b52377ad08
@@@ -1,8 -1,8 +1,8 @@@
  /* Output like sprintf to a buffer of specified size.
     Also takes args differently: pass one pointer to an array of strings
     in addition to the format string which is separate.
-    Copyright (C) 1985, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+    Copyright (C) 1985, 2001, 2002, 2003, 2004, 2005,
+                  2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -47,7 -47,7 +47,7 @@@ Boston, MA 02110-1301, USA.  *
  /* Since we use the macro CHAR_HEAD_P, we have to include this, but
     don't have to include others because CHAR_HEAD_P does not contains
     another macro.  */
 -#include "charset.h"
 +#include "character.h"
  
  static int doprnt1 ();
  
diff --combined src/dosfns.c
index 37085ebeb5fcb5f1b3040b13af04c0ff196dd236,e57a6a197be41e9ed0903c8dcc748ac7adcc8f57..801df68ae7e4039762242fea80223f2c536bdfd3
@@@ -1,7 -1,7 +1,7 @@@
  /* MS-DOS specific Lisp utilities.  Coded by Manabu Higashida, 1991.
     Major changes May-July 1993 Morten Welinder (only 10% original code left)
     Copyright (C) 1991, 1993, 1996, 1997, 1998, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -38,7 -38,7 +38,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "dosfns.h"
  #include "msdos.h"
  #include "dispextern.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include <dpmi.h>
  #include <go32.h>
diff --combined src/editfns.c
index 79a88604d8c3d5388ae1070943d29775ab2fc7b8,6ef2efe313e2e70c05d05e753ae6bfa4a725c0fc..3e27ca0cf433bfc480d88baacc0151f5cb9d4d87
@@@ -1,7 -1,7 +1,7 @@@
  /* Lisp functions pertaining to editing.
     Copyright (C) 1985, 1986, 1987, 1989, 1993, 1994, 1995, 1996,
                   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -52,7 -52,7 +52,7 @@@ Boston, MA 02110-1301, USA.  *
  
  #include "intervals.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "frame.h"
  #include "window.h"
@@@ -207,7 -207,9 +207,7 @@@ usage: (char-to-string CHAR)  */
  
    CHECK_NUMBER (character);
  
 -  len = (SINGLE_BYTE_CHAR_P (XFASTINT (character))
 -       ? (*str = (unsigned char)(XFASTINT (character)), 1)
 -       : char_to_string (XFASTINT (character), str));
 +  len = CHAR_STRING (XFASTINT (character), str);
    return make_string_from_bytes (str, 1, len);
  }
  
@@@ -1312,7 -1314,10 +1312,10 @@@ DEFUN ("user-uid", Fuser_uid, Suser_uid
  Value is an integer or float, depending on the value.  */)
       ()
  {
-   return make_fixnum_or_float (geteuid ());
+   /* Assignment to EMACS_INT stops GCC whining about limited range of
+      data type.  */
+   EMACS_INT euid = geteuid ();
+   return make_fixnum_or_float (euid);
  }
  
  DEFUN ("user-real-uid", Fuser_real_uid, Suser_real_uid, 0, 0, 0,
  Value is an integer or float, depending on the value.  */)
       ()
  {
-   return make_fixnum_or_float (getuid ());
+   /* Assignment to EMACS_INT stops GCC whining about limited range of
+      data type.  */
+   EMACS_INT uid = getuid ();
+   return make_fixnum_or_float (uid);
  }
  
  DEFUN ("user-full-name", Fuser_full_name, Suser_full_name, 0, 1, 0,
@@@ -1448,9 -1456,9 +1454,9 @@@ most significant 16 bits of the seconds
  least significant 16 bits.  The third integer gives the microsecond
  count.
  
- On systems that can't determine the run time, get-internal-run-time
- does the same thing as current-time.  The microsecond count is zero on
- systems that do not provide resolution finer than a second.  */)
+ On systems that can't determine the run time, `get-internal-run-time'
+ does the same thing as `current-time'.  The microsecond count is zero
on systems that do not provide resolution finer than a second.  */)
       ()
  {
  #ifdef HAVE_GETRUSAGE
@@@ -1676,7 -1684,9 +1682,9 @@@ For example, to produce full ISO 8601 f
    /* This is probably enough.  */
    size = SBYTES (format_string) * 6 + 50;
  
+   BLOCK_INPUT;
    tm = ut ? gmtime (&value) : localtime (&value);
+   UNBLOCK_INPUT;
    if (! tm)
      error ("Specified time is not representable");
  
        int result;
  
        buf[0] = '\1';
+       BLOCK_INPUT;
        result = emacs_memftimeu (buf, size, SDATA (format_string),
                                SBYTES (format_string),
                                tm, ut);
+       UNBLOCK_INPUT;
        if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
        return code_convert_string_norecord (make_unibyte_string (buf, result),
                                             Vlocale_coding_system, 0);
  
        /* If buffer was too small, make it bigger and try again.  */
+       BLOCK_INPUT;
        result = emacs_memftimeu (NULL, (size_t) -1,
                                SDATA (format_string),
                                SBYTES (format_string),
                                tm, ut);
+       UNBLOCK_INPUT;
        size = result + 1;
      }
  }
  DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 1, 0,
         doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST ZONE).
  The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED),
- as from `current-time' and `file-attributes', or `nil' to use the
+ as from `current-time' and `file-attributes', or nil to use the
  current time.  The obsolete form (HIGH . LOW) is also still accepted.
  The list has the following nine members: SEC is an integer between 0
  and 60; SEC is 60 for a leap second, which only some operating systems
@@@ -1730,7 -1744,9 +1742,9 @@@ DOW and ZONE.)  */
    if (! lisp_time_argument (specified_time, &time_spec, NULL))
      error ("Invalid time specification");
  
+   BLOCK_INPUT;
    decoded_time = localtime (&time_spec);
+   UNBLOCK_INPUT;
    if (! decoded_time)
      error ("Specified time is not representable");
    XSETFASTINT (list_args[0], decoded_time->tm_sec);
  
    /* Make a copy, in case gmtime modifies the struct.  */
    save_tm = *decoded_time;
+   BLOCK_INPUT;
    decoded_time = gmtime (&time_spec);
+   UNBLOCK_INPUT;
    if (decoded_time == 0)
      list_args[8] = Qnil;
    else
@@@ -1802,7 -1820,11 +1818,11 @@@ usage: (encode-time SECOND MINUTE HOUR 
    if (CONSP (zone))
      zone = Fcar (zone);
    if (NILP (zone))
-     time = mktime (&tm);
+     {
+       BLOCK_INPUT;
+       time = mktime (&tm);
+       UNBLOCK_INPUT;
+     }
    else
      {
        char tzbuf[100];
         value doesn't suffice, since that would mishandle leap seconds.  */
        set_time_zone_rule (tzstring);
  
+       BLOCK_INPUT;
        time = mktime (&tm);
+       UNBLOCK_INPUT;
  
        /* Restore TZ to previous value.  */
        newenv = environ;
@@@ -1871,7 -1895,9 +1893,9 @@@ but this is considered obsolete.  */
    /* Convert to a string, checking for out-of-range time stamps.
       Don't use 'ctime', as that might dump core if VALUE is out of
       range.  */
+   BLOCK_INPUT;
    tm = localtime (&value);
+   UNBLOCK_INPUT;
    if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year) && (tem = asctime (tm))))
      error ("Specified time is not representable");
  
@@@ -1927,9 -1953,21 +1951,21 @@@ the data it can't find.  */
    struct tm *t;
    struct tm gmt;
  
-   if (lisp_time_argument (specified_time, &value, NULL)
-       && (t = gmtime (&value)) != 0
-       && (gmt = *t, t = localtime (&value)) != 0)
+   if (!lisp_time_argument (specified_time, &value, NULL))
+     t = NULL;
+   else
+     {
+       BLOCK_INPUT;
+       t = gmtime (&value);
+       if (t)
+       {
+         gmt = *t;
+         t = localtime (&value);
+       }
+       UNBLOCK_INPUT;
+     }
+   if (t)
      {
        int offset = tm_diff (t, &gmt);
        char *s = 0;
@@@ -2126,7 -2164,7 +2162,7 @@@ general_insert_function (insert_func, i
            len = CHAR_STRING (XFASTINT (val), str);
          else
            {
 -            str[0] = (SINGLE_BYTE_CHAR_P (XINT (val))
 +            str[0] = (ASCII_CHAR_P (XINT (val))
                        ? XINT (val)
                        : multibyte_char_to_unibyte (XINT (val), Qnil));
              len = 1;
@@@ -2247,8 -2285,7 +2283,7 @@@ usage: (insert-before-markers-and-inher
  }
  \f
  DEFUN ("insert-char", Finsert_char, Sinsert_char, 2, 3, 0,
-        doc: /* Insert COUNT (second arg) copies of CHARACTER (first arg).
- Both arguments are required.
+        doc: /* Insert COUNT copies of CHARACTER.
  Point, and before-insertion markers, are relocated as in the function `insert'.
  The optional third arg INHERIT, if non-nil, says to inherit text properties
  from adjoining text, if those properties are sticky.  */)
    return Qnil;
  }
  
 +DEFUN ("insert-byte", Finsert_byte, Sinsert_byte, 2, 3, 0,
 +       doc: /* Insert COUNT (second arg) copies of BYTE (first arg).
 +Both arguments are required.
 +BYTE is a number of the range 0..255.
 +
 +If BYTE is 128..255 and the current buffer is multibyte, the
 +corresponding eight-bit character is inserted.
 +
 +Point, and before-insertion markers, are relocated as in the function `insert'.
 +The optional third arg INHERIT, if non-nil, says to inherit text properties
 +from adjoining text, if those properties are sticky.  */)
 +     (byte, count, inherit)
 +       Lisp_Object byte, count, inherit;
 +{
 +  CHECK_NUMBER (byte);
 +  if (XINT (byte) < 0 || XINT (byte) > 255)
 +    args_out_of_range_3 (byte, make_number (0), make_number (255));
 +  if (XINT (byte) >= 128
 +      && ! NILP (current_buffer->enable_multibyte_characters))
 +    XSETFASTINT (byte, BYTE8_TO_CHAR (XINT (byte)));
 +  return Finsert_char (byte, count, inherit);
 +}
 +
  \f
  /* Making strings from buffer contents.  */
  
@@@ -2878,73 -2892,12 +2913,73 @@@ Both characters must have the same leng
    return Qnil;
  }
  
 +
 +static Lisp_Object check_translation P_ ((int, int, int, Lisp_Object));
 +
 +/* Helper function for Ftranslate_region_internal.
 +
 +   Check if a character sequence at POS (POS_BYTE) matches an element
 +   of VAL.  VAL is a list (([FROM-CHAR ...] . TO) ...).  If a matching
 +   element is found, return it.  Otherwise return Qnil.  */
 +
 +static Lisp_Object
 +check_translation (pos, pos_byte, end, val)
 +     int pos, pos_byte, end;
 +     Lisp_Object val;
 +{
 +  int buf_size = 16, buf_used = 0;
 +  int *buf = alloca (sizeof (int) * buf_size);
 +
 +  for (; CONSP (val); val = XCDR (val))
 +    {
 +      Lisp_Object elt;
 +      int len, i;
 +
 +      elt = XCAR (val);
 +      if (! CONSP (elt))
 +      continue;
 +      elt = XCAR (elt);
 +      if (! VECTORP (elt))
 +      continue;
 +      len = ASIZE (elt);
 +      if (len <= end - pos)
 +      {
 +        for (i = 0; i < len; i++)
 +          {
 +            if (buf_used <= i)
 +              {
 +                unsigned char *p = BYTE_POS_ADDR (pos_byte);
 +                int len;
 +
 +                if (buf_used == buf_size)
 +                  {
 +                    int *newbuf;
 +
 +                    buf_size += 16;
 +                    newbuf = alloca (sizeof (int) * buf_size);
 +                    memcpy (newbuf, buf, sizeof (int) * buf_used);
 +                    buf = newbuf;
 +                  }
 +                buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, 0, len);
 +                pos_byte += len;
 +              }
 +            if (XINT (AREF (elt, i)) != buf[i])
 +              break;
 +          }
 +        if (i == len)
 +          return XCAR (val);
 +      }
 +    }
 +  return Qnil;
 +}
 +
 +
  DEFUN ("translate-region-internal", Ftranslate_region_internal,
         Stranslate_region_internal, 3, 3, 0,
         doc: /* Internal use only.
  From START to END, translate characters according to TABLE.
 -TABLE is a string; the Nth character in it is the mapping
 -for the character with code N.
 +TABLE is a string or a char-table; the Nth character in it is the
 +mapping for the character with code N.
  It returns the number of characters changed.  */)
       (start, end, table)
       Lisp_Object start;
    int pos, pos_byte, end_pos;
    int multibyte = !NILP (current_buffer->enable_multibyte_characters);
    int string_multibyte;
 +  Lisp_Object val;
  
    validate_region (&start, &end);
    if (CHAR_TABLE_P (table))
      {
 +      if (! EQ (XCHAR_TABLE (table)->purpose, Qtranslation_table))
 +      error ("Not a translation table");
        size = MAX_CHAR;
        tt = NULL;
      }
        if (! multibyte && (SCHARS (table) < SBYTES (table)))
        table = string_make_unibyte (table);
        string_multibyte = SCHARS (table) < SBYTES (table);
 -      size = SCHARS (table);
 +      size = SBYTES (table);
        tt = SDATA (table);
      }
  
    pos = XINT (start);
    pos_byte = CHAR_TO_BYTE (pos);
    end_pos = XINT (end);
 -  modify_region (current_buffer, pos, XINT (end), 0);
 +  modify_region (current_buffer, pos, end_pos, 0);
  
    cnt = 0;
    for (; pos < end_pos; )
        unsigned char *str, buf[MAX_MULTIBYTE_LENGTH];
        int len, str_len;
        int oc;
 +      Lisp_Object val;
  
        if (multibyte)
        oc = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len);
              if (string_multibyte)
                {
                  str = tt + string_char_to_byte (table, oc);
 -                nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH,
 +                nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH, 
                                               str_len);
                }
              else
                  nc = tt[oc];
                  if (! ASCII_BYTE_P (nc) && multibyte)
                    {
 -                    str_len = CHAR_STRING (nc, buf);
 +                    str_len = BYTE8_STRING (nc, buf);
                      str = buf;
                    }
                  else
            }
          else
            {
 -            Lisp_Object val;
              int c;
  
              nc = oc;
              val = CHAR_TABLE_REF (table, oc);
 -            if (INTEGERP (val)
 +            if (CHARACTERP (val)
                  && (c = XINT (val), CHAR_VALID_P (c, 0)))
                {
                  nc = c;
                  str_len = CHAR_STRING (nc, buf);
                  str = buf;
                }
 +            else if (VECTORP (val) || (CONSP (val)))
 +              {
 +                /* VAL is [TO_CHAR ...] or (([FROM-CHAR ...] .  TO) ...)
 +                   where TO is TO-CHAR or [TO-CHAR ...].  */
 +                nc = -1;
 +              }
            }
  
 -        if (nc != oc)
 +        if (nc != oc && nc >= 0)
            {
 +            /* Simple one char to one char translation.  */
              if (len != str_len)
                {
                  Lisp_Object string;
  
                  /* This is less efficient, because it moves the gap,
 -                   but it should multibyte characters correctly.  */
 +                   but it should handle multibyte characters correctly.  */
                  string = make_multibyte_string (str, 1, str_len);
                  replace_range (pos, pos + 1, string, 1, 0, 1);
                  len = str_len;
                }
              ++cnt;
            }
 +        else if (nc < 0)
 +          {
 +            Lisp_Object string;
 +
 +            if (CONSP (val))
 +              {
 +                val = check_translation (pos, pos_byte, end_pos, val);
 +                if (NILP (val))
 +                  {
 +                    pos_byte += len;
 +                    pos++;
 +                    continue;
 +                  }
 +                /* VAL is ([FROM-CHAR ...] . TO).  */
 +                len = ASIZE (XCAR (val));
 +                val = XCDR (val);
 +              }
 +            else
 +              len = 1;
 +
 +            if (VECTORP (val))
 +              {
 +                int i;
 +
 +                string = Fmake_string (make_number (ASIZE (val)),
 +                                       AREF (val, 0));
 +                for (i = 1; i < ASIZE (val); i++)
 +                  Faset (string, make_number (i), AREF (val, i));
 +              }
 +            else
 +              {
 +                string = Fmake_string (make_number (1), val);
 +              }
 +            replace_range (pos, pos + len, string, 1, 0, 1);
 +            pos_byte += SBYTES (string);
 +            pos += SCHARS (string);
 +            cnt += SCHARS (string);
 +            end_pos += SCHARS (string) - len;
 +            continue;
 +          }
        }
        pos_byte += len;
        pos++;
@@@ -3271,7 -3174,7 +3306,7 @@@ save_restriction_restore (data
  DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
         doc: /* Execute BODY, saving and restoring current buffer's restrictions.
  The buffer's restrictions make parts of the beginning and end invisible.
- (They are set up with `narrow-to-region' and eliminated with `widen'.)
\(They are set up with `narrow-to-region' and eliminated with `widen'.)
  This special form, `save-restriction', saves the current buffer's restrictions
  when it is entered, and restores them when it is exited.
  So any `narrow-to-region' within BODY lasts only until the end of the form.
@@@ -3703,8 -3606,8 +3738,8 @@@ usage: (format STRING &rest OBJECTS)  *
            thissize = 30;
            if (*format == 'c')
              {
 -              if (! SINGLE_BYTE_CHAR_P (XINT (args[n]))
 -                  /* Note: No one can remember why we have to treat
 +              if (! ASCII_CHAR_P (XINT (args[n]))
 +                  /* Note: No one can remeber why we have to treat
                       the character 0 as a multibyte character here.
                       But, until it causes a real problem, let's
                       don't change it.  */
                if (*format != 'd' && *format != 'o' && *format != 'x'
                    && *format != 'i' && *format != 'X' && *format != 'c')
                  error ("Invalid format operation %%%c", *format);
-               args[n] = Ftruncate (args[n], Qnil);
+               /* This fails unnecessarily if args[n] is bigger than
+                  most-positive-fixnum but smaller than MAXINT.
+                  These cases are important because we sometimes use floats
+                  to represent such integer values (typically such values
+                  come from UIDs or PIDs).  */
+               /* args[n] = Ftruncate (args[n], Qnil); */
              }
  
            /* Note that we're using sprintf to print floats,
                  else
                    sprintf (p, this_format, XUINT (args[n]));
                }
-             else
+             else if (format[-1] == 'e' || format[-1] == 'f' || format[-1] == 'g')
                sprintf (p, this_format, XFLOAT_DATA (args[n]));
+             else if (format[-1] == 'd')
+               /* Maybe we should use "%1.0f" instead so it also works
+                  for values larger than MAXINT.  */
+               sprintf (p, this_format, (EMACS_INT) XFLOAT_DATA (args[n]));
+             else
+               /* Don't sign-extend for octal or hex printing.  */
+               sprintf (p, this_format, (EMACS_UINT) XFLOAT_DATA (args[n]));
  
              if (p > buf
                  && multibyte
@@@ -4096,20 -4011,8 +4143,20 @@@ Case is ignored if `case-fold-search' i
    /* Do these in separate statements,
       then compare the variables.
       because of the way DOWNCASE uses temp variables.  */
 -  i1 = DOWNCASE (XFASTINT (c1));
 -  i2 = DOWNCASE (XFASTINT (c2));
 +  i1 = XFASTINT (c1);
 +  if (NILP (current_buffer->enable_multibyte_characters)
 +      && ! ASCII_CHAR_P (i1))
 +    {
 +      MAKE_CHAR_MULTIBYTE (i1);
 +    }
 +  i2 = XFASTINT (c2);
 +  if (NILP (current_buffer->enable_multibyte_characters)
 +      && ! ASCII_CHAR_P (i2))
 +    {
 +      MAKE_CHAR_MULTIBYTE (i2);
 +    }
 +  i1 = DOWNCASE (i1);
 +  i2 = DOWNCASE (i2);
    return (i1 == i2 ? Qt :  Qnil);
  }
  \f
@@@ -4589,7 -4492,6 +4636,7 @@@ functions if all the text being accesse
    defsubr (&Sinsert_and_inherit);
    defsubr (&Sinsert_and_inherit_before_markers);
    defsubr (&Sinsert_char);
 +  defsubr (&Sinsert_byte);
  
    defsubr (&Suser_login_name);
    defsubr (&Suser_real_login_name);
diff --combined src/emacs.c
index 1db552c33e5c9c146d910980422f884cac4c0793,543f7a8d5eaa323a9e660b7fbf7fb49a3ee39085..5219176eda98b547ff73fd84e442b927e71c2804
@@@ -1,6 -1,6 +1,6 @@@
  /* Fully extensible Emacs, running on Unix, intended for GNU.
     Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 1998, 1999,
-                  2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -788,9 -788,6 +788,9 @@@ bug_reporting_address (
    return count >= 3 ? REPORT_EMACS_BUG_PRETEST_ADDRESS : REPORT_EMACS_BUG_ADDRESS;
  }
  
 +#ifdef USE_FONT_BACKEND
 +extern int enable_font_backend;
 +#endif        /* USE_FONT_BACKEND */
  
  /* ARGSUSED */
  int
@@@ -869,7 -866,7 +869,7 @@@ main (argc, arg
        else
        {
          printf ("GNU Emacs %s\n", SDATA (tem));
-         printf ("Copyright (C) 2006 Free Software Foundation, Inc.\n");
+         printf ("Copyright (C) 2007 Free Software Foundation, Inc.\n");
          printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
          printf ("You may redistribute copies of Emacs\n");
          printf ("under the terms of the GNU General Public License.\n");
        init_alloc_once ();
        init_obarray ();
        init_eval_once ();
 +      init_character_once ();
        init_charset_once ();
        init_coding_once ();
        init_syntax_once ();    /* Create standard syntax table.  */
              Lisp_Object buffer;
  
              buffer = Fcdr (XCAR (tail));
 -            /* Verify that all buffers are empty now, as they
 -               ought to be.  */
 -            if (BUF_Z (XBUFFER (buffer)) > BUF_BEG (XBUFFER (buffer)))
 -              abort ();
 -            /* It is safe to do this crudely in an empty buffer.  */
 -            XBUFFER (buffer)->enable_multibyte_characters = Qnil;
 +            /* Make a multibyte buffer unibyte.  */
 +            if (BUF_Z_BYTE (XBUFFER (buffer)) > BUF_Z (XBUFFER (buffer)))
 +              {
 +                struct buffer *current = current_buffer;
 +
 +                set_buffer_temp (XBUFFER (buffer));
 +                Fset_buffer_multibyte (Qnil);
 +                set_buffer_temp (current);
 +              }
            }
        }
      }
    no_loadup
      = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
  
 +#ifdef USE_FONT_BACKEND
 +  enable_font_backend = 0;
 +  if (argmatch (argv, argc, "-enable-font-backend", "--enable-font-backend",
 +              4, NULL, &skip_args))
 +    enable_font_backend = 1;
 +#endif        /* USE_FONT_BACKEND */
  
  #ifdef HAVE_X_WINDOWS
    /* Stupid kludge to catch command-line display spec.  We can't
        syms_of_data ();
  #endif
        syms_of_alloc ();
 +      syms_of_chartab ();
        syms_of_lread ();
        syms_of_print ();
        syms_of_eval ();
        /* Called before init_window_once for Mac OS Classic.  */
        syms_of_ccl ();
  #endif
 +      syms_of_character ();
        syms_of_charset ();
        syms_of_cmds ();
  #ifndef NO_DIR_LIBRARY
        syms_of_window ();
        syms_of_xdisp ();
  #ifdef HAVE_WINDOW_SYSTEM
 +#ifdef USE_FONT_BACKEND
 +      syms_of_font ();
 +#endif        /* USE_FONT_BACKEND */
        syms_of_fringe ();
        syms_of_image ();
  #endif /* HAVE_WINDOW_SYSTEM */
  #endif  /* HAVE_NTGUI */
      }
  
 +  init_charset ();
 +
    if (!noninteractive)
      {
  #ifdef VMS
@@@ -1816,7 -1796,6 +1816,7 @@@ struct standard_args standard_args[] 
    { "-unibyte", "--unibyte", 81, 0 },
    { "-no-multibyte", "--no-multibyte", 80, 0 },
    { "-nl", "--no-loadup", 70, 0 },
 +  { "-enable-font-backend", "--enable-font-backend", 65, 0 },
    /* -d must come last before the options handled in startup.el.  */
    { "-d", "--display", 60, 1 },
    { "-display", 0, 60, 1 },
@@@ -2501,7 -2480,8 +2501,8 @@@ before you compile Emacs, to enable th
    emacs_priority = 0;
  
    DEFVAR_LISP ("path-separator", &Vpath_separator,
-              doc: /* The directory separator in search paths, as a string.  */);
+              doc: /* String containing the character that separates directories in
+ search paths, such as PATH and other similar environment variables.  */);
    {
      char c = SEPCHAR;
      Vpath_separator = make_string (&c, 1);
diff --combined src/fileio.c
index e276426487ee6fd3610905c45488bbbb2759b88d,df6a6668766ad75c1144ce6d55672ec3d810f8d0..c6589e989ecc751bd58f9949f54921071f545442
@@@ -1,7 -1,7 +1,7 @@@
  /* File IO for GNU Emacs.
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996,
                   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -74,7 -74,7 +74,7 @@@ extern int errno
  #include "lisp.h"
  #include "intervals.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "window.h"
  #include "blockinput.h"
@@@ -271,12 -271,9 +271,12 @@@ report_file_error (string, data
  {
    Lisp_Object errstring;
    int errorno = errno;
 +  char *str;
  
    synchronize_system_messages_locale ();
 -  errstring = code_convert_string_norecord (build_string (strerror (errorno)),
 +  str = strerror (errorno);
 +  errstring = code_convert_string_norecord (make_unibyte_string (str,
 +                                                               strlen (str)),
                                            Vlocale_coding_system, 0);
  
    while (1)
@@@ -314,7 -311,6 +314,7 @@@ restore_point_unwind (location
    Fset_marker (location, Qnil, Qnil);
    return Qnil;
  }
 +
  \f
  Lisp_Object Qexpand_file_name;
  Lisp_Object Qsubstitute_in_file_name;
@@@ -2295,8 -2291,7 +2295,8 @@@ duplicates what `expand-file-name' does
               convert what we substitute into multibyte.  */
            while (*o)
              {
 -              int c = unibyte_char_to_multibyte (*o++);
 +              int c = *o++;
 +              c = unibyte_char_to_multibyte (c);
                x += CHAR_STRING (c, x);
              }
          }
@@@ -3735,7 -3730,7 +3735,7 @@@ actually used.  */
    unsigned char buffer[1 << 14];
    int replace_handled = 0;
    int set_coding_system = 0;
 -  int coding_system_decided = 0;
 +  Lisp_Object coding_system;
    int read_quit = 0;
    Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
    int we_locked_file = 0;
    CHECK_STRING (filename);
    filename = Fexpand_file_name (filename, Qnil);
  
 +  /* The value Qnil means that the coding system is not yet
 +     decided.  */
 +  coding_system = Qnil;
 +
    /* If the file name has special constructs in it,
       call the corresponding file handler.  */
    handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
  
    if (EQ (Vcoding_system_for_read, Qauto_save_coding))
      {
 -      /* We use emacs-mule for auto saving... */
 -      setup_coding_system (Qemacs_mule, &coding);
 -      /* ... but with the special flag to indicate to read in a
 -       multibyte sequence for eight-bit-control char as is.  */
 -      coding.flags = 1;
 -      coding.src_multibyte = 0;
 -      coding.dst_multibyte
 -      = !NILP (current_buffer->enable_multibyte_characters);
 -      coding.eol_type = CODING_EOL_LF;
 -      coding_system_decided = 1;
 +      coding_system = coding_inherit_eol_type (Qutf_8_emacs, Qunix);
 +      setup_coding_system (coding_system, &coding);
 +      /* Ensure we set Vlast_coding_system_used.  */
 +      set_coding_system = 1;
      }
    else if (BEG < Z)
      {
        /* Decide the coding system to use for reading the file now
           because we can't use an optimized method for handling
           `coding:' tag if the current buffer is not empty.  */
 -      Lisp_Object val;
 -      val = Qnil;
 -
        if (!NILP (Vcoding_system_for_read))
 -      val = Vcoding_system_for_read;
 +      coding_system = Vcoding_system_for_read;
        else
        {
          /* Don't try looking inside a file for a coding system
  
                  insert_1_both (read_buf, nread, nread, 0, 0, 0);
                  TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
 -                val = call2 (Vset_auto_coding_function,
 -                             filename, make_number (nread));
 +                coding_system = call2 (Vset_auto_coding_function,
 +                                       filename, make_number (nread));
                  set_buffer_internal (prev);
  
                  /* Discard the unwind protect for recovering the
                }
            }
  
 -        if (NILP (val))
 +        if (NILP (coding_system))
            {
              /* If we have not yet decided a coding system, check
                   file-coding-system-alist.  */
 -            Lisp_Object args[6], coding_systems;
 +            Lisp_Object args[6];
  
              args[0] = Qinsert_file_contents, args[1] = orig_filename;
              args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
 -            coding_systems = Ffind_operation_coding_system (6, args);
 -            if (CONSP (coding_systems))
 -              val = XCAR (coding_systems);
 +            coding_system = Ffind_operation_coding_system (6, args);
 +            if (CONSP (coding_system))
 +              coding_system = XCAR (coding_system);
            }
        }
  
 -      setup_coding_system (Fcheck_coding_system (val), &coding);
 -      /* Ensure we set Vlast_coding_system_used.  */
 -      set_coding_system = 1;
 +      if (NILP (coding_system))
 +      coding_system = Qundecided;
 +      else
 +      CHECK_CODING_SYSTEM (coding_system);
  
 -      if (NILP (current_buffer->enable_multibyte_characters)
 -        && ! NILP (val))
 +      if (NILP (current_buffer->enable_multibyte_characters))
        /* We must suppress all character code conversion except for
           end-of-line conversion.  */
 -      setup_raw_text_coding_system (&coding);
 +      coding_system = raw_text_coding_system (coding_system);
  
 -      coding.src_multibyte = 0;
 -      coding.dst_multibyte
 -      = !NILP (current_buffer->enable_multibyte_characters);
 -      coding_system_decided = 1;
 +      setup_coding_system (coding_system, &coding);
 +      /* Ensure we set Vlast_coding_system_used.  */
 +      set_coding_system = 1;
      }
  
    /* If requested, replace the accessible part of the buffer
       and let the following if-statement handle the replace job.  */
    if (!NILP (replace)
        && BEGV < ZV
 -      && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK))
 +      && (NILP (coding_system)
 +        || ! CODING_REQUIRE_DECODING (&coding)))
      {
        /* same_at_start and same_at_end count bytes,
         because file access counts bytes
          else if (nread == 0)
            break;
  
 -        if (coding.type == coding_type_undecided)
 -          detect_coding (&coding, buffer, nread);
 -        if (coding.common_flags & CODING_REQUIRE_DECODING_MASK)
 -          /* We found that the file should be decoded somehow.
 -               Let's give up here.  */
 +        if (CODING_REQUIRE_DETECTION (&coding))
            {
 -            giveup_match_end = 1;
 -            break;
 +            coding_system = detect_coding_system (buffer, nread, nread, 1, 0,
 +                                                  coding_system);
 +            setup_coding_system (coding_system, &coding);
            }
  
 -        if (coding.eol_type == CODING_EOL_UNDECIDED)
 -          detect_eol (&coding, buffer, nread);
 -        if (coding.eol_type != CODING_EOL_UNDECIDED
 -            && coding.eol_type != CODING_EOL_LF)
 -          /* We found that the format of eol should be decoded.
 +        if (CODING_REQUIRE_DECODING (&coding))
 +          /* We found that the file should be decoded somehow.
                 Let's give up here.  */
            {
              giveup_match_end = 1;
      {
        int same_at_start = BEGV_BYTE;
        int same_at_end = ZV_BYTE;
 +      int same_at_start_charpos;
 +      int inserted_chars;
        int overlap;
        int bufpos;
 -      /* Make sure that the gap is large enough.  */
 -      int bufsize = 2 * st.st_size;
 -      unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
 +      unsigned char *decoded;
        int temp;
 +      int this_count = SPECPDL_INDEX ();
 +      int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
 +      Lisp_Object conversion_buffer;
 +
 +      conversion_buffer = code_conversion_save (1, multibyte);
  
        /* First read the whole file, performing code conversion into
         CONVERSION_BUFFER.  */
  
        if (lseek (fd, XINT (beg), 0) < 0)
 -      {
 -        xfree (conversion_buffer);
 -        report_file_error ("Setting file position",
 -                           Fcons (orig_filename, Qnil));
 -      }
 +      report_file_error ("Setting file position",
 +                         Fcons (orig_filename, Qnil));
  
        total = st.st_size;     /* Total bytes in the file.  */
        how_much = 0;           /* Bytes read from file so far.  */
        inserted = 0;           /* Bytes put into CONVERSION_BUFFER so far.  */
        unprocessed = 0;                /* Bytes not processed in previous loop.  */
  
 +      GCPRO1 (conversion_buffer);
        while (how_much < total)
        {
 +        /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
 +           quitting while reading a huge while.  */
          /* try is reserved in some compilers (Microsoft C) */
          int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
 -        unsigned char *destination = read_buf + unprocessed;
          int this;
  
          /* Allow quitting out of the actual I/O.  */
          immediate_quit = 1;
          QUIT;
 -        this = emacs_read (fd, destination, trytry);
 +        this = emacs_read (fd, read_buf + unprocessed, trytry);
          immediate_quit = 0;
  
 -        if (this < 0 || this + unprocessed == 0)
 +        if (this <= 0)
            {
 -            how_much = this;
 +            if (this < 0)
 +              how_much = this;
              break;
            }
  
          how_much += this;
  
 -        if (CODING_MAY_REQUIRE_DECODING (&coding))
 -          {
 -            int require, result;
 -
 -            this += unprocessed;
 -
 -            /* If we are using more space than estimated,
 -               make CONVERSION_BUFFER bigger.  */
 -            require = decoding_buffer_size (&coding, this);
 -            if (inserted + require + 2 * (total - how_much) > bufsize)
 -              {
 -                bufsize = inserted + require + 2 * (total - how_much);
 -                conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
 -              }
 -
 -            /* Convert this batch with results in CONVERSION_BUFFER.  */
 -            if (how_much >= total)  /* This is the last block.  */
 -              coding.mode |= CODING_MODE_LAST_BLOCK;
 -            if (coding.composing != COMPOSITION_DISABLED)
 -              coding_allocate_composition_data (&coding, BEGV);
 -            result = decode_coding (&coding, read_buf,
 -                                    conversion_buffer + inserted,
 -                                    this, bufsize - inserted);
 -
 -            /* Save for next iteration whatever we didn't convert.  */
 -            unprocessed = this - coding.consumed;
 -            bcopy (read_buf + coding.consumed, read_buf, unprocessed);
 -            if (!NILP (current_buffer->enable_multibyte_characters))
 -              this = coding.produced;
 -            else
 -              this = str_as_unibyte (conversion_buffer + inserted,
 -                                     coding.produced);
 -          }
 -
 -        inserted += this;
 +        BUF_SET_PT (XBUFFER (conversion_buffer),
 +                    BUF_Z (XBUFFER (conversion_buffer)));
 +        decode_coding_c_string (&coding, read_buf, unprocessed + this,
 +                                conversion_buffer);
 +        unprocessed = coding.carryover_bytes;
 +        if (coding.carryover_bytes > 0)
 +          bcopy (coding.carryover, read_buf, unprocessed);
        }
 +      UNGCPRO;
 +      emacs_close (fd);
  
 -      /* At this point, INSERTED is how many characters (i.e. bytes)
 -       are present in CONVERSION_BUFFER.
 -       HOW_MUCH should equal TOTAL,
 -       or should be <= 0 if we couldn't read the file.  */
 +      /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0
 +       if we couldn't read the file.  */
  
        if (how_much < 0)
 +      error ("IO error reading %s: %s",
 +             SDATA (orig_filename), emacs_strerror (errno));
 +
 +      if (unprocessed > 0)
        {
 -        xfree (conversion_buffer);
 -        coding_free_composition_data (&coding);
 -        error ("IO error reading %s: %s",
 -               SDATA (orig_filename), emacs_strerror (errno));
 +        coding.mode |= CODING_MODE_LAST_BLOCK;
 +        decode_coding_c_string (&coding, read_buf, unprocessed,
 +                                conversion_buffer);
 +        coding.mode &= ~CODING_MODE_LAST_BLOCK;
        }
  
 -      /* Compare the beginning of the converted file
 -       with the buffer text.  */
 +      decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer));
 +      inserted = (BUF_Z_BYTE (XBUFFER (conversion_buffer))
 +                - BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
 +
 +      /* Compare the beginning of the converted string with the buffer
 +       text.  */
  
        bufpos = 0;
        while (bufpos < inserted && same_at_start < same_at_end
 -           && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
 +           && FETCH_BYTE (same_at_start) == decoded[bufpos])
        same_at_start++, bufpos++;
  
 -      /* If the file matches the buffer completely,
 +      /* If the file matches the head of buffer completely,
         there's no need to replace anything.  */
  
        if (bufpos == inserted)
        {
 -        xfree (conversion_buffer);
 -        coding_free_composition_data (&coding);
 -        emacs_close (fd);
          specpdl_ptr--;
          /* Truncate the buffer to the size of the file.  */
          del_range_byte (same_at_start, same_at_end, 0);
          inserted = 0;
 +
 +        unbind_to (this_count, Qnil);
          goto handled;
        }
  
 -      /* Extend the start of non-matching text area to multibyte
 -       character boundary.  */
 +      /* Extend the start of non-matching text area to the previous
 +       multibyte character boundary.  */
        if (! NILP (current_buffer->enable_multibyte_characters))
        while (same_at_start > BEGV_BYTE
               && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
        /* Compare with same_at_start to avoid counting some buffer text
         as matching both at the file's beginning and at the end.  */
        while (bufpos > 0 && same_at_end > same_at_start
 -           && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
 +           && FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1])
        same_at_end--, bufpos--;
  
 -      /* Extend the end of non-matching text area to multibyte
 -       character boundary.  */
 +      /* Extend the end of non-matching text area to the next
 +       multibyte character boundary.  */
        if (! NILP (current_buffer->enable_multibyte_characters))
        while (same_at_end < ZV_BYTE
               && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
  
        /* Replace the chars that we need to replace,
         and update INSERTED to equal the number of bytes
 -       we are taking from the file.  */
 +       we are taking from the decoded string.  */
        inserted -= (ZV_BYTE - same_at_end) + (same_at_start - BEGV_BYTE);
  
        if (same_at_end != same_at_start)
        }
        /* Insert from the file at the proper position.  */
        SET_PT_BOTH (temp, same_at_start);
 -      insert_1 (conversion_buffer + same_at_start - BEGV_BYTE, inserted,
 -              0, 0, 0);
 -      if (coding.cmp_data && coding.cmp_data->used)
 -      coding_restore_composition (&coding, Fcurrent_buffer ());
 -      coding_free_composition_data (&coding);
 -
 +      same_at_start_charpos
 +      = buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
 +                                same_at_start);
 +      inserted_chars
 +      = (buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
 +                                 same_at_start + inserted)
 +         - same_at_start_charpos);
 +      /* This binding is to avoid ask-user-about-supersession-threat
 +       being called in insert_from_buffer (via in
 +       prepare_to_modify_buffer).  */
 +      specbind (intern ("buffer-file-name"), Qnil);
 +      insert_from_buffer (XBUFFER (conversion_buffer),
 +                        same_at_start_charpos, inserted_chars, 0);
        /* Set `inserted' to the number of inserted characters.  */
        inserted = PT - temp;
        /* Set point before the inserted characters.  */
        SET_PT_BOTH (temp, same_at_start);
  
 -      xfree (conversion_buffer);
 -      emacs_close (fd);
 -      specpdl_ptr--;
 +      unbind_to (this_count, Qnil);
  
        goto handled;
      }
    inserted = 0;
  
    /* Here, we don't do code conversion in the loop.  It is done by
 -     code_convert_region after all data are read into the buffer.  */
 +     decode_coding_gap after all data are read into the buffer.  */
    {
      int gap_size = GAP_SIZE;
  
  
   notfound:
  
 -  if (! coding_system_decided)
 +  if (NILP (coding_system))
      {
        /* The coding system is not yet decided.  Decide it by an
         optimized method for handling `coding:' tag.
  
         Note that we can get here only if the buffer was empty
         before the insertion.  */
 -      Lisp_Object val;
 -      val = Qnil;
  
        if (!NILP (Vcoding_system_for_read))
 -      val = Vcoding_system_for_read;
 +      coding_system = Vcoding_system_for_read;
        else
        {
          /* Since we are sure that the current buffer was empty
             before the insertion, we can toggle
             enable-multibyte-characters directly here without taking
 -           care of marker adjustment and byte combining problem.  By
 -           this way, we can run Lisp program safely before decoding
 -           the inserted text.  */
 +           care of marker adjustment.  By this way, we can run Lisp
 +           program safely before decoding the inserted text.  */
          Lisp_Object unwind_data;
          int count = SPECPDL_INDEX ();
  
          unwind_data = Fcons (current_buffer->enable_multibyte_characters,
                               Fcons (current_buffer->undo_list,
                                      Fcurrent_buffer ()));
 -        current_buffer->enable_multibyte_characters = Qnil;
 +            current_buffer->enable_multibyte_characters = Qnil;
          current_buffer->undo_list = Qt;
          record_unwind_protect (decide_coding_unwind, unwind_data);
  
          if (inserted > 0 && ! NILP (Vset_auto_coding_function))
            {
 -            val = call2 (Vset_auto_coding_function,
 -                         filename, make_number (inserted));
 +            coding_system = call2 (Vset_auto_coding_function,
 +                                   filename, make_number (inserted));
            }
  
 -        if (NILP (val))
 +        if (NILP (coding_system))
            {
              /* If the coding system is not yet decided, check
                 file-coding-system-alist.  */
 -            Lisp_Object args[6], coding_systems;
 +            Lisp_Object args[6];
  
              args[0] = Qinsert_file_contents, args[1] = orig_filename;
              args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
 -            coding_systems = Ffind_operation_coding_system (6, args);
 -            if (CONSP (coding_systems))
 -              val = XCAR (coding_systems);
 +            coding_system = Ffind_operation_coding_system (6, args);
 +            if (CONSP (coding_system))
 +              coding_system = XCAR (coding_system);
            }
          unbind_to (count, Qnil);
          inserted = Z_BYTE - BEG_BYTE;
        }
  
 -      /* The following kludgy code is to avoid some compiler bug.
 -       We can't simply do
 -       setup_coding_system (val, &coding);
 -       on some system.  */
 -      {
 -      struct coding_system temp_coding;
 -      setup_coding_system (Fcheck_coding_system (val), &temp_coding);
 -      bcopy (&temp_coding, &coding, sizeof coding);
 -      }
 -      /* Ensure we set Vlast_coding_system_used.  */
 -      set_coding_system = 1;
 +      if (NILP (coding_system))
 +      coding_system = Qundecided;
 +      else
 +      CHECK_CODING_SYSTEM (coding_system);
  
 -      if (NILP (current_buffer->enable_multibyte_characters)
 -        && ! NILP (val))
 +      if (NILP (current_buffer->enable_multibyte_characters))
        /* We must suppress all character code conversion except for
           end-of-line conversion.  */
 -      setup_raw_text_coding_system (&coding);
 -      coding.src_multibyte = 0;
 -      coding.dst_multibyte
 -      = !NILP (current_buffer->enable_multibyte_characters);
 +      coding_system = raw_text_coding_system (coding_system);
 +      setup_coding_system (coding_system, &coding);
 +      /* Ensure we set Vlast_coding_system_used.  */
 +      set_coding_system = 1;
      }
  
 -  if (!NILP (visit)
 -      /* Can't do this if part of the buffer might be preserved.  */
 -      && NILP (replace)
 -      && (coding.type == coding_type_no_conversion
 -        || coding.type == coding_type_raw_text))
 +  if (!NILP (visit))
      {
 -      /* Visiting a file with these coding system makes the buffer
 -         unibyte. */
 -      current_buffer->enable_multibyte_characters = Qnil;
 -      coding.dst_multibyte = 0;
 +      /* When we visit a file by raw-text, we change the buffer to
 +       unibyte.  */
 +      if (CODING_FOR_UNIBYTE (&coding)
 +        /* Can't do this if part of the buffer might be preserved.  */
 +        && NILP (replace))
 +      /* Visiting a file with these coding system makes the buffer
 +         unibyte. */
 +      current_buffer->enable_multibyte_characters = Qnil;
      }
  
 -  if (inserted > 0 || coding.type == coding_type_ccl)
 +  coding.dst_multibyte = ! NILP (current_buffer->enable_multibyte_characters);
 +  if (CODING_MAY_REQUIRE_DECODING (&coding)
 +      && (inserted > 0 || CODING_REQUIRE_FLUSHING (&coding)))
      {
 -      if (CODING_MAY_REQUIRE_DECODING (&coding))
 -      {
 -        code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
 -                             &coding, 0, 0);
 -        inserted = coding.produced_char;
 -      }
 -      else
 -      adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
 -                           inserted);
 +      move_gap_both (PT, PT_BYTE);
 +      GAP_SIZE += inserted;
 +      ZV_BYTE -= inserted;
 +      Z_BYTE -= inserted;
 +      ZV -= inserted;
 +      Z -= inserted;
 +      decode_coding_gap (&coding, inserted, inserted);
 +      inserted = coding.produced_char;
 +      coding_system = CODING_ID_NAME (coding.id);
      }
 +  else if (inserted > 0)
 +    adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
 +                       inserted);
  
    /* Now INSERTED is measured in characters.  */
  
    /* Use the conversion type to determine buffer-file-type
       (find-buffer-file-type is now used to help determine the
       conversion).  */
 -  if ((coding.eol_type == CODING_EOL_UNDECIDED
 -       || coding.eol_type == CODING_EOL_LF)
 +  if ((VECTORP (CODING_ID_EOL_TYPE (coding.id))
 +       || EQ (CODING_ID_EOL_TYPE (coding.id), Qunix))
        && ! CODING_REQUIRE_DECODING (&coding))
      current_buffer->buffer_file_type = Qt;
    else
      }
  
    if (set_coding_system)
 -    Vlast_coding_system_used = coding.symbol;
 +    Vlast_coding_system_used = coding_system;
  
    if (! NILP (Ffboundp (Qafter_insert_file_set_coding)))
      {
  }
  \f
  static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
 -static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object,
 -                                          Lisp_Object, Lisp_Object));
  
  /* If build_annotations switched buffers, switch back to BUF.
     Kill the temporary buffer that was selected in the meantime.
@@@ -4768,21 -4793,26 +4768,21 @@@ build_annotations_unwind (buf
  
  /* Decide the coding-system to encode the data with.  */
  
 -void
 +static Lisp_Object
  choose_write_coding_system (start, end, filename,
                            append, visit, lockname, coding)
       Lisp_Object start, end, filename, append, visit, lockname;
       struct coding_system *coding;
  {
    Lisp_Object val;
 +  Lisp_Object eol_parent = Qnil;
  
    if (auto_saving
        && NILP (Fstring_equal (current_buffer->filename,
                              current_buffer->auto_save_file_name)))
      {
 -      /* We use emacs-mule for auto saving... */
 -      setup_coding_system (Qemacs_mule, coding);
 -      /* ... but with the special flag to indicate not to strip off
 -       leading code of eight-bit-control chars.  */
 -      coding->flags = 1;
 -      /* We force LF for end-of-line because that is faster.  */
 -      coding->eol_type = CODING_EOL_LF;
 -      goto done_setup_coding;
 +      val = Qutf_8_emacs;
 +      eol_parent = Qunix;
      }
    else if (!NILP (Vcoding_system_for_write))
      {
            val = XCDR (coding_systems);
        }
  
 -      if (NILP (val)
 -        && !NILP (current_buffer->buffer_file_coding_system))
 +      if (NILP (val))
        {
          /* If we still have not decided a coding system, use the
             default value of buffer-file-coding-system.  */
          using_default_coding = 1;
        }
  
 +      if (! NILP (val) && ! force_raw_text)
 +      {
 +        Lisp_Object spec, attrs;
 +
 +        CHECK_CODING_SYSTEM_GET_SPEC (val, spec);
 +        attrs = AREF (spec, 0);
 +        if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
 +          force_raw_text = 1;
 +      }
 +
        if (!force_raw_text
          && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
        /* Confirm that VAL can surely encode the current region.  */
        val = call5 (Vselect_safe_coding_system_function,
                     start, end, val, Qnil, filename);
  
 -      setup_coding_system (Fcheck_coding_system (val), coding);
 -      if (coding->eol_type == CODING_EOL_UNDECIDED
 -        && !using_default_coding)
 -      {
 -        if (! EQ (default_buffer_file_coding.symbol,
 -                  buffer_defaults.buffer_file_coding_system))
 -          setup_coding_system (buffer_defaults.buffer_file_coding_system,
 -                               &default_buffer_file_coding);
 -        if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED)
 -          {
 -            Lisp_Object subsidiaries;
 -
 -            coding->eol_type = default_buffer_file_coding.eol_type;
 -            subsidiaries = Fget (coding->symbol, Qeol_type);
 -            if (VECTORP (subsidiaries)
 -                && XVECTOR (subsidiaries)->size == 3)
 -              coding->symbol
 -                = XVECTOR (subsidiaries)->contents[coding->eol_type];
 -          }
 -      }
 +      /* If the decided coding-system doesn't specify end-of-line
 +       format, we use that of
 +       `default-buffer-file-coding-system'.  */
 +      if (! using_default_coding
 +        && ! NILP (buffer_defaults.buffer_file_coding_system))
 +      val = (coding_inherit_eol_type
 +             (val, buffer_defaults.buffer_file_coding_system));
  
 +      /* If we decide not to encode text, use `raw-text' or one of its
 +       subsidiaries.  */
        if (force_raw_text)
 -      setup_raw_text_coding_system (coding);
 -      goto done_setup_coding;
 +      val = raw_text_coding_system (val);
      }
  
 -  setup_coding_system (Fcheck_coding_system (val), coding);
 +  val = coding_inherit_eol_type (val, eol_parent);
 +  setup_coding_system (val, coding);
  
 - done_setup_coding:
 -  if (coding->eol_type == CODING_EOL_UNDECIDED)
 -    coding->eol_type = system_eol_type;
    if (!STRINGP (start) && !NILP (current_buffer->selective_display))
      coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
 +  return val;
  }
  
  DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
@@@ -4918,6 -4952,7 +4918,6 @@@ This does code conversion according to 
    int save_errno = 0;
    const unsigned char *fn;
    struct stat st;
 -  int tem;
    int count = SPECPDL_INDEX ();
    int count1;
  #ifdef VMS
       We used to make this choice before calling build_annotations, but that
       leads to problems when a write-annotate-function takes care of
       unsavable chars (as was the case with X-Symbol).  */
 -  choose_write_coding_system (start, end, filename,
 -                            append, visit, lockname, &coding);
 -  Vlast_coding_system_used = coding.symbol;
 -
 -  given_buffer = current_buffer;
 -  if (! STRINGP (start))
 -    {
 -      annotations = build_annotations_2 (start, end,
 -                                       coding.pre_write_conversion, annotations);
 -      if (current_buffer != given_buffer)
 -      {
 -        XSETFASTINT (start, BEGV);
 -        XSETFASTINT (end, ZV);
 -      }
 -    }
 +  Vlast_coding_system_used
 +    = choose_write_coding_system (start, end, filename,
 +                                append, visit, lockname, &coding);
  
  #ifdef CLASH_DETECTION
    if (!auto_saving)
    if (GPT > BEG && GPT_ADDR[-1] != '\n')
      move_gap (find_next_newline (GPT, 1));
  #else
 +#if 0
 +  /* The new encoding routine doesn't require the following.  */
 +
    /* Whether VMS or not, we must move the gap to the next of newline
       when we must put designation sequences at beginning of line.  */
    if (INTEGERP (start)
        move_gap_both (PT, PT_BYTE);
        SET_PT_BOTH (opoint, opoint_byte);
      }
 +#endif
  #endif
  
    failure = 0;
      }
    else if (XINT (start) != XINT (end))
      {
 -      tem = CHAR_TO_BYTE (XINT (start));
 -
 -      if (XINT (start) < GPT)
 -      {
 -        failure = 0 > a_write (desc, Qnil, XINT (start),
 -                               min (GPT, XINT (end)) - XINT (start),
 -                               &annotations, &coding);
 -        save_errno = errno;
 -      }
 -
 -      if (XINT (end) > GPT && !failure)
 -      {
 -        tem = max (XINT (start), GPT);
 -        failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,
 -                               &annotations, &coding);
 -        save_errno = errno;
 -      }
 +      failure = 0 > a_write (desc, Qnil,
 +                           XINT (start), XINT (end) - XINT (start),
 +                           &annotations, &coding);
 +      save_errno = errno;
      }
    else
      {
      {
        /* We have to flush out a data. */
        coding.mode |= CODING_MODE_LAST_BLOCK;
 -      failure = 0 > e_write (desc, Qnil, 0, 0, &coding);
 +      failure = 0 > e_write (desc, Qnil, 1, 1, &coding);
        save_errno = errno;
      }
  
@@@ -5402,6 -5458,30 +5402,6 @@@ build_annotations (start, end
    return annotations;
  }
  
 -static Lisp_Object
 -build_annotations_2 (start, end, pre_write_conversion, annotations)
 -     Lisp_Object start, end, pre_write_conversion, annotations;
 -{
 -  struct gcpro gcpro1;
 -  Lisp_Object res;
 -
 -  GCPRO1 (annotations);
 -  /* At last, do the same for the function PRE_WRITE_CONVERSION
 -     implied by the current coding-system.  */
 -  if (!NILP (pre_write_conversion))
 -    {
 -      struct buffer *given_buffer = current_buffer;
 -      Vwrite_region_annotations_so_far = annotations;
 -      res = call2 (pre_write_conversion, start, end);
 -      Flength (res);
 -      annotations = (current_buffer != given_buffer
 -                   ? res
 -                   : merge (annotations, res, Qcar_less_than_car));
 -    }
 -
 -  UNGCPRO;
 -  return annotations;
 -}
  \f
  /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
     If STRING is nil, POS is the character position in the current buffer.
@@@ -5457,6 -5537,9 +5457,6 @@@ a_write (desc, string, pos, nchars, ann
    return 0;
  }
  
 -#ifndef WRITE_BUF_SIZE
 -#define WRITE_BUF_SIZE (16 * 1024)
 -#endif
  
  /* Write text in the range START and END into descriptor DESC,
     encoding them with coding system CODING.  If STRING is nil, START
@@@ -5470,77 -5553,78 +5470,77 @@@ e_write (desc, string, start, end, codi
       int start, end;
       struct coding_system *coding;
  {
 -  register char *addr;
 -  register int nbytes;
 -  char buf[WRITE_BUF_SIZE];
 -  int return_val = 0;
 -
 -  if (start >= end)
 -    coding->composing = COMPOSITION_DISABLED;
 -  if (coding->composing != COMPOSITION_DISABLED)
 -    coding_save_composition (coding, start, end, string);
 -
    if (STRINGP (string))
      {
 -      addr = SDATA (string);
 -      nbytes = SBYTES (string);
 -      coding->src_multibyte = STRING_MULTIBYTE (string);
 -    }
 -  else if (start < end)
 -    {
 -      /* It is assured that the gap is not in the range START and END-1.  */
 -      addr = CHAR_POS_ADDR (start);
 -      nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);
 -      coding->src_multibyte
 -      = !NILP (current_buffer->enable_multibyte_characters);
 -    }
 -  else
 -    {
 -      addr = "";
 -      nbytes = 0;
 -      coding->src_multibyte = 1;
 +      start = 0;
 +      end = SCHARS (string);
      }
  
    /* We used to have a code for handling selective display here.  But,
       now it is handled within encode_coding.  */
 -  while (1)
 -    {
 -      int result;
  
 -      result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
 -      if (coding->produced > 0)
 +  while (start < end)
 +    {
 +      if (STRINGP (string))
        {
 -        coding->produced -= emacs_write (desc, buf, coding->produced);
 -        if (coding->produced)
 +        coding->src_multibyte = SCHARS (string) < SBYTES (string);
 +        if (CODING_REQUIRE_ENCODING (coding))
            {
 -            return_val = -1;
 -            break;
 +            encode_coding_object (coding, string,
 +                                  start, string_char_to_byte (string, start),
 +                                  end, string_char_to_byte (string, end), Qt);
 +          }
 +        else
 +          {
 +            coding->dst_object = string;
 +            coding->consumed_char = SCHARS (string);
 +            coding->produced = SBYTES (string);
            }
        }
 -      nbytes -= coding->consumed;
 -      addr += coding->consumed;
 -      if (result == CODING_FINISH_INSUFFICIENT_SRC
 -        && nbytes > 0)
 +      else
        {
 -        /* The source text ends by an incomplete multibyte form.
 -             There's no way other than write it out as is.  */
 -        nbytes -= emacs_write (desc, addr, nbytes);
 -        if (nbytes)
 +        int start_byte = CHAR_TO_BYTE (start);
 +        int end_byte = CHAR_TO_BYTE (end);
 +
 +        coding->src_multibyte = (end - start) < (end_byte - start_byte);
 +        if (CODING_REQUIRE_ENCODING (coding))
            {
 -            return_val = -1;
 -            break;
 +            encode_coding_object (coding, Fcurrent_buffer (),
 +                                  start, start_byte, end, end_byte, Qt);
 +          }
 +        else
 +          {
 +            coding->dst_object = Qnil;
 +            coding->dst_pos_byte = start_byte;
 +            if (start >= GPT || end <= GPT)
 +              {
 +                coding->consumed_char = end - start;
 +                coding->produced = end_byte - start_byte;
 +              }
 +            else
 +              {
 +                coding->consumed_char = GPT - start;
 +                coding->produced = GPT_BYTE - start_byte;
 +              }
            }
        }
 -      if (nbytes <= 0)
 -      break;
 +
 +      if (coding->produced > 0)
 +      {
 +        coding->produced -=
 +          emacs_write (desc,
 +                       STRINGP (coding->dst_object)
 +                       ? SDATA (coding->dst_object)
 +                       : BYTE_POS_ADDR (coding->dst_pos_byte),
 +                       coding->produced);
 +
 +        if (coding->produced)
 +          return -1;
 +      }
        start += coding->consumed_char;
 -      if (coding->cmp_data)
 -      coding_adjust_composition_offset (coding, start);
      }
  
 -  if (coding->cmp_data)
 -    coding_free_composition_data (coding);
 -
 -  return return_val;
 +  return 0;
  }
  \f
  DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
@@@ -6113,9 -6197,9 +6113,9 @@@ DEFUN ("read-file-name-internal", Fread
            {
              Lisp_Object tem = XCAR (all);
              int len;
 -            if (STRINGP (tem)
 -                && (len = SBYTES (tem), len > 0)
 -                && IS_DIRECTORY_SEP (SREF (tem, len-1)))
 +            if (STRINGP (tem) &&
 +                (len = SBYTES (tem), len > 0) &&
 +                IS_DIRECTORY_SEP (SREF (tem, len-1)))
                comp = Fcons (tem, comp);
            }
        }
diff --combined src/filelock.c
index 6a3972dad42abbc1874500c73f384f6ede395a3e,689a80a4209cab29e1df1377b6c0f86985e1a460..261a644ccdef4de9fd421e7e28958bae40a31975
@@@ -1,6 -1,6 +1,6 @@@
  /* Lock files for editing.
     Copyright (C) 1985, 1986, 1987, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -53,7 -53,7 +53,7 @@@ extern int errno
  
  #include "lisp.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "systime.h"
  
diff --combined src/fns.c
index da2c43fd6a9032e26e07c85c6556028737a07e74,345aa0a35e0baa9b04b65e23324e57d4f0d8d11d..86d9407db9a2734ae4868313a81dfbed0212d93a
+++ b/src/fns.c
@@@ -1,7 -1,7 +1,7 @@@
  /* Random utility Lisp functions.
     Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997,
                   1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -39,7 -39,7 +39,7 @@@ Boston, MA 02110-1301, USA.  *
  
  #include "lisp.h"
  #include "commands.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "buffer.h"
  #include "keyboard.h"
@@@ -151,6 -151,8 +151,6 @@@ To get the number of bytes, use `string
      XSETFASTINT (val, SCHARS (sequence));
    else if (VECTORP (sequence))
      XSETFASTINT (val, ASIZE (sequence));
 -  else if (SUB_CHAR_TABLE_P (sequence))
 -    XSETFASTINT (val, SUB_CHAR_TABLE_ORDINARY_SLOTS);
    else if (CHAR_TABLE_P (sequence))
      XSETFASTINT (val, MAX_CHAR);
    else if (BOOL_VECTOR_P (sequence))
@@@ -215,7 -217,7 +215,7 @@@ which is at least the number of distinc
  
  DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
         doc: /* Return the number of bytes in STRING.
 -If STRING is a multibyte string, this is greater than the length of STRING.  */)
 +If STRING is multibyte, this may be greater than the length of STRING.  */)
       (string)
       Lisp_Object string;
  {
@@@ -462,6 -464,28 +462,6 @@@ usage: (vconcat &rest SEQUENCES)   */
    return concat (nargs, args, Lisp_Vectorlike, 0);
  }
  
 -/* Return a copy of a sub char table ARG.  The elements except for a
 -   nested sub char table are not copied.  */
 -static Lisp_Object
 -copy_sub_char_table (arg)
 -     Lisp_Object arg;
 -{
 -  Lisp_Object copy = make_sub_char_table (Qnil);
 -  int i;
 -
 -  XCHAR_TABLE (copy)->defalt = XCHAR_TABLE (arg)->defalt;
 -  /* Copy all the contents.  */
 -  bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
 -       SUB_CHAR_TABLE_ORDINARY_SLOTS * sizeof (Lisp_Object));
 -  /* Recursively copy any sub char-tables in the ordinary slots.  */
 -  for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
 -    if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
 -      XCHAR_TABLE (copy)->contents[i]
 -      = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
 -
 -  return copy;
 -}
 -
  
  DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
         doc: /* Return a copy of a list, vector, string or char-table.
@@@ -474,7 -498,24 +474,7 @@@ with the original.  */
  
    if (CHAR_TABLE_P (arg))
      {
 -      int i;
 -      Lisp_Object copy;
 -
 -      copy = Fmake_char_table (XCHAR_TABLE (arg)->purpose, Qnil);
 -      /* Copy all the slots, including the extra ones.  */
 -      bcopy (XVECTOR (arg)->contents, XVECTOR (copy)->contents,
 -           ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK)
 -            * sizeof (Lisp_Object)));
 -
 -      /* Recursively copy any sub char tables in the ordinary slots
 -         for multibyte characters.  */
 -      for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS;
 -         i < CHAR_TABLE_ORDINARY_SLOTS; i++)
 -      if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
 -        XCHAR_TABLE (copy)->contents[i]
 -          = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
 -
 -      return copy;
 +      return copy_char_table (arg);
      }
  
    if (BOOL_VECTOR_P (arg))
@@@ -577,10 -618,10 +577,10 @@@ concat (nargs, args, target_type, last_
            for (i = 0; i < len; i++)
              {
                ch = AREF (this, i);
 -              CHECK_NUMBER (ch);
 +              CHECK_CHARACTER (ch);
                this_len_byte = CHAR_BYTES (XINT (ch));
                result_len_byte += this_len_byte;
 -              if (!SINGLE_BYTE_CHAR_P (XINT (ch)))
 +              if (! ASCII_CHAR_P (XINT (ch)) && ! CHAR_BYTE8_P (XINT (ch)))
                  some_multibyte = 1;
              }
          else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0)
            for (; CONSP (this); this = XCDR (this))
              {
                ch = XCAR (this);
 -              CHECK_NUMBER (ch);
 +              CHECK_CHARACTER (ch);
                this_len_byte = CHAR_BYTES (XINT (ch));
                result_len_byte += this_len_byte;
 -              if (!SINGLE_BYTE_CHAR_P (XINT (ch)))
 +              if (! ASCII_CHAR_P (XINT (ch)) && ! CHAR_BYTE8_P (XINT (ch)))
                  some_multibyte = 1;
              }
          else if (STRINGP (this))
                  {
                    XSETFASTINT (elt, SREF (this, thisindex)); thisindex++;
                    if (some_multibyte
 -                      && (XINT (elt) >= 0240
 -                          || (XINT (elt) >= 0200
 -                              && ! NILP (Vnonascii_translation_table)))
 +                      && XINT (elt) >= 0200
                        && XINT (elt) < 0400)
                      {
                        c = unibyte_char_to_multibyte (XINT (elt));
            else
              {
                CHECK_NUMBER (elt);
 -              if (SINGLE_BYTE_CHAR_P (XINT (elt)))
 -                {
 -                  if (some_multibyte)
 -                    toindex_byte
 -                      += CHAR_STRING (XINT (elt),
 -                                      SDATA (val) + toindex_byte);
 -                  else
 -                    SSET (val, toindex_byte++, XINT (elt));
 -                  toindex++;
 -                }
 +              if (some_multibyte)
 +                toindex_byte += CHAR_STRING (XINT (elt),
 +                                             SDATA (val) + toindex_byte);
                else
 -                /* If we have any multibyte characters,
 -                   we already decided to make a multibyte string.  */
 -                {
 -                  int c = XINT (elt);
 -                  /* P exists as a variable
 -                     to avoid a bug on the Masscomp C compiler.  */
 -                  unsigned char *p = SDATA (val) + toindex_byte;
 -
 -                  toindex_byte += CHAR_STRING (c, p);
 -                  toindex++;
 -                }
 +                SSET (val, toindex_byte++, XINT (elt));
 +              toindex++;
              }
          }
      }
@@@ -796,7 -855,7 +796,7 @@@ string_char_to_byte (string, char_index
       Lisp_Object string;
       int char_index;
  {
 -  int i, i_byte;
 +  int i_byte;
    int best_below, best_below_byte;
    int best_above, best_above_byte;
  
  
    if (char_index - best_below < best_above - char_index)
      {
 +      unsigned char *p = SDATA (string) + best_below_byte;
 +
        while (best_below < char_index)
        {
 -        int c;
 -        FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string,
 -                                            best_below, best_below_byte);
 +        p += BYTES_BY_CHAR_HEAD (*p);
 +        best_below++;
        }
 -      i = best_below;
 -      i_byte = best_below_byte;
 +      i_byte = p - SDATA (string);
      }
    else
      {
 +      unsigned char *p = SDATA (string) + best_above_byte;
 +
        while (best_above > char_index)
        {
 -        unsigned char *pend = SDATA (string) + best_above_byte;
 -        unsigned char *pbeg = pend - best_above_byte;
 -        unsigned char *p = pend - 1;
 -        int bytes;
 -
 -        while (p > pbeg  && !CHAR_HEAD_P (*p)) p--;
 -        PARSE_MULTIBYTE_SEQ (p, pend - p, bytes);
 -        if (bytes == pend - p)
 -          best_above_byte -= bytes;
 -        else if (bytes > pend - p)
 -          best_above_byte -= (pend - p);
 -        else
 -          best_above_byte--;
 +        p--;
 +        while (!CHAR_HEAD_P (*p)) p--;
          best_above--;
        }
 -      i = best_above;
 -      i_byte = best_above_byte;
 +      i_byte = p - SDATA (string);
      }
  
    string_char_byte_cache_bytepos = i_byte;
 -  string_char_byte_cache_charpos = i;
 +  string_char_byte_cache_charpos = char_index;
    string_char_byte_cache_string = string;
  
    return i_byte;
@@@ -884,30 -953,36 +884,30 @@@ string_byte_to_char (string, byte_index
  
    if (byte_index - best_below_byte < best_above_byte - byte_index)
      {
 -      while (best_below_byte < byte_index)
 +      unsigned char *p = SDATA (string) + best_below_byte;
 +      unsigned char *pend = SDATA (string) + byte_index;
 +
 +      while (p < pend)
        {
 -        int c;
 -        FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string,
 -                                            best_below, best_below_byte);
 +        p += BYTES_BY_CHAR_HEAD (*p);
 +        best_below++;
        }
        i = best_below;
 -      i_byte = best_below_byte;
 +      i_byte = p - SDATA (string);
      }
    else
      {
 -      while (best_above_byte > byte_index)
 +      unsigned char *p = SDATA (string) + best_above_byte;
 +      unsigned char *pbeg = SDATA (string) + byte_index;
 +
 +      while (p > pbeg)
        {
 -        unsigned char *pend = SDATA (string) + best_above_byte;
 -        unsigned char *pbeg = pend - best_above_byte;
 -        unsigned char *p = pend - 1;
 -        int bytes;
 -
 -        while (p > pbeg  && !CHAR_HEAD_P (*p)) p--;
 -        PARSE_MULTIBYTE_SEQ (p, pend - p, bytes);
 -        if (bytes == pend - p)
 -          best_above_byte -= bytes;
 -        else if (bytes > pend - p)
 -          best_above_byte -= (pend - p);
 -        else
 -          best_above_byte--;
 +        p--;
 +        while (!CHAR_HEAD_P (*p)) p--;
          best_above--;
        }
        i = best_above;
 -      i_byte = best_above_byte;
 +      i_byte = p - SDATA (string);
      }
  
    string_char_byte_cache_bytepos = i_byte;
    return i;
  }
  \f
 -/* Convert STRING to a multibyte string.
 -   Single-byte characters 0240 through 0377 are converted
 -   by adding nonascii_insert_offset to each.  */
 +/* Convert STRING to a multibyte string.  */
  
  Lisp_Object
  string_make_multibyte (string)
  }
  
  
 -/* Convert STRING to a multibyte string without changing each
 -   character codes.  Thus, characters 0200 trough 0237 are converted
 -   to eight-bit-control characters, and characters 0240 through 0377
 -   are converted eight-bit-graphic characters. */
 +/* Convert STRING (if unibyte) to a multibyte string without changing
 +   the number of characters.  Characters 0200 trough 0237 are
 +   converted to eight-bit characters. */
  
  Lisp_Object
  string_to_multibyte (string)
      return string;
  
    nbytes = parse_str_to_multibyte (SDATA (string), SBYTES (string));
 -  /* If all the chars are ASCII or eight-bit-graphic, they won't need
 -     any more bytes once converted.  */
 +  /* If all the chars are ASCII, they won't need any more bytes once
 +     converted.  */
    if (nbytes == SBYTES (string))
      return make_multibyte_string (SDATA (string), nbytes, nbytes);
  
@@@ -1048,7 -1126,8 +1048,7 @@@ DEFUN ("string-as-unibyte", Fstring_as_
  If STRING is unibyte, the result is STRING itself.
  Otherwise it is a newly created string, with no text properties.
  If STRING is multibyte and contains a character of charset
 -`eight-bit-control' or `eight-bit-graphic', it is converted to the
 -corresponding single byte.  */)
 +`eight-bit', it is converted to the corresponding single byte.  */)
       (string)
       Lisp_Object string;
  {
@@@ -1072,16 -1151,20 +1072,16 @@@ DEFUN ("string-as-multibyte", Fstring_a
         doc: /* Return a multibyte string with the same individual bytes as STRING.
  If STRING is multibyte, the result is STRING itself.
  Otherwise it is a newly created string, with no text properties.
 +
  If STRING is unibyte and contains an individual 8-bit byte (i.e. not
 -part of a multibyte form), it is converted to the corresponding
 -multibyte character of charset `eight-bit-control' or `eight-bit-graphic'.
 +part of a correct utf-8 sequence), it is converted to the corresponding
 +multibyte character of charset `eight-bit'.
 +See also `string-to-multibyte'.
 +
  Beware, this often doesn't really do what you think it does.
 -It is similar to (decode-coding-string STRING 'emacs-mule-unix).
 +It is similar to (decode-coding-string STRING 'utf-8-emacs).
  If you're not sure, whether to use `string-as-multibyte' or
 -`string-to-multibyte', use `string-to-multibyte'.  Beware:
 -   (aref (string-as-multibyte "\\201") 0) -> 129 (aka ?\\201)
 -   (aref (string-as-multibyte "\\300") 0) -> 192 (aka ?\\300)
 -   (aref (string-as-multibyte "\\300\\201") 0) -> 192 (aka ?\\300)
 -   (aref (string-as-multibyte "\\300\\201") 1) -> 129 (aka ?\\201)
 -but
 -   (aref (string-as-multibyte "\\201\\300") 0) -> 2240
 -   (aref (string-as-multibyte "\\201\\300") 1) -> <error>  */)
 +`string-to-multibyte', use `string-to-multibyte'.  */)
       (string)
       Lisp_Object string;
  {
@@@ -1112,13 -1195,11 +1112,13 @@@ DEFUN ("string-to-multibyte", Fstring_t
         doc: /* Return a multibyte string with the same individual chars as STRING.
  If STRING is multibyte, the result is STRING itself.
  Otherwise it is a newly created string, with no text properties.
 -Characters 0200 through 0237 are converted to eight-bit-control
 -characters of the same character code.  Characters 0240 through 0377
 -are converted to eight-bit-graphic characters of the same character
 -codes.
 -This is similar to (decode-coding-string STRING 'binary)  */)
 +
 +If STRING is unibyte and contains an 8-bit byte, it is converted to
 +the corresponding multibyte character of charset `eight-bit'.
 +
 +This differs from `string-as-multibyte' by converting each byte of a correct
 +utf-8 sequence to an eight-bit character, not just bytes that don't form a
 +correct sequence.  */)
       (string)
       Lisp_Object string;
  {
@@@ -1518,22 -1599,6 +1518,22 @@@ The value is actually the first elemen
    return CAR (list);
  }
  
 +/* Like Fassoc but never report an error and do not allow quits.
 +   Use only on lists known never to be circular.  */
 +
 +Lisp_Object
 +assoc_no_quit (key, list)
 +     Lisp_Object key, list;
 +{
 +  while (CONSP (list)
 +       && (!CONSP (XCAR (list))
 +           || (!EQ (XCAR (XCAR (list)), key)
 +               && NILP (Fequal (XCAR (XCAR (list)), key)))))
 +    list = XCDR (list);
 +
 +  return CONSP (list) ? XCAR (list) : Qnil;
 +}
 +
  DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
         doc: /* Return non-nil if KEY is `eq' to the cdr of an element of LIST.
  The value is actually the first element of LIST whose cdr is KEY.  */)
@@@ -2205,8 -2270,7 +2205,8 @@@ internal_equal (o1, o2, depth, props
           functions are sensible to compare, so eliminate the others now.  */
        if (size & PSEUDOVECTOR_FLAG)
          {
 -          if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
 +          if (!(size & (PVEC_COMPILED
 +                        | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE)))
              return 0;
            size &= PSEUDOVECTOR_SIZE_MASK;
          }
@@@ -2261,11 -2325,11 +2261,11 @@@ ARRAY is a vector, string, char-table, 
      }
    else if (CHAR_TABLE_P (array))
      {
 -      register Lisp_Object *p = XCHAR_TABLE (array)->contents;
 -      size = CHAR_TABLE_ORDINARY_SLOTS;
 -      for (index = 0; index < size; index++)
 -      p[index] = item;
 -      XCHAR_TABLE (array)->defalt = Qnil;
 +      int i;
 +
 +      for (i = 0; i < (1 << CHARTAB_SIZE_BITS_0); i++)
 +      XCHAR_TABLE (array)->contents[i] = item;
 +      XCHAR_TABLE (array)->defalt = item;
      }
    else if (STRINGP (array))
      {
@@@ -2334,6 -2398,581 +2334,6 @@@ This makes STRING unibyte and may chang
    STRING_SET_UNIBYTE (string);
    return Qnil;
  }
 -\f
 -DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
 -       1, 1, 0,
 -       doc: /* Return the subtype of char-table CHAR-TABLE.  The value is a symbol.  */)
 -     (char_table)
 -     Lisp_Object char_table;
 -{
 -  CHECK_CHAR_TABLE (char_table);
 -
 -  return XCHAR_TABLE (char_table)->purpose;
 -}
 -
 -DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
 -       1, 1, 0,
 -       doc: /* Return the parent char-table of CHAR-TABLE.
 -The value is either nil or another char-table.
 -If CHAR-TABLE holds nil for a given character,
 -then the actual applicable value is inherited from the parent char-table
 -\(or from its parents, if necessary).  */)
 -     (char_table)
 -     Lisp_Object char_table;
 -{
 -  CHECK_CHAR_TABLE (char_table);
 -
 -  return XCHAR_TABLE (char_table)->parent;
 -}
 -
 -DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
 -       2, 2, 0,
 -       doc: /* Set the parent char-table of CHAR-TABLE to PARENT.
 -Return PARENT.  PARENT must be either nil or another char-table.  */)
 -     (char_table, parent)
 -     Lisp_Object char_table, parent;
 -{
 -  Lisp_Object temp;
 -
 -  CHECK_CHAR_TABLE (char_table);
 -
 -  if (!NILP (parent))
 -    {
 -      CHECK_CHAR_TABLE (parent);
 -
 -      for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
 -      if (EQ (temp, char_table))
 -        error ("Attempt to make a chartable be its own parent");
 -    }
 -
 -  XCHAR_TABLE (char_table)->parent = parent;
 -
 -  return parent;
 -}
 -
 -DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
 -       2, 2, 0,
 -       doc: /* Return the value of CHAR-TABLE's extra-slot number N.  */)
 -     (char_table, n)
 -     Lisp_Object char_table, n;
 -{
 -  CHECK_CHAR_TABLE (char_table);
 -  CHECK_NUMBER (n);
 -  if (XINT (n) < 0
 -      || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
 -    args_out_of_range (char_table, n);
 -
 -  return XCHAR_TABLE (char_table)->extras[XINT (n)];
 -}
 -
 -DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
 -       Sset_char_table_extra_slot,
 -       3, 3, 0,
 -       doc: /* Set CHAR-TABLE's extra-slot number N to VALUE.  */)
 -     (char_table, n, value)
 -     Lisp_Object char_table, n, value;
 -{
 -  CHECK_CHAR_TABLE (char_table);
 -  CHECK_NUMBER (n);
 -  if (XINT (n) < 0
 -      || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
 -    args_out_of_range (char_table, n);
 -
 -  return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
 -}
 -\f
 -static Lisp_Object
 -char_table_range (table, from, to, defalt)
 -     Lisp_Object table;
 -     int from, to;
 -     Lisp_Object defalt;
 -{
 -  Lisp_Object val;
 -
 -  if (! NILP (XCHAR_TABLE (table)->defalt))
 -    defalt = XCHAR_TABLE (table)->defalt;
 -  val = XCHAR_TABLE (table)->contents[from];
 -  if (SUB_CHAR_TABLE_P (val))
 -    val = char_table_range (val, 32, 127, defalt);
 -  else if (NILP (val))
 -    val = defalt;
 -  for (from++; from <= to; from++)
 -    {
 -      Lisp_Object this_val;
 -
 -      this_val = XCHAR_TABLE (table)->contents[from];
 -      if (SUB_CHAR_TABLE_P (this_val))
 -      this_val = char_table_range (this_val, 32, 127, defalt);
 -      else if (NILP (this_val))
 -      this_val = defalt;
 -      if (! EQ (val, this_val))
 -      error ("Characters in the range have inconsistent values");
 -    }
 -  return val;
 -}
 -
 -
 -DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
 -       2, 2, 0,
 -       doc: /* Return the value in CHAR-TABLE for a range of characters RANGE.
 -RANGE should be nil (for the default value),
 -a vector which identifies a character set or a row of a character set,
 -a character set name, or a character code.
 -If the characters in the specified range have different values,
 -an error is signaled.
 -
 -Note that this function doesn't check the parent of CHAR-TABLE.  */)
 -     (char_table, range)
 -     Lisp_Object char_table, range;
 -{
 -  int charset_id, c1 = 0, c2 = 0;
 -  int size;
 -  Lisp_Object ch, val, current_default;
 -
 -  CHECK_CHAR_TABLE (char_table);
 -
 -  if (EQ (range, Qnil))
 -    return XCHAR_TABLE (char_table)->defalt;
 -  if (INTEGERP (range))
 -    {
 -      int c = XINT (range);
 -      if (! CHAR_VALID_P (c, 0))
 -      error ("Invalid character code: %d", c);
 -      ch = range;
 -      SPLIT_CHAR (c, charset_id, c1, c2);
 -    }
 -  else if (SYMBOLP (range))
 -    {
 -      Lisp_Object charset_info;
 -
 -      charset_info = Fget (range, Qcharset);
 -      CHECK_VECTOR (charset_info);
 -      charset_id = XINT (AREF (charset_info, 0));
 -      ch = Fmake_char_internal (make_number (charset_id),
 -                              make_number (0), make_number (0));
 -    }
 -  else if (VECTORP (range))
 -    {
 -      size = ASIZE (range);
 -      if (size == 0)
 -      args_out_of_range (range, make_number (0));
 -      CHECK_NUMBER (AREF (range, 0));
 -      charset_id = XINT (AREF (range, 0));
 -      if (size > 1)
 -      {
 -        CHECK_NUMBER (AREF (range, 1));
 -        c1 = XINT (AREF (range, 1));
 -        if (size > 2)
 -          {
 -            CHECK_NUMBER (AREF (range, 2));
 -            c2 = XINT (AREF (range, 2));
 -          }
 -      }
 -
 -      /* This checks if charset_id, c0, and c1 are all valid or not.  */
 -      ch = Fmake_char_internal (make_number (charset_id),
 -                              make_number (c1), make_number (c2));
 -    }
 -  else
 -    error ("Invalid RANGE argument to `char-table-range'");
 -
 -  if (c1 > 0 && (CHARSET_DIMENSION (charset_id) == 1 || c2 > 0))
 -    {
 -      /* Fully specified character.  */
 -      Lisp_Object parent = XCHAR_TABLE (char_table)->parent;
 -
 -      XCHAR_TABLE (char_table)->parent = Qnil;
 -      val = Faref (char_table, ch);
 -      XCHAR_TABLE (char_table)->parent = parent;
 -      return val;
 -    }
 -
 -  current_default = XCHAR_TABLE (char_table)->defalt;
 -  if (charset_id == CHARSET_ASCII
 -      || charset_id == CHARSET_8_BIT_CONTROL
 -      || charset_id == CHARSET_8_BIT_GRAPHIC)
 -    {
 -      int from, to, defalt;
 -
 -      if (charset_id == CHARSET_ASCII)
 -      from = 0, to = 127, defalt = CHAR_TABLE_DEFAULT_SLOT_ASCII;
 -      else if (charset_id == CHARSET_8_BIT_CONTROL)
 -      from = 128, to = 159, defalt = CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL;
 -      else
 -      from = 160, to = 255, defalt = CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC;
 -      if (! NILP (XCHAR_TABLE (char_table)->contents[defalt]))
 -      current_default = XCHAR_TABLE (char_table)->contents[defalt];
 -      return char_table_range (char_table, from, to, current_default);
 -    }
 -
 -  val = XCHAR_TABLE (char_table)->contents[128 + charset_id];
 -  if (! SUB_CHAR_TABLE_P (val))
 -    return (NILP (val) ? current_default : val);
 -  if (! NILP (XCHAR_TABLE (val)->defalt))
 -    current_default = XCHAR_TABLE (val)->defalt;
 -  if (c1 == 0)
 -    return char_table_range (val, 32, 127, current_default);
 -  val = XCHAR_TABLE (val)->contents[c1];
 -  if (! SUB_CHAR_TABLE_P (val))
 -    return (NILP (val) ? current_default : val);
 -  if (! NILP (XCHAR_TABLE (val)->defalt))
 -    current_default = XCHAR_TABLE (val)->defalt;
 -  return char_table_range (val, 32, 127, current_default);
 -}
 -
 -DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
 -       3, 3, 0,
 -       doc: /* Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.
 -RANGE should be t (for all characters), nil (for the default value),
 -a character set, a vector which identifies a character set, a row of a
 -character set, or a character code.  Return VALUE.  */)
 -     (char_table, range, value)
 -     Lisp_Object char_table, range, value;
 -{
 -  int i;
 -
 -  CHECK_CHAR_TABLE (char_table);
 -
 -  if (EQ (range, Qt))
 -    for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
 -      {
 -      /* Don't set these special slots used for default values of
 -         ascii, eight-bit-control, and eight-bit-graphic.  */
 -      if (i != CHAR_TABLE_DEFAULT_SLOT_ASCII
 -          && i != CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL
 -          && i != CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC)
 -        XCHAR_TABLE (char_table)->contents[i] = value;
 -      }
 -  else if (EQ (range, Qnil))
 -    XCHAR_TABLE (char_table)->defalt = value;
 -  else if (SYMBOLP (range))
 -    {
 -      Lisp_Object charset_info;
 -      int charset_id;
 -
 -      charset_info = Fget (range, Qcharset);
 -      if (! VECTORP (charset_info)
 -        || ! NATNUMP (AREF (charset_info, 0))
 -        || (charset_id = XINT (AREF (charset_info, 0)),
 -            ! CHARSET_DEFINED_P (charset_id)))
 -      error ("Invalid charset: %s", SDATA (SYMBOL_NAME (range)));
 -
 -      if (charset_id == CHARSET_ASCII)
 -      for (i = 0; i < 128; i++)
 -        XCHAR_TABLE (char_table)->contents[i] = value;
 -      else if (charset_id == CHARSET_8_BIT_CONTROL)
 -      for (i = 128; i < 160; i++)
 -        XCHAR_TABLE (char_table)->contents[i] = value;
 -      else if (charset_id == CHARSET_8_BIT_GRAPHIC)
 -      for (i = 160; i < 256; i++)
 -        XCHAR_TABLE (char_table)->contents[i] = value;
 -      else
 -      XCHAR_TABLE (char_table)->contents[charset_id + 128] = value;
 -    }
 -  else if (INTEGERP (range))
 -    Faset (char_table, range, value);
 -  else if (VECTORP (range))
 -    {
 -      int size = ASIZE (range);
 -      Lisp_Object *val = XVECTOR (range)->contents;
 -      Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
 -                                          size <= 1 ? Qnil : val[1],
 -                                          size <= 2 ? Qnil : val[2]);
 -      Faset (char_table, ch, value);
 -    }
 -  else
 -    error ("Invalid RANGE argument to `set-char-table-range'");
 -
 -  return value;
 -}
 -
 -DEFUN ("set-char-table-default", Fset_char_table_default,
 -       Sset_char_table_default, 3, 3, 0,
 -       doc: /* Set the default value in CHAR-TABLE for generic character CH to VALUE.
 -The generic character specifies the group of characters.
 -If CH is a normal character, set the default value for a group of
 -characters to which CH belongs.
 -See also the documentation of `make-char'.  */)
 -     (char_table, ch, value)
 -     Lisp_Object char_table, ch, value;
 -{
 -  int c, charset, code1, code2;
 -  Lisp_Object temp;
 -
 -  CHECK_CHAR_TABLE (char_table);
 -  CHECK_NUMBER (ch);
 -
 -  c = XINT (ch);
 -  SPLIT_CHAR (c, charset, code1, code2);
 -
 -  /* Since we may want to set the default value for a character set
 -     not yet defined, we check only if the character set is in the
 -     valid range or not, instead of it is already defined or not.  */
 -  if (! CHARSET_VALID_P (charset))
 -    invalid_character (c);
 -
 -  if (SINGLE_BYTE_CHAR_P (c))
 -    {
 -      /* We use special slots for the default values of single byte
 -       characters.  */
 -      int default_slot
 -      = (c < 0x80 ? CHAR_TABLE_DEFAULT_SLOT_ASCII
 -         : c < 0xA0 ? CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL
 -         : CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC);
 -
 -      return (XCHAR_TABLE (char_table)->contents[default_slot] = value);
 -    }
 -
 -  /* Even if C is not a generic char, we had better behave as if a
 -     generic char is specified.  */
 -  if (!CHARSET_DEFINED_P (charset) || CHARSET_DIMENSION (charset) == 1)
 -    code1 = 0;
 -  temp = XCHAR_TABLE (char_table)->contents[charset + 128];
 -  if (! SUB_CHAR_TABLE_P (temp))
 -    {
 -      temp = make_sub_char_table (temp);
 -      XCHAR_TABLE (char_table)->contents[charset + 128] = temp;
 -    }
 -  if (!code1)
 -    {
 -      XCHAR_TABLE (temp)->defalt = value;
 -      return value;
 -    }
 -  char_table = temp;
 -  temp = XCHAR_TABLE (char_table)->contents[code1];
 -  if (SUB_CHAR_TABLE_P (temp))
 -    XCHAR_TABLE (temp)->defalt = value;
 -  else
 -    XCHAR_TABLE (char_table)->contents[code1] = value;
 -  return value;
 -}
 -
 -/* Look up the element in TABLE at index CH,
 -   and return it as an integer.
 -   If the element is nil, return CH itself.
 -   (Actually we do that for any non-integer.)  */
 -
 -int
 -char_table_translate (table, ch)
 -     Lisp_Object table;
 -     int ch;
 -{
 -  Lisp_Object value;
 -  value = Faref (table, make_number (ch));
 -  if (! INTEGERP (value))
 -    return ch;
 -  return XINT (value);
 -}
 -
 -static void
 -optimize_sub_char_table (table, chars)
 -     Lisp_Object *table;
 -     int chars;
 -{
 -  Lisp_Object elt;
 -  int from, to;
 -
 -  if (chars == 94)
 -    from = 33, to = 127;
 -  else
 -    from = 32, to = 128;
 -
 -  if (!SUB_CHAR_TABLE_P (*table)
 -      || ! NILP (XCHAR_TABLE (*table)->defalt))
 -    return;
 -  elt = XCHAR_TABLE (*table)->contents[from++];
 -  for (; from < to; from++)
 -    if (NILP (Fequal (elt, XCHAR_TABLE (*table)->contents[from])))
 -      return;
 -  *table = elt;
 -}
 -
 -DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
 -       1, 1, 0, doc: /* Optimize char table TABLE.  */)
 -     (table)
 -     Lisp_Object table;
 -{
 -  Lisp_Object elt;
 -  int dim, chars;
 -  int i, j;
 -
 -  CHECK_CHAR_TABLE (table);
 -
 -  for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
 -    {
 -      elt = XCHAR_TABLE (table)->contents[i];
 -      if (!SUB_CHAR_TABLE_P (elt))
 -      continue;
 -      dim = CHARSET_DIMENSION (i - 128);
 -      chars = CHARSET_CHARS (i - 128);
 -      if (dim == 2)
 -      for (j = 32; j < SUB_CHAR_TABLE_ORDINARY_SLOTS; j++)
 -        optimize_sub_char_table (XCHAR_TABLE (elt)->contents + j, chars);
 -      optimize_sub_char_table (XCHAR_TABLE (table)->contents + i, chars);
 -    }
 -  return Qnil;
 -}
 -
 -\f
 -/* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
 -   character or group of characters that share a value.
 -   DEPTH is the current depth in the originally specified
 -   chartable, and INDICES contains the vector indices
 -   for the levels our callers have descended.
 -
 -   ARG is passed to C_FUNCTION when that is called.  */
 -
 -void
 -map_char_table (c_function, function, table, subtable, arg, depth, indices)
 -     void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 -     Lisp_Object function, table, subtable, arg, *indices;
 -     int depth;
 -{
 -  int i, to;
 -  struct gcpro gcpro1, gcpro2,  gcpro3, gcpro4;
 -
 -  GCPRO4 (arg, table, subtable, function);
 -
 -  if (depth == 0)
 -    {
 -      /* At first, handle ASCII and 8-bit European characters.  */
 -      for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
 -      {
 -        Lisp_Object elt= XCHAR_TABLE (subtable)->contents[i];
 -        if (NILP (elt))
 -          elt = XCHAR_TABLE (subtable)->defalt;
 -        if (NILP (elt))
 -          elt = Faref (subtable, make_number (i));
 -        if (c_function)
 -          (*c_function) (arg, make_number (i), elt);
 -        else
 -          call2 (function, make_number (i), elt);
 -      }
 -#if 0 /* If the char table has entries for higher characters,
 -       we should report them.  */
 -      if (NILP (current_buffer->enable_multibyte_characters))
 -      {
 -        UNGCPRO;
 -        return;
 -      }
 -#endif
 -      to = CHAR_TABLE_ORDINARY_SLOTS;
 -    }
 -  else
 -    {
 -      int charset = XFASTINT (indices[0]) - 128;
 -
 -      i = 32;
 -      to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
 -      if (CHARSET_CHARS (charset) == 94)
 -      i++, to--;
 -    }
 -
 -  for (; i < to; i++)
 -    {
 -      Lisp_Object elt;
 -      int charset;
 -
 -      elt = XCHAR_TABLE (subtable)->contents[i];
 -      XSETFASTINT (indices[depth], i);
 -      charset = XFASTINT (indices[0]) - 128;
 -      if (depth == 0
 -        && (!CHARSET_DEFINED_P (charset)
 -            || charset == CHARSET_8_BIT_CONTROL
 -            || charset == CHARSET_8_BIT_GRAPHIC))
 -      continue;
 -
 -      if (SUB_CHAR_TABLE_P (elt))
 -      {
 -        if (depth >= 3)
 -          error ("Too deep char table");
 -        map_char_table (c_function, function, table, elt, arg, depth + 1, indices);
 -      }
 -      else
 -      {
 -        int c1, c2, c;
 -
 -        c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
 -        c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
 -        c = MAKE_CHAR (charset, c1, c2);
 -
 -        if (NILP (elt))
 -          elt = XCHAR_TABLE (subtable)->defalt;
 -        if (NILP  (elt))
 -          elt = Faref (table, make_number (c));
 -
 -        if (c_function)
 -          (*c_function) (arg, make_number (c), elt);
 -        else
 -          call2 (function, make_number (c), elt);
 -      }
 -    }
 -  UNGCPRO;
 -}
 -
 -static void void_call2 P_ ((Lisp_Object a, Lisp_Object b, Lisp_Object c));
 -static void
 -void_call2 (a, b, c)
 -     Lisp_Object a, b, c;
 -{
 -  call2 (a, b, c);
 -}
 -
 -DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
 -       2, 2, 0,
 -       doc: /* Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.
 -FUNCTION is called with two arguments--a key and a value.
 -The key is always a possible IDX argument to `aref'.  */)
 -     (function, char_table)
 -     Lisp_Object function, char_table;
 -{
 -  /* The depth of char table is at most 3. */
 -  Lisp_Object indices[3];
 -
 -  CHECK_CHAR_TABLE (char_table);
 -
 -  /* When Lisp_Object is represented as a union, `call2' cannot directly
 -     be passed to map_char_table because it returns a Lisp_Object rather
 -     than returning nothing.
 -     Casting leads to crashes on some architectures.  -stef  */
 -  map_char_table (void_call2, Qnil, char_table, char_table, function, 0, indices);
 -  return Qnil;
 -}
 -
 -/* Return a value for character C in char-table TABLE.  Store the
 -   actual index for that value in *IDX.  Ignore the default value of
 -   TABLE.  */
 -
 -Lisp_Object
 -char_table_ref_and_index (table, c, idx)
 -     Lisp_Object table;
 -     int c, *idx;
 -{
 -  int charset, c1, c2;
 -  Lisp_Object elt;
 -
 -  if (SINGLE_BYTE_CHAR_P (c))
 -    {
 -      *idx = c;
 -      return XCHAR_TABLE (table)->contents[c];
 -    }
 -  SPLIT_CHAR (c, charset, c1, c2);
 -  elt = XCHAR_TABLE (table)->contents[charset + 128];
 -  *idx = MAKE_CHAR (charset, 0, 0);
 -  if (!SUB_CHAR_TABLE_P (elt))
 -    return elt;
 -  if (c1 < 32 || NILP (XCHAR_TABLE (elt)->contents[c1]))
 -    return XCHAR_TABLE (elt)->defalt;
 -  elt = XCHAR_TABLE (elt)->contents[c1];
 -  *idx = MAKE_CHAR (charset, c1, 0);
 -  if (!SUB_CHAR_TABLE_P (elt))
 -    return elt;
 -  if (c2 < 32 || NILP (XCHAR_TABLE (elt)->contents[c2]))
 -    return XCHAR_TABLE (elt)->defalt;
 -  *idx = c;
 -  return XCHAR_TABLE (elt)->contents[c2];
 -}
 -
  \f
  /* ARGSUSED */
  Lisp_Object
@@@ -2493,8 -3132,6 +2493,8 @@@ SEQUENCE may be a list, a vector, a boo
    USE_SAFE_ALLOCA;
  
    len = Flength (sequence);
 +  if (CHAR_TABLE_P (sequence))
 +    wrong_type_argument (Qlistp, sequence);
    leni = XINT (len);
    nargs = leni + leni - 1;
    if (nargs < 0) return build_string ("");
@@@ -2531,8 -3168,6 +2531,8 @@@ SEQUENCE may be a list, a vector, a boo
    USE_SAFE_ALLOCA;
  
    len = Flength (sequence);
 +  if (CHAR_TABLE_P (sequence))
 +    wrong_type_argument (Qlistp, sequence);
    leni = XFASTINT (len);
  
    SAFE_ALLOCA_LISP (args, leni);
@@@ -2555,8 -3190,6 +2555,8 @@@ SEQUENCE may be a list, a vector, a boo
    register int leni;
  
    leni = XFASTINT (Flength (sequence));
 +  if (CHAR_TABLE_P (sequence))
 +    wrong_type_argument (Qlistp, sequence);
    mapcar1 (leni, 0, function, sequence);
  
    return sequence;
@@@ -3350,9 -3983,7 +3350,9 @@@ base64_encode_1 (from, to, length, line
        if (multibyte)
        {
          c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes);
 -        if (c >= 256)
 +        if (CHAR_BYTE8_P (c))
 +          c = CHAR_TO_BYTE8 (c);
 +        else if (c >= 256)
            return -1;
          i += bytes;
        }
        if (multibyte)
        {
          c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes);
 -        if (c >= 256)
 +        if (CHAR_BYTE8_P (c))
 +          c = CHAR_TO_BYTE8 (c);
 +        else if (c >= 256)
            return -1;
          i += bytes;
        }
        if (multibyte)
        {
          c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes);
 -        if (c >= 256)
 +        if (CHAR_BYTE8_P (c))
 +          c = CHAR_TO_BYTE8 (c);
 +        else if (c >= 256)
            return -1;
          i += bytes;
        }
@@@ -3566,8 -4193,8 +3566,8 @@@ base64_decode_1 (from, to, length, mult
        value |= base64_char_to_value[c] << 12;
  
        c = (unsigned char) (value >> 16);
 -      if (multibyte)
 -      e += CHAR_STRING (c, e);
 +      if (multibyte && c >= 128)
 +      e += BYTE8_STRING (c, e);
        else
        *e++ = c;
        nchars++;
        value |= base64_char_to_value[c] << 6;
  
        c = (unsigned char) (0xff & value >> 8);
 -      if (multibyte)
 -      e += CHAR_STRING (c, e);
 +      if (multibyte && c >= 128)
 +      e += BYTE8_STRING (c, e);
        else
        *e++ = c;
        nchars++;
        value |= base64_char_to_value[c];
  
        c = (unsigned char) (0xff & value);
 -      if (multibyte)
 -      e += CHAR_STRING (c, e);
 +      if (multibyte && c >= 128)
 +      e += BYTE8_STRING (c, e);
        else
        *e++ = c;
        nchars++;
@@@ -4041,6 -4668,7 +4041,7 @@@ maybe_resize_hash_table (h
      {
        int old_size = HASH_TABLE_SIZE (h);
        int i, new_size, index_size;
+       EMACS_INT nsize;
  
        if (INTEGERP (h->rehash_size))
        new_size = old_size + XFASTINT (h->rehash_size);
        index_size = next_almost_prime ((int)
                                      (new_size
                                       / XFLOATINT (h->rehash_threshold)));
-       if (max (index_size, 2 * new_size) > MOST_POSITIVE_FIXNUM)
+       /* Assignment to EMACS_INT stops GCC whining about limited range
+        of data type.  */
+       nsize = max (index_size, 2 * new_size);
+       if (nsize > MOST_POSITIVE_FIXNUM)
        error ("Hash table too large to resize");
  
        h->key_and_value = larger_vector (h->key_and_value, 2 * new_size, Qnil);
@@@ -4876,6 -5507,7 +4880,6 @@@ including negative integers.  */
   ************************************************************************/
  
  #include "md5.h"
 -#include "coding.h"
  
  DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
         doc: /* Return MD5 message digest of OBJECT, a buffer or string.
@@@ -4926,7 -5558,7 +4930,7 @@@ guesswork fails.  Normally, an error i
  
          if (STRING_MULTIBYTE (object))
            /* use default, we can't guess correct value */
 -          coding_system = SYMBOL_VALUE (XCAR (Vcoding_category_list));
 +          coding_system = preferred_coding_system ();
          else
            coding_system = Qraw_text;
        }
        }
  
        if (STRING_MULTIBYTE (object))
 -      object = code_convert_string1 (object, coding_system, Qnil, 1);
 +      object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
  
        size = SCHARS (object);
        size_byte = SBYTES (object);
        specpdl_ptr--;
  
        if (STRING_MULTIBYTE (object))
 -      object = code_convert_string1 (object, coding_system, Qnil, 1);
 +      object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
      }
  
    md5_buffer (SDATA (object) + start_byte,
@@@ -5247,6 -5879,16 +5251,6 @@@ used if both `use-dialog-box' and this 
    defsubr (&Sequal_including_properties);
    defsubr (&Sfillarray);
    defsubr (&Sclear_string);
 -  defsubr (&Schar_table_subtype);
 -  defsubr (&Schar_table_parent);
 -  defsubr (&Sset_char_table_parent);
 -  defsubr (&Schar_table_extra_slot);
 -  defsubr (&Sset_char_table_extra_slot);
 -  defsubr (&Schar_table_range);
 -  defsubr (&Sset_char_table_range);
 -  defsubr (&Sset_char_table_default);
 -  defsubr (&Soptimize_char_table);
 -  defsubr (&Smap_char_table);
    defsubr (&Snconc);
    defsubr (&Smapcar);
    defsubr (&Smapc);
diff --combined src/fontset.c
index 5a50012fef4317ffc40e78a4adbea84c190b3758,2df60a5afcc067ae08f268ff2ffa963ac7faae3e..c92e05c3f028d7007ac027b32ee7d5ec9e10eec7
@@@ -1,13 -1,11 +1,14 @@@
  /* Fontset handler.
-    Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+      Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 -
 +   Copyright (C) 2003, 2006
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
 + 
  This file is part of GNU Emacs.
  
  GNU Emacs is free software; you can redistribute it and/or modify
@@@ -34,15 -32,12 +35,15 @@@ Boston, MA 02110-1301, USA.  *
  #endif
  
  #include "lisp.h"
 +#include "blockinput.h"
  #include "buffer.h"
 +#include "character.h"
  #include "charset.h"
  #include "ccl.h"
  #include "keyboard.h"
  #include "frame.h"
  #include "dispextern.h"
 +#include "intervals.h"
  #include "fontset.h"
  #include "window.h"
  #ifdef HAVE_X_WINDOWS
  #include "macterm.h"
  #endif
  
 -#ifdef FONTSET_DEBUG
 +#ifdef USE_FONT_BACKEND
 +#include "font.h"
 +#endif        /* USE_FONT_BACKEND */
 +
  #undef xassert
 +#ifdef FONTSET_DEBUG
  #define xassert(X)    do {if (!(X)) abort ();} while (0)
  #undef INLINE
  #define INLINE
 -#endif
 +#else   /* not FONTSET_DEBUG */
 +#define xassert(X)    (void) 0
 +#endif        /* not FONTSET_DEBUG */
  
 +EXFUN (Fclear_face_cache, 1);
  
  /* FONTSET
  
     A fontset is a collection of font related information to give
 -   similar appearance (style, size, etc) of characters.  There are two
 -   kinds of fontsets; base and realized.  A base fontset is created by
 -   new-fontset from Emacs Lisp explicitly.  A realized fontset is
 -   created implicitly when a face is realized for ASCII characters.  A
 -   face is also realized for multibyte characters based on an ASCII
 -   face.  All of the multibyte faces based on the same ASCII face
 -   share the same realized fontset.
 +   similar appearance (style, etc) of characters.  A fontset has two
 +   roles.  One is to use for the frame parameter `font' as if it is an
 +   ASCII font.  In that case, Emacs uses the font specified for
 +   `ascii' script for the frame's default font.
 +
 +   Another role, the more important one, is to provide information
 +   about which font to use for each non-ASCII character.
 +
 +   There are two kinds of fontsets; base and realized.  A base fontset
 +   is created by `new-fontset' from Emacs Lisp explicitly.  A realized
 +   fontset is created implicitly when a face is realized for ASCII
 +   characters.  A face is also realized for non-ASCII characters based
 +   on an ASCII face.  All of non-ASCII faces based on the same ASCII
 +   face share the same realized fontset.
 +
 +   A fontset object is implemented by a char-table whose default value
 +   and parent are always nil.
 +
 +   An element of a base fontset is a vector of FONT-DEFs which itself
 +   is a vector [ FONT-SPEC ENCODING REPERTORY ].
 +
 +   FONT-SPEC is:
 +      [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
 +   or
 +      FONT-NAME
 +   where FAMILY, WEIGHT, SLANT, SWIDTH, ADSTYLE, REGISTRY, and
 +   FONT-NAME are strings.
 +
 +   Note: Currently WEIGHT through ADSTYLE are ignored.
 +
 +   ENCODING is a charset ID that can convert characters to glyph codes
 +   of the corresponding font.
  
 -   A fontset object is implemented by a char-table.
 +   REPERTORY is a charset ID, a char-table, or nil.  If REPERTORY is a
 +   charset ID, the repertory of the charset exactly matches with that
 +   of the font.  If REPERTORY is a char-table, all characters who have
 +   a non-nil value in the table are supported.  If REPERTORY is nil,
 +   we consult with the font itself to get the repertory.
  
 -   An element of a base fontset is:
 -      (INDEX . FONTNAME) or
 -      (INDEX . (FOUNDRY . REGISTRY ))
 -   FONTNAME is a font name pattern for the corresponding character.
 -   FOUNDRY and REGISTRY are respectively foundry and registry fields of
 -   a font name for the corresponding character.  INDEX specifies for
 -   which character (or generic character) the element is defined.  It
 -   may be different from an index to access this element.  For
 -   instance, if a fontset defines some font for all characters of
 -   charset `japanese-jisx0208', INDEX is the generic character of this
 -   charset.  REGISTRY is the
 +   ENCODING and REPERTORY are extracted from the variable
 +   Vfont_encoding_alist by using a font name generated from FONT-SPEC
 +   (if it is a vector) or FONT-NAME as a matching target.
  
 -   An element of a realized fontset is FACE-ID which is a face to use
 -   for displaying the corresponding character.
  
 -   All single byte characters (ASCII and 8bit-unibyte) share the same
 -   element in a fontset.  The element is stored in the first element
 -   of the fontset.
 +   An element of a realized fontset is nil or t, or has this form:
  
 -   To access or set each element, use macros FONTSET_REF and
 -   FONTSET_SET respectively for efficiency.
 +      [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID
 +       PREFERRED-RFONT-DEF RFONT-DEF0 RFONT-DEF1 ...].
  
 -   A fontset has 3 extra slots.
 +   RFONT-DEFn (i.e. Realized FONT-DEF) has this form:
  
 -   The 1st slot is an ID number of the fontset.
 +      [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ]
  
 -   The 2nd slot is a name of the fontset.  This is nil for a realized
 -   face.
 +   RFONT-DEFn is automatically reordered by the current charset
 +   priority list.
  
 -   The 3rd slot is a frame that the fontset belongs to.  This is nil
 -   for a default face.
 +   The value nil means that we have not yet generated the above vector
 +   from the base of the fontset.
  
 -   A parent of a base fontset is nil.  A parent of a realized fontset
 -   is a base fontset.
 +   The value t means that no font is available for the corresponding
 +   range of characters.
  
 -   All fontsets are recorded in Vfontset_table.
 +
 +   A fontset has 9 extra slots.
 +
 +   The 1st slot: the ID number of the fontset
 +
 +   The 2nd slot:
 +      base: the name of the fontset
 +      realized: nil
 +
 +   The 3rd slot:
 +      base: nil
 +      realized: the base fontset
 +
 +   The 4th slot:
 +      base: nil
 +      realized: the frame that the fontset belongs to
 +
 +   The 5th slot:
 +      base: the font name for ASCII characters
 +      realized: nil
 +
 +   The 6th slot:
 +      base: nil
 +      realized: the ID number of a face to use for characters that
 +                has no font in a realized fontset.
 +
 +   The 7th slot:
 +      base: nil
 +      realized: Alist of font index vs the corresponding repertory
 +      char-table.
 +      
 +   The 8th slot:
 +      base: nil
 +      realized: If the base is not the default fontset, a fontset
 +      realized from the default fontset, else nil.
 +
 +   The 9th slot:
 +      base: Same as element value (but for fallback fonts).
 +      realized: Likewise.
 +
 +   All fontsets are recorded in the vector Vfontset_table.
  
  
     DEFAULT FONTSET
  
 -   There's a special fontset named `default fontset' which defines a
 -   default fontname pattern.  When a base fontset doesn't specify a
 -   font for a specific character, the corresponding value in the
 -   default fontset is used.  The format is the same as a base fontset.
 +   There's a special base fontset named `default fontset' which
 +   defines the default font specifications.  When a base fontset
 +   doesn't specify a font for a specific character, the corresponding
 +   value in the default fontset is used.
  
     The parent of a realized fontset created for such a face that has
     no fontset is the default fontset.
  
     These structures are hidden from the other codes than this file.
     The other codes handle fontsets only by their ID numbers.  They
 -   usually use variable name `fontset' for IDs.  But, in this file, we
 -   always use variable name `id' for IDs, and name `fontset' for the
 -   actual fontset objects.
 +   usually use the variable name `fontset' for IDs.  But, in this
 +   file, we always use varialbe name `id' for IDs, and name `fontset'
 +   for an actual fontset object, i.e., char-table.
  
  */
  
  /********** VARIABLES and FUNCTION PROTOTYPES **********/
  
  extern Lisp_Object Qfont;
 -Lisp_Object Qfontset;
 +static Lisp_Object Qfontset;
 +static Lisp_Object Qfontset_info;
 +static Lisp_Object Qprepend, Qappend;
 +static Lisp_Object Qlatin;
  
  /* Vector containing all fontsets.  */
  static Lisp_Object Vfontset_table;
  static int next_fontset_id;
  
  /* The default fontset.  This gives default FAMILY and REGISTRY of
 -   font for each characters.  */
 +   font for each character.  */
  static Lisp_Object Vdefault_fontset;
  
 -/* Alist of font specifications.  It override the font specification
 -   in the default fontset.  */
 -static Lisp_Object Voverriding_fontspec_alist;
 -
  Lisp_Object Vfont_encoding_alist;
  Lisp_Object Vuse_default_ascent;
  Lisp_Object Vignore_relative_composition;
  Lisp_Object Valternate_fontname_alist;
  Lisp_Object Vfontset_alias_alist;
  Lisp_Object Vvertical_centering_font_regexp;
 +Lisp_Object Votf_script_alist;
  
  /* The following six are declarations of callback functions depending
     on window system.  See the comments in src/fontset.h for more
@@@ -255,38 -186,19 +256,38 @@@ void (*set_frame_fontset_func) P_ ((FRA
     This function set the member `encoder' of the structure.  */
  void (*find_ccl_program_func) P_ ((struct font_info *));
  
 +Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
 +                                          struct font_info *));
 +
  /* Check if any window system is used now.  */
  void (*check_window_system_func) P_ ((void));
  
  
  /* Prototype declarations for static functions.  */
 -static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
 -static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
 -static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
 +static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
 +                                  Lisp_Object));
 +static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
  static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 -static int fontset_id_valid_p P_ ((int));
  static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
 -static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
 -static Lisp_Object regularize_fontname P_ ((Lisp_Object));
 +static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object,
 +                                        Lisp_Object));
 +Lisp_Object find_font_encoding P_ ((Lisp_Object));
 +
 +static void set_fontset_font P_ ((Lisp_Object, Lisp_Object));
 +
 +#ifdef FONTSET_DEBUG
 +
 +/* Return 1 if ID is a valid fontset id, else return 0.  */
 +
 +static int
 +fontset_id_valid_p (id)
 +     int id;
 +{
 +  return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
 +}
 +
 +#endif
 +
  
  \f
  /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
  
  /* Macros to access special values of FONTSET.  */
  #define FONTSET_ID(fontset)           XCHAR_TABLE (fontset)->extras[0]
 +
 +/* Macros to access special values of (base) FONTSET.  */
  #define FONTSET_NAME(fontset)         XCHAR_TABLE (fontset)->extras[1]
 -#define FONTSET_FRAME(fontset)                XCHAR_TABLE (fontset)->extras[2]
 -#define FONTSET_ASCII(fontset)                XCHAR_TABLE (fontset)->contents[0]
 -#define FONTSET_BASE(fontset)         XCHAR_TABLE (fontset)->parent
 +#define FONTSET_ASCII(fontset)                XCHAR_TABLE (fontset)->extras[4]
 +
 +/* Macros to access special values of (realized) FONTSET.  */
 +#define FONTSET_BASE(fontset)         XCHAR_TABLE (fontset)->extras[2]
 +#define FONTSET_FRAME(fontset)                XCHAR_TABLE (fontset)->extras[3]
 +#define FONTSET_NOFONT_FACE(fontset)  XCHAR_TABLE (fontset)->extras[5]
 +#define FONTSET_REPERTORY(fontset)    XCHAR_TABLE (fontset)->extras[6]
 +#define FONTSET_DEFAULT(fontset)      XCHAR_TABLE (fontset)->extras[7]
 +
 +/* For both base and realized fontset.  */
 +#define FONTSET_FALLBACK(fontset)     XCHAR_TABLE (fontset)->extras[8]
  
 -#define BASE_FONTSET_P(fontset)               NILP (FONTSET_BASE(fontset))
 +#define BASE_FONTSET_P(fontset)               (NILP (FONTSET_BASE (fontset)))
  
  
 -/* Return the element of FONTSET (char-table) at index C (character).  */
 +/* Return the element of FONTSET for the character C.  If FONTSET is a
 +   base fontset other then the default fontset and FONTSET doesn't
 +   contain information for C, return the information in the default
 +   fontset.  */
  
 -#define FONTSET_REF(fontset, c)       fontset_ref (fontset, c)
 +#define FONTSET_REF(fontset, c)               \
 +  (EQ (fontset, Vdefault_fontset)     \
 +   ? CHAR_TABLE_REF (fontset, c)      \
 +   : fontset_ref ((fontset), (c)))
  
  static Lisp_Object
  fontset_ref (fontset, c)
       Lisp_Object fontset;
       int c;
  {
 -  int charset, c1, c2;
 -  Lisp_Object elt, defalt;
 -
 -  if (SINGLE_BYTE_CHAR_P (c))
 -    return FONTSET_ASCII (fontset);
 -
 -  SPLIT_CHAR (c, charset, c1, c2);
 -  elt = XCHAR_TABLE (fontset)->contents[charset + 128];
 -  if (!SUB_CHAR_TABLE_P (elt))
 -    return elt;
 -  defalt = XCHAR_TABLE (elt)->defalt;
 -  if (c1 < 32
 -      || (elt = XCHAR_TABLE (elt)->contents[c1],
 -        NILP (elt)))
 -    return defalt;
 -  if (!SUB_CHAR_TABLE_P (elt))
 -    return elt;
 -  defalt = XCHAR_TABLE (elt)->defalt;
 -  if (c2 < 32
 -      || (elt = XCHAR_TABLE (elt)->contents[c2],
 -        NILP (elt)))
 -    return defalt;
 +  Lisp_Object elt;
 +
 +  elt = CHAR_TABLE_REF (fontset, c);
 +  if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
 +      /* Don't check Vdefault_fontset for a realized fontset.  */
 +      && NILP (FONTSET_BASE (fontset)))
 +    elt = CHAR_TABLE_REF (Vdefault_fontset, c);
    return elt;
  }
  
  
 +/* Return the element of FONTSET for the character C, set FROM and TO
 +   to the range of characters around C that have the same value as C.
 +   If FONTSET is a base fontset other then the default fontset and
 +   FONTSET doesn't contain information for C, return the information
 +   in the default fontset.  */
 +
 +#define FONTSET_REF_AND_RANGE(fontset, c, form, to)   \
 +  (EQ (fontset, Vdefault_fontset)                     \
 +   ? char_table_ref_and_range (fontset, c, &from, &to)        \
 +   : fontset_ref_and_range (fontset, c, &from, &to))
 +
  static Lisp_Object
 -lookup_overriding_fontspec (frame, c)
 -     Lisp_Object frame;
 +fontset_ref_and_range (fontset, c, from, to)
 +     Lisp_Object fontset;
       int c;
 +     int *from, *to;
  {
 -  Lisp_Object tail;
 +  Lisp_Object elt;
  
 -  for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
 +  elt = char_table_ref_and_range (fontset, c, from, to);
 +  if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
 +      /* Don't check Vdefault_fontset for a realized fontset.  */
 +      && NILP (FONTSET_BASE (fontset)))
      {
 -      Lisp_Object val, target, elt;
 -
 -      val = XCAR (tail);
 -      target = XCAR (val);
 -      val = XCDR (val);
 -      /* Now VAL is (NO-FRAME-LIST OK-FRAME-LIST CHAR FONTNAME).  */
 -      if (NILP (Fmemq (frame, XCAR (val)))
 -        && (CHAR_TABLE_P (target)
 -            ? ! NILP (CHAR_TABLE_REF (target, c))
 -            : XINT (target) == CHAR_CHARSET (c)))
 -      {
 -        val = XCDR (val);
 -        elt = XCDR (val);
 -        if (NILP (Fmemq (frame, XCAR (val))))
 -          {
 -            if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
 -              {
 -                val = XCDR (XCAR (tail));
 -                XSETCAR (val, Fcons (frame, XCAR (val)));
 -                continue;
 -              }
 -            XSETCAR (val, Fcons (frame, XCAR (val)));
 -          }
 -        if (NILP (XCAR (elt)))
 -          XSETCAR (elt, make_number (c));
 -        return elt;
 -      }
 +      int from1, to1;
 +
 +      elt = char_table_ref_and_range (Vdefault_fontset, c, &from1, &to1);
 +      if (*from < from1)
 +      *from = from1;
 +      if (*to > to1)
 +      *to = to1;
      }
 -  return Qnil;
 +  return elt;
  }
  
 -#define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
 +
 +/* Set elements of FONTSET for characters in RANGE to the value ELT.
 +   RANGE is a cons (FROM . TO), where FROM and TO are character codes
 +   specifying a range.  */
 +
 +#define FONTSET_SET(fontset, range, elt)      \
 +  Fset_char_table_range ((fontset), (range), (elt))
 +
 +
 +/* Modify the elements of FONTSET for characters in RANGE by replacing
 +   with ELT or adding ELT.  RANGE is a cons (FROM . TO), where FROM
 +   and TO are character codes specifying a range.  If ADD is nil,
 +   replace with ELT, if ADD is `prepend', prepend ELT, otherwise,
 +   append ELT.  */
 +
 +#define FONTSET_ADD(fontset, range, elt, add)                              \
 +  (NILP (add)                                                              \
 +   ? (NILP (range)                                                         \
 +      ? (FONTSET_FALLBACK (fontset) = Fmake_vector (make_number (1), (elt))) \
 +      : Fset_char_table_range ((fontset), (range),                         \
 +                             Fmake_vector (make_number (1), (elt))))       \
 +   : fontset_add ((fontset), (range), (elt), (add)))
  
  static Lisp_Object
 -fontset_ref_via_base (fontset, c)
 -     Lisp_Object fontset;
 -     int *c;
 +fontset_add (fontset, range, elt, add)
 +     Lisp_Object fontset, range, elt, add;
  {
 -  int charset, c1, c2;
 -  Lisp_Object elt;
 +  Lisp_Object args[2];
 +  int idx = (EQ (add, Qappend) ? 0 : 1);
  
 -  if (SINGLE_BYTE_CHAR_P (*c))
 -    return FONTSET_ASCII (fontset);
 -
 -  elt = Qnil;
 -  if (! EQ (FONTSET_BASE (fontset), Vdefault_fontset))
 -    elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
 -  if (NILP (elt))
 -    elt = lookup_overriding_fontspec (FONTSET_FRAME (fontset), *c);
 -  if (NILP (elt))
 -    elt = FONTSET_REF (Vdefault_fontset, *c);
 -  if (NILP (elt))
 -    return Qnil;
 +  args[1 - idx] = Fmake_vector (make_number (1), elt);
  
 -  *c = XINT (XCAR (elt));
 -  SPLIT_CHAR (*c, charset, c1, c2);
 -  elt = XCHAR_TABLE (fontset)->contents[charset + 128];
 -  if (c1 < 32)
 -    return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
 -  if (!SUB_CHAR_TABLE_P (elt))
 -    return Qnil;
 -  elt = XCHAR_TABLE (elt)->contents[c1];
 -  if (c2 < 32)
 -    return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
 -  if (!SUB_CHAR_TABLE_P (elt))
 -    return Qnil;
 -  elt = XCHAR_TABLE (elt)->contents[c2];
 -  return elt;
 +  if (CONSP (range))
 +    {
 +      int from = XINT (XCAR (range));
 +      int to = XINT (XCDR (range));
 +      int from1, to1;
 +
 +      do {
 +      args[idx] = char_table_ref_and_range (fontset, from, &from1, &to1);
 +      if (to < to1)
 +        to1 = to;
 +      char_table_set_range (fontset, from, to1,
 +                            NILP (args[idx]) ? args[1 - idx]
 +                            : Fvconcat (2, args));
 +      from = to1 + 1;
 +      } while (from < to);
 +    }
 +  else
 +    {
 +      args[idx] = FONTSET_FALLBACK (fontset);
 +      FONTSET_FALLBACK (fontset)
 +      = NILP (args[idx]) ? args[1 - idx] : Fvconcat (2, args);
 +    }
 +  return Qnil;
  }
  
  
 -/* Store into the element of FONTSET at index C the value NEWELT.  */
 -#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
 +/* Update FONTSET_ELEMENT which has this form:
 +      [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-RFONT-DEF
 +       RFONT-DEF0 RFONT-DEF1 ...].
 +   Reorder RFONT-DEFs according to the current order of charset
 +   (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to
 +   the latest value.  */
  
  static void
 -fontset_set (fontset, c, newelt)
 +reorder_font_vector (fontset_element)
 +     Lisp_Object fontset_element;
 +{
 +  Lisp_Object list, *new_vec;
 +  Lisp_Object font_def;
 +  int size;
 +  int *charset_id_table;
 +  int i, idx;
 +
 +  ASET (fontset_element, 0, make_number (charset_ordered_list_tick));
 +  size = ASIZE (fontset_element) - 3;
 +  if (size <= 1)
 +    /* No need to reorder VEC.  */
 +    return;
 +  charset_id_table = (int *) alloca (sizeof (int) * size);
 +  new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
 +
 +  /* At first, extract ENCODING (a chaset ID) from each FONT-DEF.
 +     FONT-DEF has this form:
 +      [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] */
 +  for (i = 0; i < size; i++)
 +    {
 +      font_def = AREF (fontset_element, i + 3);
 +      if (! NILP (AREF (font_def, 2)))
 +      charset_id_table[i] = XINT (AREF (AREF (font_def, 2), 1));
 +      else
 +      charset_id_table[i] = -1;
 +    }
 +
 +  /* Then, store FONT-DEFs in NEW_VEC in the correct order.  */
 +  for (idx = 0, list = Vcharset_ordered_list;
 +       idx < size && CONSP (list); list = XCDR (list))
 +    {
 +      for (i = 0; i < size; i++)
 +      if (charset_id_table[i] == XINT (XCAR (list)))
 +        new_vec[idx++] = AREF (fontset_element, i + 3);
 +    }
 +  for (i = 0; i < size; i++)
 +    if (charset_id_table[i] < 0)
 +      new_vec[idx++] = AREF (fontset_element, i + 3);
 +
 +  /* At last, update FONT-DEFs.  */
 +  for (i = 0; i < size; i++)
 +    ASET (fontset_element, i + 3, new_vec[i]);
 +}
 +
 +
 +/* Load a font matching the font related attributes in FACE->lface and
 +   font pattern in FONT_DEF of FONTSET, and return an index of the
 +   font.  FONT_DEF has this form:
 +      [ FONT-SPEC ENCODING REPERTORY ]
 +   If REPERTORY is nil, generate a char-table representing the font
 +   repertory by looking into the font itself.  */
 +
 +static int
 +load_font_get_repertory (f, face, font_def, fontset)
 +     FRAME_PTR f;
 +     struct face *face;
 +     Lisp_Object font_def;
 +     Lisp_Object fontset;
 +{
 +  char *font_name;
 +  struct font_info *font_info;
 +  int charset;
 +
 +  font_name = choose_face_font (f, face->lface, AREF (font_def, 0), NULL);
 +  charset = XINT (AREF (font_def, 1));
 +  if (! (font_info = fs_load_font (f, font_name, charset)))
 +    return -1;
 +
 +  if (NILP (AREF (font_def, 2))
 +      && NILP (Fassq (make_number (font_info->font_idx),
 +                    FONTSET_REPERTORY (fontset))))
 +    {
 +      /* We must look into the font to get the correct repertory as a
 +       char-table.  */
 +      Lisp_Object repertory;
 +
 +      repertory = (*get_font_repertory_func) (f, font_info);
 +      FONTSET_REPERTORY (fontset)
 +      = Fcons (Fcons (make_number (font_info->font_idx), repertory),
 +               FONTSET_REPERTORY (fontset));
 +    }
 +      
 +  return font_info->font_idx;
 +}
 +
 +
 +/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
 +   character C.  If the corresponding font is not yet opened, open it
 +   (if FACE is not NULL) or return Qnil (if FACE is NULL).
 +   If no proper font is found for C, return Qnil.  */
 +
 +static Lisp_Object
 +fontset_font (fontset, c, face, id)
       Lisp_Object fontset;
       int c;
 -     Lisp_Object newelt;
 +     struct face *face;
 +     int id;
  {
 -  int charset, code[3];
 -  Lisp_Object *elt;
 -  int i;
 +  Lisp_Object base_fontset, elt, vec;
 +  int i, from, to;
 +  int font_idx;
 +  FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
 +
 +  base_fontset = FONTSET_BASE (fontset);
 +  vec = CHAR_TABLE_REF (fontset, c);
 +  if (EQ (vec, Qt))
 +    goto try_fallback;
  
 -  if (SINGLE_BYTE_CHAR_P (c))
 +  if (NILP (vec))
      {
 -      FONTSET_ASCII (fontset) = newelt;
 -      return;
 +      /* We have not yet decided a face for C.  */
 +      Lisp_Object range;
 +
 +      if (! face)
 +      return Qnil;
 +      elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to);
 +      range = Fcons (make_number (from), make_number (to));
 +      if (NILP (elt))
 +      {
 +        /* Record that we have no font for characters of this
 +           range.  */
 +        vec = Qt;
 +        FONTSET_SET (fontset, range, vec);
 +        goto try_fallback;
 +      }
 +      /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ],
 +       where the first -1 is to force reordering of NEW-ELTn,
 +       NEW-ETLn is [nil nil AREF (elt, n) nil].  */
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend
 +        && EQ (base_fontset, Vdefault_fontset))
 +      vec = Fmake_vector (make_number (ASIZE (elt) + 4), make_number (-1));
 +      else
 +#endif        /* not USE_FONT_BACKEND */
 +      vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1));
 +      ASET (vec, 2, Qnil);
 +      for (i = 0; i < ASIZE (elt); i++)
 +      {
 +        Lisp_Object tmp;
 +
 +#ifdef USE_FONT_BACKEND
 +        if (enable_font_backend)
 +          tmp = Fmake_vector (make_number (5), Qnil);
 +        else
 +#endif        /* USE_FONT_BACKEND */
 +        tmp = Fmake_vector (make_number (4), Qnil);
 +        ASET (tmp, 2, AREF (elt, i));
 +        ASET (vec, 3 + i, tmp);
 +      }
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend
 +        && EQ (base_fontset, Vdefault_fontset))
 +      {
 +        Lisp_Object script, font_spec, tmp;
 +
 +        script = CHAR_TABLE_REF (Vchar_script_table, c);
 +        if (NILP (script))
 +          script = intern ("latin");
 +        font_spec = Ffont_spec (0, NULL);
 +        ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
 +        ASET (font_spec, FONT_EXTRA_INDEX,
 +              Fcons (Fcons (QCscript, script), Qnil));
 +        tmp = Fmake_vector (make_number (5), Qnil);
 +        ASET (tmp, 3, font_spec);
 +        ASET (vec, 3 + i, tmp);
 +      }
 +#endif        /* USE_FONT_BACKEND */
 +
 +      /* Then store it in the fontset.  */
 +      FONTSET_SET (fontset, range, vec);
      }
  
 -  SPLIT_CHAR (c, charset, code[0], code[1]);
 -  code[2] = 0;                        /* anchor */
 -  elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
 -  for (i = 0; code[i] > 0; i++)
 + retry:
 +  if (XINT (AREF (vec, 0)) != charset_ordered_list_tick)
 +    /* The priority of charsets is changed after we selected a face
 +       for C last time.  */
 +    reorder_font_vector (vec);
 +
 +  if (id < 0)
 +    i = 3;
 +  else if (id == XFASTINT (AREF (vec, 1)))
 +    i = 2;
 +  else
      {
 -      if (!SUB_CHAR_TABLE_P (*elt))
 +      ASET (vec, 1, make_number (id));
 +      for (i = 3; i < ASIZE (vec); i++)
 +      if (id == XFASTINT (AREF (AREF (AREF (vec, i), 2), 1)))
 +        break;
 +      if (i < ASIZE (vec))
 +      {
 +        ASET (vec, 2, AREF (vec, i));
 +        i = 2;
 +      }
 +      else
        {
 -        Lisp_Object val = *elt;
 -        *elt = make_sub_char_table (Qnil);
 -        XCHAR_TABLE (*elt)->defalt = val;
 +        ASET (vec, 2, Qnil);
 +        i = 3;
        }
 -      elt = &XCHAR_TABLE (*elt)->contents[code[i]];
      }
 -  if (SUB_CHAR_TABLE_P (*elt))
 -    XCHAR_TABLE (*elt)->defalt = newelt;
 -  else
 -    *elt = newelt;
 +
 +  /* Find the first available font in the vector of RFONT-DEF.  */
 +  for (; i < ASIZE (vec); i++)
 +    {
 +      Lisp_Object font_def;
 +
 +      elt = AREF (vec, i);
 +      if (NILP (elt))
 +      continue;
 +      /* ELT == [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ] */
 +      if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
 +      /* We couldn't open this font last time.  */
 +      continue;
 +
 +      if (!face && NILP (AREF (elt, 1)))
 +      /* We have not yet opened the font.  */
 +      return Qnil;
 +
 +      font_def = AREF (elt, 2);
 +      /* FONT_DEF == [ FONT-SPEC ENCODING REPERTORY ] */
 +
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend)
 +      {
 +        /* ELT == [ FACE-ID FONT-INDEX FONT-DEF FONT-ENTITY FONT-OBJECT ] */
 +        Lisp_Object font_entity = AREF (elt, 3);
 +        Lisp_Object font_object = AREF (elt, 4);
 +        int has_char;
 +
 +        if (NILP (font_entity) && ! NILP (AREF (font_def, 0)))
 +          {
 +            Lisp_Object tmp = AREF (font_def, 0);
 +            Lisp_Object spec = Ffont_spec (0, NULL);
 +
 +            if (STRINGP (tmp))
 +              font_merge_old_spec (tmp, Qnil, Qnil, spec);
 +            else
 +              {
 +                Lisp_Object family = AREF (tmp, 0);
 +                Lisp_Object registry = AREF (tmp, 5);;
 +
 +                font_merge_old_spec (Qnil, family, registry, spec);
 +              }
 +            font_entity = font_find_for_lface (f, face->lface, spec);
 +            ASET (elt, 3, font_entity);
 +          }
 +        else if (FONT_SPEC_P (font_entity))
 +          {
 +            font_entity = font_find_for_lface (f, face->lface, font_entity);
 +            ASET (elt, 3, font_entity);
 +          }
 +        if (NILP (font_entity))
 +          {
 +            ASET (elt, 1, make_number (-1));
 +            continue;
 +          }
 +        has_char = font_has_char (f, font_entity, c);
 +        if (has_char == 0)
 +          continue;
 +        if (NILP (font_object))
 +          font_object = font_open_for_lface (f, face->lface, font_entity);
 +        if (NILP (font_object))
 +          {
 +            ASET (elt, 1, make_number (-1));
 +            continue;
 +          }
 +        ASET (elt, 1, make_number (0));
 +        ASET (elt, 4, font_object);
 +        if (has_char < 0
 +            && font_encode_char (font_object, c) == FONT_INVALID_CODE)
 +          continue;
 +      }
 +      else
 +#endif        /* USE_FONT_BACKEND */
 +
 +      if (INTEGERP (AREF (font_def, 2)))
 +      {
 +        /* The repertory is specified by charset ID.  */
 +        struct charset *charset
 +          = CHARSET_FROM_ID (XINT (AREF (font_def, 2)));
 +
 +        if (! CHAR_CHARSET_P (c, charset))
 +          /* This font can't display C.  */
 +          continue;
 +      }
 +      else if (CHAR_TABLE_P (AREF (font_def, 2)))
 +      {
 +        /* The repertory is specified by a char table.  */
 +        if (NILP (CHAR_TABLE_REF (AREF (font_def, 2), c)))
 +          /* This font can't display C.  */
 +          continue;
 +      }
 +      else
 +      {
 +        Lisp_Object slot;
 +
 +        if (! INTEGERP (AREF (elt, 1)))
 +          {
 +            /* We have not yet opened a font matching this spec.
 +               Open the best matching font now and register the
 +               repertory.  */
 +            struct font_info *font_info;
 +
 +            font_idx = load_font_get_repertory (f, face, font_def, fontset);
 +            ASET (elt, 1, make_number (font_idx));
 +            if (font_idx < 0)
 +              /* This means that we couldn't find a font matching
 +                 FONT_DEF.  */
 +              continue;
 +            font_info = (*get_font_info_func) (f, font_idx);
 +            ASET (elt, 3, build_string (font_info->full_name));
 +          }
 +
 +        slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
 +        xassert (CONSP (slot));
 +        if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
 +          /* This font can't display C.  */
 +          continue;
 +      }
 +
 +      /* Now we have decided to use this font spec to display C.  */
 +      if (! INTEGERP (AREF (elt, 1)))
 +      {
 +        /* But not yet opened the best matching font.  */
 +        struct font_info *font_info;
 +
 +        font_idx = load_font_get_repertory (f, face, font_def, fontset);
 +        ASET (elt, 1, make_number (font_idx));
 +        if (font_idx < 0)
 +          /* Can't open it.  Try the other one.  */
 +          continue;
 +        font_info = (*get_font_info_func) (f, font_idx);
 +        ASET (elt, 3, build_string (font_info->full_name));
 +      }
 +
 +      /* Now we have the opened font.  */
 +      return elt;
 +    }
 +
 + try_fallback:
 +  if (! EQ (vec, FONTSET_FALLBACK (fontset)))
 +    {
 +      vec = FONTSET_FALLBACK (fontset);
 +      if (VECTORP (vec))
 +      goto retry;
 +      if (EQ (vec, Qt))
 +      goto try_default;
 +      elt = FONTSET_FALLBACK (base_fontset);
 +      if (! NILP (elt))
 +      {
 +        vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1));
 +        ASET (vec, 2, Qnil);
 +        for (i = 0; i < ASIZE (elt); i++)
 +          {
 +            Lisp_Object tmp;
 +
 +#ifdef USE_FONT_BACKEND
 +            if (enable_font_backend)
 +              tmp = Fmake_vector (make_number (5), Qnil);
 +            else
 +#endif        /* USE_FONT_BACKEND */
 +            tmp = Fmake_vector (make_number (4), Qnil);
 +            ASET (tmp, 2, AREF (elt, i));
 +            ASET (vec, 3 + i, tmp);
 +          }
 +        FONTSET_FALLBACK (fontset) = vec;       
 +        goto retry;
 +      }
 +      /* Record that this fontset has no fallback fonts.  */
 +      FONTSET_FALLBACK (fontset) = Qt;
 +    }
 +
 +  /* Try the default fontset.  */
 + try_default:
 +  if (! EQ (base_fontset, Vdefault_fontset))
 +    {
 +      if (NILP (FONTSET_DEFAULT (fontset)))
 +      FONTSET_DEFAULT (fontset)
 +        = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
 +      return fontset_font (FONTSET_DEFAULT (fontset), c, face, id);
 +    }
 +  return Qnil;
  }
  
  
  /* Return a newly created fontset with NAME.  If BASE is nil, make a
 -   base fontset.  Otherwise make a realized fontset whose parent is
 +   base fontset.  Otherwise make a realized fontset whose base is
     BASE.  */
  
  static Lisp_Object
@@@ -848,11 -391,10 +849,11 @@@ make_fontset (frame, name, base
  
    if (id + 1 == size)
      {
 +      /* We must grow Vfontset_table.  */
        Lisp_Object tem;
        int i;
  
 -      tem = Fmake_vector (make_number (size + 8), Qnil);
 +      tem = Fmake_vector (make_number (size + 32), Qnil);
        for (i = 0; i < size; i++)
        AREF (tem, i) = AREF (Vfontset_table, i);
        Vfontset_table = tem;
    fontset = Fmake_char_table (Qfontset, Qnil);
  
    FONTSET_ID (fontset) = make_number (id);
 -  FONTSET_NAME (fontset) = name;
 -  FONTSET_FRAME (fontset) = frame;
 -  FONTSET_BASE (fontset) = base;
 +  if (NILP (base))
 +    {
 +      FONTSET_NAME (fontset) = name;
 +    }
 +  else
 +    {
 +      FONTSET_NAME (fontset) = Qnil;
 +      FONTSET_FRAME (fontset) = frame;
 +      FONTSET_BASE (fontset) = base;
 +    }
  
 -  AREF (Vfontset_table, id) = fontset;
 +  ASET (Vfontset_table, id, fontset);
    next_fontset_id = id + 1;
    return fontset;
  }
  
  
 -/* Return 1 if ID is a valid fontset id, else return 0.  */
 -
 -static INLINE int
 -fontset_id_valid_p (id)
 -     int id;
 -{
 -  return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
 -}
 -
 -
 -/* Extract `family' and `registry' string from FONTNAME and a cons of
 -   them.  Actually, `family' may also contain `foundry', `registry'
 -   may also contain `encoding' of FONTNAME.  But, if FONTNAME doesn't
 -   conform to XLFD nor explicitely specifies the other fields
 -   (i.e. not using wildcard `*'), return FONTNAME.  If FORCE is
 -   nonzero, specifications of the other fields are ignored, and return
 -   a cons as far as FONTNAME conform to XLFD.  */
 -
 -static Lisp_Object
 -font_family_registry (fontname, force)
 +/* Set the ASCII font of the default fontset to FONTNAME if that is
 +   not yet set.  */
 +void
 +set_default_ascii_font (fontname)
       Lisp_Object fontname;
 -     int force;
  {
 -  Lisp_Object family, registry;
 -  const char *p = SDATA (fontname);
 -  const char *sep[15];
 -  int i = 0;
 -
 -  while (*p && i < 15)
 -    if (*p++ == '-')
 -      {
 -      if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
 -        return fontname;
 -      sep[i++] = p;
 -      }
 -  if (i != 14)
 -    return fontname;
 +  if (! STRINGP (FONTSET_ASCII (Vdefault_fontset)))
 +    {
 +      int id = fs_query_fontset (fontname, 2);
  
 -  family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
 -  registry = make_unibyte_string (sep[12], p - sep[12]);
 -  return Fcons (family, registry);
 +      if (id >= 0)
 +      fontname = FONTSET_ASCII (FONTSET_FROM_ID (id));
 +      FONTSET_ASCII (Vdefault_fontset)= fontname;
 +    }
  }
  
  \f
 -/********** INTERFACES TO xfaces.c and dispextern.h **********/
 +/********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/
  
 -/* Return name of the fontset with ID.  */
 +/* Return the name of the fontset who has ID.  */
  
  Lisp_Object
  fontset_name (id)
       int id;
  {
    Lisp_Object fontset;
 +
    fontset = FONTSET_FROM_ID (id);
    return FONTSET_NAME (fontset);
  }
  
  
 -/* Return ASCII font name of the fontset with ID.  */
 +/* Return the ASCII font name of the fontset who has ID.  */
  
  Lisp_Object
  fontset_ascii (id)
       int id;
  {
    Lisp_Object fontset, elt;
 +
    fontset= FONTSET_FROM_ID (id);
    elt = FONTSET_ASCII (fontset);
 -  return XCDR (elt);
 +#ifdef USE_FONT_BACKEND
 +  if (CONSP (elt))
 +    elt = XCAR (elt);
 +#endif  /* USE_FONT_BACKEND */
 +  /* It is assured that ELT is always a string (i.e. fontname
 +     pattern).  */
 +  return elt;
  }
  
  
 -/* Free fontset of FACE.  Called from free_realized_face.  */
 +/* Free fontset of FACE defined on frame F.  Called from
 +   free_realized_face.  */
  
  void
  free_face_fontset (f, face)
       FRAME_PTR f;
       struct face *face;
  {
 -  if (fontset_id_valid_p (face->fontset))
 +  Lisp_Object fontset;
 +
 +  fontset = AREF (Vfontset_table, face->fontset);
 +  xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
 +  xassert (f == XFRAME (FONTSET_FRAME (fontset)));
 +  ASET (Vfontset_table, face->fontset, Qnil);
 +  if (face->fontset < next_fontset_id)
 +    next_fontset_id = face->fontset;
 +  if (! NILP (FONTSET_DEFAULT (fontset)))
      {
 -      AREF (Vfontset_table, face->fontset) = Qnil;
 -      if (face->fontset < next_fontset_id)
 +      int id = XINT (FONTSET_ID (FONTSET_DEFAULT (fontset)));
 +      
 +      fontset = AREF (Vfontset_table, id);
 +      xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
 +      xassert (f == XFRAME (FONTSET_FRAME (fontset)));
 +      ASET (Vfontset_table, id, Qnil);
 +      if (id < next_fontset_id)
        next_fontset_id = face->fontset;
      }
  }
  
  /* Return 1 iff FACE is suitable for displaying character C.
     Otherwise return 0.  Called from the macro FACE_SUITABLE_FOR_CHAR_P
 -   when C is not a single byte character..  */
 +   when C is not an ASCII character.  */
  
  int
  face_suitable_for_char_p (face, c)
       struct face *face;
       int c;
  {
 -  Lisp_Object fontset, elt;
 -
 -  if (SINGLE_BYTE_CHAR_P (c))
 -    return (face == face->ascii_face);
 +  Lisp_Object fontset, rfont_def;
  
 -  xassert (fontset_id_valid_p (face->fontset));
    fontset = FONTSET_FROM_ID (face->fontset);
 -  xassert (!BASE_FONTSET_P (fontset));
 -
 -  elt = FONTSET_REF_VIA_BASE (fontset, c);
 -  return (!NILP (elt) && face->id == XFASTINT (elt));
 +  rfont_def = fontset_font (fontset, c, NULL, -1);
 +  return (VECTORP (rfont_def)
 +        && INTEGERP (AREF (rfont_def, 0))
 +        && face->id == XINT (AREF (rfont_def, 0)));
  }
  
  
  /* Return ID of face suitable for displaying character C on frame F.
 -   The selection of face is done based on the fontset of FACE.  FACE
 -   should already have been realized for ASCII characters.  Called
 -   from the macro FACE_FOR_CHAR when C is not a single byte character.  */
 +   FACE must be reazlied for ASCII characters in advance.  Called from
 +   the macro FACE_FOR_CHAR.  */
  
  int
 -face_for_char (f, face, c)
 +face_for_char (f, face, c, pos, object)
       FRAME_PTR f;
       struct face *face;
 -     int c;
 +     int c, pos;
 +     Lisp_Object object;
  {
 -  Lisp_Object fontset, elt;
 +  Lisp_Object fontset, charset, rfont_def;
    int face_id;
 +  int id;
 +
 +  if (ASCII_CHAR_P (c))
 +    return face->ascii_face->id;
  
    xassert (fontset_id_valid_p (face->fontset));
    fontset = FONTSET_FROM_ID (face->fontset);
    xassert (!BASE_FONTSET_P (fontset));
 +  if (pos < 0)
 +    id = -1;
 +  else
 +    {
 +      charset = Fget_char_property (make_number (pos), Qcharset, object);
 +      if (NILP (charset))
 +      id = -1;
 +      else if (CHARSETP (charset))
 +      id = XINT (CHARSET_SYMBOL_ID (charset));
 +    }
 +  rfont_def = fontset_font (fontset, c, face, id);
 +  if (VECTORP (rfont_def))
 +    {
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend
 +        && NILP (AREF (rfont_def, 0)))
 +      {
 +        struct font *font = XSAVE_VALUE (AREF (rfont_def, 4))->pointer;
  
 -  elt = FONTSET_REF_VIA_BASE (fontset, c);
 -  if (!NILP (elt))
 -    return XINT (elt);
 +        face_id = face_for_font (f, font, face);
 +        ASET (rfont_def, 0, make_number (face_id));
 +      }
 +      else
 +#endif        /* USE_FONT_BACKEND */
 +      if (NILP (AREF (rfont_def, 0)))
 +      {
 +        /* We have not yet made a realized face that uses this font.  */
 +        int font_idx = XINT (AREF (rfont_def, 1));
  
 -  /* No face is recorded for C in the fontset of FACE.  Make a new
 -     realized face for C that has the same fontset.  */
 -  face_id = lookup_face (f, face->lface, c, face);
 +        face_id = lookup_non_ascii_face (f, font_idx, face);
 +        ASET (rfont_def, 0, make_number (face_id));
 +      }
 +      return XINT (AREF (rfont_def, 0));
 +    }
  
 -  /* Record the face ID in FONTSET at the same index as the
 -     information in the base fontset.  */
 -  FONTSET_SET (fontset, c, make_number (face_id));
 -  return face_id;
 +  if (NILP (FONTSET_NOFONT_FACE (fontset)))
 +    {
 +      face_id = lookup_non_ascii_face (f, -1, face);
 +      FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
 +    }
 +  return XINT (FONTSET_NOFONT_FACE (fontset));
  }
  
  
     Called from realize_x_face.  */
  
  int
 -make_fontset_for_ascii_face (f, base_fontset_id)
 +make_fontset_for_ascii_face (f, base_fontset_id, face)
       FRAME_PTR f;
       int base_fontset_id;
 +     struct face *face;
  {
    Lisp_Object base_fontset, fontset, frame;
  
        if (!BASE_FONTSET_P (base_fontset))
        base_fontset = FONTSET_BASE (base_fontset);
        xassert (BASE_FONTSET_P (base_fontset));
 +      if (! BASE_FONTSET_P (base_fontset))
 +      abort ();
      }
    else
      base_fontset = Vdefault_fontset;
  
    fontset = make_fontset (frame, Qnil, base_fontset);
 -  return XINT (FONTSET_ID (fontset));
 -}
 -
 -
 -/* Return the font name pattern for C that is recorded in the fontset
 -   with ID.  If a font name pattern is specified (instead of a cons of
 -   family and registry), check if a font can be opened by that pattern
 -   to get the fullname.  If a font is opened, return that name.
 -   Otherwise, return nil.  If ID is -1, or the fontset doesn't contain
 -   information about C, get the registry and encoding of C from the
 -   default fontset.  Called from choose_face_font.  */
 +  {
 +    Lisp_Object elt, rfont_def;
  
 -Lisp_Object
 -fontset_font_pattern (f, id, c)
 -     FRAME_PTR f;
 -     int id, c;
 -{
 -  Lisp_Object fontset, elt;
 -  struct font_info *fontp;
 +    elt = FONTSET_REF (base_fontset, 0);
 +    xassert (VECTORP (elt) && ASIZE (elt) > 0);
 +#ifdef USE_FONT_BACKEND
 +    rfont_def = Fmake_vector (make_number (5), Qnil);
 +    if (enable_font_backend && face->font_info)
 +      {
 +      struct font *font = (struct font *) face->font_info;
  
 -  elt = Qnil;
 -  if (fontset_id_valid_p (id))
 -    {
 -      fontset = FONTSET_FROM_ID (id);
 -      xassert (!BASE_FONTSET_P (fontset));
 -      fontset = FONTSET_BASE (fontset);
 -      if (! EQ (fontset, Vdefault_fontset))
 -      elt = FONTSET_REF (fontset, c);
 -    }
 -  if (NILP (elt))
 +      ASET (rfont_def, 3, font->entity);
 +      ASET (rfont_def, 4, font_find_object (font));
 +      }
 +    else
 +#endif  /* USE_FONT_BACKEND */
      {
 -      Lisp_Object frame;
 -
 -      XSETFRAME (frame, f);
 -      elt = lookup_overriding_fontspec (frame, c);
 +      rfont_def = Fmake_vector (make_number (4), Qnil);
 +      ASET (rfont_def, 3, build_string (face->font_name));
      }
 -  if (NILP (elt))
 -    elt = FONTSET_REF (Vdefault_fontset, c);
 -
 -  if (!CONSP (elt))
 -    return Qnil;
 -  if (CONSP (XCDR (elt)))
 -    return XCDR (elt);
 -
 -  /* The fontset specifies only a font name pattern (not cons of
 -     family and registry).  If a font can be opened by that pattern,
 -     return the name of opened font.  Otherwise return nil.  The
 -     exception is a font for single byte characters.  In that case, we
 -     return a cons of FAMILY and REGISTRY extracted from the opened
 -     font name.  */
 -  elt = XCDR (elt);
 -  xassert (STRINGP (elt));
 -  fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
 -  if (!fontp)
 -    return Qnil;
 -
 -  return font_family_registry (build_string (fontp->full_name),
 -                             SINGLE_BYTE_CHAR_P (c));
 +    ASET (rfont_def, 0, make_number (face->id));
 +    ASET (rfont_def, 1, make_number (face->font_info_id));
 +    ASET (rfont_def, 2, AREF (elt, 0));
 +    elt = Fmake_vector (make_number (4), Qnil);
 +    ASET (elt, 0, make_number (charset_ordered_list_tick));
 +    ASET (elt, 1, make_number (charset_ascii));
 +    ASET (elt, 2, rfont_def);
 +    ASET (elt, 3, rfont_def);
 +    char_table_set_range (fontset, 0, 127, elt);
 +  }
 +  return XINT (FONTSET_ID (fontset));
  }
  
  
  #pragma optimize("", off)
  #endif
  
 -/* Load a font named FONTNAME to display character C on frame F.
 -   Return a pointer to the struct font_info of the loaded font.  If
 -   loading fails, return NULL.  If FACE is non-zero and a fontset is
 -   assigned to it, record FACE->id in the fontset for C.  If FONTNAME
 -   is NULL, the name is taken from the fontset of FACE or what
 -   specified by ID.  */
 +/* Load a font named FONTNAME on frame F.  Return a pointer to the
 +   struct font_info of the loaded font.  If loading fails, return
 +   NULL.  CHARSET is an ID of charset to encode characters for this
 +   font.  If it is -1, find one from Vfont_encoding_alist.  */
  
  struct font_info *
 -fs_load_font (f, c, fontname, id, face)
 +fs_load_font (f, fontname, charset)
       FRAME_PTR f;
 -     int c;
       char *fontname;
 -     int id;
 -     struct face *face;
 +     int charset;
  {
 -  Lisp_Object fontset;
 -  Lisp_Object list, elt, fullname;
 -  int size = 0;
    struct font_info *fontp;
 -  int charset = CHAR_CHARSET (c);
 -
 -  if (face)
 -    id = face->fontset;
 -  if (id < 0)
 -    fontset = Qnil;
 -  else
 -    fontset = FONTSET_FROM_ID (id);
 -
 -  if (!NILP (fontset)
 -      && !BASE_FONTSET_P (fontset))
 -    {
 -      elt = FONTSET_REF_VIA_BASE (fontset, c);
 -      if (!NILP (elt))
 -      {
 -        /* A suitable face for C is already recorded, which means
 -           that a proper font is already loaded.  */
 -        int face_id = XINT (elt);
 -
 -        xassert (face_id == face->id);
 -        face = FACE_FROM_ID (f, face_id);
 -        return (*get_font_info_func) (f, face->font_info_id);
 -      }
 -
 -      if (!fontname && charset == CHARSET_ASCII)
 -      {
 -        elt = FONTSET_ASCII (fontset);
 -        fontname = SDATA (XCDR (elt));
 -      }
 -    }
 +  Lisp_Object fullname;
  
    if (!fontname)
      /* No way to get fontname.  */
 -    return 0;
 +    return NULL;
  
 -  fontp = (*load_font_func) (f, fontname, size);
 -  if (!fontp)
 -    return 0;
 -
 -  /* Fill in members (charset, vertical_centering, encoding, etc) of
 -     font_info structure that are not set by (*load_font_func).  */
 -  fontp->charset = charset;
 +  fontp = (*load_font_func) (f, fontname, 0);
 +  if (! fontp || fontp->charset >= 0)
 +    return fontp;
  
 +  fontname = fontp->full_name;
    fullname = build_string (fontp->full_name);
 -  fontp->vertical_centering
 -    = (STRINGP (Vvertical_centering_font_regexp)
 -       && (fast_string_match_ignore_case
 -         (Vvertical_centering_font_regexp, fullname) >= 0));
  
 -  if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
 +  if (charset < 0)
      {
 -      /* The font itself tells which code points to be used.  Use this
 -       encoding for all other charsets.  */
 -      int i;
 -
 -      fontp->encoding[0] = fontp->encoding[1];
 -      for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
 -      fontp->encoding[i] = fontp->encoding[1];
 +      Lisp_Object charset_symbol;
 +
 +      charset_symbol = find_font_encoding (fullname);
 +      if (CONSP (charset_symbol))
 +      charset_symbol = XCAR (charset_symbol);
 +      if (NILP (charset_symbol))
 +      charset_symbol = Qascii;
 +      charset = XINT (CHARSET_SYMBOL_ID (charset_symbol));
      }
 -  else
 -    {
 -      /* The font itself doesn't have information about encoding.  */
 -      int i;
 +  fontp->charset = charset;
 +  fontp->vertical_centering = 0;
 +  fontp->font_encoder = NULL;
  
 -      /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
 -       others is 1 (i.e. 0x80..0xFF).  */
 -      fontp->encoding[0] = 0;
 -      for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
 -      fontp->encoding[i] = 1;
 -      /* Then override them by a specification in Vfont_encoding_alist.  */
 -      for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
 -      {
 -        elt = XCAR (list);
 -        if (CONSP (elt)
 -            && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
 -            && (fast_string_match_ignore_case (XCAR (elt), fullname) >= 0))
 -          {
 -            Lisp_Object tmp;
 +  if (charset != charset_ascii)
 +    {
 +      fontp->vertical_centering
 +      = (STRINGP (Vvertical_centering_font_regexp)
 +         && (fast_string_match_ignore_case
 +             (Vvertical_centering_font_regexp, fullname) >= 0));
  
 -            for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
 -              if (CONSP (XCAR (tmp))
 -                  && ((i = get_charset_id (XCAR (XCAR (tmp))))
 -                      >= 0)
 -                  && INTEGERP (XCDR (XCAR (tmp)))
 -                  && XFASTINT (XCDR (XCAR (tmp))) < 4)
 -                fontp->encoding[i]
 -                  = XFASTINT (XCDR (XCAR (tmp)));
 -          }
 -      }
 +      if (find_ccl_program_func)
 +      (*find_ccl_program_func) (fontp);
      }
  
 -  if (! fontp->font_encoder && find_ccl_program_func)
 -    (*find_ccl_program_func) (fontp);
 -
 -  /* If we loaded a font for a face that has fontset, record the face
 -     ID in the fontset for C.  */
 -  if (face
 -      && !NILP (fontset)
 -      && !BASE_FONTSET_P (fontset))
 -    FONTSET_SET (fontset, c, make_number (face->id));
    return fontp;
  }
  
  #pragma optimize("", on)
  #endif
  
 -/* Set the ASCII font of the default fontset to FONTNAME if that is
 -   not yet set.  */
 -void
 -set_default_ascii_font (fontname)
 +\f
 +/* Return ENCODING or a cons of ENCODING and REPERTORY of the font
 +   FONTNAME.  ENCODING is a charset symbol that specifies the encoding
 +   of the font.  REPERTORY is a charset symbol or nil.  */
 +
 +
 +Lisp_Object
 +find_font_encoding (fontname)
       Lisp_Object fontname;
  {
 -  if (! CONSP (FONTSET_ASCII (Vdefault_fontset)))
 -    {
 -      int id = fs_query_fontset (fontname, 2);
 +  Lisp_Object tail, elt;
  
 -      if (id >= 0)
 -      fontname = XCDR (FONTSET_ASCII (FONTSET_FROM_ID (id)));
 -      FONTSET_ASCII (Vdefault_fontset)
 -      = Fcons (make_number (0), fontname);
 +  for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail))
 +    {
 +      elt = XCAR (tail);
 +      if (CONSP (elt)
 +        && STRINGP (XCAR (elt))
 +        && fast_string_match_ignore_case (XCAR (elt), fontname) >= 0
 +        && (SYMBOLP (XCDR (elt))
 +            ? CHARSETP (XCDR (elt))
 +            : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt)))))
 +      return (XCDR (elt));
      }
 +  /* We don't know the encoding of this font.  Let's assume `ascii'.  */
 +  return Qascii;
  }
  
 -\f
 +
  /* Cache data used by fontset_pattern_regexp.  The car part is a
     pattern string containing at least one wild card, the cdr part is
     the corresponding regular expression.  */
@@@ -1283,8 -877,6 +1284,8 @@@ fs_query_fontset (name, name_pattern
    if (name_pattern != 1)
      {
        tem = Frassoc (name, Vfontset_alias_alist);
 +      if (NILP (tem))
 +      tem = Fassoc (name, Vfontset_alias_alist);
        if (CONSP (tem) && STRINGP (XCAR (tem)))
        name = XCAR (tem);
        else if (name_pattern == 0)
@@@ -1344,7 -936,9 +1345,7 @@@ If REGEXPP is non-nil, PATTERN is a reg
    return FONTSET_NAME (fontset);
  }
  
 -/* Return a list of base fontset names matching PATTERN on frame F.
 -   If SIZE is not 0, it is the size (maximum bound width) of fontsets
 -   to be listed.  */
 +/* Return a list of base fontset names matching PATTERN on frame F.  */
  
  Lisp_Object
  list_fontsets (f, pattern, size)
    Lisp_Object frame, regexp, val;
    int id;
  
 -  XSETFRAME (frame, f);
 +  XSETFRAME (frame, f);
 +
 +  regexp = fontset_pattern_regexp (pattern);
 +  val = Qnil;
 +
 +  for (id = 0; id < ASIZE (Vfontset_table); id++)
 +    {
 +      Lisp_Object fontset, name;
 +
 +      fontset = FONTSET_FROM_ID (id);
 +      if (NILP (fontset)
 +        || !BASE_FONTSET_P (fontset)
 +        || !EQ (frame, FONTSET_FRAME (fontset)))
 +      continue;
 +      name = FONTSET_NAME (fontset);
 +
 +      if (STRINGP (regexp)
 +        ? (fast_string_match (regexp, name) < 0)
 +        : strcmp (SDATA (pattern), SDATA (name)))
 +      continue;
 +
 +      val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
 +    }
 +
 +  return val;
 +}
 +
 +
 +/* Free all realized fontsets whose base fontset is BASE.  */
 +
 +static void
 +free_realized_fontsets (base)
 +     Lisp_Object base;
 +{
 +#if 0
 +  int id;
 +
 +  /* For the moment, this doesn't work because free_realized_face
 +     doesn't remove FACE from a cache.  Until we find a solution, we
 +     suppress this code, and simply use Fclear_face_cache even though
 +     that is not efficient.  */
 +  BLOCK_INPUT;
 +  for (id = 0; id < ASIZE (Vfontset_table); id++)
 +    {
 +      Lisp_Object this = AREF (Vfontset_table, id);
 +
 +      if (EQ (FONTSET_BASE (this), base))
 +      {
 +        Lisp_Object tail;
 +
 +        for (tail = FONTSET_FACE_ALIST (this); CONSP (tail);
 +             tail = XCDR (tail))
 +          {
 +            FRAME_PTR f = XFRAME (FONTSET_FRAME (this));
 +            int face_id = XINT (XCDR (XCAR (tail)));
 +            struct face *face = FACE_FROM_ID (f, face_id);
 +
 +            /* Face THIS itself is also freed by the following call.  */
 +            free_realized_face (f, face);
 +          }
 +      }
 +    }
 +  UNBLOCK_INPUT;
 +#else  /* not 0 */
 +  Fclear_face_cache (Qt);
 +#endif /* not 0 */
 +}
 +
 +
 +/* Check validity of NAME as a fontset name and return the
 +   corresponding fontset.  If not valid, signal an error.
 +   If NAME is t, return Vdefault_fontset.  */
 +
 +static Lisp_Object
 +check_fontset_name (name)
 +     Lisp_Object name;
 +{
 +  int id;
 +
 +  if (EQ (name, Qt))
 +    return Vdefault_fontset;
 +
 +  CHECK_STRING (name);
 +  /* First try NAME as literal.  */
 +  id = fs_query_fontset (name, 2);
 +  if (id < 0)
 +    /* For backward compatibility, try again NAME as pattern.  */
 +    id = fs_query_fontset (name, 0);
 +  if (id < 0)
 +    error ("Fontset `%s' does not exist", SDATA (name));
 +  return FONTSET_FROM_ID (id);
 +}
 +
 +static void
 +accumulate_script_ranges (arg, range, val)
 +     Lisp_Object arg, range, val;
 +{
 +  if (EQ (XCAR (arg), val))
 +    {
 +      if (CONSP (range))
 +      XSETCDR (arg, Fcons (Fcons (XCAR (range), XCDR (range)), XCDR (arg)));
 +      else
 +      XSETCDR (arg, Fcons (Fcons (range, range), XCDR (arg)));
 +    }
 +}
 +
 +
 +/* Return an ASCII font name generated from fontset name NAME and
 +   ASCII font specification ASCII_SPEC.  NAME is a string conforming
 +   to XLFD.  ASCII_SPEC is a vector:
 +      [FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY].  */
 +
 +static INLINE Lisp_Object
 +generate_ascii_font_name (name, ascii_spec)
 +     Lisp_Object name, ascii_spec;
 +{
 +  Lisp_Object vec;
 +  int i;
 +
 +  vec = split_font_name_into_vector (name);
 +  for (i = FONT_SPEC_FAMILY_INDEX; i <= FONT_SPEC_ADSTYLE_INDEX; i++)
 +    if (! NILP (AREF (ascii_spec, i)))
 +      ASET (vec, 1 + i, AREF (ascii_spec, i));
 +  if (! NILP (AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX)))
 +    ASET (vec, 12, AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX));
 +  return build_font_name_from_vector (vec);
 +}
 +
 +/* Variables referred in set_fontset_font.  They are set before
 +   map_charset_chars is called in Fset_fontset_font.  */
 +static Lisp_Object font_def_arg, add_arg;
 +static int from_arg, to_arg;
 +
 +/* Callback function for map_charset_chars in Fset_fontset_font.  In
 +   FONTSET, set font_def_arg in a fashion specified by add_arg for
 +   characters in RANGE while ignoring the range between from_arg and
 +   to_arg.  */
 +
 +static void
 +set_fontset_font (fontset, range)
 +     Lisp_Object fontset, range;
 +{
 +  if (from_arg < to_arg)
 +    {
 +      int from = XINT (XCAR (range)), to = XINT (XCDR (range));
 +
 +      if (from < from_arg)
 +      {
 +        if (to > to_arg)
 +          {
 +            Lisp_Object range2;
 +
 +            range2 = Fcons (make_number (to_arg), XCDR (range));
 +            FONTSET_ADD (fontset, range, font_def_arg, add_arg);
 +            to = to_arg;
 +          }
 +        if (to > from_arg)
 +          range = Fcons (XCAR (range), make_number (from_arg));
 +      }
 +      else if (to <= to_arg)
 +      return;
 +      else
 +      {
 +        if (from < to_arg)
 +          range = Fcons (make_number (to_arg), XCDR (range));
 +      }
 +    }
 +  FONTSET_ADD (fontset, range, font_def_arg, add_arg);
 +}
 +
  
 -  regexp = fontset_pattern_regexp (pattern);
 -  val = Qnil;
 +DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0,
 +       doc: /*
 +Modify fontset NAME to use FONT-SPEC for TARGET characters.
  
 -  for (id = 0; id < ASIZE (Vfontset_table); id++)
 -    {
 -      Lisp_Object fontset, name;
 +TARGET may be a cons; (FROM . TO), where FROM and TO are characters.
 +In that case, use FONT-SPEC for all characters in the range FROM and
 +TO (inclusive).
  
 -      fontset = FONTSET_FROM_ID (id);
 -      if (NILP (fontset)
 -        || !BASE_FONTSET_P (fontset)
 -        || !EQ (frame, FONTSET_FRAME (fontset)))
 -      continue;
 -      name = FONTSET_NAME (fontset);
 +TARGET may be a script name symbol.  In that case, use FONT-SPEC for
 +all characters that belong to the script.
  
 -      if (!NILP (regexp)
 -        ? (fast_string_match (regexp, name) < 0)
 -        : strcmp (SDATA (pattern), SDATA (name)))
 -      continue;
 +TARGET may be a charset.  In that case, use FONT-SPEC for all
 +characters in the charset.
  
 -      if (size)
 -      {
 -        struct font_info *fontp;
 -        fontp = FS_LOAD_FONT (f, 0, NULL, id);
 -        if (!fontp || size != fontp->size)
 -          continue;
 -      }
 -      val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
 -    }
 +TARGET may be nil.  In that case, use FONT-SPEC for any characters for
 +that no FONT-SPEC is specified.
  
 -  return val;
 -}
 +FONT-SPEC may one of these:
 + * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
 +   REGISTRY is a font registry name.  FAMILY may contains foundry
 +   name, and REGISTRY may contains encoding name.
 + * A font name string.
  
 -DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
 -       doc: /* Create a new fontset NAME that contains font information in FONTLIST.
 -FONTLIST is an alist of charsets vs corresponding font name patterns.  */)
 -     (name, fontlist)
 -     Lisp_Object name, fontlist;
 +Optional 4th argument FRAME, if non-nil, is a frame.  This argument is
 +kept for backward compatibility and has no meaning.
 +
 +Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC
 +to the font specifications for TARGET previously set.  If it is
 +`prepend', FONT-SPEC is prepended.  If it is `append', FONT-SPEC is
 +appended.  By default, FONT-SPEC overrides the previous settings.  */)
 +     (name, target, font_spec, frame, add)
 +     Lisp_Object name, target, font_spec, frame, add;
  {
 -  Lisp_Object fontset, elements, ascii_font;
 -  Lisp_Object tem, tail, elt;
 -  int id;
 +  Lisp_Object fontset;
 +  Lisp_Object font_def, registry, family;
 +  Lisp_Object encoding, repertory;
 +  Lisp_Object range_list;
 +  struct charset *charset = NULL;
  
 -  (*check_window_system_func) ();
 +  fontset = check_fontset_name (name);
  
 -  CHECK_STRING (name);
 -  CHECK_LIST (fontlist);
 +  /* The arg FRAME is kept for backward compatibility.  We only check
 +     the validity.  */
 +  if (!NILP (frame))
 +    CHECK_LIVE_FRAME (frame);
  
 -  name = Fdowncase (name);
 -  id = fs_query_fontset (name, 2);
 -  if (id >= 0)
 +  if (VECTORP (font_spec))
      {
 -      fontset = FONTSET_FROM_ID (id);
 -      tem = FONTSET_NAME (fontset);
 -      error ("Fontset `%s' matches the existing fontset `%s'",
 -           SDATA (name),  SDATA (tem));
 +      /* FONT_SPEC should have this form:
 +              [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ]
 +       This is a feature not yet documented because WEIGHT thru
 +       ADSTYLE are ignored for the moment.  */
 +      int j;
 +
 +      if (ASIZE (font_spec) != FONT_SPEC_MAX_INDEX)
 +      args_out_of_range (make_number (FONT_SPEC_MAX_INDEX),
 +                         make_number (ASIZE (font_spec)));
 +
 +      font_spec = Fcopy_sequence (font_spec);
 +      for (j = 0; j < FONT_SPEC_MAX_INDEX - 1; j++)
 +      if (! NILP (AREF (font_spec, j)))
 +        {
 +          CHECK_STRING (AREF (font_spec, j));
 +          ASET (font_spec, j, Fdowncase (AREF (font_spec, j)));
 +        }
 +      family = AREF (font_spec, FONT_SPEC_FAMILY_INDEX);
 +      /* REGISTRY should not be omitted.  */
 +      CHECK_STRING (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX));
 +      registry = AREF (font_spec, FONT_SPEC_REGISTRY_INDEX);
      }
 +  else if (CONSP (font_spec))
 +    {
 +      family = XCAR (font_spec);
 +      registry = XCDR (font_spec);
  
 -  /* Check the validity of FONTLIST while creating a template for
 -     fontset elements.  */
 -  elements = ascii_font = Qnil;
 -  for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
 +      if (! NILP (family))
 +      {
 +        CHECK_STRING (family);
 +        family = Fdowncase (family);
 +      }
 +      CHECK_STRING (registry);
 +      registry = Fdowncase (registry);
 +      font_spec = Fmake_vector (make_number (FONT_SPEC_MAX_INDEX), Qnil);
 +      ASET (font_spec, FONT_SPEC_FAMILY_INDEX, family);
 +      ASET (font_spec, FONT_SPEC_REGISTRY_INDEX, registry);
 +    }
 +  else
      {
 -      int c, charset;
 +      CHECK_STRING (font_spec);
 +      font_spec = Fdowncase (font_spec);
 +    }
  
 -      tem = XCAR (tail);
 -      if (!CONSP (tem)
 -        || (charset = get_charset_id (XCAR (tem))) < 0
 -        || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
 -      error ("Elements of fontlist must be a cons of charset and font name pattern");
 +  if (STRINGP (font_spec))
 +    encoding = find_font_encoding (font_spec);
 +  else
 +    encoding = find_font_encoding (concat2 (family, registry));
 +  if (NILP (encoding))
 +    encoding = Qascii;
  
 -      tem = XCDR (tem);
 -      if (STRINGP (tem))
 -      tem = Fdowncase (tem);
 -      else
 -      tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
 -      if (charset == CHARSET_ASCII)
 -      ascii_font = tem;
 -      else
 +  if (SYMBOLP (encoding))
 +    {
 +      CHECK_CHARSET (encoding);
 +      encoding = repertory = CHARSET_SYMBOL_ID (encoding);
 +    }
 +  else
 +    {
 +      repertory = XCDR (encoding);
 +      encoding = XCAR (encoding);
 +      CHECK_CHARSET (encoding);
 +      encoding = CHARSET_SYMBOL_ID (encoding);
 +      if (! NILP (repertory) && SYMBOLP (repertory))
        {
 -        c = MAKE_CHAR (charset, 0, 0);
 -        elements = Fcons (Fcons (make_number (c), tem), elements);
 +        CHECK_CHARSET (repertory);
 +        repertory = CHARSET_SYMBOL_ID (repertory);
        }
      }
 +  font_def = Fmake_vector (make_number (3), font_spec);
 +  ASET (font_def, 1, encoding);
 +  ASET (font_def, 2, repertory);
  
 -  if (NILP (ascii_font))
 -    error ("No ASCII font in the fontlist");
 +  if (CHARACTERP (target))
 +    range_list = Fcons (Fcons (target, target), Qnil);
 +  else if (CONSP (target))
 +    {
 +      Lisp_Object from, to;
  
 -  fontset = make_fontset (Qnil, name, Qnil);
 -  FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
 -  for (; CONSP (elements); elements = XCDR (elements))
 +      from = Fcar (target);
 +      to = Fcdr (target);
 +      CHECK_CHARACTER (from);
 +      CHECK_CHARACTER (to);
 +      range_list = Fcons (target, Qnil);
 +    }
 +  else if (SYMBOLP (target) && !NILP (target))
      {
 -      elt = XCAR (elements);
 -      tem = XCDR (elt);
 -      if (STRINGP (tem))
 -      tem = font_family_registry (tem, 0);
 -      tem = Fcons (XCAR (elt), tem);
 -      FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
 +      Lisp_Object script_list;
 +      Lisp_Object val;
 +
 +      range_list = Qnil;
 +      script_list = XCHAR_TABLE (Vchar_script_table)->extras[0];
 +      if (! NILP (Fmemq (target, script_list)))
 +      {
 +        val = Fcons (target, Qnil);
 +        map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
 +                        val);
 +        range_list = XCDR (val);
 +        if (EQ (target, Qlatin))
 +          {
 +            if (VECTORP (font_spec))
 +              val = generate_ascii_font_name (FONTSET_NAME (fontset),
 +                                              font_spec);
 +            else
 +              val = font_spec;
 +            FONTSET_ASCII (fontset) = val;
 +          }
 +      }
 +      if (CHARSETP (target))
 +      {
 +        if (EQ (target, Qascii))
 +          {
 +            if (VECTORP (font_spec))
 +              font_spec = generate_ascii_font_name (FONTSET_NAME (fontset),
 +                                                    font_spec);
 +            FONTSET_ASCII (fontset) = font_spec;
 +            range_list = Fcons (Fcons (make_number (0), make_number (127)),
 +                                Qnil);
 +          }
 +        else
 +          {
 +            CHECK_CHARSET_GET_CHARSET (target, charset);
 +          }
 +      }
 +      else if (NILP (range_list))
 +      error ("Invalid script or charset name: %s",
 +             SDATA (SYMBOL_NAME (target)));
      }
 +  else if (NILP (target))
 +    range_list = Fcons (Qnil, Qnil);
 +  else
 +    error ("Invalid target for setting a font");
  
 -  return Qnil;
 -}
  
 +  if (charset)
 +    {
 +      font_def_arg = font_def;
 +      add_arg = add;
 +      if (NILP (range_list))
 +      from_arg = to_arg = 0;
 +      else
 +      from_arg = XINT (XCAR (XCAR (range_list))),
 +        to_arg = XINT (XCDR (XCAR (range_list)));
  
 -/* Clear all elements of FONTSET for multibyte characters.  */
 +      map_charset_chars (set_fontset_font, Qnil, fontset, charset,
 +                       CHARSET_MIN_CODE (charset),
 +                       CHARSET_MAX_CODE (charset));
 +    }
 +  for (; CONSP (range_list); range_list = XCDR (range_list))
 +    FONTSET_ADD (fontset, XCAR (range_list), font_def, add);
  
 -static void
 -clear_fontset_elements (fontset)
 -     Lisp_Object fontset;
 -{
 -  int i;
 +  /* Free all realized fontsets whose base is FONTSET.  This way, the
 +     specified character(s) are surely redisplayed by a correct
 +     font.  */
 +  free_realized_fontsets (fontset);
  
 -  for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
 -    XCHAR_TABLE (fontset)->contents[i] = Qnil;
 +  return Qnil;
  }
  
  
 -/* Check validity of NAME as a fontset name and return the
 -   corresponding fontset.  If not valid, signal an error.
 -   If NAME is nil, return Vdefault_fontset.  */
 -
 -static Lisp_Object
 -check_fontset_name (name)
 -     Lisp_Object name;
 -{
 -  int id;
 -
 -  if (EQ (name, Qnil))
 -    return Vdefault_fontset;
 +DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
 +       doc: /* Create a new fontset NAME from font information in FONTLIST.
  
 -  CHECK_STRING (name);
 -  /* First try NAME as literal.  */
 -  id = fs_query_fontset (name, 2);
 -  if (id < 0)
 -    /* For backward compatibility, try again NAME as pattern.  */
 -    id = fs_query_fontset (name, 0);
 -  if (id < 0)
 -    error ("Fontset `%s' does not exist", SDATA (name));
 -  return FONTSET_FROM_ID (id);
 -}
 +FONTLIST is an alist of scripts vs the corresponding font specification list.
 +Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where a
 +character of SCRIPT is displayed by a font that matches one of
 +FONT-SPEC.
  
 -/* Downcase FONTNAME or car and cdr of FONTNAME.  If FONTNAME is a
 -   string, maybe change FONTNAME to (FAMILY . REGISTRY).  */
 +SCRIPT is a symbol that appears in the first extra slot of the
 +char-table `char-script-table'.
  
 -static Lisp_Object
 -regularize_fontname (Lisp_Object fontname)
 +FONT-SPEC is a vector, a cons, or a string.  See the documentation of
 +`set-fontset-font' for the meaning.  */)
 +  (name, fontlist)
 +     Lisp_Object name, fontlist;
  {
 -  Lisp_Object family, registry;
 +  Lisp_Object fontset;
 +  Lisp_Object val;
 +  int id;
  
 -  if (STRINGP (fontname))
 -    return font_family_registry (Fdowncase (fontname), 0);
 +  CHECK_STRING (name);
 +  CHECK_LIST (fontlist);
  
 -  CHECK_CONS (fontname);
 -  family = XCAR (fontname);
 -  registry = XCDR (fontname);
 -  if (!NILP (family))
 +  id = fs_query_fontset (name, 0);
 +  if (id < 0)
      {
 -      CHECK_STRING (family);
 -      family = Fdowncase (family);
 +      name = Fdowncase (name);
 +      val = split_font_name_into_vector (name);
 +      if (NILP (val) || NILP (AREF (val, 12)) || NILP (AREF (val, 13)))
 +      error ("Fontset name must be in XLFD format");
 +      if (strcmp (SDATA (AREF (val, 12)), "fontset"))
 +      error ("Registry field of fontset name must be \"fontset\"");
 +      Vfontset_alias_alist
 +      = Fcons (Fcons (name,
 +                      concat2 (concat2 (AREF (val, 12), build_string ("-")),
 +                               AREF (val, 13))),
 +               Vfontset_alias_alist);
 +      ASET (val, 12, build_string ("iso8859-1"));
 +      fontset = make_fontset (Qnil, name, Qnil);
 +      FONTSET_ASCII (fontset) = build_font_name_from_vector (val);
      }
 -  if (!NILP (registry))
 +  else
      {
 -      CHECK_STRING (registry);
 -      registry = Fdowncase (registry);
 +      fontset = FONTSET_FROM_ID (id);;
 +      free_realized_fontsets (fontset);
 +      Fset_char_table_range (fontset, Qt, Qnil);
 +    }
 +
 +  for (; ! NILP (fontlist); fontlist = Fcdr (fontlist))
 +    {
 +      Lisp_Object elt, script;
 +
 +      elt = Fcar (fontlist);
 +      script = Fcar (elt);
 +      elt = Fcdr (elt);
 +      if (CONSP (elt) && (NILP (XCDR (elt)) || CONSP (XCDR (elt))))
 +      for (; CONSP (elt); elt = XCDR (elt))
 +        Fset_fontset_font (name, script, XCAR (elt), Qnil, Qappend);
 +      else
 +      Fset_fontset_font (name, script, elt, Qnil, Qappend);
      }
 -  return Fcons (family, registry);
 +  return name;
  }
  
 -DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
 -       doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
  
 -If NAME is nil, modify the default fontset.
 -CHARACTER may be a cons; (FROM . TO), where FROM and TO are
 -non-generic characters.  In that case, use FONTNAME
 -for all characters in the range FROM and TO (inclusive).
 -CHARACTER may be a charset.  In that case, use FONTNAME
 -for all character in the charsets.
 +/* Alist of automatically created fontsets.  Each element is a cons
 +   (FONTNAME . FONTSET-ID).  */
 +static Lisp_Object auto_fontset_alist;
  
 -FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
 -name of a font, REGISTRY is a registry name of a font.  */)
 -     (name, character, fontname, frame)
 -     Lisp_Object name, character, fontname, frame;
 +int
 +new_fontset_from_font_name (Lisp_Object fontname)
  {
 -  Lisp_Object fontset, elt;
 -  Lisp_Object realized;
 -  int from, to;
 +  Lisp_Object val;
 +  Lisp_Object name;
 +  Lisp_Object vec;
    int id;
  
 -  fontset = check_fontset_name (name);
 +  fontname = Fdowncase (fontname);
 +  val = Fassoc (fontname, auto_fontset_alist);
 +  if (CONSP (val))
 +    return XINT (XCDR (val));
  
 -  if (CONSP (character))
 +  vec = split_font_name_into_vector (fontname);
 +  if ( NILP (vec))
 +    vec = Fmake_vector (make_number (14), build_string (""));
 +  ASET (vec, 12, build_string ("fontset"));
 +  if (NILP (auto_fontset_alist))
      {
 -      /* CH should be (FROM . TO) where FROM and TO are non-generic
 -       characters.  */
 -      CHECK_NUMBER_CAR (character);
 -      CHECK_NUMBER_CDR (character);
 -      from = XINT (XCAR (character));
 -      to = XINT (XCDR (character));
 -      if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
 -      error ("Character range should be by non-generic characters");
 -      if (!NILP (name)
 -        && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
 -      error ("Can't change font for a single byte character");
 +      ASET (vec, 13, build_string ("startup"));
 +      name = build_font_name_from_vector (vec);
      }
 -  else if (SYMBOLP (character))
 +  else
      {
 -      elt = Fget (character, Qcharset);
 -      if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
 -      error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
 -      from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
 -      to = from;
 +      char temp[20];
 +      int len = XINT (Flength (auto_fontset_alist));
 +
 +      sprintf (temp, "auto%d", len);
 +      ASET (vec, 13, build_string (temp));
 +      name = build_font_name_from_vector (vec);
      }
 +  name = Fnew_fontset (name, list2 (list2 (Qascii, fontname),
 +                                  list2 (Fcons (make_number (0),
 +                                                make_number (MAX_CHAR)),
 +                                         fontname)));
 +  id = fs_query_fontset (name, 0);
 +  auto_fontset_alist
 +    = Fcons (Fcons (fontname, make_number (id)), auto_fontset_alist);
 +  return id;
 +}
 +
 +#ifdef USE_FONT_BACKEND
 +int
 +new_fontset_from_font (font_object)
 +     Lisp_Object font_object;
 +{
 +  Lisp_Object font_name = font_get_name (font_object);
 +  Lisp_Object font_spec = font_get_spec (font_object);
 +  Lisp_Object short_name, name, fontset;
 +
 +  if (NILP (auto_fontset_alist))
 +    short_name = build_string ("fontset-startup");
    else
      {
 -      CHECK_NUMBER (character);
 -      from = XINT (character);
 -      to = from;
 +      char temp[32];
 +      int len = XINT (Flength (auto_fontset_alist));
 +
 +      sprintf (temp, "fontset-auto%d", len);
 +      short_name = build_string (temp);
      }
 -  if (!char_valid_p (from, 1))
 -    invalid_character (from);
 -  if (SINGLE_BYTE_CHAR_P (from))
 -    error ("Can't change font for a single byte character");
 -  if (from < to)
 +  ASET (font_spec, FONT_REGISTRY_INDEX, short_name);
 +  name = Ffont_xlfd_name (font_spec);
 +  if (NILP (name))
      {
 -      if (!char_valid_p (to, 1))
 -      invalid_character (to);
 -      if (SINGLE_BYTE_CHAR_P (to))
 -      error ("Can't change font for a single byte character");
 -    }
 +      int i;
  
 -  /* The arg FRAME is kept for backward compatibility.  We only check
 -     the validity.  */
 -  if (!NILP (frame))
 -    CHECK_LIVE_FRAME (frame);
 +      for (i = 0; i < FONT_SIZE_INDEX; i++)
 +      if ((i != FONT_FAMILY_INDEX) && (i != FONT_REGISTRY_INDEX))
 +        ASET (font_spec, i, Qnil);
 +      name = Ffont_xlfd_name (font_spec);
 +      if (NILP (name))
 +      abort ();
 +    }
 +  fontset = make_fontset (Qnil, name, Qnil);
 +  FONTSET_ASCII (fontset) = font_name;
 +  return XINT (FONTSET_ID (fontset));
 +}
  
 -  elt = Fcons (make_number (from), regularize_fontname (fontname));
 -  for (; from <= to; from++)
 -    FONTSET_SET (fontset, from, elt);
 -  Foptimize_char_table (fontset);
 +struct font *
 +fontset_ascii_font (f, id)
 +     FRAME_PTR f;
 +     int id;
 +{
 +  Lisp_Object fontset = FONTSET_FROM_ID (id);
 +  Lisp_Object ascii_slot = FONTSET_ASCII (fontset);
 +  Lisp_Object val, font_object;
  
 -  /* If there's a realized fontset REALIZED whose parent is FONTSET,
 -     clear all the elements of REALIZED and free all multibyte faces
 -     whose fontset is REALIZED.  This way, the specified character(s)
 -     are surely redisplayed by a correct font.  */
 -  for (id = 0; id < ASIZE (Vfontset_table); id++)
 +  if (CONSP (ascii_slot))
      {
 -      realized = AREF (Vfontset_table, id);
 -      if (!NILP (realized)
 -        && !BASE_FONTSET_P (realized)
 -        && EQ (FONTSET_BASE (realized), fontset))
 +      Lisp_Object ascii_font_name = XCAR (ascii_slot);
 +
 +      font_object = Qnil;
 +      for (val = XCDR (ascii_slot); ! NILP (val); val = XCDR (val))
 +      {
 +        Lisp_Object frame = font_get_frame (XCAR (val));
 +
 +        if (NILP (frame) || XFRAME (frame) == f)
 +          {
 +            font_object = XCAR (val);
 +            if (XSAVE_VALUE (font_object)->integer == 0)
 +              {
 +                font_object = font_open_by_name (f, SDATA (ascii_font_name));
 +                XSETCAR (val, font_object);
 +              }
 +            break;
 +          }
 +      }
 +      if (NILP (font_object))
        {
 -        FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
 -        clear_fontset_elements (realized);
 -        free_realized_multibyte_face (f, id);
 +        font_object = font_open_by_name (f, SDATA (ascii_font_name));
 +        XSETCDR (ascii_slot, Fcons (font_object, XCDR (ascii_slot)));
        }
      }
 -
 -  return Qnil;
 +  else
 +    {
 +      font_object = font_open_by_name (f, SDATA (ascii_slot));
 +      FONTSET_ASCII (fontset) = Fcons (ascii_slot, Fcons (font_object, Qnil));
 +    }
 +  if (NILP (font_object))
 +    return NULL;
 +  return XSAVE_VALUE (font_object)->pointer;
  }
  
 +#endif        /* USE_FONT_BACKEND */
 +
  DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
         doc: /* Return information about a font named NAME on frame FRAME.
  If FRAME is omitted or nil, use the selected frame.
@@@ -1947,7 -1230,6 +1948,7 @@@ If the named font is not yet loaded, re
    FRAME_PTR f;
    struct font_info *fontp;
    Lisp_Object info;
 +  Lisp_Object font_object;
  
    (*check_window_system_func) ();
  
    if (!query_font_func)
      error ("Font query function is not supported");
  
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      font_object = font_open_by_name (f, SDATA (name));
 +      if (NILP (font_object))
 +      fontp = NULL;
 +      else
 +      fontp = (struct font_info *) XSAVE_VALUE (font_object)->pointer;
 +    }
 +  else
 +#endif        /* USE_FONT_BACKEND */
    fontp = (*query_font_func) (f, SDATA (name));
    if (!fontp)
      return Qnil;
    XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
    XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
  
 +#ifdef USE_FONT_BACKEND
 +  if (! NILP (font_object))
 +    font_close_object (f, font_object);
 +#endif        /* USE_FONT_BACKEND */
    return info;
  }
  
@@@ -2028,24 -1295,20 +2029,24 @@@ DEFUN ("internal-char-font", Finternal_
  {
    int pos, pos_byte, dummy;
    int face_id;
 -  int c, code;
 +  int c;
    struct frame *f;
    struct face *face;
 +  Lisp_Object charset, rfont_def;
 +  int cs_id;
  
    if (NILP (position))
      {
 -      CHECK_NATNUM (ch);
 +      CHECK_CHARACTER (ch);
        c = XINT (ch);
        f = XFRAME (selected_frame);
        face_id = DEFAULT_FACE_ID;
 +      pos = -1;
 +      cs_id = -1;
      }
    else
      {
 -      Lisp_Object window;
 +      Lisp_Object window, charset;
        struct window *w;
  
        CHECK_NUMBER_COERCE_MARKER (position);
        w = XWINDOW (window);
        f = XFRAME (w->frame);
        face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
 +      charset = Fget_char_property (position, Qcharset, Qnil);
 +      if (CHARSETP (charset))
 +      cs_id = XINT (CHARSET_SYMBOL_ID (charset));
 +      else
 +      cs_id = -1;
      }
    if (! CHAR_VALID_P (c, 0))
      return Qnil;
 -  face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
 +  face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil);
    face = FACE_FROM_ID (f, face_id);
 -  if (! face->font || ! face->font_name)
 -    return Qnil;
 -
 -  {
 -    struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
 -    XChar2b char2b;
 -    int c1, c2, charset;
 -
 -    SPLIT_CHAR (c, charset, c1, c2);
 -    if (c2 > 0)
 -      STORE_XCHAR2B (&char2b, c1, c2);
 -    else
 -      STORE_XCHAR2B (&char2b, 0, c1);
 -    rif->encode_char (c, &char2b, fontp, NULL);
 -    code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
 -  }
 -  return Fcons (build_string (face->font_name), make_number (code));
 +  rfont_def = fontset_font (FONTSET_FROM_ID (face->fontset), c, face, cs_id);
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      if (VECTORP (rfont_def) && ! NILP (AREF (rfont_def, 4)))
 +      {
 +        Lisp_Object font_object = AREF (rfont_def, 4);
 +        struct font *font = XSAVE_VALUE (font_object)->pointer;
 +        unsigned code = font->driver->encode_char (font, c);
 +        Lisp_Object fontname = font_get_name (font_object);
 +
 +        if (code == FONT_INVALID_CODE)
 +          return Fcons (fontname, Qnil);
 +        if (code <= MOST_POSITIVE_FIXNUM)
 +          return Fcons (fontname, make_number (code));
 +        return Fcons (fontname, Fcons (make_number (code >> 16),
 +                                       make_number (code & 0xFFFF)));
 +      }
 +      return Qnil;
 +    }
 +#endif        /* USE_FONT_BACKEND */
 +  if (VECTORP (rfont_def) && STRINGP (AREF (rfont_def, 3)))
 +    {
 +      Lisp_Object font_def;
 +      struct font_info *fontp;
 +      struct charset *charset;
 +      XChar2b char2b;
 +      int code;
 +
 +      font_def = AREF (rfont_def, 2);
 +      charset = CHARSET_FROM_ID (XINT (AREF (font_def, 1)));
 +      code = ENCODE_CHAR (charset, c);
 +      if (code == CHARSET_INVALID_CODE (charset))
 +      return (Fcons (AREF (rfont_def, 3), Qnil));
 +      STORE_XCHAR2B (&char2b, ((code >> 8) & 0xFF), (code & 0xFF));
 +      fontp = (*get_font_info_func) (f, XINT (AREF (rfont_def, 1)));
 +      rif->encode_char (c, &char2b, fontp, charset, NULL);
 +      code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
 +      return (Fcons (AREF (rfont_def, 3), make_number (code)));
 +    }
 +  return Qnil;
  }
  
  
 -/* Called from Ffontset_info via map_char_table on each leaf of
 -   fontset.  ARG is a copy of the default fontset.  The current leaf
 -   is indexed by CHARACTER and has value ELT.  This function override
 -   the copy by ELT if ELT is not nil.  */
 -
 -static void
 -override_font_info (fontset, character, elt)
 -     Lisp_Object fontset, character, elt;
 -{
 -  if (! NILP (elt))
 -    Faset (fontset, character, elt);
 -}
 +DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
 +       doc: /* Return information about a fontset FONTSET on frame FRAME.
 +The value is a char-table of which elements has this form.
  
 -/* Called from Ffontset_info via map_char_table on each leaf of
 -   fontset.  ARG is a list (LAST FONT-INFO ...), where LAST is `(last
 -   ARG)' and FONT-INFOs have this form:
 -      (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
 -   The current leaf is indexed by CHARACTER and has value ELT.  This
 -   function add the information of the current leaf to ARG by
 -   appending a new element or modifying the last element.  */
 +    ((FONT-PATTERN OPENED-FONT ...) ...)
  
 -static void
 -accumulate_font_info (arg, character, elt)
 -     Lisp_Object arg, character, elt;
 -{
 -  Lisp_Object last, last_char, last_elt;
 +FONT-PATTERN is a vector:
  
 -  if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
 -    elt = FONTSET_REF (Vdefault_fontset, XINT (character));
 -  if (!CONSP (elt))
 -    return;
 -  last = XCAR (arg);
 -  last_char = XCAR (XCAR (last));
 -  last_elt = XCAR (XCDR (XCAR (last)));
 -  elt = XCDR (elt);
 -  if (!NILP (Fequal (elt, last_elt)))
 -    {
 -      int this_charset = CHAR_CHARSET (XINT (character));
 +      [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
  
 -      if (CONSP (last_char))  /* LAST_CHAR == (FROM . TO)  */
 -      {
 -        if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
 -          {
 -            XSETCDR (last_char, character);
 -            return;
 -          }
 -      }
 -      else if (XINT (last_char) == XINT (character))
 -      return;
 -      else if (this_charset == CHAR_CHARSET (XINT (last_char)))
 -      {
 -        XSETCAR (XCAR (last), Fcons (last_char, character));
 -        return;
 -      }
 -    }
 -  XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
 -  XSETCAR (arg, XCDR (last));
 -}
 +or a string of font name pattern.
  
 +OPENED-FONT is a name of a font actually opened.
  
 -DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
 -       doc: /* Return information about a fontset named NAME on frame FRAME.
 -If NAME is nil, return information about the default fontset.
 -The value is a vector:
 -  [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
 -where,
 -  SIZE is the maximum bound width of ASCII font in the fontset,
 -  HEIGHT is the maximum bound height of ASCII font in the fontset,
 -  CHARSET-OR-RANGE is a charset, a character (may be a generic character)
 -    or a cons of two characters specifying the range of characters.
 -  FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
 -    where FAMILY is a `FAMILY' field of a XLFD font name,
 -    REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
 -    FAMILY may contain a `FOUNDRY' field at the head.
 -    REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
 -  OPENEDs are names of fonts actually opened.
 -If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
 -If FRAME is omitted, it defaults to the currently selected frame.  */)
 -     (name, frame)
 -     Lisp_Object name, frame;
 +The char-table has one extra slot.  The value is a char-table
 +containing the information about the derived fonts from the default
 +fontset.  The format is the same as abobe.  */)
 +     (fontset, frame)
 +     Lisp_Object fontset, frame;
  {
 -  Lisp_Object fontset;
    FRAME_PTR f;
 -  Lisp_Object indices[3];
 -  Lisp_Object val, tail, elt;
 -  Lisp_Object *realized;
 -  struct font_info *fontp = NULL;
 -  int n_realized = 0;
 -  int i;
 +  Lisp_Object *realized[2], fontsets[2], tables[2];
 +  Lisp_Object val, elt;
 +  int c, i, j, k;
  
    (*check_window_system_func) ();
  
 -  fontset = check_fontset_name (name);
 +  fontset = check_fontset_name (fontset);
  
    if (NILP (frame))
      frame = selected_frame;
    CHECK_LIVE_FRAME (frame);
    f = XFRAME (frame);
  
 -  /* Recode realized fontsets whose base is FONTSET in the table
 -     `realized'.  */
 -  realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
 -                                   * ASIZE (Vfontset_table));
 -  for (i = 0; i < ASIZE (Vfontset_table); i++)
 +  /* Recode fontsets realized on FRAME from the base fontset FONTSET
 +     in the table `realized'.  */
 +  realized[0] = (Lisp_Object *) alloca (sizeof (Lisp_Object)
 +                                      * ASIZE (Vfontset_table));
 +  for (i = j = 0; i < ASIZE (Vfontset_table); i++)
      {
        elt = FONTSET_FROM_ID (i);
        if (!NILP (elt)
 -        && EQ (FONTSET_BASE (elt), fontset))
 -      realized[n_realized++] = elt;
 +        && EQ (FONTSET_BASE (elt), fontset)
 +        && EQ (FONTSET_FRAME (elt), frame))
 +      realized[0][j++] = elt;
      }
 +  realized[0][j] = Qnil;
  
 -  if (! EQ (fontset, Vdefault_fontset))
 +  realized[1] = (Lisp_Object *) alloca (sizeof (Lisp_Object)
 +                                      * ASIZE (Vfontset_table));
 +  for (i = j = 0; ! NILP (realized[0][i]); i++)
      {
 -      /* Merge FONTSET onto the default fontset.  */
 -      val = Fcopy_sequence (Vdefault_fontset);
 -      map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
 -      fontset = val;
 +      elt = FONTSET_DEFAULT (realized[0][i]);
 +      if (! NILP (elt))
 +      realized[1][j++] = elt;
      }
 +  realized[1][j] = Qnil;
  
 -  /* Accumulate information of the fontset in VAL.  The format is
 -     (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
 -     FONT-SPEC).  See the comment for accumulate_font_info for the
 -     detail.  */
 -  val = Fcons (Fcons (make_number (0),
 -                    Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
 -             Qnil);
 -  val = Fcons (val, val);
 -  map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
 -  val = XCDR (val);
 -
 -  /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
 -     character for a charset, replace it with the charset symbol.  If
 -     fonts are opened for FONT-SPEC, append the names of the fonts to
 -     FONT-SPEC.  */
 -  for (tail = val; CONSP (tail); tail = XCDR (tail))
 +  tables[0] = Fmake_char_table (Qfontset_info, Qnil);
 +  tables[1] = Fmake_char_table (Qnil, Qnil);
 +  XCHAR_TABLE (tables[0])->extras[0] = tables[1];
 +  fontsets[0] = fontset;
 +  fontsets[1] = Vdefault_fontset;
 +
 +  /* Accumulate information of the fontset in TABLE.  The format of
 +     each element is ((FONT-SPEC OPENED-FONT ...) ...).  */
 +  for (k = 0; k <= 1; k++)
      {
 -      int c;
 -      elt = XCAR (tail);
 -      if (INTEGERP (XCAR (elt)))
 +      for (c = 0; c <= MAX_CHAR; )
        {
 -        int charset, c1, c2;
 -        c = XINT (XCAR (elt));
 -        SPLIT_CHAR (c, charset, c1, c2);
 -        if (c1 == 0)
 -          XSETCAR (elt, CHARSET_SYMBOL (charset));
 -      }
 -      else
 -      c = XINT (XCAR (XCAR (elt)));
 -      for (i = 0; i < n_realized; i++)
 -      {
 -        Lisp_Object face_id, font;
 -        struct face *face;
 +        int from, to;
  
 -        face_id = FONTSET_REF_VIA_BASE (realized[i], c);
 -        if (INTEGERP (face_id))
 +        if (c <= MAX_5_BYTE_CHAR)
 +          {
 +            val = char_table_ref_and_range (fontsets[k], c, &from, &to);
 +            if (to > MAX_5_BYTE_CHAR)
 +              to = MAX_5_BYTE_CHAR;
 +          }
 +        else
 +          {
 +            val = FONTSET_FALLBACK (fontsets[k]);
 +            to = MAX_CHAR;
 +          }
 +        if (VECTORP (val))
            {
 -            face = FACE_FROM_ID (f, XINT (face_id));
 -            if (face && face->font && face->font_name)
 +            Lisp_Object alist;
 +
 +            /* At first, set ALIST to ((FONT-SPEC) ...).  */
 +            for (alist = Qnil, i = 0; i < ASIZE (val); i++)
 +              alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist);
 +            alist = Fnreverse (alist);
 +
 +            /* Then store opend font names to cdr of each elements.  */
 +            for (i = 0; ! NILP (realized[k][i]); i++)
                {
 -                font = build_string (face->font_name);
 -                if (NILP (Fmember (font, XCDR (XCDR (elt)))))
 -                  XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
 +                if (c <= MAX_5_BYTE_CHAR)
 +                  val = FONTSET_REF (realized[k][i], c);
 +                else
 +                  val = FONTSET_FALLBACK (realized[k][i]);
 +                if (! VECTORP (val))
 +                  continue;
 +                /* VAL is [int int ?
 +                           [FACE-ID FONT-INDEX FONT-DEF FONT-NAME] ...].
 +                   If a font of an element is already opened,
 +                   FONT-NAME is the name of a opened font.  */
 +                for (j = 3; j < ASIZE (val); j++)
 +                  if (STRINGP (AREF (AREF (val, j), 3)))
 +                    {
 +                      Lisp_Object font_idx;
 +
 +                      font_idx = AREF (AREF (val, j), 1);
 +                      elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), alist);
 +                      if (CONSP (elt)
 +                          && NILP (Fmemq (font_idx, XCDR(elt))))
 +                        nconc2 (elt, Fcons (font_idx, Qnil));
 +                    }
                }
 +            for (val = alist; CONSP (val); val = XCDR (val))
 +              for (elt = XCDR (XCAR (val)); CONSP (elt); elt = XCDR (elt))
 +                {
 +                  struct font_info *font_info
 +                    = (*get_font_info_func) (f, XINT (XCAR (elt)));
 +                  XSETCAR (elt, build_string (font_info->full_name));
 +                }
 +
 +            /* Store ALIST in TBL for characters C..TO.  */
 +            if (c <= MAX_5_BYTE_CHAR)
 +              char_table_set_range (tables[k], c, to, alist);
 +            else
 +              XCHAR_TABLE (tables[k])->defalt = alist;
            }
 +        c = to + 1;
        }
      }
  
 -  elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
 -  if (CONSP (elt))
 -    {
 -      elt = XCAR (elt);
 -      fontp = (*query_font_func) (f, SDATA (elt));
 -    }
 -  val = Fmake_vector (make_number (3), val);
 -  AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
 -  AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
 -  return val;
 +  return tables[0];
  }
  
 -DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
 +
 +DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 3, 0,
         doc: /* Return a font name pattern for character CH in fontset NAME.
 -If NAME is nil, find a font name pattern in the default fontset.  */)
 -     (name, ch)
 -     Lisp_Object name, ch;
 +If NAME is t, find a pattern in the default fontset.
 +
 +The value has the form (FAMILY . REGISTRY), where FAMILY is a font
 +family name and REGISTRY is a font registry name.  This is actually
 +the first font name pattern for CH in the fontset or in the default
 +fontset.
 +
 +If the 2nd optional arg ALL is non-nil, return a list of all font name
 +patterns.  */)
 +  (name, ch, all)
 +     Lisp_Object name, ch, all;
  {
    int c;
 -  Lisp_Object fontset, elt;
 +  Lisp_Object fontset, elt, list, repertory, val;
 +  int i, j;
  
    fontset = check_fontset_name (name);
  
 -  CHECK_NUMBER (ch);
 +  CHECK_CHARACTER (ch);
    c = XINT (ch);
 -  if (!char_valid_p (c, 1))
 -    invalid_character (c);
 -
 -  elt = FONTSET_REF (fontset, c);
 -  if (CONSP (elt))
 -    elt = XCDR (elt);
 +  list = Qnil;
 +  while (1)
 +    {
 +      for (i = 0, elt = FONTSET_REF (fontset, c); i < 2;
 +         i++, elt = FONTSET_FALLBACK (fontset))
 +      if (VECTORP (elt))
 +        for (j = 0; j < ASIZE (elt); j++)
 +          {
 +            val = AREF (elt, j);
 +            repertory = AREF (val, 1);
 +            if (INTEGERP (repertory))
 +              {
 +                struct charset *charset = CHARSET_FROM_ID (XINT (repertory));
  
 -  return elt;
 +                if (! CHAR_CHARSET_P (c, charset))
 +                  continue;
 +              }
 +            else if (CHAR_TABLE_P (repertory))
 +              {
 +                if (NILP (CHAR_TABLE_REF (repertory, c)))
 +                  continue;
 +              }
 +            val = AREF (val, 0);
 +            val = Fcons (AREF (val, 0), AREF (val, 5));
 +            if (NILP (all))
 +              return val;
 +            list = Fcons (val, list);
 +          }
 +      if (EQ (fontset, Vdefault_fontset))
 +      break;
 +      fontset = Vdefault_fontset;
 +    }
 +  return (Fnreverse (list));
  }
  
  DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
    return list;
  }
  
 -DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
 -       Sset_overriding_fontspec_internal, 1, 1, 0,
 -       doc: /* Internal use only.
 -
 -FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
 -or a char-table, FONTNAME have the same meanings as in
 -`set-fontset-font'.
  
 -It overrides the font specifications for each TARGET in the default
 -fontset by the corresponding FONTNAME.
 -
 -If TARGET is a charset, targets are all characters in the charset.  If
 -TARGET is a char-table, targets are characters whose value is non-nil
 -in the table.
 +#ifdef FONTSET_DEBUG
  
 -It is intended that this function is called only from
 -`set-language-environment'.  */)
 -     (fontlist)
 -     Lisp_Object fontlist;
 +Lisp_Object
 +dump_fontset (fontset)
 +     Lisp_Object fontset;
  {
 -  Lisp_Object tail;
 +  Lisp_Object vec;
  
 -  fontlist = Fcopy_sequence (fontlist);
 -  /* Now FONTLIST is ((TARGET . FONTNAME) ...).  Reform it to ((TARGET
 -     nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
 -     char-table.  */
 -  for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
 +  vec = Fmake_vector (make_number (3), Qnil);
 +  ASET (vec, 0, FONTSET_ID (fontset));
 +
 +  if (BASE_FONTSET_P (fontset))
 +    {
 +      ASET (vec, 1, FONTSET_NAME (fontset));
 +    }
 +  else
      {
 -      Lisp_Object elt, target;
 +      Lisp_Object frame;
  
 -      elt = XCAR (tail);
 -      target = Fcar (elt);
 -      elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
 -      if (! CHAR_TABLE_P (target))
 +      frame = FONTSET_FRAME (fontset);
 +      if (FRAMEP (frame))
        {
 -        int charset, c;
 -
 -        CHECK_SYMBOL (target);
 -        charset = get_charset_id (target);
 -        if (charset < 0)
 -          error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
 -        target = make_number (charset);
 -        c = MAKE_CHAR (charset, 0, 0);
 -        XSETCAR (elt, make_number (c));
 +        FRAME_PTR f = XFRAME (frame);
 +
 +        if (FRAME_LIVE_P (f))
 +          ASET (vec, 1, f->name);
 +        else
 +          ASET (vec, 1, Qt);
        }
 -      elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
 -      XSETCAR (tail, elt);
 +      if (!NILP (FONTSET_DEFAULT (fontset)))
 +      ASET (vec, 2, FONTSET_ID (FONTSET_DEFAULT (fontset)));
      }
 -  if (! NILP (Fequal (fontlist, Voverriding_fontspec_alist)))
 -    return Qnil;
 -  Voverriding_fontspec_alist = fontlist;
 -  clear_face_cache (0);
 -  ++windows_or_buffers_changed;
 -  return Qnil;
 +  return vec;
 +}
 +
 +DEFUN ("fontset-list-all", Ffontset_list_all, Sfontset_list_all, 0, 0, 0,
 +       doc: /* Return a brief summary of all fontsets for debug use.  */)
 +     ()
 +{
 +  Lisp_Object val;
 +  int i;
 +
 +  for (i = 0, val = Qnil; i < ASIZE (Vfontset_table); i++)
 +    if (! NILP (AREF (Vfontset_table, i)))
 +      val = Fcons (dump_fontset (AREF (Vfontset_table, i)), val);
 +  return (Fnreverse (val));
  }
 +#endif        /* FONTSET_DEBUG */
  
  void
  syms_of_fontset ()
      /* Window system initializer should have set proper functions.  */
      abort ();
  
 -  Qfontset = intern ("fontset");
 -  staticpro (&Qfontset);
 -  Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
 +  DEFSYM (Qfontset, "fontset");
 +  Fput (Qfontset, Qchar_table_extra_slots, make_number (9));
 +  DEFSYM (Qfontset_info, "fontset-info");
 +  Fput (Qfontset_info, Qchar_table_extra_slots, make_number (1));
 +
 +  DEFSYM (Qprepend, "prepend");
 +  DEFSYM (Qappend, "append");
 +  DEFSYM (Qlatin, "latin");
  
    Vcached_fontset_data = Qnil;
    staticpro (&Vcached_fontset_data);
    AREF (Vfontset_table, 0) = Vdefault_fontset;
    next_fontset_id = 1;
  
 -  Voverriding_fontspec_alist = Qnil;
 -  staticpro (&Voverriding_fontspec_alist);
 +  auto_fontset_alist = Qnil;
 +  staticpro (&auto_fontset_alist);
  
    DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
 -             doc: /* Alist of fontname patterns vs corresponding encoding info.
 -Each element looks like (REGEXP . ENCODING-INFO),
 - where ENCODING-INFO is an alist of CHARSET vs ENCODING.
 -ENCODING is one of the following integer values:
 -      0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
 -      1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
 -      2: code points 0x20A0..0x7FFF are used,
 -      3: code points 0xA020..0xFF7F are used.  */);
 +             doc: /*
 +Alist of fontname patterns vs the corresponding encoding and repertory info.
 +Each element looks like (REGEXP . (ENCODING . REPERTORY)),
 +where ENCODING is a charset or a char-table,
 +and REPERTORY is a charset, a char-table, or nil.
 +
 +ENCODING is for converting a character to a glyph code of the font.
 +If ENCODING is a charset, encoding a character by the charset gives
 +the corresponding glyph code.  If ENCODING is a char-table, looking up
 +the table by a character gives the corresponding glyph code.
 +
 +REPERTORY specifies a repertory of characters supported by the font.
 +If REPERTORY is a charset, all characters beloging to the charset are
 +supported.  If REPERTORY is a char-table, all characters who have a
 +non-nil value in the table are supported.  It REPERTORY is nil, Emacs
 +gets the repertory information by an opened font and ENCODING.  */);
    Vfont_encoding_alist = Qnil;
 -  Vfont_encoding_alist
 -    = Fcons (Fcons (build_string ("JISX0201"),
 -                  Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
 -                         Qnil)),
 -           Vfont_encoding_alist);
 -  Vfont_encoding_alist
 -    = Fcons (Fcons (build_string ("ISO8859-1"),
 -                  Fcons (Fcons (intern ("ascii"), make_number (0)),
 -                         Qnil)),
 -           Vfont_encoding_alist);
  
    DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
 -             doc: /* Char table of characters whose ascent values should be ignored.
 +             doc: /*
 +Char table of characters whose ascent values should be ignored.
  If an entry for a character is non-nil, the ascent value of the glyph
  is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
  
@@@ -2448,8 -1690,7 +2449,8 @@@ such a character is displayed on screen
    Vuse_default_ascent = Qnil;
  
    DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
 -             doc: /* Char table of characters which is not composed relatively.
 +             doc: /*
 +Char table of characters which is not composed relatively.
  If an entry for a character is non-nil, a composition sequence
  which contains that character is displayed so that
  the glyph of that character is put without considering
@@@ -2475,10 -1716,6 +2476,10 @@@ When a character is displayed with suc
  at the vertical center of lines.  */);
    Vvertical_centering_font_regexp = Qnil;
  
 +  DEFVAR_LISP ("otf-script-alist", &Votf_script_alist,
 +             doc: /* Alist of OpenType script tags vs the corresponding script names.  */);
 +  Votf_script_alist = Qnil;
 +
    defsubr (&Squery_fontset);
    defsubr (&Snew_fontset);
    defsubr (&Sset_fontset_font);
    defsubr (&Sfontset_info);
    defsubr (&Sfontset_font);
    defsubr (&Sfontset_list);
 -  defsubr (&Sset_overriding_fontspec_internal);
 +#ifdef FONTSET_DEBUG
 +  defsubr (&Sfontset_list_all);
 +#endif
  }
  
  /* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
diff --combined src/fontset.h
index b86c26784c74f63a112561d0f450b2afb3aea56a,a2bac100396ed69b8f2b34fc1855820e1b5dfd5e..506b34a4dc74651cfa019adc0ea592330448551d
@@@ -1,13 -1,10 +1,13 @@@
  /* Header for fontset handler.
-    Copyright (C) 1998, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+    Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005,
+                  2006, 2007  Free Software Foundation, Inc.
     Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-      2005, 2006
+      2005, 2006, 2007
       National Institute of Advanced Industrial Science and Technology (AIST)
       Registration Number H14PRO021
 +   Copyright (C) 2003, 2006
 +     National Institute of Advanced Industrial Science and Technology (AIST)
 +     Registration Number H13PRO009
  
  This file is part of GNU Emacs.
  
@@@ -47,8 -44,7 +47,8 @@@ struct font_inf
    /* Full name of the font given by a window system.  */
    char *full_name;
  
 -  /* Charset of characters displayed by the font.  */
 +  /* Charset to encode a character code into a glyph code of the
 +     font.  */
    int charset;
  
  #ifdef WINDOWSNT
       of lines.  */
    int vertical_centering;
  
 -  /* Encodings of the font indexed by CHARSET.  The value is one of
 +  /* Encoding type of the font.  The value is one of
       0, 1, 2, or 3:
        0: code points 0x20..0x7F or 0x2020..0x7F7F are used
        1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used
        2: code points 0x20A0..0x7FFF are used
        3: code points 0xA020..0xFF7F are used
 -     For instance, ASCII and Latin-1 characters may use the same font
 -     but different code points (ASCII uses 0x20..0x7F and Latin-1 uses
 -     0xA0..0xFF).
 -
 -     If the value can't be decided from information of the font, we
 -     consult `font-encoding-alist' to get of the corresponding charset
 -     whose default value is defined in lisp/fontset.el.  Since there's
 -     no charset whose id is 1, we use encoding[1] to store the
 -     encoding information decided by the font itself.
 -
       If the member `font_encoder' is not NULL, this member is ignored.
    */
 -  unsigned char encoding[MAX_CHARSET + 1];
 +  unsigned char encoding_type;
  
    /* The baseline position of a font is normally `ascent' value of the
       font.  However, there exists many fonts which don't set `ascent'
     to be used.  */
  #define FONT_ENCODING_NOT_DECIDED 255
  
 +enum FONT_SPEC_INDEX
 +  {
 +    FONT_SPEC_FAMILY_INDEX,
 +    FONT_SPEC_WEIGHT_INDEX,
 +    FONT_SPEC_SLANT_INDEX,
 +    FONT_SPEC_SWIDTH_INDEX,
 +    FONT_SPEC_ADSTYLE_INDEX,
 +    FONT_SPEC_REGISTRY_INDEX,
 +    FONT_SPEC_MAX_INDEX
 +  };
 +
  /* Forward declaration for prototypes.  */
  struct frame;
  
@@@ -193,41 -188,43 +193,41 @@@ extern void (*set_frame_fontset_func) P
     This function set the memer `encoder' of the structure.  */
  extern void (*find_ccl_program_func) P_ ((struct font_info *));
  
 +extern Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
 +                                                 struct font_info *));
 +
  /* Check if any window system is used now.  */
  extern void (*check_window_system_func) P_ ((void));
  
  struct face;
  
  extern void free_face_fontset P_ ((FRAME_PTR, struct face *));
 -extern Lisp_Object fontset_font_pattern P_ ((FRAME_PTR, int, int));
 +extern Lisp_Object fontset_font_pattern P_ ((FRAME_PTR, struct face *, int));
  extern int face_suitable_for_char_p P_ ((struct face *, int));
 -extern int face_for_char P_ ((FRAME_PTR, struct face *, int));
 -extern int make_fontset_for_ascii_face P_ ((FRAME_PTR, int));
 +extern int face_for_char P_ ((FRAME_PTR, struct face *, int,
 +                            int, Lisp_Object));
 +extern int make_fontset_for_ascii_face P_ ((FRAME_PTR, int, struct face *));
 +extern int new_fontset_from_font_name P_ ((Lisp_Object));
  extern void set_default_ascii_font P_ ((Lisp_Object));
 -extern struct font_info *fs_load_font P_ ((struct frame *, int, char *, int,
 -                                         struct face *));
 +extern struct font_info *fs_load_font P_ ((struct frame *, char *, int));
  extern int fs_query_fontset P_ ((Lisp_Object, int));
  EXFUN (Fquery_fontset, 2);
  extern Lisp_Object list_fontsets P_ ((struct frame *, Lisp_Object, int));
  
 -extern Lisp_Object Qfontset;
  extern Lisp_Object Vuse_default_ascent;
  extern Lisp_Object Vignore_relative_composition;
  extern Lisp_Object Valternate_fontname_alist;
  extern Lisp_Object Vfontset_alias_alist;
  extern Lisp_Object Vvertical_centering_font_regexp;
 +extern Lisp_Object Votf_script_alist;
  
 -/* Load a font named FONTNAME for displaying character C.  All fonts
 -   for frame F is stored in a table pointed by FONT_TABLE.  Return a
 -   pointer to the struct font_info of the loaded font.  If loading
 -   fails, return 0; If FONTNAME is NULL, the name is taken from the
 -   information of FONTSET.  If FONTSET is given, try to load a font
 -   whose size matches that of FONTSET, and, the font index is stored
 -   in the table for FONTSET.  */
 +/* Load a font named FONTNAME on frame F.  All fonts for frame F is
 +   stored in a table pointed by FONT_TABLE.  Return a pointer to the
 +   struct font_info of the loaded font.  If loading fails, return
 +   NULL.  */
  
 -#define FS_LOAD_FONT(f, c, fontname, fontset)  \
 -  fs_load_font (f, c, fontname, fontset, NULL)
 +#define FS_LOAD_FONT(f, fontname) fs_load_font (f, fontname, -1)
  
 -#define FS_LOAD_FACE_FONT(f, c, fontname, face) \
 -  fs_load_font (f, c, fontname, -1, face)
  
  /* Return an immutable id for font_info FONT_INFO on frame F.  The
     reason for this macro is hat one cannot hold pointers to font_info
        ? (FRAME_X_DISPLAY_INFO ((F))->font_table + (ID))                       \
        : 0)
  
 +#ifdef USE_FONT_BACKEND
 +#define FONT_INFO_FROM_FACE(F, FACE)          \
 +  (enable_font_backend ? (FACE)->font_info    \
 +   : FONT_INFO_FROM_ID ((F), (FACE)->font_info_id))
 +#else  /* not USE_FONT_BACKEND */
 +#define FONT_INFO_FROM_FACE(F, FACE)  \
 +  FONT_INFO_FROM_ID ((F), (FACE)->font_info_id)
 +#endif        /* not USE_FONT_BACKEND */
 +
  extern Lisp_Object fontset_name P_ ((int));
  extern Lisp_Object fontset_ascii P_ ((int));
  extern int fontset_height P_ ((int));
  
 +#ifdef USE_FONT_BACKEND
 +struct font;
 +extern int face_for_font P_ ((struct frame *, struct font *, struct face *));
 +extern int new_fontset_from_font P_ ((Lisp_Object));
 +extern struct font *fontset_ascii_font P_ ((FRAME_PTR, int));
 +#endif        /* USE_FONT_BACKEND */
 +
  #endif /* EMACS_FONTSET_H */
  
  /* arch-tag: c27cef7b-3cab-488a-8398-7a4daa96bb77
diff --combined src/frame.c
index 18ed9e02c10185a02a8e82c3bb2c2b60bd0f3195,c4ba9af176b6fdb8587a8265cee6be11a02399ea..171cdcd49f0c7138ac43a9aba633e7cf297657d9
@@@ -1,6 -1,6 +1,6 @@@
  /* Generic frame functions.
-    Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2006,
-                  2004, 2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
+                  2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -23,7 -23,7 +23,7 @@@ Boston, MA 02110-1301, USA.  *
  
  #include <stdio.h>
  #include "lisp.h"
 -#include "charset.h"
 +#include "character.h"
  #ifdef HAVE_X_WINDOWS
  #include "xterm.h"
  #endif
  
  #ifdef HAVE_WINDOW_SYSTEM
  
 +#ifdef USE_FONT_BACKEND
 +#include "font.h"
 +#endif        /* USE_FONT_BACKEND */
 +
  /* The name we're using in resource queries.  Most often "emacs".  */
  
  Lisp_Object Vx_resource_name;
@@@ -112,9 -108,6 +112,9 @@@ Lisp_Object Qbuffer_predicate, Qbuffer_
  Lisp_Object Qtty_color_mode;
  
  Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
 +#ifdef USE_FONT_BACKEND
 +Lisp_Object Qfont_backend;
 +#endif        /* USE_FONT_BACKEND */
  
  Lisp_Object Qinhibit_face_set_after_frame_default;
  Lisp_Object Qface_set_after_frame_default;
@@@ -307,9 -300,6 +307,9 @@@ make_frame (mini_p
  #endif
    f->size_hint_flags = 0;
    f->win_gravity = 0;
 +#ifdef USE_FONT_BACKEND
 +  f->font_driver_list = NULL;
 +#endif        /* USE_FONT_BACKEND */
  
    root_window = make_window ();
    if (mini_p)
@@@ -1955,7 -1945,7 +1955,7 @@@ store_in_alist (alistptr, prop, val
  static int
  frame_name_fnn_p (str, len)
       char *str;
 -     int len;
 +     EMACS_INT len;
  {
    if (len > 1 && str[0] == 'F')
      {
@@@ -2600,9 -2590,6 +2600,9 @@@ static struct frame_parm_table frame_pa
    {"right-fringe",            &Qright_fringe},
    {"wait-for-wm",             &Qwait_for_wm},
    {"fullscreen",                &Qfullscreen},
 +#ifdef USE_FONT_BACKEND
 +  {"font-backend",            &Qfont_backend}
 +#endif        /* USE_FONT_BACKEND */
  };
  
  #ifdef HAVE_WINDOW_SYSTEM
@@@ -3102,60 -3089,20 +3102,60 @@@ x_set_font (f, arg, oldval
    Lisp_Object frame;
    int old_fontset = FRAME_FONTSET(f);
  
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      int fontset = -1;
 +      Lisp_Object font_object;
 +
 +      /* ARG is a fontset name, a font name, or a font object.
 +       In the last case, this function never fail.  */
 +      if (STRINGP (arg))
 +      {
 +        fontset = fs_query_fontset (arg, 0);
 +        if (fontset < 0)
 +          font_object = font_open_by_name (f, SDATA (arg));
 +        else if (fontset > 0)
 +          {
 +            Lisp_Object ascii_font = fontset_ascii (fontset);
 +
 +            font_object = font_open_by_name (f, SDATA (ascii_font));
 +          }
 +      }
 +      else
 +      font_object = arg;
 +
 +      if (fontset < 0 && ! NILP (font_object))
 +      fontset = new_fontset_from_font (font_object);
 +
 +      if (fontset == 0)
 +      /* Refuse the default fontset.  */
 +      result = Qt;
 +      else if (NILP (font_object))
 +      result = Qnil;
 +      else
 +      result = x_new_fontset2 (f, fontset, font_object);
 +    }
 +  else
 +    {
 +#endif        /* USE_FONT_BACKEND */
    CHECK_STRING (arg);
  
    fontset_name = Fquery_fontset (arg, Qnil);
  
    BLOCK_INPUT;
    result = (STRINGP (fontset_name)
 -            ? x_new_fontset (f, SDATA (fontset_name))
 -            : x_new_font (f, SDATA (arg)));
 +            ? x_new_fontset (f, fontset_name)
 +            : x_new_fontset (f, arg));
    UNBLOCK_INPUT;
 +#ifdef USE_FONT_BACKEND
 +    }
 +#endif
  
    if (EQ (result, Qnil))
      error ("Font `%s' is not defined", SDATA (arg));
    else if (EQ (result, Qt))
 -    error ("The characters of the given font have varying widths");
 +    error ("The default fontset can't be used for a frame font");
    else if (STRINGP (result))
      {
        set_default_ascii_font (result);
          if (old_fontset == FRAME_FONTSET (f))
            return;
        }
 -      else if (!NILP (Fequal (result, oldval)))
 +      store_frame_param (f, Qfont, result);
 +
 +      if (!NILP (Fequal (result, oldval)))
          return;
  
        /* Recalculate toolbar height.  */
        /* Ensure we redraw it.  */
        clear_current_matrices (f);
  
 -      store_frame_param (f, Qfont, result);
        recompute_basic_faces (f);
      }
    else
  }
  
  
 +#ifdef USE_FONT_BACKEND
 +void
 +x_set_font_backend (f, new_value, old_value)
 +     struct frame *f;
 +     Lisp_Object new_value, old_value;
 +{
 +  if (! NILP (new_value)
 +      && !CONSP (new_value))
 +    {
 +      char *p0, *p1;
 +      
 +      CHECK_STRING (new_value);
 +      p0 = p1 = SDATA (new_value);
 +      new_value = Qnil;
 +      while (*p0)
 +      {
 +        while (*p1 && *p1 != ',') p1++;
 +        if (p0 < p1)
 +          new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
 +                             new_value);
 +        if (*p1)
 +          p1++;
 +        p0 = p1;
 +      }
 +      new_value = Fnreverse (new_value);
 +    }
 +
 +  if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
 +    return;
 +
 +  if (FRAME_FONT_OBJECT (f))
 +    {
 +      free_all_realized_faces (Qnil);
 +      Fclear_font_cache ();
 +    }
 +
 +  new_value = font_update_drivers (f, new_value);
 +  if (NILP (new_value))
 +    error ("No font backend available");
 +  store_frame_param (f, Qfont_backend, new_value);
 +
 +  if (FRAME_FONT_OBJECT (f))
 +    {
 +      Lisp_Object frame;
 +
 +      XSETFRAME (frame, f);
 +      x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
 +      ++face_change_count;
 +      ++windows_or_buffers_changed;
 +    }
 +}
 +#endif        /* USE_FONT_BACKEND */
 +
 +
  void
  x_set_fringe_width (f, new_value, old_value)
       struct frame *f;
diff --combined src/frame.h
index 9c74a2d777cc40097b00729e042082793474848a,d09a0d1ae04273a267e0d13effcbe1e016fd8995..db60700c5ad07a635e970340cb808245735ccb5c
@@@ -1,6 -1,6 +1,6 @@@
  /* Define frame-object for GNU Emacs.
     Copyright (C) 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -93,10 -93,6 +93,10 @@@ extern struct x_output tty_display
  
  #endif /* ! MSDOS && ! WINDOWSNT && ! MAC_OS */
  
 +#ifdef USE_FONT_BACKEND
 +struct font_driver_list;
 +#endif        /* USE_FONT_BACKEND */
 +
  struct frame
  {
    EMACS_INT size;
    /* Size of the frame window in pixels.  */
    int pixel_height, pixel_width;
  
 +  /* Dots per inch of the screen the frame is on.  */
 +  double resx, resy;
 +
    /* These many pixels are the difference between the outer window (i.e. the
       left and top of the window manager decoration) and FRAME_X_WINDOW. */
    int x_pixels_diff, y_pixels_diff;
    }
    output_data;
  
 +#ifdef USE_FONT_BACKEND
 +  /* List of font-drivers available on the frame. */
 +  struct font_driver_list *font_driver_list;
 +#endif        /* USE_FONT_BACKEND */
 +
    /* Total width of fringes reserved for drawing truncation bitmaps,
       continuation bitmaps and alike.  The width is in canonical char
       units of the frame.  This must currently be the case because window
@@@ -1021,7 -1009,6 +1021,7 @@@ extern Lisp_Object Qscreen_gamma
  extern Lisp_Object Qline_spacing;
  extern Lisp_Object Qwait_for_wm;
  extern Lisp_Object Qfullscreen;
 +extern Lisp_Object Qfont_backend;
  
  extern Lisp_Object Qleft_fringe, Qright_fringe;
  extern Lisp_Object Qheight, Qwidth;
@@@ -1060,10 -1047,8 +1060,10 @@@ extern void x_set_offset P_ ((struct fr
  extern void x_wm_set_icon_position P_ ((struct frame *, int, int));
  
  extern Lisp_Object x_new_font P_ ((struct frame *, char *));
 -extern Lisp_Object x_new_fontset P_ ((struct frame *, char *));
 -
 +extern Lisp_Object x_new_fontset P_ ((struct frame *, Lisp_Object));
 +#ifdef USE_FONT_BACKEND
 +extern Lisp_Object x_new_fontset2 P_ ((struct frame *, int, Lisp_Object));
 +#endif        /* USE_FONT_BACKEND */
  
  /* These are in frame.c  */
  
@@@ -1083,7 -1068,6 +1083,7 @@@ extern void x_set_fullscreen P_ ((struc
  extern void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object));
  extern void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object));
  extern void x_set_font P_ ((struct frame *, Lisp_Object, Lisp_Object));
 +extern void x_set_font_backend P_ ((struct frame *, Lisp_Object, Lisp_Object));
  extern void x_set_fringe_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
  extern void x_set_border_width P_ ((struct frame *, Lisp_Object, Lisp_Object));
  extern void x_set_internal_border_width P_ ((struct frame *, Lisp_Object,
diff --combined src/fringe.c
index a42c2d704394e4e506a232edb769e4b09dd5fdce,a3a28ba987ebfa3301db975c922e01eb513d7e5b..1688f68f231aefbc535e8206596a8e32fc33d2ee
@@@ -1,7 -1,7 +1,7 @@@
  /* Fringe handling (split from xdisp.c).
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
-                  1998, 1999, 2000, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+                  2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -585,7 -585,7 +585,7 @@@ draw_fringe_bitmap_1 (w, row, left_p, o
        Lisp_Object face;
  
        if ((face = fringe_faces[which], NILP (face))
 -        || (face_id = lookup_derived_face (f, face, 'A', FRINGE_FACE_ID, 0),
 +        || (face_id = lookup_derived_face (f, face, FRINGE_FACE_ID, 0),
              face_id < 0))
        face_id = FRINGE_FACE_ID;
      }
@@@ -1554,7 -1554,7 +1554,7 @@@ If FACE is nil, reset face to default f
    if (!NILP (face))
      {
        face_id = lookup_derived_face (SELECTED_FRAME (), face,
 -                                   'A', FRINGE_FACE_ID, 1);
 +                                   FRINGE_FACE_ID, 1);
        if (face_id < 0)
        error ("No such face");
      }
diff --combined src/indent.c
index 368609bad64e48691007b21e2acf90388e0e333e,89d83164560d5c2d73b38a8afb4fefce797cc493..429c2722a1d84d7f5182749089252e7e0351de6e
@@@ -1,6 -1,6 +1,6 @@@
  /* Indentation functions.
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -22,7 -22,7 +22,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <config.h>
  #include "lisp.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "category.h"
  #include "indent.h"
  #include "keyboard.h"
@@@ -288,7 -288,7 +288,7 @@@ check_composition (pos, pos_byte, point
       int *len, *len_byte, *width;
  {
    Lisp_Object prop;
 -  int start, end;
 +  EMACS_INT start, end;
    int id;
  
    if (! find_composition (pos, -1, &start, &end, &prop, Qnil)
        if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))              \
          width = XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;             \
        else                                                            \
 -        width = WIDTH_BY_CHAR_HEAD (*p);                              \
 +        width = CHAR_WIDTH (c);                                       \
        if (width > 1)                                                  \
          wide_column = width;                                          \
        }                                                                       \
@@@ -2074,7 -2074,7 +2074,7 @@@ whether or not it is currently displaye
      {
        int it_start;
        int oselective;
-       int it_overshoot_expected_p;
+       int it_overshoot_expected;
  
        SET_TEXT_POS (pt, PT, PT_BYTE);
        start_display (&it, w, pt);
          while (s < e && *s != '\n')
            ++s;
  
-         it_overshoot_expected_p = (s == e);
+         /* If there is no newline in the string, we need to check
+            whether there is a newline immediately after the string
+            in move_it_to below.  This may happen if there is an
+            overlay with an after-string just before the newline.  */
+         it_overshoot_expected = (s == e) ? -1 : 0;
        }
        else
-       it_overshoot_expected_p = (it.method == GET_FROM_IMAGE
-                                  || it.method == GET_FROM_STRETCH
-                                  || it.method == GET_FROM_COMPOSITION);
+       it_overshoot_expected = (it.method == GET_FROM_IMAGE
+                                || it.method == GET_FROM_STRETCH
+                                || it.method == GET_FROM_COMPOSITION);
  
        reseat_at_previous_visible_line_start (&it);
        it.current_x = it.hpos = 0;
         truncate-lines is on and PT is beyond right margin.
         Don't go back if the overshoot is expected (see above).  */
        if (IT_CHARPOS (it) > it_start && XINT (lines) > 0
-         && !it_overshoot_expected_p)
+         && (!it_overshoot_expected
+             || (it_overshoot_expected < 0
+                 && it.method == GET_FROM_BUFFER
+                 && it.c == '\n')))
        move_it_by_lines (&it, -1, 0);
  
        it.vpos = 0;
diff --combined src/insdel.c
index 5e0eec936d493935e9b1b5d1016fb98df2131cfb,08043147cdf6ebf15454cb8c4096a7e05bd0a3e2..6f8aac3d6da01cc6843896c7c87703bcd395fe5b
@@@ -1,6 -1,6 +1,6 @@@
  /* Buffer insertion/deletion and gap motion for GNU Emacs.
     Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -24,7 -24,7 +24,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "lisp.h"
  #include "intervals.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "window.h"
  #include "blockinput.h"
  #include "region-cache.h"
@@@ -659,11 -659,22 +659,11 @@@ copy_text (from_addr, to_addr, nbytes
        int bytes_left = nbytes;
        Lisp_Object tbl = Qnil;
  
 -      /* We set the variable tbl to the reverse table of
 -         Vnonascii_translation_table in advance.  */
 -      if (CHAR_TABLE_P (Vnonascii_translation_table))
 -      {
 -        tbl = Fchar_table_extra_slot (Vnonascii_translation_table,
 -                                      make_number (0));
 -        if (!CHAR_TABLE_P (tbl))
 -          tbl = Qnil;
 -      }
 -
 -      /* Convert multibyte to single byte.  */
        while (bytes_left > 0)
        {
          int thislen, c;
          c = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
 -        if (!SINGLE_BYTE_CHAR_P (c))
 +        if (!ASCII_CHAR_P (c))
            c = multibyte_char_to_unibyte (c, tbl);
          *to_addr++ = c;
          from_addr += thislen;
@@@ -1169,50 -1180,6 +1169,50 @@@ insert_from_string_1 (string, pos, pos_
                               current_buffer, inherit);
  
    adjust_point (nchars, outgoing_nbytes);
 +
 +  CHECK_MARKERS ();
 +}
 +\f
 +/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
 +   starting at GPT_ADDR.  */
 +
 +void
 +insert_from_gap (nchars, nbytes)
 +     register int nchars, nbytes;
 +{
 +  if (NILP (current_buffer->enable_multibyte_characters))
 +    nchars = nbytes;
 +
 +  record_insert (GPT, nchars);
 +  MODIFF++;
 +
 +  GAP_SIZE -= nbytes;
 +  GPT += nchars;
 +  ZV += nchars;
 +  Z += nchars;
 +  GPT_BYTE += nbytes;
 +  ZV_BYTE += nbytes;
 +  Z_BYTE += nbytes;
 +  if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor.  */
 +
 +  if (GPT_BYTE < GPT)
 +    abort ();
 +
 +  adjust_overlays_for_insert (GPT - nchars, nchars);
 +  adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes,
 +                           GPT, GPT_BYTE, 0);
 +
 +  if (BUF_INTERVALS (current_buffer) != 0)
 +    {
 +      offset_intervals (current_buffer, GPT - nchars, nchars);
 +      graft_intervals_into_buffer (NULL_INTERVAL, GPT - nchars, nchars,
 +                                 current_buffer, 0);
 +    }
 +
 +  if (GPT - nchars < PT)
 +    adjust_point (nchars, nbytes);
 +
 +  CHECK_MARKERS ();
  }
  \f
  /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
diff --combined src/intervals.c
index fecd1d181dc044e24a4330720234e922c100e5eb,861cb24c598ca2dcba56c9e8ecffa75ce3e13f88..ef97aa4973a4ce4f2fdcfda03041c180b4df1328
@@@ -1,6 -1,6 +1,6 @@@
  /* Code for doing intervals.
-    Copyright (C) 1993, 1994, 1995, 1997, 1998, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1993, 1994, 1995, 1997, 1998, 2001, 2002, 2003, 2004,
+                  2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -2306,7 -2306,7 +2306,7 @@@ in
  get_property_and_range (pos, prop, val, start, end, object)
       int pos;
       Lisp_Object prop, *val;
 -     int *start, *end;
 +     EMACS_INT *start, *end;
       Lisp_Object object;
  {
    INTERVAL i, prev, next;
diff --combined src/intervals.h
index 5aec706afea995dce2d745a267f8f2986139db94,7e07a6b4f31b405c7d7d905e1de1460b245cd1cd..d42462bc7ea4e32efb4762608ebcb9cf5c615bf8
@@@ -1,6 -1,6 +1,6 @@@
  /* Definitions and global variables for intervals.
-    Copyright (C) 1993, 1994, 2000, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1993, 1994, 2000, 2001, 2002, 2003, 2004,
+                  2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -300,7 -300,7 +300,7 @@@ extern Lisp_Object textget P_ ((Lisp_Ob
  extern Lisp_Object lookup_char_property P_ ((Lisp_Object, Lisp_Object, int));
  extern void move_if_not_intangible P_ ((int));
  extern int get_property_and_range P_ ((int, Lisp_Object, Lisp_Object *,
 -                                     int *, int *, Lisp_Object));
 +                                     EMACS_INT *, EMACS_INT *, Lisp_Object));
  extern Lisp_Object get_local_map P_ ((int, struct buffer *, Lisp_Object));
  extern INTERVAL update_interval P_ ((INTERVAL, int));
  extern void set_intervals_multibyte P_ ((int));
diff --combined src/keyboard.c
index 75b78d63d190ac77d4c841971ce85fd8ead53c31,ca1c1d5168f34c7c57c41857e5b71c9a999213c5..572b3096c06d69f5361f6446a48cc1ffd132bfac
@@@ -1,7 -1,7 +1,7 @@@
  /* Keyboard and mouse input; editor command loop.
     Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995,
                   1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -33,7 -33,7 +33,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "window.h"
  #include "commands.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "disptab.h"
  #include "dispextern.h"
  #include "syntax.h"
@@@ -1751,7 -1751,7 +1751,7 @@@ command_loop_1 (
                          : (lose >= 0x20 && lose < 0x7f))
                      /* To extract the case of continuation on
                           wide-column characters.  */
 -                    && (WIDTH_BY_CHAR_HEAD (FETCH_BYTE (PT_BYTE)) == 1)
 +                    && ASCII_BYTE_P (lose)
                      && (XFASTINT (XWINDOW (selected_window)->last_modified)
                          >= MODIFF)
                      && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
                {
                  unsigned int c
                    = translate_char (Vtranslation_table_for_input,
 -                                    XFASTINT (last_command_char), 0, 0, 0);
 +                                    XFASTINT (last_command_char));
                  int value;
                  if (NILP (Vexecuting_kbd_macro)
                      && !EQ (minibuf_window, selected_window))
@@@ -1984,7 -1984,7 +1984,7 @@@ adjust_point_for_property (last_pt, mod
       int last_pt;
       int modified;
  {
 -  int beg, end;
 +  EMACS_INT beg, end;
    Lisp_Object val, overlay, tmp;
    int check_composition = 1, check_display = 1, check_invisible = 1;
    int orig_pt = PT;
@@@ -3100,7 -3100,7 +3100,7 @@@ read_char (commandflag, nmaps, maps, pr
          || (VECTORP (Vkeyboard_translate_table)
              && XVECTOR (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
          || (CHAR_TABLE_P (Vkeyboard_translate_table)
 -            && CHAR_VALID_P (XINT (c), 0)))
 +            && CHARACTERP (c)))
        {
          Lisp_Object d;
          d = Faref (Vkeyboard_translate_table, c);
@@@ -9286,7 -9286,8 +9286,8 @@@ read_key_sequence (keybuf, bufsize, pro
                    {
                      pos = POSN_BUFFER_POSN (start);
                      if (INTEGERP (pos)
-                         && XINT (pos) >= BEG && XINT (pos) <= Z)
+                         && XINT (pos) >= BEGV
+                         && XINT (pos) <= ZV)
                        {
                          map_here = get_local_map (XINT (pos),
                                                    current_buffer, Qlocal_map);
        if (first_binding >= nmaps
          && fkey.start >= t && keytran.start >= t
          && INTEGERP (key)
 -        && ((((XINT (key) & 0x3ffff)
 -              < XCHAR_TABLE (current_buffer->downcase_table)->size)
 -             && UPPERCASEP (XINT (key) & 0x3ffff))
 +        && ((CHARACTERP (make_number (XINT (key) & ~CHAR_MODIFIER_MASK))
 +             && UPPERCASEP (XINT (key) & ~CHAR_MODIFIER_MASK))
              || (XINT (key) & shift_modifier)))
        {
          Lisp_Object new_key;
          if (XINT (key) & shift_modifier)
            XSETINT (new_key, XINT (key) & ~shift_modifier);
          else
 -          XSETINT (new_key, (DOWNCASE (XINT (key) & 0x3ffff)
 -                             | (XINT (key) & ~0x3ffff)));
 +          XSETINT (new_key, (DOWNCASE (XINT (key) & ~CHAR_MODIFIER_MASK)
 +                             | (XINT (key) & ~CHAR_MODIFIER_MASK)));
  
          /* We have to do this unconditionally, regardless of whether
             the lower-case char is defined in the keymaps, because they
@@@ -11019,6 -11021,8 +11020,8 @@@ init_keyboard (
    do_mouse_tracking = Qnil;
  #endif
    input_pending = 0;
+   interrupt_input_blocked = 0;
+   interrupt_input_pending = 0;
  
    /* This means that command_loop_1 won't try to select anything the first
       time through.  */
diff --combined src/keymap.c
index 3fd81effb0471bc5c39cabf9e3a4131fd22334b5,6b4b8536fe19f0532ede5e8e6ff9dab12159e0ef..671801fa1ba068f8187514cf6ad0ff1159aef37c
@@@ -1,7 -1,7 +1,7 @@@
  /* Manipulation of keymaps
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                   1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -29,7 -29,6 +29,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "lisp.h"
  #include "commands.h"
  #include "buffer.h"
 +#include "character.h"
  #include "charset.h"
  #include "keyboard.h"
  #include "termhooks.h"
@@@ -430,7 -429,11 +430,7 @@@ Return PARENT.  PARENT should be nil o
  
        if (CHAR_TABLE_P (XCAR (list)))
        {
 -        Lisp_Object indices[3];
 -
 -        map_char_table (fix_submap_inheritance, Qnil,
 -                        XCAR (list), XCAR (list),
 -                        keymap, 0, indices);
 +        map_char_table (fix_submap_inheritance, Qnil, XCAR (list), keymap);
        }
      }
  
@@@ -570,7 -573,9 +570,7 @@@ access_keymap (map, idx, t_ok, noinheri
  
      GCPRO4 (map, tail, idx, t_binding);
  
 -    /* If `t_ok' is 2, both `t' and generic-char bindings are accepted.
 -       If it is 1, only generic-char bindings are accepted.
 -       Otherwise, neither are.  */
 +    /* If `t_ok' is 2, both `t' is accepted.  */
      t_ok = t_ok ? 2 : 0;
  
      for (tail = XCDR (map);
  
            if (EQ (key, idx))
              val = XCDR (binding);
 -          else if (t_ok
 -                   && INTEGERP (idx)
 -                   && (XINT (idx) & CHAR_MODIFIER_MASK) == 0
 -                   && INTEGERP (key)
 -                   && (XINT (key) & CHAR_MODIFIER_MASK) == 0
 -                   && !SINGLE_BYTE_CHAR_P (XINT (idx))
 -                   && !SINGLE_BYTE_CHAR_P (XINT (key))
 -                   && CHAR_VALID_P (XINT (key), 1)
 -                   && !CHAR_VALID_P (XINT (key), 0)
 -                   && (CHAR_CHARSET (XINT (key))
 -                       == CHAR_CHARSET (XINT (idx))))
 -            {
 -              /* KEY is the generic character of the charset of IDX.
 -                 Use KEY's binding if there isn't a binding for IDX
 -                 itself.  */
 -              t_binding = XCDR (binding);
 -              t_ok = 0;
 -            }
            else if (t_ok > 1 && EQ (key, Qt))
              {
                t_binding = XCDR (binding);
@@@ -705,10 -728,12 +705,10 @@@ map_keymap (map, fun, args, data, autol
        }
        else if (CHAR_TABLE_P (binding))
        {
 -        Lisp_Object indices[3];
 -        map_char_table (map_keymap_char_table_item, Qnil, binding, binding,
 +        map_char_table (map_keymap_char_table_item, Qnil, binding,
                          Fcons (make_save_value (fun, 0),
                                 Fcons (make_save_value (data, 0),
 -                                      args)),
 -                        0, indices);
 +                                      args)));
        }
      }
    UNGCPRO;
@@@ -863,15 -888,10 +863,15 @@@ store_in_keymap (keymap, idx, def
    if (!CONSP (keymap) || !EQ (XCAR (keymap), Qkeymap))
      error ("attempt to define a key in a non-keymap");
  
 -  /* If idx is a list (some sort of mouse click, perhaps?),
 -     the index we want to use is the car of the list, which
 -     ought to be a symbol.  */
 -  idx = EVENT_HEAD (idx);
 +  /* If idx is a cons, and the car part is a character, idx must be of
 +     the form (FROM-CHAR . TO-CHAR).  */
 +  if (CONSP (idx) && CHARACTERP (XCAR (idx)))
 +    CHECK_CHARACTER_CDR (idx);
 +  else
 +    /* If idx is a list (some sort of mouse click, perhaps?),
 +       the index we want to use is the car of the list, which
 +       ought to be a symbol.  */
 +    idx = EVENT_HEAD (idx);
  
    /* If idx is a symbol, it might have modifiers, which need to
       be put in the canonical order.  */
                ASET (elt, XFASTINT (idx), def);
                return def;
              }
 +          else if (CONSP (idx) && CHARACTERP (XCAR (idx)))
 +            {
 +              int from = XFASTINT (XCAR (idx));
 +              int to = XFASTINT (XCDR (idx));
 +
 +              if (to >= ASIZE (elt))
 +                to = ASIZE (elt) - 1;
 +              for (; from <= to; from++)
 +                ASET (elt, from, def);
 +              if (to == XFASTINT (XCDR (idx)))
 +                /* We have defined all keys in IDX.  */
 +                return def;
 +            }
            insertion_point = tail;
          }
        else if (CHAR_TABLE_P (elt))
                       NILP (def) ? Qt : def);
                return def;
              }
 +          else if (CONSP (idx) && CHARACTERP (XCAR (idx)))
 +            {
 +              Fset_char_table_range (elt, idx, NILP (def) ? Qt : def);
 +              return def;
 +            }
            insertion_point = tail;
          }
        else if (CONSP (elt))
                XSETCDR (elt, def);
                return def;
              }
 +          else if (CONSP (idx) && CHARACTERP (XCAR (idx)))
 +            {
 +              int from = XFASTINT (XCAR (idx));
 +              int to = XFASTINT (XCDR (idx));
 +
 +              if (from <= XFASTINT (XCAR (elt))
 +                  && to >= XFASTINT (XCAR (elt)))
 +                {
 +                  XSETCDR (elt, def);
 +                  if (from == to)
 +                    return def;
 +                }
 +            }
          }
        else if (EQ (elt, Qkeymap))
          /* If we find a 'keymap' symbol in the spine of KEYMAP,
    keymap_end:
      /* We have scanned the entire keymap, and not found a binding for
         IDX.  Let's add one.  */
 -    CHECK_IMPURE (insertion_point);
 -    XSETCDR (insertion_point,
 -           Fcons (Fcons (idx, def), XCDR (insertion_point)));
 +    {
 +      Lisp_Object elt;
 +
 +      if (CONSP (idx) && CHARACTERP (XCAR (idx)))
 +      {
 +        /* IDX specifies a range of characters, and not all of them
 +           were handled yet, which means this keymap doesn't have a
 +           char-table.  So, we insert a char-table now.  */
 +        elt = Fmake_char_table (Qkeymap, Qnil);
 +        Fset_char_table_range (elt, idx, NILP (def) ? Qt : def);
 +      }
 +      else
 +      elt = Fcons (idx, def);
 +      CHECK_IMPURE (insertion_point);
 +      XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point)));
 +    }
    }
  
    return def;
@@@ -1080,7 -1056,7 +1080,7 @@@ static voi
  copy_keymap_1 (chartable, idx, elt)
       Lisp_Object chartable, idx, elt;
  {
 -  Faset (chartable, idx, copy_keymap_item (elt));
 +  Fset_char_table_range (chartable, idx, copy_keymap_item (elt));
  }
  
  DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0,
@@@ -1103,8 -1079,9 +1103,8 @@@ is not copied.  */
        Lisp_Object elt = XCAR (keymap);
        if (CHAR_TABLE_P (elt))
        {
 -        Lisp_Object indices[3];
          elt = Fcopy_sequence (elt);
 -        map_char_table (copy_keymap_1, Qnil, elt, elt, elt, 0, indices);
 +        map_char_table (copy_keymap_1, Qnil, elt, elt);
        }
        else if (VECTORP (elt))
        {
@@@ -1199,15 -1176,8 +1199,15 @@@ binding KEY to DEF is added at the fron
      {
        c = Faref (key, make_number (idx));
  
 -      if (CONSP (c) && lucid_event_type_list_p (c))
 -      c = Fevent_convert_list (c);
 +      if (CONSP (c))
 +      {
 +        /* C may be a Lucid style event type list or a cons (FROM .
 +           TO) specifying a range of characters.  */
 +        if (lucid_event_type_list_p (c))
 +          c = Fevent_convert_list (c);
 +        else if (CHARACTERP (XCAR (c)))
 +          CHECK_CHARACTER_CDR (c);
 +      }
  
        if (SYMBOLP (c))
        silly_event_symbol_error (c);
          idx++;
        }
  
 -      if (!INTEGERP (c) && !SYMBOLP (c) && !CONSP (c))
 +      if (!INTEGERP (c) && !SYMBOLP (c)
 +        && (!CONSP (c)
 +            /* If C is a range, it must be a leaf.  */
 +            || (INTEGERP (XCAR (c)) && idx != length)))
        error ("Key sequence contains invalid event");
  
        if (idx == length)
@@@ -2126,9 -2093,12 +2126,9 @@@ then the value includes only maps for p
  
          if (CHAR_TABLE_P (elt))
            {
 -            Lisp_Object indices[3];
 -
 -            map_char_table (accessible_keymaps_char_table, Qnil, elt,
 +            map_char_table (accessible_keymaps_char_table, Qnil,
                              elt, Fcons (Fcons (maps, make_number (is_metized)),
 -                                        Fcons (tail, thisseq)),
 -                            0, indices);
 +                                        Fcons (tail, thisseq)));
            }
          else if (VECTORP (elt))
            {
@@@ -2265,13 -2235,15 +2265,13 @@@ push_key_description (c, p, force_multi
       int force_multibyte;
  {
    unsigned c2;
 -  int valid_p;
  
    /* Clear all the meaningless bits above the meta bit.  */
    c &= meta_modifier | ~ - meta_modifier;
    c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
             | meta_modifier | shift_modifier | super_modifier);
  
 -  valid_p = SINGLE_BYTE_CHAR_P (c2) || char_valid_p (c2, 0);
 -  if (! valid_p)
 +  if (! CHARACTERP (make_number (c2)))
      {
        /* KEY_DESCRIPTION_SIZE is large enough for this.  */
        p += sprintf (p, "[%d]", c);
      }
    else
      {
 -      if (force_multibyte)
 -      {
 -        if (SINGLE_BYTE_CHAR_P (c))
 -          c = unibyte_char_to_multibyte (c);
 -        p += CHAR_STRING (c, p);
 -      }
 -      else if (NILP (current_buffer->enable_multibyte_characters))
 -      {
 -        int bit_offset;
 -        *p++ = '\\';
 -        /* The biggest character code uses 19 bits.  */
 -        for (bit_offset = 18; bit_offset >= 0; bit_offset -= 3)
 -          {
 -            if (c >= (1 << bit_offset))
 -              *p++ = ((c & (7 << bit_offset)) >> bit_offset) + '0';
 -          }
 -      }
 +      /* Now we are sure that C is a valid character code.  */
 +      if (NILP (current_buffer->enable_multibyte_characters)
 +        && ! force_multibyte)
 +      *p++ = multibyte_char_to_unibyte (c, Qnil);
        else
 -      p += CHAR_STRING (c, p);
 +      p += CHAR_STRING (c, (unsigned char *) p);
      }
  
    return p;
@@@ -2394,10 -2379,56 +2394,10 @@@ around function keys and event symbols
  
    if (INTEGERP (key))         /* Normal character */
      {
 -      unsigned int charset, c1, c2;
 -      int without_bits = XINT (key) & ~((-1) << CHARACTERBITS);
 +      char tem[KEY_DESCRIPTION_SIZE];
  
 -      if (SINGLE_BYTE_CHAR_P (without_bits))
 -      charset = 0;
 -      else
 -      SPLIT_CHAR (without_bits, charset, c1, c2);
 -
 -      if (! CHAR_VALID_P (without_bits, 1))
 -      {
 -        char buf[256];
 -
 -        sprintf (buf, "Invalid char code %d", XINT (key));
 -        return build_string (buf);
 -      }
 -      else if (charset
 -             && ((c1 == 0 && c2 == -1) || c2 == 0))
 -      {
 -        /* Handle a generic character.  */
 -        Lisp_Object name;
 -        char buf[256];
 -
 -        name = CHARSET_TABLE_INFO (charset, CHARSET_SHORT_NAME_IDX);
 -        CHECK_STRING (name);
 -        if (c1 == 0)
 -          /* Only a charset is specified.   */
 -          sprintf (buf, "Generic char %d: all of ", without_bits);
 -        else
 -          /* 1st code-point of 2-dimensional charset is specified.   */
 -          sprintf (buf, "Generic char %d: row %d of ", without_bits, c1);
 -        return concat2 (build_string (buf), name);
 -      }
 -      else
 -      {
 -        char tem[KEY_DESCRIPTION_SIZE], *end;
 -        int nbytes, nchars;
 -        Lisp_Object string;
 -
 -        end = push_key_description (XUINT (key), tem, 1);
 -        nbytes = end - tem;
 -        nchars = multibyte_chars_in_text (tem, nbytes);
 -        if (nchars == nbytes)
 -          {
 -            *end = '\0';
 -            string = build_string (tem);
 -          }
 -        else
 -          string = make_multibyte_string (tem, nchars, nbytes);
 -        return string;
 -      }
 +      *push_key_description (XUINT (key), tem, 1) = 0;
 +      return build_string (tem);
      }
    else if (SYMBOLP (key))     /* Function key or event-symbol */
      {
@@@ -2463,7 -2494,7 +2463,7 @@@ See Info node `(elisp)Describing Charac
    CHECK_NUMBER (character);
  
    c = XINT (character);
 -  if (!SINGLE_BYTE_CHAR_P (c))
 +  if (!ASCII_CHAR_P (c))
      {
        int len = CHAR_STRING (c, str);
  
@@@ -2634,6 -2665,7 +2634,6 @@@ where_is_internal (definition, keymaps
            }
          else if (CHAR_TABLE_P (elt))
            {
 -            Lisp_Object indices[3];
              Lisp_Object args;
  
              args = Fcons (Fcons (Fcons (definition, noindirect),
                            Fcons (Fcons (this, last),
                                   Fcons (make_number (nomenus),
                                          make_number (last_is_meta))));
 -            map_char_table (where_is_internal_2, Qnil, elt, elt, args,
 -                            0, indices);
 +            map_char_table (where_is_internal_2, Qnil, elt, args);
              sequences = XCDR (XCAR (args));
            }
          else if (CONSP (elt))
@@@ -2856,15 -2889,12 +2856,15 @@@ remapped command in the returned list
  
  /* This is the function that Fwhere_is_internal calls using map_char_table.
     ARGS has the form
 -   (((DEFINITION . NOINDIRECT) . (KEYMAP . RESULT))
 +   (((DEFINITION . NOINDIRECT) . RESULT)
      .
      ((THIS . LAST) . (NOMENUS . LAST_IS_META)))
     Since map_char_table doesn't really use the return value from this function,
     we the result append to RESULT, the slot in ARGS.
  
 +   KEY may be a cons (FROM . TO) where both FROM and TO are integers
 +   (i.e. character events).
 +
     This function can GC because it calls where_is_internal_1 which can
     GC.  */
  
@@@ -2878,6 -2908,7 +2878,6 @@@ where_is_internal_2 (args, key, binding
    struct gcpro gcpro1, gcpro2, gcpro3;
  
    GCPRO3 (args, key, binding);
 -  result = XCDR (XCAR (args));
    definition = XCAR (XCAR (XCAR (args)));
    noindirect = XCDR (XCAR (XCAR (args)));
    this = XCAR (XCAR (XCDR (args)));
    nomenus = XFASTINT (XCAR (XCDR (XCDR (args))));
    last_is_meta = XFASTINT (XCDR (XCDR (XCDR (args))));
  
 -  sequence = where_is_internal_1 (binding, key, definition, noindirect,
 -                                this, last, nomenus, last_is_meta);
 +  result = Qnil;
 +  if (CONSP (key) && INTEGERP (XCAR (key)) && INTEGERP (XCDR (key)))
 +    {
 +      /* Try all ASCII characters.  Try also non-ASCII characters but
 +       only the first and last one because trying all of them is
 +       extremely memory and time consuming.
  
 -  if (!NILP (sequence))
 -    XSETCDR (XCAR (args), Fcons (sequence, result));
 +       Fixme: Perhaps it should be allowed to store a cons directly
 +       in RESULT.  -- handa@m17n.org   */
 +      int from = XINT (XCAR (key)), to = XINT (XCDR (key));
 +      Lisp_Object k;
 +
 +      for (; from <= to; to--)
 +      {
 +        k = make_number (to);
 +        sequence = where_is_internal_1 (binding, k, definition, noindirect,
 +                                        this, last, nomenus, last_is_meta);
 +        if (!NILP (sequence))
 +          result = Fcons (sequence, result);
 +        if (to > 129)
 +          to = 129;
 +      }
 +    }
 +  else
 +    {
 +      sequence = where_is_internal_1 (binding, key, definition, noindirect,
 +                                    this, last, nomenus, last_is_meta);
 +      if (!NILP (sequence))
 +      result = Fcons (sequence, Qnil);
 +    }
 +
 +  if (! NILP (result))
 +    nconc2 (XCAR (args), result);
  
    UNGCPRO;
  }
@@@ -3452,9 -3455,13 +3452,13 @@@ describe_map (map, prefix, elt_describe
              tem = shadow_lookup (shadow, kludge, Qt);
              if (!NILP (tem))
                {
+                 /* If both bindings are keymaps, this key is a prefix key,
+                    so don't say it is shadowed.  */
+                 if (KEYMAPP (definition) && KEYMAPP (tem))
+                   ;
                  /* Avoid generating duplicate entries if the
-                    shadowed binding has the same definition. */
-                 if (mention_shadow && !EQ (tem, definition))
+                    shadowed binding has the same definition.  */
+                 else if (mention_shadow && !EQ (tem, definition))
                    this_shadowed = 1;
                  else
                    continue;
@@@ -3599,10 -3606,9 +3603,10 @@@ DESCRIBER is the output function used; 
     If the definition in effect in the whole map does not match
     the one in this vector, we ignore this one.
  
 -   When describing a sub-char-table, INDICES is a list of
 -   indices at higher levels in this char-table,
 -   and CHAR_TABLE_DEPTH says how many levels down we have gone.
 +   ARGS is simply passed as the second argument to ELT_DESCRIBER.
 +
 +   INDICES and CHAR_TABLE_DEPTH are ignored.  They will be removed in
 +   the near future.
  
     KEYMAP_P is 1 if vector is known to be a keymap, so map ESC to M-.
  
@@@ -3627,18 -3633,24 +3631,18 @@@ describe_vector (vector, prefix, args, 
    Lisp_Object definition;
    Lisp_Object tem2;
    Lisp_Object elt_prefix = Qnil;
 -  register int i;
 +  int i;
    Lisp_Object suppress;
    Lisp_Object kludge;
    int first = 1;
    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
    /* Range of elements to be handled.  */
    int from, to;
 -  /* A flag to tell if a leaf in this level of char-table is not a
 -     generic character (i.e. a complete multibyte character).  */
 -  int complete_char;
 -  int character;
 +  Lisp_Object character;
    int starting_i;
  
    suppress = Qnil;
  
 -  if (indices == 0)
 -    indices = (int *) alloca (3 * sizeof (int));
 -
    definition = Qnil;
  
    if (!keymap_p)
    if (partial)
      suppress = intern ("suppress-keymap");
  
 -  if (CHAR_TABLE_P (vector))
 -    {
 -      if (char_table_depth == 0)
 -      {
 -        /* VECTOR is a top level char-table.  */
 -        complete_char = 1;
 -        from = 0;
 -        to = CHAR_TABLE_ORDINARY_SLOTS;
 -      }
 -      else
 -      {
 -        /* VECTOR is a sub char-table.  */
 -        if (char_table_depth >= 3)
 -          /* A char-table is never that deep.  */
 -          error ("Too deep char table");
 -
 -        complete_char
 -          = (CHARSET_VALID_P (indices[0])
 -             && ((CHARSET_DIMENSION (indices[0]) == 1
 -                  && char_table_depth == 1)
 -                 || char_table_depth == 2));
 -
 -        /* Meaningful elements are from 32th to 127th.  */
 -        from = 32;
 -        to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
 -      }
 -    }
 -  else
 -    {
 -      /* This does the right thing for ordinary vectors.  */
 -
 -      complete_char = 1;
 -      from = 0;
 -      to = XVECTOR (vector)->size;
 -    }
 +  from = 0;
 +  to = CHAR_TABLE_P (vector) ? MAX_CHAR + 1 : XVECTOR (vector)->size;
  
    for (i = from; i < to; i++)
      {
        int this_shadowed = 0;
 -      QUIT;
 +      int range_beg, range_end;
 +      Lisp_Object val;
  
 -      if (CHAR_TABLE_P (vector))
 -      {
 -        if (char_table_depth == 0 && i >= CHAR_TABLE_SINGLE_BYTE_SLOTS)
 -          complete_char = 0;
 +      QUIT;
  
 -        if (i >= CHAR_TABLE_SINGLE_BYTE_SLOTS
 -            && !CHARSET_DEFINED_P (i - 128))
 -          continue;
 +      starting_i = i;
  
 -        definition
 -          = get_keyelt (XCHAR_TABLE (vector)->contents[i], 0);
 -      }
 +      if (CHAR_TABLE_P (vector))
 +      val = char_table_ref_and_range (vector, i, &range_beg, &i);
        else
 -      definition = get_keyelt (AREF (vector, i), 0);
 +      val = AREF (vector, i);
 +      definition = get_keyelt (val, 0);
  
        if (NILP (definition)) continue;
  
          if (!NILP (tem)) continue;
        }
  
 -      /* Set CHARACTER to the character this entry describes, if any.
 -       Also update *INDICES.  */
 -      if (CHAR_TABLE_P (vector))
 -      {
 -        indices[char_table_depth] = i;
 -
 -        if (char_table_depth == 0)
 -          {
 -            character = i;
 -            indices[0] = i - 128;
 -          }
 -        else if (complete_char)
 -          {
 -            character = MAKE_CHAR (indices[0], indices[1], indices[2]);
 -          }
 -        else
 -          character = 0;
 -      }
 -      else
 -      character = i;
 -
 -      ASET (kludge, 0, make_number (character));
 +      character = make_number (starting_i);
 +      ASET (kludge, 0, character);
  
        /* If this binding is shadowed by some other map, ignore it.  */
 -      if (!NILP (shadow) && complete_char)
 +      if (!NILP (shadow))
        {
          Lisp_Object tem;
  
  
        /* Ignore this definition if it is shadowed by an earlier
         one in the same keymap.  */
 -      if (!NILP (entire_map) && complete_char)
 +      if (!NILP (entire_map))
        {
          Lisp_Object tem;
  
  
        if (first)
        {
 -        if (char_table_depth == 0)
 -          insert ("\n", 1);
 +        insert ("\n", 1);
          first = 0;
        }
  
 -      /* For a sub char-table, show the depth by indentation.
 -       CHAR_TABLE_DEPTH can be greater than 0 only for a char-table.  */
 -      if (char_table_depth > 0)
 -      insert ("    ", char_table_depth * 2); /* depth is 1 or 2.  */
 -
        /* Output the prefix that applies to every entry in this map.  */
        if (!NILP (elt_prefix))
        insert1 (elt_prefix);
  
 -      /* Insert or describe the character this slot is for,
 -       or a description of what it is for.  */
 -      if (SUB_CHAR_TABLE_P (vector))
 -      {
 -        if (complete_char)
 -          insert_char (character);
 -        else
 -          {
 -            /* We need an octal representation for this block of
 -                 characters.  */
 -            char work[16];
 -            sprintf (work, "(row %d)", i);
 -            insert (work, strlen (work));
 -          }
 -      }
 -      else if (CHAR_TABLE_P (vector))
 -      {
 -        if (complete_char)
 -          insert1 (Fkey_description (kludge, prefix));
 -        else
 -          {
 -            /* Print the information for this character set.  */
 -            insert_string ("<");
 -            tem2 = CHARSET_TABLE_INFO (i - 128, CHARSET_SHORT_NAME_IDX);
 -            if (STRINGP (tem2))
 -              insert_from_string (tem2, 0, 0, SCHARS (tem2),
 -                                  SBYTES (tem2), 0);
 -            else
 -              insert ("?", 1);
 -            insert (">", 1);
 -          }
 -      }
 -      else
 -      {
 -        insert1 (Fkey_description (kludge, prefix));
 -      }
 -
 -      /* If we find a sub char-table within a char-table,
 -       scan it recursively; it defines the details for
 -       a character set or a portion of a character set.  */
 -      if (CHAR_TABLE_P (vector) && SUB_CHAR_TABLE_P (definition))
 -      {
 -        insert ("\n", 1);
 -        describe_vector (definition, prefix, args, elt_describer,
 -                         partial, shadow, entire_map,
 -                         indices, char_table_depth + 1, keymap_p,
 -                         mention_shadow);
 -        continue;
 -      }
 -
 -      starting_i = i;
 +      insert1 (Fkey_description (kludge, prefix));
  
        /* Find all consecutive characters or rows that have the same
           definition.  But, for elements of a top level char table, if
           they are for charsets, we had better describe one by one even
           if they have the same definition.  */
        if (CHAR_TABLE_P (vector))
 -      {
 -        int limit = to;
 -
 -        if (char_table_depth == 0)
 -          limit = CHAR_TABLE_SINGLE_BYTE_SLOTS;
 -
 -        while (i + 1 < limit
 -               && (tem2 = get_keyelt (XCHAR_TABLE (vector)->contents[i + 1], 0),
 -                   !NILP (tem2))
 -               && !NILP (Fequal (tem2, definition)))
 -          i++;
 -      }
 +      while (i + 1 < to
 +             && (val = char_table_ref_and_range (vector, i + 1,
 +                                                 &range_beg, &range_end),
 +                 tem2 = get_keyelt (val, 0),
 +                 !NILP (tem2))
 +             && !NILP (Fequal (tem2, definition)))
 +        i = range_end;
        else
        while (i + 1 < to
               && (tem2 = get_keyelt (AREF (vector, i + 1), 0),
               && !NILP (Fequal (tem2, definition)))
          i++;
  
 -
        /* If we have a range of more than one character,
         print where the range reaches to.  */
  
          if (!NILP (elt_prefix))
            insert1 (elt_prefix);
  
 -        if (CHAR_TABLE_P (vector))
 -          {
 -            if (char_table_depth == 0)
 -              {
 -                insert1 (Fkey_description (kludge, prefix));
 -              }
 -            else if (complete_char)
 -              {
 -                indices[char_table_depth] = i;
 -                character = MAKE_CHAR (indices[0], indices[1], indices[2]);
 -                insert_char (character);
 -              }
 -            else
 -              {
 -                /* We need an octal representation for this block of
 -                   characters.  */
 -                char work[16];
 -                sprintf (work, "(row %d)", i);
 -                insert (work, strlen (work));
 -              }
 -          }
 -        else
 -          {
 -            insert1 (Fkey_description (kludge, prefix));
 -          }
 +        insert1 (Fkey_description (kludge, prefix));
        }
  
        /* Print a description of the definition of this character.
        }
      }
  
 -  /* For (sub) char-table, print `defalt' slot at last.  */
 -  if (CHAR_TABLE_P (vector) && !NILP (XCHAR_TABLE (vector)->defalt))
 +  if (CHAR_TABLE_P (vector) && ! NILP (XCHAR_TABLE (vector)->defalt))
      {
 -      insert ("    ", char_table_depth * 2);
 -      insert_string ("<<default>>");
 +      if (!NILP (elt_prefix))
 +      insert1 (elt_prefix);
 +      insert ("default", 7);
        (*elt_describer) (XCHAR_TABLE (vector)->defalt, args);
      }
  
diff --combined src/lisp.h
index 787eface0eecd9961eaee5a162a137eeb3f46759,012d66e4d5ae7e95b63f0ad56cab4ab5ae88ec66..31c7e50718f1b3753d057e3d5813ca80adef3a17
@@@ -1,6 -1,6 +1,6 @@@
  /* Fundamental definitions for GNU Emacs Lisp interpreter.
     Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
-                  2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -288,8 -288,7 +288,8 @@@ enum pvec_typ
    PVEC_BOOL_VECTOR = 0x10000,
    PVEC_BUFFER = 0x20000,
    PVEC_HASH_TABLE = 0x40000,
 -  PVEC_TYPE_MASK = 0x7fe00
 +  PVEC_SUB_CHAR_TABLE = 0x80000,
 +  PVEC_TYPE_MASK = 0x0ffe00
  
  #if 0 /* This is used to make the value of PSEUDOVECTOR_FLAG available to
         GDB.  It doesn't work on OS Alpha.  Moved to a variable in
@@@ -542,7 -541,6 +542,7 @@@ extern size_t pure_size
  #define XSUBR(a) (eassert (GC_SUBRP(a)),(struct Lisp_Subr *) XPNTR(a))
  #define XBUFFER(a) (eassert (GC_BUFFERP(a)),(struct buffer *) XPNTR(a))
  #define XCHAR_TABLE(a) ((struct Lisp_Char_Table *) XPNTR(a))
 +#define XSUB_CHAR_TABLE(a) ((struct Lisp_Sub_Char_Table *) XPNTR(a))
  #define XBOOL_VECTOR(a) ((struct Lisp_Bool_Vector *) XPNTR(a))
  
  /* Construct a Lisp_Object from a value or address.  */
  #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
  #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
  #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR))
 +#define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE))
  
  /* Convenience macros for dealing with Lisp arrays.  */
  
@@@ -750,20 -747,49 +750,20 @@@ struct Lisp_Vecto
    ((OFFSETOF(type, nonlispfield) - OFFSETOF(struct Lisp_Vector, contents[0])) \
     / sizeof (Lisp_Object))
  
 -/* A char table is a kind of vectorlike, with contents are like a
 +/* A char-table is a kind of vectorlike, with contents are like a
     vector but with a few other slots.  For some purposes, it makes
 -   sense to handle a chartable with type struct Lisp_Vector.  An
 +   sense to handle a char-table with type struct Lisp_Vector.  An
     element of a char table can be any Lisp objects, but if it is a sub
     char-table, we treat it a table that contains information of a
 -   group of characters of the same charsets or a specific character of
 -   a charset.  A sub char-table has the same structure as a char table
 -   except for that the former omits several slots at the tail.  A sub
 -   char table appears only in an element of a char table, and there's
 -   no way to access it directly from Emacs Lisp program.  */
 -
 -/* This is the number of slots that apply to characters or character
 -   sets.  The first 128 are for ASCII, the next 128 are for 8-bit
 -   European characters, and the last 128 are for multibyte characters.
 -   The first 256 are indexed by the code itself, but the last 128 are
 -   indexed by (charset-id + 128).  */
 -#define CHAR_TABLE_ORDINARY_SLOTS 384
 -
 -/* These are the slot of the default values for single byte
 -   characters.  As 0x9A is never be a charset-id, it is safe to use
 -   that slot for ASCII.  0x9E and 0x80 are charset-ids of
 -   eight-bit-control and eight-bit-graphic respectively.  */
 -#define CHAR_TABLE_DEFAULT_SLOT_ASCII (0x9A + 128)
 -#define CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL (0x9E + 128)
 -#define CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC (0x80 + 128)
 -
 -/* This is the number of slots that apply to characters of ASCII and
 -   8-bit Europeans only.  */
 -#define CHAR_TABLE_SINGLE_BYTE_SLOTS 256
 +   specific range of characters.  A sub char-table has the same
 +   structure as a vector.  A sub char table appears only in an element
 +   of a char-table, and there's no way to access it directly from
 +   Emacs Lisp program.  */
  
  /* This is the number of slots that every char table must have.  This
     counts the ordinary slots and the top, defalt, parent, and purpose
     slots.  */
 -#define CHAR_TABLE_STANDARD_SLOTS (CHAR_TABLE_ORDINARY_SLOTS + 4)
 -
 -/* This is the number of slots that apply to position-code-1 and
 -   position-code-2 of a multibyte character at the 2nd and 3rd level
 -   sub char tables respectively.  */
 -#define SUB_CHAR_TABLE_ORDINARY_SLOTS 128
 -
 -/* This is the number of slots that every sub char table must have.
 -   This counts the ordinary slots and the top and defalt slot.  */
 -#define SUB_CHAR_TABLE_STANDARD_SLOTS (SUB_CHAR_TABLE_ORDINARY_SLOTS + 2)
 +#define CHAR_TABLE_STANDARD_SLOTS (VECSIZE (struct Lisp_Char_Table) - 1)
  
  /* Return the number of "extra" slots in the char table CT.  */
  
    (((CT)->size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS)
  
  /* Almost equivalent to Faref (CT, IDX) with optimization for ASCII
 -   and 8-bit Europeans characters.  For these characters, do not check
 -   validity of CT.  Do not follow parent.  */
 -#define CHAR_TABLE_REF(CT, IDX)                               \
 -  ((IDX) >= 0 && (IDX) < CHAR_TABLE_SINGLE_BYTE_SLOTS \
 -   ? (!NILP (XCHAR_TABLE (CT)->contents[IDX])         \
 -      ? XCHAR_TABLE (CT)->contents[IDX]                       \
 -      : XCHAR_TABLE (CT)->defalt)                     \
 -   : Faref (CT, make_number (IDX)))
 +   characters.  Do not check validity of CT.  */
 +#define CHAR_TABLE_REF(CT, IDX)                                                \
 +  ((ASCII_CHAR_P (IDX)                                                         \
 +    && SUB_CHAR_TABLE_P (XCHAR_TABLE (CT)->ascii)                      \
 +    && !NILP (XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX])) \
 +   ? XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX]          \
 +   : char_table_ref ((CT), (IDX)))
  
 -/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII
 -   and 8-bit Europeans characters.  However, if the result is nil,
 -   return IDX.
 +/* Almost equivalent to Faref (CT, IDX).  However, if the result is
 +   not a character, return IDX.
  
     For these characters, do not check validity of CT
     and do not follow parent.  */
 -#define CHAR_TABLE_TRANSLATE(CT, IDX)                 \
 -  ((IDX) < CHAR_TABLE_SINGLE_BYTE_SLOTS                       \
 -   ? (!NILP (XCHAR_TABLE (CT)->contents[IDX])         \
 -      ? XINT (XCHAR_TABLE (CT)->contents[IDX])                \
 -      : IDX)                                          \
 -   : char_table_translate (CT, IDX))
 +#define CHAR_TABLE_TRANSLATE(CT, IDX) \
 +  char_table_translate (CT, IDX)
  
  /* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and
 -   8-bit Europeans characters.  Do not check validity of CT.  */
 -#define CHAR_TABLE_SET(CT, IDX, VAL)                  \
 -  do {                                                        \
 -    if (XFASTINT (IDX) < CHAR_TABLE_SINGLE_BYTE_SLOTS)        \
 -      XCHAR_TABLE (CT)->contents[XFASTINT (IDX)] = VAL;       \
 -    else                                              \
 -      Faset (CT, IDX, VAL);                           \
 -  } while (0)
 +   8-bit European characters.  Do not check validity of CT.  */
 +#define CHAR_TABLE_SET(CT, IDX, VAL)                                  \
 +  (((IDX) >= 0 && ASCII_CHAR_P (IDX)                                  \
 +    && SUB_CHAR_TABLE_P (XCHAR_TABLE (CT)->ascii))                    \
 +   ? XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX] = VAL   \
 +   : char_table_set (CT, IDX, VAL))
 +
 +#define CHARTAB_SIZE_BITS_0 6
 +#define CHARTAB_SIZE_BITS_1 4
 +#define CHARTAB_SIZE_BITS_2 5
 +#define CHARTAB_SIZE_BITS_3 7
 +
 +extern const int chartab_size[4];
 +
 +struct Lisp_Sub_Char_Table;
  
  struct Lisp_Char_Table
    {
      /* This is the vector's size field, which also holds the
 -       pseudovector type information.  It holds the size, too.
 -       The size counts the top, defalt, purpose, and parent slots.
 -       The last three are not counted if this is a sub char table.  */
 +       pseudovector type information.  It holds the size, too.  The size
 +       counts the defalt, parent, purpose, ascii, contents, and extras
 +       slots.  */
      EMACS_INT size;
      struct Lisp_Vector *next;
 -    /* This holds a flag to tell if this is a top level char table (t)
 -       or a sub char table (nil).  */
 -    Lisp_Object top;
 +
      /* This holds a default value,
         which is used whenever the value for a specific character is nil.  */
      Lisp_Object defalt;
 -    /* This holds an actual value of each element.  A sub char table
 -       has only SUB_CHAR_TABLE_ORDINARY_SLOTS number of elements.  */
 -    Lisp_Object contents[CHAR_TABLE_ORDINARY_SLOTS];
 -
 -    /* A sub char table doesn't has the following slots.  */
  
 -    /* This points to another char table, which we inherit from
 -       when the value for a specific character is nil.
 -       The `defalt' slot takes precedence over this.  */
 +    /* This points to another char table, which we inherit from when the
 +       value for a specific character is nil.  The `defalt' slot takes
 +       precedence over this.  */
      Lisp_Object parent;
 -    /* This should be a symbol which says what kind of use
 -       this char-table is meant for.
 -       Typically now the values can be `syntax-table' and `display-table'.  */
 +
 +    /* This is a symbol which says what kind of use this char-table is
 +       meant for.  */
      Lisp_Object purpose;
 -    /* These hold additional data.  */
 +
 +    /* The bottom sub char-table for characters of the range 0..127.  It
 +       is nil if none of ASCII character has a specific value.  */
 +    Lisp_Object ascii;
 +
 +    Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)];
 +
 +    /* These hold additional data.  It is a vector.  */
      Lisp_Object extras[1];
    };
  
 +struct Lisp_Sub_Char_Table
 +  {
 +    /* This is the vector's size field, which also holds the
 +       pseudovector type information.  It holds the size, too.  */
 +    EMACS_INT size;
 +    struct Lisp_Vector *next;
 +
 +    /* Depth of this sub char-table.  It should be 1, 2, or 3.  A sub
 +       char-table of depth 1 contains 16 elments, and each element
 +       covers 4096 (128*32) characters.  A sub char-table of depth 2
 +       contains 32 elements, and each element covers 128 characters.  A
 +       sub char-table of depth 3 contains 128 elements, and each element
 +       is for one character.  */
 +    Lisp_Object depth;
 +
 +    /* Minimum character covered by the sub char-table.  */
 +    Lisp_Object min_char;
 +
 +    Lisp_Object contents[1];
 +  };
 +
  /* A boolvector is a kind of vectorlike, with contents are like a string.  */
  struct Lisp_Bool_Vector
    {
@@@ -1359,9 -1363,9 +1359,9 @@@ typedef unsigned char UCHAR
    (CHAR_ALT | CHAR_SUPER | CHAR_HYPER  | CHAR_SHIFT | CHAR_CTL | CHAR_META)
  
  
 -/* Actually, the current Emacs uses 19 bits for the character value
 +/* Actually, the current Emacs uses 22 bits for the character value
     itself.  */
 -#define CHARACTERBITS 19
 +#define CHARACTERBITS 22
  
  /* The maximum byte size consumed by push_key_description.
     All callers should assure that at least this size of memory is
  #define GLYPH int
  
  /* Mask bits for face.  */
 -#define GLYPH_MASK_FACE    0x7FF80000
 +#define GLYPH_MASK_FACE    0x7FC00000
   /* Mask bits for character code.  */
 -#define GLYPH_MASK_CHAR    0x0007FFFF /* The lowest 19 bits */
 +#define GLYPH_MASK_CHAR    0x003FFFFF /* The lowest 22 bits */
  
  /* The FAST macros assume that we already know we're in an X window.  */
  
  #define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)
  #define GC_BUFFERP(x) GC_PSEUDOVECTORP (x, PVEC_BUFFER)
  #define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE)
 +#define SUB_CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_SUB_CHAR_TABLE)
 +#define GC_SUB_CHAR_TABLE_P(x) GC_PSEUDOVECTORP (x, PVEC_SUB_CHAR_TABLE)
  #define GC_CHAR_TABLE_P(x) GC_PSEUDOVECTORP (x, PVEC_CHAR_TABLE)
  #define BOOL_VECTOR_P(x) PSEUDOVECTORP (x, PVEC_BOOL_VECTOR)
  #define GC_BOOL_VECTOR_P(x) GC_PSEUDOVECTORP (x, PVEC_BOOL_VECTOR)
  #define FRAMEP(x) PSEUDOVECTORP (x, PVEC_FRAME)
  #define GC_FRAMEP(x) GC_PSEUDOVECTORP (x, PVEC_FRAME)
  
 -#define SUB_CHAR_TABLE_P(x) (CHAR_TABLE_P (x) && NILP (XCHAR_TABLE (x)->top))
 -
  /* Test for image (image . spec)  */
  #define IMAGEP(x) (CONSP (x) && EQ (XCAR (x), Qimage))
  
      XSETCDR ((x), tmp);                       \
    } while (0)
  
 +#define CHECK_NATNUM_CAR(x) \
 +  do {                                        \
 +    Lisp_Object tmp = XCAR (x);               \
 +    CHECK_NATNUM (tmp);                       \
 +    XSETCAR ((x), tmp);                       \
 +  } while (0)
 +
 +#define CHECK_NATNUM_CDR(x) \
 +  do {                                        \
 +    Lisp_Object tmp = XCDR (x);               \
 +    CHECK_NATNUM (tmp);                       \
 +    XSETCDR ((x), tmp);                       \
 +  } while (0)
 +
  /* Cast pointers to this type to compare them.  Some machines want int.  */
  #ifndef PNTR_COMPARISON_TYPE
  #define PNTR_COMPARISON_TYPE EMACS_UINT
@@@ -2295,43 -2285,34 +2295,43 @@@ extern void keys_of_cmds P_ ((void))
  
  /* Defined in coding.c */
  EXFUN (Fcoding_system_p, 1);
 +EXFUN (Fcoding_system_base, 1);
 +EXFUN (Fcoding_system_eol_type, 1);
 +EXFUN (Fcheck_coding_system, 1);
  EXFUN (Fcheck_coding_system, 1);
  EXFUN (Fread_coding_system, 2);
  EXFUN (Fread_non_nil_coding_system, 1);
  EXFUN (Ffind_operation_coding_system, MANY);
  EXFUN (Fupdate_coding_systems_internal, 0);
 -EXFUN (Fencode_coding_string, 3);
 -EXFUN (Fdecode_coding_string, 3);
 -extern Lisp_Object detect_coding_system P_ ((const unsigned char *, int, int,
 -                                           int));
 +EXFUN (Fencode_coding_string, 4);
 +EXFUN (Fdecode_coding_string, 4);
 +extern Lisp_Object detect_coding_system P_ ((const unsigned char *, int,
 +                                           int, int, int, Lisp_Object));
  extern void init_coding P_ ((void));
  extern void init_coding_once P_ ((void));
  extern void syms_of_coding P_ ((void));
 -extern Lisp_Object code_convert_string_norecord P_ ((Lisp_Object, Lisp_Object,
 -                                                   int));
 +
 +/* Defined in character.c */
 +extern void init_character_once P_ ((void));
 +extern void syms_of_character P_ ((void));
 +EXFUN (Funibyte_char_to_multibyte, 1);
  
  /* Defined in charset.c */
 -extern EMACS_INT nonascii_insert_offset;
 -extern Lisp_Object Vnonascii_translation_table;
  EXFUN (Fchar_bytes, 1);
  EXFUN (Fchar_width, 1);
  EXFUN (Fstring, MANY);
  extern int chars_in_text P_ ((const unsigned char *, int));
  extern int multibyte_chars_in_text P_ ((const unsigned char *, int));
 -extern int unibyte_char_to_multibyte P_ ((int));
  extern int multibyte_char_to_unibyte P_ ((int, Lisp_Object));
  extern Lisp_Object Qcharset;
 +extern void init_charset P_ ((void));
  extern void init_charset_once P_ ((void));
  extern void syms_of_charset P_ ((void));
 +/* Structure forward declarations.  */
 +struct charset;
 +
 +/* Defined in composite.c */
 +extern void syms_of_composite P_ ((void));
  
  /* Defined in syntax.c */
  EXFUN (Fforward_word, 1);
@@@ -2349,8 -2330,9 +2349,8 @@@ extern int next_almost_prime P_ ((int))
  extern Lisp_Object larger_vector P_ ((Lisp_Object, int, Lisp_Object));
  extern void sweep_weak_hash_tables P_ ((void));
  extern Lisp_Object Qstring_lessp;
 -EXFUN (Foptimize_char_table, 1);
  extern Lisp_Object Vfeatures;
 -extern Lisp_Object QCtest, QCweakness, Qequal;
 +extern Lisp_Object QCtest, QCweakness, Qequal, Qeq;
  unsigned sxhash P_ ((Lisp_Object, int));
  Lisp_Object make_hash_table P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
                                 Lisp_Object, Lisp_Object, Lisp_Object,
@@@ -2365,7 -2347,6 +2365,7 @@@ void remove_hash_entry P_ ((struct Lisp
  extern void init_fns P_ ((void));
  EXFUN (Fsxhash, 1);
  EXFUN (Fmake_hash_table, MANY);
 +EXFUN (Fmakehash, 1);
  EXFUN (Fcopy_hash_table, 1);
  EXFUN (Fhash_table_count, 1);
  EXFUN (Fhash_table_rehash_size, 1);
@@@ -2424,7 -2405,6 +2424,7 @@@ extern Lisp_Object concat2 P_ ((Lisp_Ob
  extern Lisp_Object concat3 P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
  extern Lisp_Object nconc2 P_ ((Lisp_Object, Lisp_Object));
  extern Lisp_Object assq_no_quit P_ ((Lisp_Object, Lisp_Object));
 +extern Lisp_Object assoc_no_quit P_ ((Lisp_Object, Lisp_Object));
  extern void clear_string_char_byte_cache P_ ((void));
  extern int string_char_to_byte P_ ((Lisp_Object, int));
  extern int string_byte_to_char P_ ((Lisp_Object, int));
@@@ -2435,10 -2415,18 +2435,10 @@@ EXFUN (Fcopy_alist, 1)
  EXFUN (Fplist_get, 2);
  EXFUN (Fplist_put, 3);
  EXFUN (Fplist_member, 2);
 -EXFUN (Fset_char_table_parent, 2);
 -EXFUN (Fchar_table_extra_slot, 2);
 -EXFUN (Fset_char_table_extra_slot, 3);
  EXFUN (Frassoc, 2);
  EXFUN (Fstring_equal, 2);
  EXFUN (Fcompare_strings, 7);
  EXFUN (Fstring_lessp, 2);
 -extern int char_table_translate P_ ((Lisp_Object, int));
 -extern void map_char_table P_ ((void (*) (Lisp_Object, Lisp_Object, Lisp_Object),
 -                              Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, int,
 -                              Lisp_Object *));
 -extern Lisp_Object char_table_ref_and_index P_ ((Lisp_Object, int, int *));
  extern void syms_of_fns P_ ((void));
  
  /* Defined in floatfns.c */
@@@ -2471,7 -2459,6 +2471,7 @@@ extern void insert P_ ((const unsigned 
  extern void insert_and_inherit P_ ((const unsigned char *, int));
  extern void insert_1 P_ ((const unsigned char *, int, int, int, int));
  extern void insert_1_both P_ ((const unsigned char *, int, int, int, int, int));
 +extern void insert_from_gap P_ ((int, int));
  extern void insert_from_string P_ ((Lisp_Object, int, int, int, int, int));
  extern void insert_from_buffer P_ ((struct buffer *, int, int, int));
  extern void insert_char P_ ((int));
@@@ -2598,6 -2585,8 +2598,6 @@@ extern Lisp_Object make_pure_vector P_ 
  EXFUN (Fgarbage_collect, 0);
  EXFUN (Fmake_byte_code, MANY);
  EXFUN (Fmake_bool_vector, 2);
 -EXFUN (Fmake_char_table, 2);
 -extern Lisp_Object make_sub_char_table P_ ((Lisp_Object));
  extern Lisp_Object Qchar_table_extra_slots;
  extern struct Lisp_Vector *allocate_vector P_ ((EMACS_INT));
  extern struct Lisp_Vector *allocate_other_vector P_ ((EMACS_INT));
@@@ -2620,31 -2609,6 +2620,31 @@@ extern void syms_of_alloc P_ ((void))
  extern struct buffer * allocate_buffer P_ ((void));
  extern int valid_lisp_object_p P_ ((Lisp_Object));
  
 +/* Defined in chartab.c */
 +EXFUN (Fmake_char_table, 2);
 +EXFUN (Fchar_table_parent, 1);
 +EXFUN (Fset_char_table_parent, 2);
 +EXFUN (Fchar_table_extra_slot, 2);
 +EXFUN (Fset_char_table_extra_slot, 3);
 +EXFUN (Fchar_table_range, 2);
 +EXFUN (Fset_char_table_range, 3);
 +EXFUN (Fset_char_table_default, 3);
 +EXFUN (Foptimize_char_table, 1);
 +EXFUN (Fmap_char_table, 2);
 +extern Lisp_Object copy_char_table P_ ((Lisp_Object));
 +extern Lisp_Object sub_char_table_ref P_ ((Lisp_Object, int));
 +extern Lisp_Object char_table_ref P_ ((Lisp_Object, int));
 +extern Lisp_Object char_table_ref_and_range P_ ((Lisp_Object, int,
 +                                               int *, int *));
 +extern Lisp_Object char_table_set P_ ((Lisp_Object, int, Lisp_Object));
 +extern Lisp_Object char_table_set_range P_ ((Lisp_Object, int, int,
 +                                           Lisp_Object));
 +extern int char_table_translate P_ ((Lisp_Object, int));
 +extern void map_char_table P_ ((void (*) (Lisp_Object, Lisp_Object,
 +                                        Lisp_Object),
 +                              Lisp_Object, Lisp_Object, Lisp_Object));
 +extern void syms_of_chartab P_ ((void));
 +
  /* Defined in print.c */
  extern Lisp_Object Vprin1_to_string_buffer;
  extern void debug_print P_ ((Lisp_Object));
@@@ -2857,7 -2821,6 +2857,7 @@@ extern int overlay_touches_p P_ ((int))
  extern Lisp_Object Vbuffer_alist, Vinhibit_read_only;
  EXFUN (Fget_buffer, 1);
  EXFUN (Fget_buffer_create, 1);
 +EXFUN (Fgenerate_new_buffer_name, 2);
  EXFUN (Fset_buffer, 1);
  EXFUN (set_buffer_if_live, 1);
  EXFUN (Fbarf_if_buffer_read_only, 0);
@@@ -3193,7 -3156,6 +3193,7 @@@ extern Lisp_Object Qinsert_in_front_hoo
  EXFUN (Fnext_single_property_change, 4);
  EXFUN (Fnext_single_char_property_change, 4);
  EXFUN (Fprevious_single_property_change, 4);
 +EXFUN (Fget_text_property, 3);
  EXFUN (Fput_text_property, 5);
  EXFUN (Fprevious_char_property_change, 2);
  EXFUN (Fnext_char_property_change, 2);
@@@ -3251,7 -3213,6 +3251,7 @@@ extern void init_sound P_ ((void))
  
  /* Defined in category.c */
  extern void init_category_once P_ ((void));
 +extern Lisp_Object char_category_set P_ ((int));
  extern void syms_of_category P_ ((void));
  
  /* Defined in ccl.c */
@@@ -3268,8 -3229,7 +3268,8 @@@ extern void fatal () NO_RETURN
  #ifdef HAVE_WINDOW_SYSTEM
  /* Defined in fontset.c */
  extern void syms_of_fontset P_ ((void));
 -EXFUN (Fset_fontset_font, 4);
 +EXFUN (Fset_fontset_font, 5);
 +EXFUN (Fnew_fontset, 2);
  
  /* Defined in xfns.c, w32fns.c, or macfns.c */
  EXFUN (Fxw_display_color_p, 1);
diff --combined src/lread.c
index d6fab4ffc8cc9c31ad292d22599307bde53861cc,b77a621f51881f19b3bb6808a1f342e3779590a6..197dc8c3582d603a1caa28f7aed77b0524c033b6
@@@ -1,7 -1,7 +1,7 @@@
  /* Lisp parsing and input streams.
     Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995,
                   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -30,9 -30,7 +30,9 @@@ Boston, MA 02110-1301, USA.  *
  #include "lisp.h"
  #include "intervals.h"
  #include "buffer.h"
 +#include "character.h"
  #include "charset.h"
 +#include "coding.h"
  #include <epaths.h>
  #include "commands.h"
  #include "keyboard.h"
@@@ -91,12 -89,6 +91,12 @@@ Lisp_Object Qinhibit_file_name_operatio
  Lisp_Object Qeval_buffer_list, Veval_buffer_list;
  Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */
  
 +/* Used instead of Qget_file_char while loading *.elc files compiled
 +   by Emacs 21 or older.  */
 +static Lisp_Object Qget_emacs_mule_file_char;
 +
 +static Lisp_Object Qload_force_doc_strings;
 +
  extern Lisp_Object Qevent_symbol_element_mask;
  extern Lisp_Object Qfile_exists_p;
  
@@@ -140,11 -132,6 +140,11 @@@ static int load_force_doc_strings
  /* Nonzero means read should convert strings to unibyte.  */
  static int load_convert_to_unibyte;
  
 +/* Nonzero means READCHAR should read bytes one by one (not character)
 +   when READCHARFUN is Qget_file_char or Qget_emacs_mule_file_char.
 +   This is set to 1 by read1 temporarily while handling #@NUMBER.  */
 +static int load_each_byte;
 +
  /* Function to use for loading an Emacs Lisp source file (not
     compiled) instead of readevalloop.  */
  Lisp_Object Vload_source_file_function;
@@@ -173,6 -160,9 +173,6 @@@ static int read_from_string_index
  static int read_from_string_index_byte;
  static int read_from_string_limit;
  
 -/* Number of bytes left to read in the buffer character
 -   that `readchar' has already advanced over.  */
 -static int readchar_backlog;
  /* Number of characters read in the current call to Fread or
     Fread_from_string. */
  static int readchar_count;
@@@ -216,9 -206,7 +216,9 @@@ int load_dangerous_libraries
  
  static Lisp_Object Vbytecomp_version_regexp;
  
 -static void to_multibyte P_ ((char **, char **, int *));
 +static int read_emacs_mule_char P_ ((int, int (*) (int, Lisp_Object),
 +                                   Lisp_Object));
 +
  static void readevalloop P_ ((Lisp_Object, FILE*, Lisp_Object,
                              Lisp_Object (*) (), int,
                              Lisp_Object, Lisp_Object,
@@@ -230,41 -218,29 +230,41 @@@ static void invalid_syntax P_ ((const c
  static void end_of_file_error P_ (()) NO_RETURN;
  
  \f
 +/* Functions that read one byte from the current source READCHARFUN
 +   or unreads one byte.  If the integer argument C is -1, it returns
 +   one read byte, or -1 when there's no more byte in the source.  If C
 +   is 0 or positive, it unreads C, and the return value is not
 +   interesting.  */
 +
 +static int readbyte_for_lambda P_ ((int, Lisp_Object));
 +static int readbyte_from_file P_ ((int, Lisp_Object));
 +static int readbyte_from_string P_ ((int, Lisp_Object));
 +
  /* Handle unreading and rereading of characters.
     Write READCHAR to read a character,
     UNREAD(c) to unread c to be read again.
  
 -   The READCHAR and UNREAD macros are meant for reading/unreading a
 -   byte code; they do not handle multibyte characters.  The caller
 -   should manage them if necessary.
 -
 -   [ Actually that seems to be a lie; READCHAR will definitely read
 -     multibyte characters from buffer sources, at least.  Is the
 -     comment just out of date?
 -     -- Colin Walters <walters@gnu.org>, 22 May 2002 16:36:50 -0400 ]
 - */
 +   These macros correctly read/unread multibyte characters.  */
  
  #define READCHAR readchar (readcharfun)
  #define UNREAD(c) unreadchar (readcharfun, c)
  
 +/* When READCHARFUN is Qget_file_char, Qget_emacs_mule_file_char,
 +   Qlambda, or a cons, we use this to keep an unread character because
 +   a file stream can't handle multibyte-char unreading.  The value -1
 +   means that there's no unread character. */
 +static int unread_char;
 +
  static int
  readchar (readcharfun)
       Lisp_Object readcharfun;
  {
    Lisp_Object tem;
    register int c;
 +  int (*readbyte) P_ ((int, Lisp_Object));
 +  unsigned char buf[MAX_MULTIBYTE_LENGTH];
 +  int i, len;
 +  int emacs_mule_encoding = 0;
  
    readchar_count++;
  
        register struct buffer *inbuffer = XBUFFER (readcharfun);
  
        int pt_byte = BUF_PT_BYTE (inbuffer);
 -      int orig_pt_byte = pt_byte;
 -
 -      if (readchar_backlog > 0)
 -      /* We get the address of the byte just passed,
 -         which is the last byte of the character.
 -         The other bytes in this character are consecutive with it,
 -         because the gap can't be in the middle of a character.  */
 -      return *(BUF_BYTE_ADDRESS (inbuffer, BUF_PT_BYTE (inbuffer) - 1)
 -               - --readchar_backlog);
  
        if (pt_byte >= BUF_ZV_BYTE (inbuffer))
        return -1;
  
 -      readchar_backlog = -1;
 -
        if (! NILP (inbuffer->enable_multibyte_characters))
        {
          /* Fetch the character code from the buffer.  */
        else
        {
          c = BUF_FETCH_BYTE (inbuffer, pt_byte);
 +        if (! ASCII_BYTE_P (c))
 +          c = BYTE8_TO_CHAR (c);
          pt_byte++;
        }
        SET_BUF_PT_BOTH (inbuffer, BUF_PT (inbuffer) + 1, pt_byte);
        register struct buffer *inbuffer = XMARKER (readcharfun)->buffer;
  
        int bytepos = marker_byte_position (readcharfun);
 -      int orig_bytepos = bytepos;
 -
 -      if (readchar_backlog > 0)
 -      /* We get the address of the byte just passed,
 -         which is the last byte of the character.
 -         The other bytes in this character are consecutive with it,
 -         because the gap can't be in the middle of a character.  */
 -      return *(BUF_BYTE_ADDRESS (inbuffer, XMARKER (readcharfun)->bytepos - 1)
 -               - --readchar_backlog);
  
        if (bytepos >= BUF_ZV_BYTE (inbuffer))
        return -1;
  
 -      readchar_backlog = -1;
 -
        if (! NILP (inbuffer->enable_multibyte_characters))
        {
          /* Fetch the character code from the buffer.  */
        else
        {
          c = BUF_FETCH_BYTE (inbuffer, bytepos);
 +        if (! ASCII_BYTE_P (c))
 +          c = BYTE8_TO_CHAR (c);
          bytepos++;
        }
  
      }
  
    if (EQ (readcharfun, Qlambda))
 -    return read_bytecode_char (0);
 +    {
 +      readbyte = readbyte_for_lambda;
 +      goto read_multibyte;
 +    }
  
    if (EQ (readcharfun, Qget_file_char))
      {
 -      c = getc (instream);
 -#ifdef EINTR
 -      /* Interrupted reads have been observed while reading over the network */
 -      while (c == EOF && ferror (instream) && errno == EINTR)
 -      {
 -        QUIT;
 -        clearerr (instream);
 -        c = getc (instream);
 -      }
 -#endif
 -      return c;
 +      readbyte = readbyte_from_file;
 +      goto read_multibyte;
      }
  
    if (STRINGP (readcharfun))
        return c;
      }
  
 +  if (CONSP (readcharfun))
 +    {
 +      /* This is the case that read_vector is reading from a unibyte
 +       string that contains a byte sequence previously skipped
 +       because of #@NUMBER.  The car part of readcharfun is that
 +       string, and the cdr part is a value of readcharfun given to
 +       read_vector.  */
 +      readbyte = readbyte_from_string;
 +      if (EQ (XCDR (readcharfun), Qget_emacs_mule_file_char))
 +      emacs_mule_encoding = 1;
 +      goto read_multibyte;
 +    }
 +
 +  if (EQ (readcharfun, Qget_emacs_mule_file_char))
 +    {
 +      readbyte = readbyte_from_file;
 +      emacs_mule_encoding = 1;
 +      goto read_multibyte;
 +    }
 +
    tem = call0 (readcharfun);
  
    if (NILP (tem))
      return -1;
    return XINT (tem);
 +
 + read_multibyte:
 +  if (unread_char >= 0)
 +    {
 +      c = unread_char;
 +      unread_char = -1;
 +      return c;
 +    }
 +  c = (*readbyte) (-1, readcharfun);
 +  if (c < 0 || ASCII_BYTE_P (c) || load_each_byte)
 +    return c;
 +  if (emacs_mule_encoding)
 +    return read_emacs_mule_char (c, readbyte, readcharfun);
 +  i = 0;
 +  buf[i++] = c;
 +  len = BYTES_BY_CHAR_HEAD (c);
 +  while (i < len)
 +    {
 +      c = (*readbyte) (-1, readcharfun);
 +      if (c < 0 || ! TRAILING_CODE_P (c))
 +      {
 +        while (--i > 1)
 +          (*readbyte) (buf[i], readcharfun);
 +        return BYTE8_TO_CHAR (buf[0]);
 +      }
 +      buf[i++] = c;
 +    }
 +  return STRING_CHAR (buf, i);
  }
  
  /* Unread the character C in the way appropriate for the stream READCHARFUN.
@@@ -422,26 -374,36 +422,26 @@@ unreadchar (readcharfun, c
        struct buffer *b = XBUFFER (readcharfun);
        int bytepos = BUF_PT_BYTE (b);
  
 -      if (readchar_backlog >= 0)
 -      readchar_backlog++;
 +      BUF_PT (b)--;
 +      if (! NILP (b->enable_multibyte_characters))
 +      BUF_DEC_POS (b, bytepos);
        else
 -      {
 -        BUF_PT (b)--;
 -        if (! NILP (b->enable_multibyte_characters))
 -          BUF_DEC_POS (b, bytepos);
 -        else
 -          bytepos--;
 +      bytepos--;
  
 -        BUF_PT_BYTE (b) = bytepos;
 -      }
 +      BUF_PT_BYTE (b) = bytepos;
      }
    else if (MARKERP (readcharfun))
      {
        struct buffer *b = XMARKER (readcharfun)->buffer;
        int bytepos = XMARKER (readcharfun)->bytepos;
  
 -      if (readchar_backlog >= 0)
 -      readchar_backlog++;
 +      XMARKER (readcharfun)->charpos--;
 +      if (! NILP (b->enable_multibyte_characters))
 +      BUF_DEC_POS (b, bytepos);
        else
 -      {
 -        XMARKER (readcharfun)->charpos--;
 -        if (! NILP (b->enable_multibyte_characters))
 -          BUF_DEC_POS (b, bytepos);
 -        else
 -          bytepos--;
 +      bytepos--;
  
 -        XMARKER (readcharfun)->bytepos = bytepos;
 -      }
 +      XMARKER (readcharfun)->bytepos = bytepos;
      }
    else if (STRINGP (readcharfun))
      {
        read_from_string_index_byte
        = string_char_to_byte (readcharfun, read_from_string_index);
      }
 +  else if (CONSP (readcharfun))
 +    {
 +      unread_char = c;
 +    }
    else if (EQ (readcharfun, Qlambda))
 -    read_bytecode_char (1);
 -  else if (EQ (readcharfun, Qget_file_char))
 -    ungetc (c, instream);
 +    {
 +      unread_char = c;
 +    }
 +  else if (EQ (readcharfun, Qget_file_char)
 +         || EQ (readcharfun, Qget_emacs_mule_file_char))
 +    {
 +      if (load_each_byte)
 +      ungetc (c, instream);
 +      else
 +      unread_char = c;
 +    }
    else
      call1 (readcharfun, make_number (c));
  }
  
 +static int
 +readbyte_for_lambda (c, readcharfun)
 +     int c;
 +     Lisp_Object readcharfun;
 +{
 +  return read_bytecode_char (c >= 0);
 +}
 +
 +
 +static int
 +readbyte_from_file (c, readcharfun)
 +     int c;
 +     Lisp_Object readcharfun;
 +{
 +  if (c >= 0)
 +    {
 +      ungetc (c, instream);
 +      return 0;
 +    }
 +
 +  c = getc (instream);
 +#ifdef EINTR
 +      /* Interrupted reads have been observed while reading over the network */
 +      while (c == EOF && ferror (instream) && errno == EINTR)
 +      {
 +        QUIT;
 +        clearerr (instream);
 +        c = getc (instream);
 +      }
 +#endif
 +  return (c == EOF ? -1 : c);
 +}
 +
 +static int
 +readbyte_from_string (c, readcharfun)
 +     int c;
 +     Lisp_Object readcharfun;
 +{
 +  Lisp_Object string = XCAR (readcharfun);
 +
 +  if (c >= 0)
 +    {
 +      read_from_string_index--;
 +      read_from_string_index_byte
 +      = string_char_to_byte (string, read_from_string_index);
 +    }
 +
 +  if (read_from_string_index >= read_from_string_limit)
 +    c = -1;
 +  else
 +    FETCH_STRING_CHAR_ADVANCE (c, string,
 +                             read_from_string_index,
 +                             read_from_string_index_byte);
 +  return c;
 +}
 +
 +
 +/* Read one non-ASCII character from INSTREAM.  The character is
 +   encoded in `emacs-mule' and the first byte is already read in
 +   C.  */
 +
 +extern char emacs_mule_bytes[256];
 +
 +static int
 +read_emacs_mule_char (c, readbyte, readcharfun)
 +     int c;
 +     int (*readbyte) P_ ((int, Lisp_Object));
 +     Lisp_Object readcharfun;
 +{
 +  /* Emacs-mule coding uses at most 4-byte for one character.  */
 +  unsigned char buf[4];
 +  int len = emacs_mule_bytes[c];
 +  struct charset *charset;
 +  int i;
 +  unsigned code;
 +
 +  if (len == 1)
 +    /* C is not a valid leading-code of `emacs-mule'.  */
 +    return BYTE8_TO_CHAR (c);
 +
 +  i = 0;
 +  buf[i++] = c;
 +  while (i < len)
 +    {
 +      c = (*readbyte) (-1, readcharfun);
 +      if (c < 0xA0)
 +      {
 +        while (--i > 1)
 +          (*readbyte) (buf[i], readcharfun);
 +        return BYTE8_TO_CHAR (buf[0]);
 +      }
 +      buf[i++] = c;
 +    }
 +
 +  if (len == 2)
 +    {
 +      charset = emacs_mule_charset[buf[0]];
 +      code = buf[1] & 0x7F;
 +    }
 +  else if (len == 3)
 +    {
 +      if (buf[0] == EMACS_MULE_LEADING_CODE_PRIVATE_11
 +        || buf[0] == EMACS_MULE_LEADING_CODE_PRIVATE_12)
 +      {
 +        charset = emacs_mule_charset[buf[1]];
 +        code = buf[2] & 0x7F;
 +      }
 +      else
 +      {
 +        charset = emacs_mule_charset[buf[0]];
 +        code = ((buf[1] << 8) | buf[2]) & 0x7F7F;
 +      }
 +    }
 +  else
 +    {
 +      charset = emacs_mule_charset[buf[1]];
 +      code = ((buf[2] << 8) | buf[3]) & 0x7F7F;
 +    }
 +  c = DECODE_CHAR (charset, code);
 +  if (c < 0)
 +    Fsignal (Qinvalid_read_syntax,
 +           Fcons (build_string ("invalid multibyte form"), Qnil));
 +  return c;
 +}
 +
 +
  static Lisp_Object read_internal_start P_ ((Lisp_Object, Lisp_Object,
                                            Lisp_Object));
  static Lisp_Object read0 P_ ((Lisp_Object));
@@@ -602,6 -426,7 +602,6 @@@ static Lisp_Object read1 P_ ((Lisp_Obje
  
  static Lisp_Object read_list P_ ((int, Lisp_Object));
  static Lisp_Object read_vector P_ ((Lisp_Object, int));
 -static int read_multibyte P_ ((int, Lisp_Object));
  
  static Lisp_Object substitute_object_recurse P_ ((Lisp_Object, Lisp_Object,
                                                  Lisp_Object));
@@@ -806,11 -631,11 +806,11 @@@ DEFUN ("get-file-char", Fget_file_char
  
  
  \f
 -/* Value is non-zero if the file asswociated with file descriptor FD
 -   is a compiled Lisp file that's safe to load.  Only files compiled
 -   with Emacs are safe to load.  Files compiled with XEmacs can lead
 -   to a crash in Fbyte_code because of an incompatible change in the
 -   byte compiler.  */
 +/* Value is a version number of byte compiled code if the file
 +   asswociated with file descriptor FD is a compiled Lisp file that's
 +   safe to load.  Only files compiled with Emacs are safe to load.
 +   Files compiled with XEmacs can lead to a crash in Fbyte_code
 +   because of an incompatible change in the byte compiler.  */
  
  static int
  safe_to_load_p (fd)
    char buf[512];
    int nbytes, i;
    int safe_p = 1;
 +  int version = 1;
  
    /* Read the first few bytes from the file, and look for a line
       specifying the byte compiler version used.  */
        buf[nbytes] = '\0';
  
        /* Skip to the next newline, skipping over the initial `ELC'
 -       with NUL bytes following it.  */
 +       with NUL bytes following it, but note the version.  */
        for (i = 0; i < nbytes && buf[i] != '\n'; ++i)
 -      ;
 +      if (i == 4)
 +        version = buf[i];
  
 -      if (i < nbytes
 -        && fast_c_string_match_ignore_case (Vbytecomp_version_regexp,
 +      if (i == nbytes
 +        || fast_c_string_match_ignore_case (Vbytecomp_version_regexp,
                                              buf + i) < 0)
        safe_p = 0;
      }
 +  if (safe_p)
 +    safe_p = version;
  
    lseek (fd, 0, SEEK_SET);
    return safe_p;
@@@ -941,8 -762,6 +941,8 @@@ Return t if the file exists and loads s
    int safe_p = 1;
    char *fmode = "r";
    Lisp_Object tmp[2];
 +  int version;
 +
  #ifdef DOS_NT
    fmode = "rt";
  #endif /* DOS_NT */
                                     tmp))
                      : found) ;
  
 +  version = -1;
    if (!bcmp (SDATA (found) + SBYTES (found) - 4,
 -           ".elc", 4))
 +           ".elc", 4)
 +      || (version = safe_to_load_p (fd)) > 0)
      /* Load .elc files directly, but not when they are
         remote and have no handler!  */
      {
  
          GCPRO3 (file, found, hist_file_name);
  
 -        if (!safe_to_load_p (fd))
 +        if (version < 0
 +            && ! (version = safe_to_load_p (fd)))
            {
              safe_p = 0;
              if (!load_dangerous_libraries)
    load_descriptor_list
      = Fcons (make_number (fileno (stream)), load_descriptor_list);
    load_in_progress++;
 -  readevalloop (Qget_file_char, stream, hist_file_name,
 -              Feval, 0, Qnil, Qnil, Qnil, Qnil);
 +  if (! version || version >= 22)
 +    readevalloop (Qget_file_char, stream, hist_file_name,
 +                Feval, 0, Qnil, Qnil, Qnil, Qnil);
 +  else
 +    {
 +      /* We can't handle a file which was compiled with
 +       byte-compile-dynamic by older version of Emacs.  */
 +      specbind (Qload_force_doc_strings, Qt);
 +      readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name, Feval,
 +                  0, Qnil, Qnil, Qnil, Qnil);
 +    }
    unbind_to (count, Qnil);
  
    /* Run any eval-after-load forms for this file */
@@@ -1616,6 -1423,8 +1616,6 @@@ readevalloop (readcharfun, stream, sour
    record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil);
    load_convert_to_unibyte = !NILP (unibyte);
  
 -  readchar_backlog = -1;
 -
    GCPRO4 (sourcename, readfun, start, end);
  
    /* Try to ensure sourcename is a truename, except whilst preloading. */
@@@ -1871,6 -1680,7 +1871,6 @@@ read_internal_start (stream, start, end
  {
    Lisp_Object retval;
  
 -  readchar_backlog = -1;
    readchar_count = 0;
    new_backquote_flag = 0;
    read_objects = Qnil;
        || EQ (Vread_with_symbol_positions, stream))
      Vread_symbol_positions_list = Qnil;
  
 -  if (STRINGP (stream))
 +  if (STRINGP (stream)
 +      || ((CONSP (stream) && STRINGP (XCAR (stream)))))
      {
        int startval, endval;
 +      Lisp_Object string;
 +
 +      if (STRINGP (stream))
 +      string = stream;
 +      else
 +      string = XCAR (stream);
 +
        if (NILP (end))
 -      endval = SCHARS (stream);
 +      endval = SCHARS (string);
        else
        {
          CHECK_NUMBER (end);
          endval = XINT (end);
 -        if (endval < 0 || endval > SCHARS (stream))
 -          args_out_of_range (stream, end);
 +        if (endval < 0 || endval > SCHARS (string))
 +          args_out_of_range (string, end);
        }
  
        if (NILP (start))
          CHECK_NUMBER (start);
          startval = XINT (start);
          if (startval < 0 || startval > endval)
 -          args_out_of_range (stream, start);
 +          args_out_of_range (string, start);
        }
        read_from_string_index = startval;
 -      read_from_string_index_byte = string_char_to_byte (stream, startval);
 +      read_from_string_index_byte = string_char_to_byte (string, startval);
        read_from_string_limit = endval;
      }
  
@@@ -1956,19 -1758,59 +1956,19 @@@ read0 (readcharfun
  static int read_buffer_size;
  static char *read_buffer;
  
 -/* Read multibyte form and return it as a character.  C is a first
 -   byte of multibyte form, and rest of them are read from
 -   READCHARFUN.  */
 -
 -static int
 -read_multibyte (c, readcharfun)
 -     register int c;
 -     Lisp_Object readcharfun;
 -{
 -  /* We need the actual character code of this multibyte
 -     characters.  */
 -  unsigned char str[MAX_MULTIBYTE_LENGTH];
 -  int len = 0;
 -  int bytes;
 -
 -  if (c < 0)
 -    return c;
 -
 -  str[len++] = c;
 -  while ((c = READCHAR) >= 0xA0
 -       && len < MAX_MULTIBYTE_LENGTH)
 -    {
 -      str[len++] = c;
 -      readchar_count--;
 -    }
 -  UNREAD (c);
 -  if (UNIBYTE_STR_AS_MULTIBYTE_P (str, len, bytes))
 -    return STRING_CHAR (str, len);
 -  /* The byte sequence is not valid as multibyte.  Unread all bytes
 -     but the first one, and return the first byte.  */
 -  while (--len > 0)
 -    UNREAD (str[len]);
 -  return str[0];
 -}
 -
  /* Read a \-escape sequence, assuming we already read the `\'.
 -   If the escape sequence forces unibyte, store 1 into *BYTEREP.
 -   If the escape sequence forces multibyte, store 2 into *BYTEREP.
 -   Otherwise store 0 into *BYTEREP.  */
 +   If the escape sequence forces unibyte, return eight-bit char.  */
  
  static int
 -read_escape (readcharfun, stringp, byterep)
 +read_escape (readcharfun, stringp)
       Lisp_Object readcharfun;
       int stringp;
 -     int *byterep;
  {
    register int c = READCHAR;
    /* \u allows up to four hex digits, \U up to eight. Default to the
       behaviour for \u, and change this value in the case that \U is seen. */
    int unicode_hex_count = 4;
  
 -  *byterep = 0;
 -
    switch (c)
      {
      case -1:
        error ("Invalid escape character syntax");
        c = READCHAR;
        if (c == '\\')
 -      c = read_escape (readcharfun, 0, byterep);
 +      c = read_escape (readcharfun, 0);
        return c | meta_modifier;
  
      case 'S':
        error ("Invalid escape character syntax");
        c = READCHAR;
        if (c == '\\')
 -      c = read_escape (readcharfun, 0, byterep);
 +      c = read_escape (readcharfun, 0);
        return c | shift_modifier;
  
      case 'H':
        error ("Invalid escape character syntax");
        c = READCHAR;
        if (c == '\\')
 -      c = read_escape (readcharfun, 0, byterep);
 +      c = read_escape (readcharfun, 0);
        return c | hyper_modifier;
  
      case 'A':
        error ("Invalid escape character syntax");
        c = READCHAR;
        if (c == '\\')
 -      c = read_escape (readcharfun, 0, byterep);
 +      c = read_escape (readcharfun, 0);
        return c | alt_modifier;
  
      case 's':
        }
        c = READCHAR;
        if (c == '\\')
 -      c = read_escape (readcharfun, 0, byterep);
 +      c = read_escape (readcharfun, 0);
        return c | super_modifier;
  
      case 'C':
      case '^':
        c = READCHAR;
        if (c == '\\')
 -      c = read_escape (readcharfun, 0, byterep);
 +      c = read_escape (readcharfun, 0);
        if ((c & ~CHAR_MODIFIER_MASK) == '?')
        return 0177 | (c & CHAR_MODIFIER_MASK);
        else if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
              }
          }
  
 -      *byterep = 1;
 +      if (i >= 0x80 && i < 0x100)
 +        i = BYTE8_TO_CHAR (i);
        return i;
        }
  
        /* A hex escape, as in ANSI C.  */
        {
        int i = 0;
 +      int count = 0;
        while (1)
          {
            c = READCHAR;
                UNREAD (c);
                break;
              }
 +          count++;
          }
  
 -      *byterep = 2;
 +      if (count < 3 && i >= 0x80)
 +        return BYTE8_TO_CHAR (i);
        return i;
        }
  
        {
        int i = 0;
        int count = 0;
 -      Lisp_Object lisp_char;
 -      struct gcpro gcpro1;
  
        while (++count <= unicode_hex_count)
          {
              }
          }
  
 -      GCPRO1 (readcharfun);
 -      lisp_char = call2 (intern ("decode-char"), intern ("ucs"),
 -                        make_number (i));
 -      UNGCPRO;
 -
 -      if (NILP (lisp_char))
 -        {
 -          error ("Unsupported Unicode code point: U+%x", (unsigned)i);
 -        }
 -
 -      return XFASTINT (lisp_char);
 +      return i;
        }
  
      default:
 -      if (BASE_LEADING_CODE_P (c))
 -      c = read_multibyte (c, readcharfun);
        return c;
      }
  }
@@@ -2234,6 -2086,43 +2234,6 @@@ read_integer (readcharfun, radix
  }
  
  
 -/* Convert unibyte text in read_buffer to multibyte.
 -
 -   Initially, *P is a pointer after the end of the unibyte text, and
 -   the pointer *END points after the end of read_buffer.
 -
 -   If read_buffer doesn't have enough room to hold the result
 -   of the conversion, reallocate it and adjust *P and *END.
 -
 -   At the end, make *P point after the result of the conversion, and
 -   return in *NCHARS the number of characters in the converted
 -   text.  */
 -
 -static void
 -to_multibyte (p, end, nchars)
 -     char **p, **end;
 -     int *nchars;
 -{
 -  int nbytes;
 -
 -  parse_str_as_multibyte (read_buffer, *p - read_buffer, &nbytes, nchars);
 -  if (read_buffer_size < 2 * nbytes)
 -    {
 -      int offset = *p - read_buffer;
 -      read_buffer_size = 2 * max (read_buffer_size, nbytes);
 -      read_buffer = (char *) xrealloc (read_buffer, read_buffer_size);
 -      *p = read_buffer + offset;
 -      *end = read_buffer + read_buffer_size;
 -    }
 -
 -  if (nbytes != *nchars)
 -    nbytes = str_as_multibyte (read_buffer, read_buffer_size,
 -                             *p - read_buffer, nchars);
 -
 -  *p = read_buffer + nbytes;
 -}
 -
 -
  /* If the next token is ')' or ']' or '.', we store that character
     in *PCH and the return value is not interesting.  Else, we store
     zero in *PCH and we read and return one lisp object.
@@@ -2250,7 -2139,6 +2250,7 @@@ read1 (readcharfun, pch, first_in_list
    int uninterned_symbol = 0;
  
    *pch = 0;
 +  load_each_byte = 0;
  
   retry:
  
            {
              Lisp_Object tmp;
              tmp = read_vector (readcharfun, 0);
 -            if (XVECTOR (tmp)->size < CHAR_TABLE_STANDARD_SLOTS
 -                || XVECTOR (tmp)->size > CHAR_TABLE_STANDARD_SLOTS + 10)
 +            if (XVECTOR (tmp)->size < VECSIZE (struct Lisp_Char_Table))
                error ("Invalid size char-table");
              XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp));
 -            XCHAR_TABLE (tmp)->top = Qt;
              return tmp;
            }
          else if (c == '^')
              if (c == '[')
                {
                  Lisp_Object tmp;
 +                int depth, size;
 +
                  tmp = read_vector (readcharfun, 0);
 -                if (XVECTOR (tmp)->size != SUB_CHAR_TABLE_STANDARD_SLOTS)
 +                if (!INTEGERP (AREF (tmp, 0)))
 +                  error ("Invalid depth in char-table");
 +                depth = XINT (AREF (tmp, 0));
 +                if (depth < 1 || depth > 3)
 +                  error ("Invalid depth in char-table");
 +                size = XVECTOR (tmp)->size - 2;
 +                if (chartab_size [depth] != size)
                    error ("Invalid size char-table");
 -                XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp));
 -                XCHAR_TABLE (tmp)->top = Qnil;
 +                XSETSUB_CHAR_TABLE (tmp, XSUB_CHAR_TABLE (tmp));
                  return tmp;
                }
              invalid_syntax ("#^^", 3);
  
              UNREAD (c);
              tmp = read1 (readcharfun, pch, first_in_list);
 -            if (size_in_chars != SCHARS (tmp)
 -                /* We used to print 1 char too many
 -                   when the number of bits was a multiple of 8.
 -                   Accept such input in case it came from an old version.  */
 -                && ! (XFASTINT (length)
 -                      == (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR))
 +            if (STRING_MULTIBYTE (tmp)
 +                || (size_in_chars != SCHARS (tmp)
 +                    /* We used to print 1 char too many
 +                       when the number of bits was a multiple of 8.
 +                       Accept such input in case it came from an old
 +                       version.  */
 +                    && ! (XFASTINT (length)
 +                          == (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR)))
                invalid_syntax ("#&...", 5);
  
              val = Fmake_bool_vector (length, Qnil);
        {
          int i, nskip = 0;
  
 +        load_each_byte = 1;
          /* Read a decimal integer.  */
          while ((c = READCHAR) >= 0
                 && c >= '0' && c <= '9')
          if (c >= 0)
            UNREAD (c);
  
 -        if (load_force_doc_strings && EQ (readcharfun, Qget_file_char))
 +        if (load_force_doc_strings
 +            && (EQ (readcharfun, Qget_file_char)
 +                || EQ (readcharfun, Qget_emacs_mule_file_char)))
            {
              /* If we are supposed to force doc strings into core right now,
                 record the last string that we skipped,
                c = READCHAR;
            }
  
 +        load_each_byte = 0;
          goto retry;
        }
        if (c == '!')
  
      case '?':
        {
 -      int discard;
 +      int modifiers;
        int next_char;
        int ok;
  
          return make_number (c);
  
        if (c == '\\')
 -        c = read_escape (readcharfun, 0, &discard);
 -      else if (BASE_LEADING_CODE_P (c))
 -        c = read_multibyte (c, readcharfun);
 +        c = read_escape (readcharfun, 0);
 +      modifiers = c & CHAR_MODIFIER_MASK;
 +      c &= ~CHAR_MODIFIER_MASK;
 +      if (CHAR_BYTE8_P (c))
 +        c = CHAR_TO_BYTE8 (c);
 +      c |= modifiers;
  
        next_char = READCHAR;
        if (next_char == '.')
        char *p = read_buffer;
        char *end = read_buffer + read_buffer_size;
        register int c;
 -      /* 1 if we saw an escape sequence specifying
 -         a multibyte character, or a multibyte character.  */
 +      /* Nonzero if we saw an escape sequence specifying
 +         a multibyte character.  */
        int force_multibyte = 0;
 -      /* 1 if we saw an escape sequence specifying
 +      /* Nonzero if we saw an escape sequence specifying
           a single-byte character.  */
        int force_singlebyte = 0;
 -      /* 1 if read_buffer contains multibyte text now.  */
 -      int is_multibyte = 0;
        int cancel = 0;
        int nchars = 0;
  
  
            if (c == '\\')
              {
 -              int byterep;
 +              int modifiers;
  
 -              c = read_escape (readcharfun, 1, &byterep);
 +              c = read_escape (readcharfun, 1);
  
                /* C is -1 if \ newline has just been seen */
                if (c == -1)
                    continue;
                  }
  
 -              if (byterep == 1)
 +              modifiers = c & CHAR_MODIFIER_MASK;
 +              c = c & ~CHAR_MODIFIER_MASK;
 +
 +              if (CHAR_BYTE8_P (c))
                  force_singlebyte = 1;
 -              else if (byterep == 2)
 +              else if (! ASCII_CHAR_P (c))
                  force_multibyte = 1;
 -            }
 -
 -          /* A character that must be multibyte forces multibyte.  */
 -          if (! SINGLE_BYTE_CHAR_P (c & ~CHAR_MODIFIER_MASK))
 -            force_multibyte = 1;
 +              else            /* i.e. ASCII_CHAR_P (c) */
 +                {
 +                  /* Allow `\C- ' and `\C-?'.  */
 +                  if (modifiers == CHAR_CTL)
 +                    {
 +                      if (c == ' ')
 +                        c = 0, modifiers = 0;
 +                      else if (c == '?')
 +                        c = 127, modifiers = 0;
 +                    }
 +                  if (modifiers & CHAR_SHIFT)
 +                    {
 +                      /* Shift modifier is valid only with [A-Za-z].  */
 +                      if (c >= 'A' && c <= 'Z')
 +                        modifiers &= ~CHAR_SHIFT;
 +                      else if (c >= 'a' && c <= 'z')
 +                        c -= ('a' - 'A'), modifiers &= ~CHAR_SHIFT;
 +                    }
 +
 +                  if (modifiers & CHAR_META)
 +                    {
 +                      /* Move the meta bit to the right place for a
 +                         string.  */
 +                      modifiers &= ~CHAR_META;
 +                      c = BYTE8_TO_CHAR (c | 0x80);
 +                      force_singlebyte = 1;
 +                    }
 +                }
  
 -          /* If we just discovered the need to be multibyte,
 -             convert the text accumulated thus far.  */
 -          if (force_multibyte && ! is_multibyte)
 -            {
 -              is_multibyte = 1;
 -              to_multibyte (&p, &end, &nchars);
 +              /* Any modifiers remaining are invalid.  */
 +              if (modifiers)
 +                error ("Invalid modifier in string");
 +              p += CHAR_STRING (c, (unsigned char *) p);
              }
 -
 -          /* Allow `\C- ' and `\C-?'.  */
 -          if (c == (CHAR_CTL | ' '))
 -            c = 0;
 -          else if (c == (CHAR_CTL | '?'))
 -            c = 127;
 -
 -          if (c & CHAR_SHIFT)
 +          else
              {
 -              /* Shift modifier is valid only with [A-Za-z].  */
 -              if ((c & 0377) >= 'A' && (c & 0377) <= 'Z')
 -                c &= ~CHAR_SHIFT;
 -              else if ((c & 0377) >= 'a' && (c & 0377) <= 'z')
 -                c = (c & ~CHAR_SHIFT) - ('a' - 'A');
 +              p += CHAR_STRING (c, (unsigned char *) p);
 +              if (CHAR_BYTE8_P (c))
 +                force_singlebyte = 1;
 +              else if (! ASCII_CHAR_P (c))
 +                force_multibyte = 1;
              }
 -
 -          if (c & CHAR_META)
 -            /* Move the meta bit to the right place for a string.  */
 -            c = (c & ~CHAR_META) | 0x80;
 -          if (c & CHAR_MODIFIER_MASK)
 -            error ("Invalid modifier in string");
 -
 -          if (is_multibyte)
 -            p += CHAR_STRING (c, p);
 -          else
 -            *p++ = c;
 -
            nchars++;
          }
  
        if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel)
          return make_number (0);
  
 -      if (is_multibyte || force_singlebyte)
 +      if (force_multibyte)
 +        /* READ_BUFFER already contains valid multibyte forms.  */
          ;
 -      else if (load_convert_to_unibyte)
 -        {
 -          Lisp_Object string;
 -          to_multibyte (&p, &end, &nchars);
 -          if (p - read_buffer != nchars)
 -            {
 -              string = make_multibyte_string (read_buffer, nchars,
 -                                              p - read_buffer);
 -              return Fstring_make_unibyte (string);
 -            }
 -          /* We can make a unibyte string directly.  */
 -          is_multibyte = 0;
 -        }
 -      else if (EQ (readcharfun, Qget_file_char)
 -               || EQ (readcharfun, Qlambda))
 +      else if (force_singlebyte)
          {
 -          /* Nowadays, reading directly from a file is used only for
 -             compiled Emacs Lisp files, and those always use the
 -             Emacs internal encoding.  Meanwhile, Qlambda is used
 -             for reading dynamic byte code (compiled with
 -             byte-compile-dynamic = t).  So make the string multibyte
 -             if the string contains any multibyte sequences.
 -             (to_multibyte is a no-op if not.)  */
 -          to_multibyte (&p, &end, &nchars);
 -          is_multibyte = (p - read_buffer) != nchars;
 +          nchars = str_as_unibyte (read_buffer, p - read_buffer);
 +          p = read_buffer + nchars;
          }
        else
 -        /* In all other cases, if we read these bytes as
 -           separate characters, treat them as separate characters now.  */
 +        /* Otherwise, READ_BUFFER contains only ASCII.  */
          ;
  
        /* We want readchar_count to be the number of characters, not
        /* readchar_count -= (p - read_buffer) - nchars; */
        if (read_pure)
          return make_pure_string (read_buffer, nchars, p - read_buffer,
 -                                 is_multibyte);
 +                                 (force_multibyte
 +                                  || (p - read_buffer != nchars)));
        return make_specified_string (read_buffer, nchars, p - read_buffer,
 -                                    is_multibyte);
 +                                    (force_multibyte
 +                                     || (p - read_buffer != nchars)));
        }
  
      case '.':
                  quoted = 1;
                }
  
 -            if (! SINGLE_BYTE_CHAR_P (c))
 -              p += CHAR_STRING (c, p);
 -            else
 -              *p++ = c;
 -
 +            p += CHAR_STRING (c, p);
              c = READCHAR;
            }
  
                  {
                    if (p1[-1] == '.')
                      p1[-1] = '\0';
 +                  /* Fixme: if we have strtol, use that, and check
 +                     for overflow.  */
                    if (sizeof (int) == sizeof (EMACS_INT))
                      XSETINT (val, atoi (read_buffer));
                    else if (sizeof (long) == sizeof (EMACS_INT))
@@@ -3175,7 -3067,7 +3175,7 @@@ read_vector (readcharfun, bytecodeflag
                  STRING_SET_CHARS (bytestr, SBYTES (bytestr));
                  STRING_SET_UNIBYTE (bytestr);
  
 -                item = Fread (bytestr);
 +                item = Fread (Fcons (bytestr, readcharfun));
                  if (!CONSP (item))
                    error ("Invalid byte code");
  
              /* Now handle the bytecode slot.  */
              ptr[COMPILED_BYTECODE] = read_pure ? Fpurecopy (bytestr) : bytestr;
            }
 +        else if (i == COMPILED_DOC_STRING
 +                 && STRINGP (item)
 +                 && ! STRING_MULTIBYTE (item))
 +          {
 +            if (EQ (readcharfun, Qget_emacs_mule_file_char))
 +              item = Fdecode_coding_string (item, Qemacs_mule, Qnil, Qnil);
 +            else
 +              item = Fstring_as_multibyte (item);
 +          }
        }
        ptr[i] = read_pure ? Fpurecopy (item) : item;
        otem = XCONS (tem);
@@@ -3293,15 -3176,7 +3293,15 @@@ read_list (flag, readcharfun
                  if (doc_reference == 2)
                    {
                      /* Get a doc string from the file we are loading.
 -                       If it's in saved_doc_string, get it from there.  */
 +                       If it's in saved_doc_string, get it from there.
 +
 +                       Here, we don't know if the string is a
 +                       bytecode string or a doc string.  As a
 +                       bytecode string must be unibyte, we always
 +                       return a unibyte string.  If it is actually a
 +                       doc string, caller must make it
 +                       multibyte.  */
 +
                      int pos = XINT (XCDR (val));
                      /* Position is negative for user variables.  */
                      if (pos < 0) pos = -pos;
                                saved_doc_string[to++] = c;
                            }
  
 -                        return make_string (saved_doc_string + start,
 -                                            to - start);
 +                        return make_unibyte_string (saved_doc_string + start,
 +                                                    to - start);
                        }
                      /* Look in prev_saved_doc_string the same way.  */
                      else if (pos >= prev_saved_doc_string_position
                                prev_saved_doc_string[to++] = c;
                            }
  
 -                        return make_string (prev_saved_doc_string + start,
 -                                            to - start);
 +                        return make_unibyte_string (prev_saved_doc_string
 +                                                    + start,
 +                                                    to - start);
                        }
                      else
 -                      return get_doc_string (val, 0, 0);
 +                      return get_doc_string (val, 1, 0);
                    }
  
                  return val;
@@@ -4314,12 -4188,6 +4314,12 @@@ to load.  See also `load-dangerous-libr
    Qget_file_char = intern ("get-file-char");
    staticpro (&Qget_file_char);
  
 +  Qget_emacs_mule_file_char = intern ("get-emacs-mule-file-char");
 +  staticpro (&Qget_emacs_mule_file_char);
 +
 +  Qload_force_doc_strings = intern ("load-force-doc-strings");
 +  staticpro (&Qload_force_doc_strings);
 +
    Qbackquote = intern ("`");
    staticpro (&Qbackquote);
    Qcomma = intern (",");
diff --combined src/macfns.c
index 962f837c15201c223329b9566e5ba18577c6482e,f24e8c881fadf71891138d54fd432402e0c64878..fb7e661f5fa40aa7534cdbb92c26c2f2b267f6d3
@@@ -1,6 -1,6 +1,6 @@@
  /* Graphical user interface functions for Mac OS.
     Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -2659,7 -2659,7 +2659,7 @@@ This function is an internal primitive-
        {
        tem = Fquery_fontset (font, Qnil);
        if (STRINGP (tem))
 -        font = x_new_fontset (f, SDATA (tem));
 +        font = x_new_fontset (f, tem);
        else
          font = x_new_font (f, SDATA (font));
        }
        font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
      /* If those didn't work, look for something which will at least work.  */
      if (! STRINGP (font))
 -      font = x_new_fontset (f, "fontset-standard");
 +      font = x_new_fontset (f, build_string ("fontset-standard"));
      if (! STRINGP (font))
        font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
      if (! STRINGP (font))
@@@ -3876,7 -3876,7 +3876,7 @@@ x_create_tip_frame (dpyinfo, parms, tex
        {
        tem = Fquery_fontset (font, Qnil);
        if (STRINGP (tem))
 -        font = x_new_fontset (f, SDATA (tem));
 +        font = x_new_fontset (f, tem);
        else
          font = x_new_font (f, SDATA (font));
        }
        font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
      /* If those didn't work, look for something which will at least work.  */
      if (! STRINGP (font))
 -      font = x_new_fontset (f, "fontset-standard");
 +      font = x_new_fontset (f, build_string ("fontset-standard"));
      if (! STRINGP (font))
        font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
      if (! STRINGP (font))
diff --combined src/macgui.h
index 01f5317aad6028e100bd92004bb2dd9f3d4e4e53,1348fe479cb064863f9fc38fd6391515ce42bd59..3c37b86e22aa483bc689af97923932d8d7055ff3
@@@ -1,6 -1,6 +1,6 @@@
  /* Definitions and headers for communication on the Mac OS.
     Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -24,7 -24,7 +24,7 @@@ Boston, MA 02110-1301, USA.  *
  #ifndef EMACS_MACGUI_H
  #define EMACS_MACGUI_H
  
- typedef int Display;  /* fix later */
+ typedef struct _XDisplay Display; /* opaque */
  
  typedef Lisp_Object XrmDatabase;
  
@@@ -81,13 -81,11 +81,13 @@@ typedef unsigned long Time
  
  /* Whether to use ATSUI (Apple Type Services for Unicode Imaging) for
     text drawing.  */
 +#if 0 /* Don't enable by default on the emacs-unicode-2 branch.  */
  #ifndef USE_ATSUI
  #ifdef MAC_OSX
  #define USE_ATSUI 1
  #endif
  #endif
 +#endif
  
  /* Whether to use low-level Quartz 2D (aka Core Graphics) text drawing
     in preference to ATSUI for ASCII and Latin-1 characters.  */
@@@ -246,6 -244,14 +246,14 @@@ typedef struct _XG
    /* QuickDraw background color.  */
    RGBColor back_color;
  
+ #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+   /* Quartz 2D foreground color.  */
+   CGColorRef cg_fore_color;
+   /* Quartz 2D background color.  */
+   CGColorRef cg_back_color;
+ #endif
  #define MAX_CLIP_RECTS 2
    /* Number of clipping rectangles.  */
    int n_clip_rects;
diff --combined src/macterm.c
index cb0e024b8ebef1887c1c4ee3d07f4d0d3b5dfa01,ff94a67d3f1eb58b4a236ce68f405e93d2272e9e..fa2e5da8560e95807d7956c095f358495d02c95f
@@@ -1,6 -1,6 +1,6 @@@
  /* Implementation of GUI terminal on the Mac OS.
     Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -84,8 -84,6 +84,8 @@@ Boston, MA 02110-1301, USA.  *
  #include "intervals.h"
  #include "atimer.h"
  #include "keymap.h"
 +#include "character.h"
 +#include "ccl.h"
  
  \f
  
@@@ -272,16 -270,63 +272,63 @@@ static void XSetFont P_ ((Display *, GC
  #define GC_BACK_COLOR(gc)     (&(gc)->back_color)
  #define GC_FONT(gc)           ((gc)->xgcv.font)
  #define FRAME_NORMAL_GC(f)    ((f)->output_data.mac->normal_gc)
- #define CG_SET_FILL_COLOR(context, color)                     \
+ #define CG_SET_FILL_COLOR(context, color)                             \
    CGContextSetRGBFillColor (context,                                  \
                            RED_FROM_ULONG (color) / 255.0f,            \
                            GREEN_FROM_ULONG (color) / 255.0f,          \
                            BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
- #define CG_SET_STROKE_COLOR(context, color)           \
+ #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ #define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+   do {                                                                       \
+     if (CGColorGetTypeID != NULL)                                    \
+       CGContextSetFillColorWithColor (context, cg_color);            \
+     else                                                             \
+       CG_SET_FILL_COLOR (context, color);                            \
+   } while (0)
+ #else
+ #define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color)        \
+   CGContextSetFillColorWithColor (context, cg_color)
+ #endif
+ #else
+ #define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color)        \
+   CG_SET_FILL_COLOR (context, color)
+ #endif
+ #define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, gc)             \
+   CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground,       \
+                                       (gc)->cg_fore_color)
+ #define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, gc)             \
+   CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.background,       \
+                                       (gc)->cg_back_color)
+ #define CG_SET_STROKE_COLOR(context, color)                           \
    CGContextSetRGBStrokeColor (context,                                        \
                              RED_FROM_ULONG (color) / 255.0f,          \
                              GREEN_FROM_ULONG (color) / 255.0f,        \
                              BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
+ #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ #define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+   do {                                                                       \
+     if (CGColorGetTypeID != NULL)                                    \
+       CGContextSetStrokeColorWithColor (context, cg_color);          \
+     else                                                             \
+       CG_SET_STROKE_COLOR (context, color);                          \
+   } while (0)
+ #else
+ #define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+   CGContextSetStrokeColorWithColor (context, cg_color)
+ #endif
+ #else
+ #define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+   CG_SET_STROKE_COLOR (context, color)
+ #endif
+ #define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, gc) \
+   CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
+                                         (gc)->cg_fore_color)
  #if USE_CG_DRAWING
  #define FRAME_CG_CONTEXT(f)   ((f)->output_data.mac->cg_context)
  
  static int max_fringe_bmp = 0;
  static CGImageRef *fringe_bmp = 0;
  
+ static CGColorSpaceRef mac_cg_color_space_rgb;
+ #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ static CGColorRef mac_cg_color_black;
+ #endif
+ static void
+ init_cg_color ()
+ {
+   mac_cg_color_space_rgb = CGColorSpaceCreateDeviceRGB ();
+ #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+   /* Don't check the availability of CGColorCreate; this symbol is
+      defined even in Mac OS X 10.1.  */
+   if (CGColorGetTypeID != NULL)
+ #endif
+     {
+       float rgba[] = {0.0f, 0.0f, 0.0f, 1.0f};
+       mac_cg_color_black = CGColorCreate (mac_cg_color_space_rgb, rgba);
+     }
+ #endif
+ }
  static CGContextRef
  mac_begin_cg_clip (f, gc)
       struct frame *f;
@@@ -403,7 -471,7 +473,7 @@@ mac_draw_line (f, gc, x1, y1, x2, y2
      gy1 += 0.5f, gy2 += 0.5f;
  
    context = mac_begin_cg_clip (f, gc);
-   CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+   CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
    CGContextBeginPath (context);
    CGContextMoveToPoint (context, gx1, gy1);
    CGContextAddLineToPoint (context, gx2, gy2);
  #endif
  }
  
+ /* Mac version of XDrawLine (to Pixmap).  */
  void
mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
XDrawLine (display, p, gc, x1, y1, x2, y2)
       Display *display;
       Pixmap p;
       GC gc;
@@@ -487,7 -557,7 +559,7 @@@ mac_erase_rectangle (f, gc, x, y, width
    CGContextRef context;
  
    context = mac_begin_cg_clip (f, gc);
-   CG_SET_FILL_COLOR (context, gc->xgcv.background);
+   CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
    CGContextFillRect (context, CGRectMake (x, y, width, height));
    mac_end_cg_clip (f);
  #else
@@@ -529,7 -599,7 +601,7 @@@ mac_clear_window (f
    GC gc = FRAME_NORMAL_GC (f);
  
    context = mac_begin_cg_clip (f, NULL);
-   CG_SET_FILL_COLOR (context, gc->xgcv.background);
+   CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
    CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
                                          FRAME_PIXEL_HEIGHT (f)));
    mac_end_cg_clip (f);
@@@ -572,14 -642,14 +644,14 @@@ mac_draw_cg_image (image, f, gc, src_x
    context = mac_begin_cg_clip (f, gc);
    if (!overlay_p)
      {
-       CG_SET_FILL_COLOR (context, gc->xgcv.background);
+       CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
        CGContextFillRect (context, dest_rect);
      }
    CGContextClipToRect (context, dest_rect);
    CGContextScaleCTM (context, 1, -1);
    CGContextTranslateCTM (context, 0, -port_height);
    if (CGImageIsMask (image))
-     CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+     CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
    CGContextDrawImage (context,
                      CGRectMake (dest_x - src_x,
                                  port_height - (dest_y - src_y
@@@ -766,7 -836,7 +838,7 @@@ mac_fill_rectangle (f, gc, x, y, width
    CGContextRef context;
  
    context = mac_begin_cg_clip (f, gc);
-   CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+   CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
    CGContextFillRect (context, CGRectMake (x, y, width, height));
    mac_end_cg_clip (f);
  #else
@@@ -797,7 -867,7 +869,7 @@@ mac_draw_rectangle (f, gc, x, y, width
    CGContextRef context;
  
    context = mac_begin_cg_clip (f, gc);
-   CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+   CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
    CGContextStrokeRect (context,
                       CGRectMake (x + 0.5f, y + 0.5f, width, height));
    mac_end_cg_clip (f);
@@@ -984,7 -1054,7 +1056,7 @@@ mac_draw_string_common (f, gc, x, y, bu
  #endif
              if (bg_width)
                {
-                 CG_SET_FILL_COLOR (context, gc->xgcv.background);
+                 CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
                  CGContextFillRect
                    (context,
                     CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
  #if !USE_CG_DRAWING
            }
  #endif
-         CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+         CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
          err = ATSUSetLayoutControls (text_layout,
                                       sizeof (tags) / sizeof (tags[0]),
                                       tags, sizes, values);
@@@ -1346,7 -1416,7 +1418,7 @@@ mac_draw_image_string_cg (f, gc, x, y, 
  #endif
        if (bg_width)
        {
-         CG_SET_FILL_COLOR (context, gc->xgcv.background);
+         CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
          CGContextFillRect
            (context,
             CGRectMake (gx, y - FONT_BASE (GC_FONT (gc)),
  #if !USE_CG_DRAWING
      }
  #endif
-   CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+   CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
    CGContextSetFont (context, GC_FONT (gc)->cg_font);
    CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize);
    if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold)
@@@ -1560,15 -1630,25 +1632,25 @@@ XChangeGC (display, gc, mask, xgcv
  /* Mac replacement for XCreateGC.  */
  
  GC
- XCreateGC (display, window, mask, xgcv)
+ XCreateGC (display, d, mask, xgcv)
       Display *display;
-      Window window;
+      void *d;
       unsigned long mask;
       XGCValues *xgcv;
  {
    GC gc = xmalloc (sizeof (*gc));
  
    bzero (gc, sizeof (*gc));
+ #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+   if (CGColorGetTypeID != NULL)
+ #endif
+     {
+       gc->cg_fore_color = gc->cg_back_color = mac_cg_color_black;
+       CGColorRetain (gc->cg_fore_color);
+       CGColorRetain (gc->cg_back_color);
+     }
+ #endif
    XChangeGC (display, gc, mask, xgcv);
  
    return gc;
@@@ -1584,6 -1664,15 +1666,15 @@@ XFreeGC (display, gc
  {
    if (gc->clip_region)
      DisposeRgn (gc->clip_region);
+ #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+   if (CGColorGetTypeID != NULL)
+ #endif
+     {
+       CGColorRelease (gc->cg_fore_color);
+       CGColorRelease (gc->cg_back_color);
+     }
+ #endif
    xfree (gc);
  }
  
@@@ -1620,6 -1709,29 +1711,29 @@@ XSetForeground (display, gc, color
        gc->fore_color.red = RED16_FROM_ULONG (color);
        gc->fore_color.green = GREEN16_FROM_ULONG (color);
        gc->fore_color.blue = BLUE16_FROM_ULONG (color);
+ #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+       if (CGColorGetTypeID != NULL)
+ #endif
+       {
+         CGColorRelease (gc->cg_fore_color);
+         if (color == 0)
+           {
+             gc->cg_fore_color = mac_cg_color_black;
+             CGColorRetain (gc->cg_fore_color);
+           }
+         else
+           {
+             float rgba[4];
+             rgba[0] = gc->fore_color.red / 65535.0f;
+             rgba[1] = gc->fore_color.green / 65535.0f;
+             rgba[2] = gc->fore_color.blue / 65535.0f;
+             rgba[3] = 1.0f;
+             gc->cg_fore_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+           }
+       }
+ #endif
      }
  }
  
@@@ -1638,6 -1750,29 +1752,29 @@@ XSetBackground (display, gc, color
        gc->back_color.red = RED16_FROM_ULONG (color);
        gc->back_color.green = GREEN16_FROM_ULONG (color);
        gc->back_color.blue = BLUE16_FROM_ULONG (color);
+ #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+       if (CGColorGetTypeID != NULL)
+ #endif
+       {
+         CGColorRelease (gc->cg_back_color);
+         if (color == 0)
+           {
+             gc->cg_back_color = mac_cg_color_black;
+             CGColorRetain (gc->cg_back_color);
+           }
+         else
+           {
+             float rgba[4];
+             rgba[0] = gc->back_color.red / 65535.0f;
+             rgba[1] = gc->back_color.green / 65535.0f;
+             rgba[2] = gc->back_color.blue / 65535.0f;
+             rgba[3] = 1.0f;
+             gc->cg_back_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+           }
+       }
+ #endif
      }
  }
  
@@@ -2193,8 -2328,7 +2330,8 @@@ XTreset_terminal_modes (
  /* Function prototypes of this page.  */
  
  static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
 -static int mac_encode_char P_ ((int, XChar2b *, struct font_info *, int *));
 +static int mac_encode_char P_ ((int, XChar2b *, struct font_info *, 
 +                              struct charset *, int *));
  
  
  static void
@@@ -2338,13 -2472,13 +2475,13 @@@ mac_per_char_metric (font, char2b, font
     the two-byte form of C.  Encoding is returned in *CHAR2B.  */
  
  static int
 -mac_encode_char (c, char2b, font_info, two_byte_p)
 +mac_encode_char (c, char2b, font_info, charset, two_byte_p)
       int c;
       XChar2b *char2b;
       struct font_info *font_info;
 +     struct charset *charset;
       int *two_byte_p;
  {
 -  int charset = CHAR_CHARSET (c);
    XFontStruct *font = font_info->font;
  
    /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
        check_ccl_update (ccl);
        if (CHARSET_DIMENSION (charset) == 1)
        {
 -        ccl->reg[0] = charset;
 -        ccl->reg[1] = char2b->byte2;
 +        ccl->reg[0] = CHARSET_ID (charset);
 +        ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
          ccl->reg[2] = -1;
        }
        else
        {
 -        ccl->reg[0] = charset;
 -        ccl->reg[1] = char2b->byte1;
 -        ccl->reg[2] = char2b->byte2;
 +        ccl->reg[0] = CHARSET_ID (charset);
 +        ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
 +        ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
        }
  
 -      ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
 +      ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
  
        /* We assume that MSBs are appropriately set/reset by CCL
         program.  */
        if (font->max_byte1 == 0)       /* 1-byte font */
 -      char2b->byte1 = 0, char2b->byte2 = ccl->reg[1];
 +      STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
        else
 -      char2b->byte1 = ccl->reg[1], char2b->byte2 = ccl->reg[2];
 +      STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
      }
 -  else if (font_info->encoding[charset])
 +  else if (font_info->encoding_type)
      {
        /* Fixed encoding scheme.  See fontset.h for the meaning of the
         encoding numbers.  */
 -      int enc = font_info->encoding[charset];
 +      unsigned char enc = font_info->encoding_type;
  
        if ((enc == 1 || enc == 2)
          && CHARSET_DIMENSION (charset) == 2)
        char2b->byte2 |= 0x80;
  
        if (enc == 4)
 -        {
 -          int sjis1, sjis2;
 +      {
 +        int code = (char2b->byte1 << 8) | char2b->byte2;
  
 -          ENCODE_SJIS (char2b->byte1, char2b->byte2, sjis1, sjis2);
 -          char2b->byte1 = sjis1;
 -          char2b->byte2 = sjis2;
 -        }
 +        JIS_TO_SJIS (code);
 +        STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
 +      }
      }
  
    if (two_byte_p)
@@@ -2516,9 -2651,9 +2653,9 @@@ x_set_mouse_face_gc (s
      face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
  
    if (s->first_glyph->type == CHAR_GLYPH)
 -    face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
 +    face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
    else
 -    face_id = FACE_FOR_CHAR (s->f, face, 0);
 +    face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
    s->face = FACE_FROM_ID (s->f, face_id);
    PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
  
@@@ -5746,16 -5881,11 +5883,16 @@@ x_new_font (f, fontname
       register char *fontname;
  {
    struct font_info *fontp
 -    = FS_LOAD_FONT (f, 0, fontname, -1);
 +    = FS_LOAD_FONT (f, fontname);
  
    if (!fontp)
      return Qnil;
  
 +  if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
 +    /* This font is already set in frame F.  There's nothing more to
 +       do.  */
 +    return build_string (fontp->full_name);
 +
    FRAME_FONT (f) = (XFontStruct *) (fontp->font);
    FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
    FRAME_FONTSET (f) = -1;
  
    return build_string (fontp->full_name);
  }
 +\f
 +/* Give frame F the fontset named FONTSETNAME as its default fontset,
 +   and return the full name of that fontset.  FONTSETNAME may be a
 +   wildcard pattern; in that case, we choose some fontset that fits
 +   the pattern.  FONTSETNAME may be a font name for ASCII characters;
 +   in that case, we create a fontset from that font name.
  
 -/* Give frame F the fontset named FONTSETNAME as its default font, and
 -   return the full name of that fontset.  FONTSETNAME may be a wildcard
 -   pattern; in that case, we choose some fontset that fits the pattern.
 -   The return value shows which fontset we chose.  */
 +   The return value shows which fontset we chose.
 +   If FONTSETNAME specifies the default fontset, return Qt.
 +   If an ASCII font in the specified fontset can't be loaded, return
 +   Qnil.  */
  
  Lisp_Object
  x_new_fontset (f, fontsetname)
       struct frame *f;
 -     char *fontsetname;
 +     Lisp_Object fontsetname;
  {
 -  int fontset = fs_query_fontset (build_string (fontsetname), 0);
 +  int fontset = fs_query_fontset (fontsetname, 0);
    Lisp_Object result;
  
 -  if (fontset < 0)
 -    return Qnil;
 -
 -  if (FRAME_FONTSET (f) == fontset)
 +  if (fontset > 0 && FRAME_FONTSET(f) == fontset)
      /* This fontset is already set in frame F.  There's nothing more
         to do.  */
      return fontset_name (fontset);
 +  else if (fontset == 0)
 +    /* The default fontset can't be the default font.   */
 +    return Qt;
  
 -  result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 +  if (fontset > 0)
 +    result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 +  else
 +    result = x_new_font (f, SDATA (fontsetname));
  
    if (!STRINGP (result))
      /* Can't load ASCII font.  */
      return Qnil;
  
 +  if (fontset < 0)
 +    fontset = new_fontset_from_font_name (result);
 +
    /* Since x_new_font doesn't update any fontset information, do it now.  */
    FRAME_FONTSET (f) = fontset;
  
 -  return build_string (fontsetname);
 +  return fontset_name (fontset);
  }
  
  \f
@@@ -6454,6 -6572,9 +6591,9 @@@ x_free_frame_resources (f
    if (wp != tip_window)
      remove_window_handler (wp);
  
+ #if USE_CG_DRAWING
+   mac_prepare_for_quickdraw (f);
+ #endif
    DisposeWindow (wp);
    if (wp == tip_window)
      /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
@@@ -7068,12 -7189,12 +7208,12 @@@ decode_mac_font_name (name, size, codin
          coding.src_multibyte = 0;
          coding.dst_multibyte = 1;
          coding.mode |= CODING_MODE_LAST_BLOCK;
 -        coding.composing = COMPOSITION_DISABLED;
 -        buf = (char *) alloca (size);
 +        coding.dst_bytes = size;
 +        coding.destination = (unsigned char *) alloca (coding.dst_bytes);
  
 -        decode_coding (&coding, name, buf, strlen (name), size - 1);
 -        bcopy (buf, name, coding.produced);
 -        name[coding.produced] = '\0';
 +        decode_coding_c_string (&coding, name, strlen (name), Qnil);
 +        bcopy (coding.destination, name, min (coding.produced, size));
 +        name[min (coding.produced, size)] = '\0';
        }
      }
  
@@@ -8410,7 -8531,6 +8550,7 @@@ x_load_font (f, fontname, size
      bzero (fontp, sizeof (*fontp));
      fontp->font = font;
      fontp->font_idx = i;
 +    fontp->charset = -1;      /* fs_load_font sets it.  */
      fontp->name = (char *) xmalloc (strlen (fontname) + 1);
      bcopy (fontname, fontp->name, strlen (fontname) + 1);
  
        fontp->height = max_height;
      }
  
 +    /* MAC_TODO: The script encoding is irrelevant in unicode? */
      /* The slot `encoding' specifies how to map a character
         code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
         the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
         (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
         2:0xA020..0xFF7F).  For the moment, we don't know which charset
 -       uses this font.  So, we set information in fontp->encoding[1]
 +       uses this font.  So, we set information in fontp->encoding_type
         which is never used by any charset.  If mapping can't be
         decided, set FONT_ENCODING_NOT_DECIDED.  */
      if (font->mac_scriptcode == smJapanese)
 -      fontp->encoding[1] = 4;
 +      fontp->encoding_type = 4;
      else
        {
 -        fontp->encoding[1]
 +        fontp->encoding_type
             = (font->max_byte1 == 0
              /* 1-byte font */
              ? (font->min_char_or_byte2 < 0x80
@@@ -8759,14 -8878,18 +8899,18 @@@ extern void mac_find_apple_event_spec P
  extern OSErr init_coercion_handler P_ ((void));
  
  /* Drag and Drop */
- OSErr install_drag_handler P_ ((WindowRef));
- void remove_drag_handler P_ ((WindowRef));
+ extern OSErr install_drag_handler P_ ((WindowRef));
+ extern void remove_drag_handler P_ ((WindowRef));
+ /* Showing help echo string during menu tracking  */
+ extern OSStatus install_menu_target_item_handler P_ ((WindowPtr));
  
  #if USE_CARBON_EVENTS
  #ifdef MAC_OSX
  extern void init_service_handler ();
  static Lisp_Object Qservice, Qpaste, Qperform;
  #endif
  /* Window Event Handler */
  static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
                                                EventRef, void *);
@@@ -8854,7 -8977,7 +8998,7 @@@ static const unsigned char fn_keycode_t
  };
  #endif        /* MAC_OSX */
  
- static unsigned int
+ static int
  #if USE_CARBON_EVENTS
  mac_to_emacs_modifiers (UInt32 mods)
  #else
@@@ -8901,6 -9024,23 +9045,23 @@@ mac_to_emacs_modifiers (EventModifiers 
    return result;
  }
  
+ static UInt32
+ mac_mapped_modifiers (modifiers)
+      UInt32 modifiers;
+ {
+   UInt32 mapped_modifiers_all =
+     (NILP (Vmac_control_modifier) ? 0 : controlKey)
+     | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+     | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+ #ifdef MAC_OSX
+   mapped_modifiers_all |=
+     (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+ #endif
+   return mapped_modifiers_all & modifiers;
+ }
  static int
  mac_get_emulated_btn ( UInt32 modifiers )
  {
    return result;
  }
  
+ #if TARGET_API_MAC_CARBON
+ /***** Code to handle C-g testing  *****/
+ extern int quit_char;
+ extern int make_ctrl_char P_ ((int));
+ int
+ mac_quit_char_key_p (modifiers, key_code)
+      UInt32 modifiers, key_code;
+ {
+   UInt32 char_code;
+   unsigned long some_state = 0;
+   Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+   int c, emacs_modifiers;
+   /* Mask off modifier keys that are mapped to some Emacs modifiers.  */
+   key_code |= (modifiers & ~(mac_mapped_modifiers (modifiers)));
+   char_code = KeyTranslate (kchr_ptr, key_code, &some_state);
+   if (char_code & ~0xff)
+     return 0;
+   emacs_modifiers = mac_to_emacs_modifiers (modifiers);
+   if (emacs_modifiers & ctrl_modifier)
+     c = make_ctrl_char (char_code);
+   c |= (emacs_modifiers
+       & (meta_modifier | alt_modifier
+          | hyper_modifier | super_modifier));
+   return c == quit_char;
+ }
+ #endif
  #if USE_CARBON_EVENTS
  /* Obtains the event modifiers from the event ref and then calls
     mac_to_emacs_modifiers.  */
- static UInt32
+ static int
  mac_event_to_emacs_modifiers (EventRef eventRef)
  {
    UInt32 mods = 0;
@@@ -9143,6 -9315,9 +9336,9 @@@ do_window_update (WindowPtr win
          GetPortVisibleRegion (GetWindowPort (win), region);
          GetRegionBounds (region, &r);
          expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+ #if USE_CG_DRAWING
+         mac_prepare_for_quickdraw (f);
+ #endif
          UpdateControls (win, region);
          DisposeRgn (region);
  #else
@@@ -9954,21 -10129,10 +10150,10 @@@ mac_handle_text_input_event (next_handl
          err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
                                   typeUInt32, NULL,
                                   sizeof (UInt32), NULL, &modifiers);
-       if (err == noErr)
-         {
-           mapped_modifiers =
-             (NILP (Vmac_control_modifier) ? 0 : controlKey)
-             | (NILP (Vmac_option_modifier) ? 0 : optionKey)
-             | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
- #ifdef MAC_OSX
-           mapped_modifiers |=
-             (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
- #endif
-           if (modifiers & mapped_modifiers)
-             /* There're mapped modifier keys.  Process it in
-                XTread_socket.  */
-             return eventNotHandledErr;
-         }
+       if (err == noErr && mac_mapped_modifiers (modifiers))
+         /* There're mapped modifier keys.  Process it in
+            XTread_socket.  */
+         return eventNotHandledErr;
        if (err == noErr)
          err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
                                   typeUnicodeText, NULL, 0, &actual_size,
@@@ -10189,6 -10353,8 +10374,8 @@@ install_window_handler (window
  #endif
    if (err == noErr)
      err = install_drag_handler (window);
+   if (err == noErr)
+     err = install_menu_target_item_handler (window);
  
    return err;
  }
@@@ -10236,7 -10402,7 +10423,7 @@@ main (void
  
  #if __MWERKS__
    /* set creator and type for files created by MSL */
-   _fcreator = 'EMAx';
+   _fcreator = MAC_EMACS_CREATOR_CODE;
    _ftype = 'TEXT';
  #endif
  
@@@ -10364,10 -10530,34 +10551,10 @@@ mac_set_unicode_keystroke_event (code, 
    int charset_id, c1, c2;
  
    if (code < 0x80)
 -    {
 -      buf->kind = ASCII_KEYSTROKE_EVENT;
 -      buf->code = code;
 -    }
 -  else if (code < 0x100)
 -    {
 -      if (code < 0xA0)
 -      charset_id = CHARSET_8_BIT_CONTROL;
 -      else
 -      charset_id = charset_latin_iso8859_1;
 -      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 -      buf->code = MAKE_CHAR (charset_id, code, 0);
 -    }
 +    buf->kind = ASCII_KEYSTROKE_EVENT;
    else
 -    {
 -      if (code < 0x2500)
 -      charset_id = charset_mule_unicode_0100_24ff,
 -        code -= 0x100;
 -      else if (code < 0x33FF)
 -      charset_id = charset_mule_unicode_2500_33ff,
 -        code -= 0x2500;
 -      else if (code >= 0xE000)
 -      charset_id = charset_mule_unicode_e000_ffff,
 -        code -= 0xE000;
 -      c1 = (code / 96) + 32, c2 = (code % 96) + 32;
 -      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 -      buf->code = MAKE_CHAR (charset_id, c1, c2);
 -    }
 +    buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 +  buf->code = code;
  }
  #endif
  
@@@ -10893,20 -11083,12 +11080,12 @@@ XTread_socket (sd, expected, hold_quit
            SInt16 current_key_script;
            UInt32 modifiers = er.modifiers, mapped_modifiers;
  
-           mapped_modifiers =
-             (NILP (Vmac_control_modifier) ? 0 : controlKey)
-             | (NILP (Vmac_option_modifier) ? 0 : optionKey)
-             | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
  #if USE_CARBON_EVENTS && defined (MAC_OSX)
-           mapped_modifiers |=
-             (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
            GetEventParameter (eventRef, kEventParamKeyModifiers,
                               typeUInt32, NULL,
                               sizeof (UInt32), NULL, &modifiers);
  #endif
-           mapped_modifiers &= modifiers;
+           mapped_modifiers = mac_mapped_modifiers (modifiers);
  
  #if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
            /* When using Carbon Events, we need to pass raw keyboard
@@@ -11459,35 -11641,6 +11638,6 @@@ x_delete_display (dpyinfo
  
  \f
  #ifdef MAC_OSX
- void
- mac_check_bundle()
- {
-   extern int inhibit_window_system;
-   extern int noninteractive;
-   CFBundleRef appsBundle;
-   /* No need to test if already -nw*/
-   if (inhibit_window_system || noninteractive)
-     return;
-   appsBundle = CFBundleGetMainBundle();
-   if (appsBundle != NULL)
-     {
-       CFStringRef cfBI = CFSTR("CFBundleIdentifier");
-       CFTypeRef res = CFBundleGetValueForInfoDictionaryKey(appsBundle, cfBI);
-       /* We found the bundle identifier, now we know we are valid. */
-       if (res != NULL)
-       {
-         CFRelease(res);
-         return;
-       }
-     }
-   /* MAC_TODO:  Have this start the bundled executable */
-   /* For now, prevent the fatal error by bringing it up in the terminal */
-   inhibit_window_system = 1;
- }
  void
  MakeMeTheFrontProcess ()
  {
    if (err == noErr)
      (void) SetFrontProcess (&psn);
  }
- /***** Code to handle C-g testing  *****/
- /* Contains the Mac modifier formed from quit_char */
- int mac_quit_char_modifiers = 0;
- int mac_quit_char_keycode;
- extern int quit_char;
- static void
- mac_determine_quit_char_modifiers()
- {
-   /* Todo: Determine modifiers from quit_char. */
-   UInt32 qc_modifiers = ctrl_modifier;
-   /* Map modifiers */
-   mac_quit_char_modifiers = 0;
-   if (qc_modifiers & ctrl_modifier)  mac_quit_char_modifiers |= controlKey;
-   if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= shiftKey;
-   if (qc_modifiers & alt_modifier)   mac_quit_char_modifiers |= optionKey;
- }
- static void
- init_quit_char_handler ()
- {
-   /* TODO: Let this support keys other the 'g' */
-   mac_quit_char_keycode = 5;
-   /* Look at <architecture/adb_kb_map.h> for details */
-   /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
-   mac_determine_quit_char_modifiers();
- }
  #endif        /* MAC_OSX */
  
  static void
@@@ -11664,8 -11786,6 +11783,6 @@@ mac_initialize (
  #if USE_CARBON_EVENTS
  #ifdef MAC_OSX
    init_service_handler ();
-   init_quit_char_handler ();
  #endif        /* MAC_OSX */
  
    init_command_handler ();
  #endif
  
  #if USE_CG_DRAWING
+   init_cg_color ();
    mac_init_fringe ();
  #endif
  
diff --combined src/makefile.w32-in
index e9aac2fb5a67ca5e45b8d56e330e9ff5722a95c2,c796a52fe2cd75d64a9717d2340d250db44eb2ff..b3e752ee8e3a5887d3b1f4a07a6937887d7d3a29
@@@ -1,6 -1,6 +1,6 @@@
  #  -*- Makefile -*- for GNU Emacs on the Microsoft W32 API.
  #  Copyright (C) 2000, 2001, 2002, 2003, 2004,
- #                2005, 2006 Free Software Foundation, Inc.
+ #                2005, 2006, 2007 Free Software Foundation, Inc.
  #
  #  This file is part of GNU Emacs.
  #
@@@ -118,8 -118,6 +118,8 @@@ OBJ1 =  $(BLD)/abbrev.$(O)                 
        $(BLD)/region-cache.$(O)                \
        $(BLD)/strftime.$(O)                    \
        $(BLD)/charset.$(O)                     \
 +      $(BLD)/character.$(O)                   \
 +      $(BLD)/chartab.$(O)                     \
        $(BLD)/coding.$(O)                      \
        $(BLD)/category.$(O)                    \
        $(BLD)/ccl.$(O)                         \
        $(BLD)/fringe.$(O)                      \
        $(BLD)/image.$(O)
  
 +
  WIN32OBJ = $(BLD)/w32term.$(O)                        \
           $(BLD)/w32xfns.$(O)                  \
           $(BLD)/w32fns.$(O)                   \
@@@ -174,7 -171,7 +174,7 @@@ temacs:         stamp_BLD $(TEMACS
  $(TEMACS):      $(TLIB0) $(TLIB1) $(TLIBW32) $(TLASTLIB) $(TOBJ) $(TRES) \
                  ../nt/$(BLD)/addsection.exe
        $(LINK) $(LINK_OUT)$(TEMACS_TMP) $(FULL_LINK_FLAGS) $(TOBJ) $(TRES) $(LIBS)
 -      "../nt/$(BLD)/addsection" "$(TEMACS_TMP)" "$(TEMACS)" EMHEAP 16
 +      "../nt/$(BLD)/addsection" "$(TEMACS_TMP)" "$(TEMACS)" EMHEAP 20
        echo $(OBJ0) > $(BLD)/buildobj.lst
        echo $(OBJ1) >> $(BLD)/buildobj.lst
        echo $(WIN32OBJ) >> $(BLD)/buildobj.lst
@@@ -275,7 -272,6 +275,7 @@@ $(BLD)/abbrev.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/dispextern.h \
@@@ -291,7 -287,6 +291,7 @@@ $(BLD)/alloc.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/composite.h \
        $(SRC)/dispextern.h \
@@@ -374,7 -369,6 +374,7 @@@ $(BLD)/callproc.$(O) : 
        $(EMACS_ROOT)/nt/inc/sys/file.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/commands.h \
@@@ -391,7 -385,6 +391,7 @@@ $(BLD)/casefiddle.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/composite.h \
@@@ -413,7 -406,6 +413,7 @@@ $(BLD)/category.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
        $(SRC)/category.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/keymap.h
  
@@@ -423,22 -415,9 +423,22 @@@ $(BLD)/ccl.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h
  
 +$(BLD)/character.$(O) : \
 +      $(SRC)/character.c \
 +      $(EMACS_ROOT)/src/s/ms-w32.h \
 +      $(EMACS_ROOT)/src/m/intel386.h \
 +      $(EMACS_ROOT)/src/config.h \
 +      $(SRC)/buffer.h \
 +      $(SRC)/character.h \
 +      $(SRC)/charset.h \
 +      $(SRC)/coding.h \
 +      $(SRC)/composite.h \
 +      $(SRC)/disptab.h
 +
  $(BLD)/charset.$(O) : \
        $(SRC)/charset.c \
        $(EMACS_ROOT)/src/s/ms-w32.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/composite.h \
        $(SRC)/disptab.h
  
 +$(BLD)/chartab.$(O) : \
 +      $(SRC)/chartab.c \
 +      $(EMACS_ROOT)/src/s/ms-w32.h \
 +      $(EMACS_ROOT)/src/m/intel386.h \
 +      $(EMACS_ROOT)/src/config.h \
 +      $(SRC)/charset.h \
 +      $(SRC)/character.h
 +
  $(BLD)/cm.$(O) : \
        $(SRC)/cm.c \
        $(EMACS_ROOT)/src/s/ms-w32.h \
@@@ -474,7 -444,6 +474,7 @@@ $(BLD)/cmds.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/dispextern.h \
@@@ -492,7 -461,6 +492,7 @@@ $(BLD)/coding.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/composite.h \
@@@ -508,7 -476,6 +508,7 @@@ $(BLD)/composite.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/composite.h \
        $(SRC)/dispextern.h \
@@@ -522,7 -489,6 +522,7 @@@ $(BLD)/data.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/frame.h \
        $(SRC)/keyboard.h \
@@@ -536,7 -502,6 +536,7 @@@ $(BLD)/dired.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/commands.h \
@@@ -554,7 -519,6 +554,7 @@@ $(BLD)/dispnew.$(O) : 
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/cm.h \
        $(SRC)/commands.h \
@@@ -583,7 -547,6 +583,7 @@@ $(BLD)/doc.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(EMACS_ROOT)/nt/inc/sys/file.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/keyboard.h \
        $(SRC)/keymap.h
@@@ -593,7 -556,6 +593,7 @@@ $(BLD)/doprnt.$(O) : 
        $(EMACS_ROOT)/src/s/ms-w32.h \
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.c
  
  $(BLD)/editfns.$(O) : \
        $(EMACS_ROOT)/nt/inc/pwd.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/composite.h \
@@@ -666,7 -627,6 +666,7 @@@ $(BLD)/fileio.$(O) : 
        $(EMACS_ROOT)/nt/inc/sys/file.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/commands.h \
@@@ -688,7 -648,6 +688,7 @@@ $(BLD)/filelock.$(O) : 
        $(EMACS_ROOT)/src/epaths.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/systime.h
@@@ -726,7 -685,6 +726,7 @@@ $(BLD)/fns.$(O) : 
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/commands.h \
@@@ -749,7 -707,6 +749,7 @@@ $(BLD)/fontset.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/dispextern.h \
        $(SRC)/fontset.h \
@@@ -767,7 -724,6 +767,7 @@@ $(BLD)/frame.$(O) : 
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/dispextern.h \
@@@ -829,7 -785,6 +829,7 @@@ $(BLD)/indent.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
        $(SRC)/category.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/composite.h \
        $(SRC)/dispextern.h \
@@@ -853,7 -808,6 +853,7 @@@ $(BLD)/insdel.$(O) : 
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/composite.h \
        $(SRC)/dispextern.h \
@@@ -889,7 -843,6 +889,7 @@@ $(BLD)/keyboard.$(O) : 
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/composite.h \
@@@ -921,7 -874,6 +921,7 @@@ $(BLD)/keymap.$(O) : 
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/composite.h \
@@@ -950,7 -902,6 +950,7 @@@ $(BLD)/lread.$(O) : 
        $(EMACS_ROOT)/src/epaths.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/commands.h \
@@@ -982,7 -933,6 +982,7 @@@ $(BLD)/marker.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h
  
  $(BLD)/md5.$(O) : \
@@@ -995,7 -945,6 +995,7 @@@ $(BLD)/minibuf.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/composite.h \
@@@ -1065,7 -1014,6 +1065,7 @@@ $(BLD)/w32console.$(O) : 
        $(SRC)/s/ms-w32.h \
        $(SRC)/m/intel386.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/config.h \
@@@ -1083,7 -1031,6 +1083,7 @@@ $(BLD)/print.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/composite.h \
        $(SRC)/dispextern.h \
@@@ -1107,7 -1054,6 +1107,7 @@@ $(BLD)/process.$(O) : 
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/commands.h \
@@@ -1147,7 -1093,6 +1147,7 @@@ $(BLD)/regex.$(O) : 
        $(SRC)/m/intel386.h \
        $(SRC)/buffer.h \
        $(SRC)/category.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/config.h \
        $(SRC)/regex.h \
@@@ -1183,7 -1128,6 +1183,7 @@@ $(BLD)/search.$(O) : 
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
        $(SRC)/category.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/composite.h \
@@@ -1216,7 -1160,6 +1216,7 @@@ $(BLD)/syntax.$(O) : 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/buffer.h \
        $(SRC)/category.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/commands.h \
        $(SRC)/composite.h \
@@@ -1261,7 -1204,6 +1261,7 @@@ $(BLD)/term.$(O) : 
        $(EMACS_ROOT)/src/m/intel386.h \
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/cm.h \
        $(SRC)/coding.h \
@@@ -1358,7 -1300,6 +1358,7 @@@ $(BLD)/xdisp.$(O) : 
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/commands.h \
@@@ -1390,7 -1331,6 +1390,7 @@@ $(BLD)/xfaces.$(O): 
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/composite.h \
        $(SRC)/dispextern.h \
@@@ -1413,7 -1353,6 +1413,7 @@@ $(BLD)/w32fns.$(O): 
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/composite.h \
@@@ -1439,7 -1378,6 +1439,7 @@@ $(BLD)/w32menu.$(O): 
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/dispextern.h \
@@@ -1462,7 -1400,6 +1462,7 @@@ $(BLD)/w32term.$(O): 
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/composite.h \
@@@ -1494,7 -1431,6 +1494,7 @@@ $(BLD)/w32select.$(O): 
        $(SRC)/blockinput.h \
        $(SRC)/buffer.h \
        $(SRC)/ccl.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/coding.h \
        $(SRC)/composite.h \
@@@ -1526,7 -1462,6 +1526,7 @@@ $(BLD)/w32xfns.$(O): 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/fontset.h \
        $(SRC)/frame.h \
@@@ -1543,7 -1478,6 +1543,7 @@@ $(BLD)/w32bdf.$(O): 
        $(EMACS_ROOT)/src/config.h \
        $(SRC)/atimer.h \
        $(SRC)/blockinput.h \
 +      $(SRC)/character.h \
        $(SRC)/charset.h \
        $(SRC)/dispextern.h \
        $(SRC)/fontset.h \
diff --combined src/marker.c
index bac8e46fc3f9ec65278a40b0e5e7f45eac1938f4,31849782f6c2cc946bbf532d94519b2c432bef59..b26aa404986be66a42624a9527f46e822759cde8
@@@ -1,6 -1,6 +1,6 @@@
  /* Markers: examining, setting and deleting.
-    Copyright (C) 1985, 1997, 1998, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1985, 1997, 1998, 2001, 2002, 2003, 2004,
+                  2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -23,7 -23,7 +23,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <config.h>
  #include "lisp.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  
  /* Record one cached position found recently by
     buf_charpos_to_bytepos or buf_bytepos_to_charpos.  */
diff --combined src/minibuf.c
index 85a0169e10ac0eaac60d7225e7ccedcf65e81f09,5618f0223a4a77ee3409c1dc3963820a7758bd6d..58bcf1ef1a43f07c75dc91a629457261df9ca774
@@@ -1,7 -1,7 +1,7 @@@
  /* Minibuffer input and completion.
     Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
                   2001, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+                  2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -27,7 -27,7 +27,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "lisp.h"
  #include "commands.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "dispextern.h"
  #include "keyboard.h"
  #include "frame.h"
@@@ -983,7 -983,7 +983,7 @@@ POSITION in the minibuffer.  Any intege
  one puts point at the beginning of the string.  *Note* that this
  behavior differs from the way such arguments are used in `completing-read'
  and some related functions, which use zero-indexing for POSITION.  */)
- (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
   (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
       Lisp_Object prompt, initial_contents, keymap, read, hist, default_value;
       Lisp_Object inherit_input_method;
  {
@@@ -2362,14 -2362,23 +2362,14 @@@ Return nil if there is no valid complet
  
    /* Now find first word-break in the stuff found by completion.
       i gets index in string of where to stop completing.  */
 -  {
 -    int len, c;
 -    int bytes = SBYTES (completion);
 -    register const unsigned char *completion_string = SDATA (completion);
 -    for (; i_byte < SBYTES (completion); i_byte += len, i++)
 -      {
 -      c = STRING_CHAR_AND_LENGTH (completion_string + i_byte,
 -                                  bytes - i_byte,
 -                                  len);
 -      if (SYNTAX (c) != Sword)
 -        {
 -          i_byte += len;
 -          i++;
 -          break;
 -        }
 -      }
 -  }
 +  while (i_byte < SBYTES (completion))
 +    {
 +      int c;
 +
 +      FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, completion, i, i_byte);
 +      if (SYNTAX (c) != Sword)
 +      break;
 +    }
  
    /* If got no characters, print help for user.  */
  
@@@ -2649,7 -2658,7 +2649,7 @@@ DEFUN ("self-insert-and-exit", Fself_in
         doc: /* Terminate minibuffer input.  */)
       ()
  {
 -  if (INTEGERP (last_command_char))
 +  if (CHARACTERP (last_command_char))
      internal_self_insert (XINT (last_command_char), 0);
    else
      bitch_at_user ();
diff --combined src/msdos.c
index 4e989402a8015d52b134116e94f2c91fcd7dd0b7,8e920745f3f19a6c5089a45eee9a66946d85e9f5..d40aafdcb34626be1f0c2497355f5f130615f591
@@@ -1,6 -1,6 +1,6 @@@
  /* MS-DOS specific C utilities.          -*- coding: raw-text -*-
     Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
-                  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -56,7 -56,7 +56,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "dispextern.h"
  #include "dosfns.h"
  #include "termopts.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "disptab.h"
  #include "frame.h"
@@@ -3799,15 -3799,15 +3799,15 @@@ XMenuActivate (Display *foo, XMenu *men
    screensize = screen_size * 2;
    faces[0]
      = lookup_derived_face (sf, intern ("msdos-menu-passive-face"),
 -                         0, DEFAULT_FACE_ID, 1);
 +                         DEFAULT_FACE_ID, 1);
    faces[1]
      = lookup_derived_face (sf, intern ("msdos-menu-active-face"),
 -                         0, DEFAULT_FACE_ID, 1);
 +                         DEFAULT_FACE_ID, 1);
    selectface = intern ("msdos-menu-select-face");
    faces[2] = lookup_derived_face (sf, selectface,
 -                                0, faces[0], 1);
 +                                faces[0], 1);
    faces[3] = lookup_derived_face (sf, selectface,
 -                                0, faces[1], 1);
 +                                faces[1], 1);
  
    /* Make sure the menu title is always displayed with
       `msdos-menu-active-face', no matter where the mouse pointer is.  */
diff --combined src/print.c
index f6b64e32e306e056f115173806fd2ecc4761307f,88781080e6caf70ff535e321ef3d05ee3072665d..0fef9cb9880b44ca3202fb0ed02833ec925a1380
@@@ -1,7 -1,7 +1,7 @@@
  /* Lisp object printing and output streams.
     Copyright (C) 1985, 1986, 1988, 1993, 1994, 1995, 1997,
                   1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -25,7 -25,6 +25,7 @@@ Boston, MA 02110-1301, USA.  *
  #include <stdio.h>
  #include "lisp.h"
  #include "buffer.h"
 +#include "character.h"
  #include "charset.h"
  #include "keyboard.h"
  #include "frame.h"
@@@ -476,15 -475,11 +476,15 @@@ print_string (string, printcharfun
      {
        int chars;
  
 +      if (print_escape_nonascii)
 +      string = string_escape_byte8 (string);
 +
        if (STRING_MULTIBYTE (string))
        chars = SCHARS (string);
 -      else if (EQ (printcharfun, Qt)
 -             ? ! NILP (buffer_defaults.enable_multibyte_characters)
 -             : ! NILP (current_buffer->enable_multibyte_characters))
 +      else if (! print_escape_nonascii
 +             && (EQ (printcharfun, Qt)
 +                 ? ! NILP (buffer_defaults.enable_multibyte_characters)
 +                 : ! NILP (current_buffer->enable_multibyte_characters)))
        {
          /* If unibyte string STRING contains 8-bit codes, we must
             convert STRING to a multibyte string containing the same
            int len;
            int ch = STRING_CHAR_AND_LENGTH (SDATA (string) + i,
                                             size_byte - i, len);
 -          if (!CHAR_VALID_P (ch, 0))
 -            {
 -              ch = SREF (string, i);
 -              len = 1;
 -            }
            PRINTCHAR (ch);
            i += len;
          }
@@@ -1462,93 -1462,6 +1462,93 @@@ print_preprocess_string (interval, arg
    print_preprocess (interval->plist);
  }
  
 +/* A flag to control printing of `charset' text property.
 +   The default value is Qdefault. */
 +Lisp_Object Vprint_charset_text_property;
 +extern Lisp_Object Qdefault;
 +
 +static void print_check_string_charset_prop ();
 +
 +#define PRINT_STRING_NON_CHARSET_FOUND 1
 +#define PRINT_STRING_UNSAFE_CHARSET_FOUND 2
 +
 +/* Bitwize or of the abobe macros. */
 +static int print_check_string_result;
 +
 +static void
 +print_check_string_charset_prop (interval, string)
 +     INTERVAL interval;
 +     Lisp_Object string;
 +{
 +  Lisp_Object val;
 +
 +  if (NILP (interval->plist)
 +      || (print_check_string_result == (PRINT_STRING_NON_CHARSET_FOUND
 +                                      | PRINT_STRING_UNSAFE_CHARSET_FOUND)))
 +    return;
 +  for (val = interval->plist; CONSP (val) && ! EQ (XCAR (val), Qcharset);
 +       val = XCDR (XCDR (val)));
 +  if (! CONSP (val))
 +    {
 +      print_check_string_result |= PRINT_STRING_NON_CHARSET_FOUND;
 +      return;
 +    }
 +  if (! (print_check_string_result & PRINT_STRING_NON_CHARSET_FOUND))
 +    {
 +      if (! EQ (val, interval->plist)
 +        || CONSP (XCDR (XCDR (val))))
 +      print_check_string_result |= PRINT_STRING_NON_CHARSET_FOUND;
 +    }
 +  if (NILP (Vprint_charset_text_property)
 +      || ! (print_check_string_result & PRINT_STRING_UNSAFE_CHARSET_FOUND))
 +    {
 +      int i, c;
 +      int charpos = interval->position;
 +      int bytepos = string_char_to_byte (string, charpos);
 +      Lisp_Object charset;
 +
 +      charset = XCAR (XCDR (val));
 +      for (i = 0; i < LENGTH (interval); i++)
 +      {
 +        FETCH_STRING_CHAR_ADVANCE (c, string, charpos, bytepos);
 +        if (! ASCII_CHAR_P (c)
 +            && ! EQ (CHARSET_NAME (CHAR_CHARSET (c)), charset))
 +          {
 +            print_check_string_result |= PRINT_STRING_UNSAFE_CHARSET_FOUND;
 +            break;
 +          }
 +      }
 +    }
 +}
 +
 +/* The value is (charset . nil).  */
 +static Lisp_Object print_prune_charset_plist;
 +
 +static Lisp_Object
 +print_prune_string_charset (string)
 +     Lisp_Object string;
 +{
 +  print_check_string_result = 0;
 +  traverse_intervals (STRING_INTERVALS (string), 0,
 +                    print_check_string_charset_prop, string);
 +  if (! (print_check_string_result & PRINT_STRING_UNSAFE_CHARSET_FOUND))
 +    {
 +      string = Fcopy_sequence (string);
 +      if (print_check_string_result & PRINT_STRING_NON_CHARSET_FOUND)
 +      {
 +        if (NILP (print_prune_charset_plist))
 +          print_prune_charset_plist = Fcons (Qcharset, Qnil);
 +        Fremove_text_properties (make_number (0),
 +                                 make_number (SCHARS (string)),
 +                                 print_prune_charset_plist, string);
 +      }
 +      else
 +      Fset_text_properties (make_number (0), make_number (SCHARS (string)),
 +                            Qnil, string);
 +    }
 +  return string;
 +}
 +
  static void
  print_object (obj, printcharfun, escapeflag)
       Lisp_Object obj;
  
    /* Detect circularities and truncate them.  */
    if (STRINGP (obj) || CONSP (obj) || VECTORP (obj)
 -      || COMPILEDP (obj) || CHAR_TABLE_P (obj)
 +      || COMPILEDP (obj) || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj)
        || (! NILP (Vprint_gensym)
          && SYMBOLP (obj)
          && !SYMBOL_INTERNED_P (obj)))
  
          GCPRO1 (obj);
  
 +        if (! EQ (Vprint_charset_text_property, Qt))
 +          obj = print_prune_string_charset (obj);
 +
          if (!NULL_INTERVAL_P (STRING_INTERVALS (obj)))
            {
              PRINTCHAR ('#');
                {
                  c = STRING_CHAR_AND_LENGTH (str + i_byte,
                                              size_byte - i_byte, len);
 -                if (CHAR_VALID_P (c, 0))
 -                  i_byte += len;
 -                else
 -                  c = str[i_byte++];
 +                i_byte += len;
                }
              else
                c = str[i_byte++];
                  PRINTCHAR ('f');
                }
              else if (multibyte
 -                     && ! ASCII_BYTE_P (c)
 -                     && (SINGLE_BYTE_CHAR_P (c) || print_escape_multibyte))
 +                     && (CHAR_BYTE8_P (c) 
 +                         || (! ASCII_CHAR_P (c) && print_escape_multibyte)))
                {
                  /* When multibyte is disabled,
                     print multibyte string chars using hex escapes.
                     when found in a multibyte string, always use a hex escape
                     so it reads back as multibyte.  */
                  unsigned char outbuf[50];
 -                sprintf (outbuf, "\\x%x", c);
 +
 +                if (CHAR_BYTE8_P (c))
 +                  sprintf (outbuf, "\\%03o", CHAR_TO_BYTE8 (c));
 +                else
 +                  {
 +                    sprintf (outbuf, "\\x%04x", c);
 +                    need_nonhex = 1;
 +                  }
                  strout (outbuf, -1, -1, printcharfun, 0);
 -                need_nonhex = 1;
                }
              else if (! multibyte
                       && SINGLE_BYTE_CHAR_P (c) && ! ASCII_BYTE_P (c)
            {
              QUIT;
              c = XBOOL_VECTOR (obj)->data[i];
 -            if (c == '\n' && print_escape_newlines)
 +            if (! ASCII_BYTE_P (c))
 +              {
 +                sprintf (buf, "\\%03o", c);
 +                strout (buf, -1, -1, printcharfun, 0);
 +              }
 +            else if (c == '\n' && print_escape_newlines)
                {
                  PRINTCHAR ('\\');
                  PRINTCHAR ('n');
              PRINTCHAR ('#');
              size &= PSEUDOVECTOR_SIZE_MASK;
            }
 -        if (CHAR_TABLE_P (obj))
 +        if (CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj))
            {
              /* We print a char-table as if it were a vector,
                 lumping the parent and default slots in with the
@@@ -2294,8 -2196,6 +2294,8 @@@ print_interval (interval, printcharfun
       INTERVAL interval;
       Lisp_Object printcharfun;
  {
 +  if (NILP (interval->plist))
 +    return;
    PRINTCHAR (' ');
    print_object (make_number (interval->position), printcharfun, 1);
    PRINTCHAR (' ');
@@@ -2418,19 -2318,6 +2418,19 @@@ the printing done so far has not found 
  that need to be recorded in the table.  */);
    Vprint_number_table = Qnil;
  
 +  DEFVAR_LISP ("print-charset-text-property", &Vprint_charset_text_property,
 +             doc: /* A flag to control printing of `charset' text property on printing a string.
 +The value must be nil, t, or `default'.
 +
 +If the value is nil, don't print the text property `charset'.
 +
 +If the value is t, always print the text property `charset'.
 +
 +If the value is `default', print the text property `charset' only when
 +the value is different from what is guessed in the current charset
 +priorities.  */);
 +  Vprint_charset_text_property = Qdefault;
 +
    /* prin1_to_string_buffer initialized in init_buffer_once in buffer.c */
    staticpro (&Vprin1_to_string_buffer);
  
    Qprint_escape_nonascii = intern ("print-escape-nonascii");
    staticpro (&Qprint_escape_nonascii);
  
 +  print_prune_charset_plist = Qnil;
 +  staticpro (&print_prune_charset_plist);
 +
    defsubr (&Swith_output_to_temp_buffer);
  }
  
diff --combined src/process.c
index 6dc5a88944c590bf5e83f25165e7518c77aa372b,ecc810cc621772eb4ceafa376a760e219439c170..4611ce2c05c2c7ecbe596c0d4f2cb54644a81fb8
@@@ -1,7 -1,7 +1,7 @@@
  /* Asynchronous subprocess control for GNU Emacs.
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                   1996, 1998, 1999, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -135,7 -135,7 +135,7 @@@ Boston, MA 02110-1301, USA.  *
  
  #include "window.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "process.h"
  #include "termhooks.h"
@@@ -674,7 -674,6 +674,7 @@@ setup_process_coding_systems (process
    struct Lisp_Process *p = XPROCESS (process);
    int inch = XINT (p->infd);
    int outch = XINT (p->outfd);
 +  Lisp_Object coding_system;
  
    if (inch < 0 || outch < 0)
      return;
    if (!proc_decode_coding_system[inch])
      proc_decode_coding_system[inch]
        = (struct coding_system *) xmalloc (sizeof (struct coding_system));
 -  setup_coding_system (p->decode_coding_system,
 -                     proc_decode_coding_system[inch]);
 +  coding_system = p->decode_coding_system;
    if (! NILP (p->filter))
      {
        if (NILP (p->filter_multibyte))
 -      setup_raw_text_coding_system (proc_decode_coding_system[inch]);
 +      coding_system = raw_text_coding_system (coding_system);
      }
    else if (BUFFERP (p->buffer))
      {
        if (NILP (XBUFFER (p->buffer)->enable_multibyte_characters))
 -      setup_raw_text_coding_system (proc_decode_coding_system[inch]);
 +      coding_system = raw_text_coding_system (coding_system);
      }
 +  setup_coding_system (coding_system, proc_decode_coding_system[inch]);
  
    if (!proc_encode_coding_system[outch])
      proc_encode_coding_system[outch]
        = (struct coding_system *) xmalloc (sizeof (struct coding_system));
    setup_coding_system (p->encode_coding_system,
                       proc_encode_coding_system[outch]);
 -  if (proc_encode_coding_system[outch]->eol_type == CODING_EOL_UNDECIDED)
 -    proc_encode_coding_system[outch]->eol_type = system_eol_type;
  }
  \f
  DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0,
@@@ -814,9 -815,12 +814,12 @@@ nil, indicating the current buffer's pr
      {
  #ifdef SIGCHLD
        Lisp_Object symbol;
+       /* Assignment to EMACS_INT stops GCC whining about limited range
+        of data type.  */
+       EMACS_INT pid = p->pid;;
  
        /* No problem storing the pid here, as it is still in Vprocess_alist.  */
-       deleted_pid_list = Fcons (make_fixnum_or_float (p->pid),
+       deleted_pid_list = Fcons (make_fixnum_or_float (pid),
                                /* GC treated elements set to nil.  */
                                Fdelq (Qnil, deleted_pid_list));
        /* If the process has already signaled, remove it from the list.  */
        if (CONSP (p->status))
        symbol = XCAR (p->status);
        if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
-       Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list);
+       Fdelete (make_fixnum_or_float (pid), deleted_pid_list);
        else
  #endif
        {
@@@ -911,10 -915,13 +914,13 @@@ For a network connection, this value i
       (process)
       register Lisp_Object process;
  {
+   /* Assignment to EMACS_INT stops GCC whining about limited range of
+      data type.  */
+   EMACS_INT pid;
    CHECK_PROCESS (process);
-   return (XPROCESS (process)->pid
-         ? make_fixnum_or_float (XPROCESS (process)->pid)
-         : Qnil);
+   pid = XPROCESS (process)->pid;
+   return (pid ? make_fixnum_or_float (pid) : Qnil);
  }
  
  DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0,
@@@ -5105,13 -5112,13 +5111,13 @@@ read_process_output (proc, channel
         save the match data in a special nonrecursive fashion.  */
        running_asynch_code = 1;
  
 -      text = decode_coding_string (make_unibyte_string (chars, nbytes),
 -                                 coding, 0);
 -      Vlast_coding_system_used = coding->symbol;
 +      decode_coding_c_string (coding, chars, nbytes, Qt);
 +      text = coding->dst_object;
 +      Vlast_coding_system_used = CODING_ID_NAME (coding->id);
        /* A new coding system might be found.  */
 -      if (!EQ (p->decode_coding_system, coding->symbol))
 +      if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
        {
 -        p->decode_coding_system = coding->symbol;
 +        p->decode_coding_system = Vlast_coding_system_used;
  
          /* Don't call setup_coding_system for
             proc_decode_coding_system[channel] here.  It is done in
          if (NILP (p->encode_coding_system)
              && proc_encode_coding_system[XINT (p->outfd)])
            {
 -            p->encode_coding_system = coding->symbol;
 -            setup_coding_system (coding->symbol,
 +            p->encode_coding_system
 +              = coding_inherit_eol_type (Vlast_coding_system_used, Qnil);
 +            setup_coding_system (p->encode_coding_system,
                                   proc_encode_coding_system[XINT (p->outfd)]);
 -            if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
 -                == CODING_EOL_UNDECIDED)
 -              proc_encode_coding_system[XINT (p->outfd)]->eol_type
 -                = system_eol_type;
            }
        }
  
 -      carryover = nbytes - coding->consumed;
 -      if (carryover < 0)
 -      abort ();
 -
 -      if (SCHARS (p->decoding_buf) < carryover)
 -      p->decoding_buf = make_uninit_string (carryover);
 -      bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
 -           carryover);
 -      XSETINT (p->decoding_carryover, carryover);
 +      if (coding->carryover_bytes > 0)
 +      {
 +        if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
 +          p->decoding_buf = make_uninit_string (coding->carryover_bytes);
 +        bcopy (coding->carryover, SDATA (p->decoding_buf),
 +               coding->carryover_bytes);
 +        XSETINT (p->decoding_carryover, coding->carryover_bytes);
 +      }
        /* Adjust the multibyteness of TEXT to that of the filter.  */
        if (NILP (p->filter_multibyte) != ! STRING_MULTIBYTE (text))
        text = (STRING_MULTIBYTE (text)
        if (! (BEGV <= PT && PT <= ZV))
        Fwiden ();
  
 -      text = decode_coding_string (make_unibyte_string (chars, nbytes),
 -                                 coding, 0);
 -      Vlast_coding_system_used = coding->symbol;
 +      decode_coding_c_string (coding, chars, nbytes, Qt);
 +      text = coding->dst_object;
 +      Vlast_coding_system_used = CODING_ID_NAME (coding->id);
        /* A new coding system might be found.  See the comment in the
         similar code in the previous `if' block.  */
 -      if (!EQ (p->decode_coding_system, coding->symbol))
 +      if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
        {
 -        p->decode_coding_system = coding->symbol;
 +        p->decode_coding_system = Vlast_coding_system_used;
          if (NILP (p->encode_coding_system)
              && proc_encode_coding_system[XINT (p->outfd)])
            {
 -            p->encode_coding_system = coding->symbol;
 -            setup_coding_system (coding->symbol,
 +            p->encode_coding_system
 +              = coding_inherit_eol_type (Vlast_coding_system_used, Qnil);
 +            setup_coding_system (p->encode_coding_system,
                                   proc_encode_coding_system[XINT (p->outfd)]);
 -            if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
 -                == CODING_EOL_UNDECIDED)
 -              proc_encode_coding_system[XINT (p->outfd)]->eol_type
 -                = system_eol_type;
            }
        }
 -      carryover = nbytes - coding->consumed;
 -      if (carryover < 0)
 -      abort ();
 -
 -      if (SCHARS (p->decoding_buf) < carryover)
 -      p->decoding_buf = make_uninit_string (carryover);
 -      bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
 -           carryover);
 -      XSETINT (p->decoding_carryover, carryover);
 -
 +      if (coding->carryover_bytes > 0)
 +      {
 +        if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
 +          p->decoding_buf = make_uninit_string (coding->carryover_bytes);
 +        bcopy (coding->carryover, SDATA (p->decoding_buf),
 +               coding->carryover_bytes);
 +        XSETINT (p->decoding_carryover, coding->carryover_bytes);
 +      }
        /* Adjust the multibyteness of TEXT to that of the buffer.  */
        if (NILP (current_buffer->enable_multibyte_characters)
          != ! STRING_MULTIBYTE (text))
@@@ -5372,19 -5388,24 +5378,19 @@@ send_process (proc, buf, len, object
      error ("Output file descriptor of %s is closed", SDATA (p->name));
  
    coding = proc_encode_coding_system[XINT (p->outfd)];
 -  Vlast_coding_system_used = coding->symbol;
 +  Vlast_coding_system_used = CODING_ID_NAME (coding->id);
  
    if ((STRINGP (object) && STRING_MULTIBYTE (object))
        || (BUFFERP (object)
          && !NILP (XBUFFER (object)->enable_multibyte_characters))
        || EQ (object, Qt))
      {
 -      if (!EQ (coding->symbol, p->encode_coding_system))
 +      if (!EQ (Vlast_coding_system_used, p->encode_coding_system))
        /* The coding system for encoding was changed to raw-text
           because we sent a unibyte text previously.  Now we are
           sending a multibyte text, thus we must encode it by the
           original coding system specified for the current process.  */
        setup_coding_system (p->encode_coding_system, coding);
 -      if (coding->eol_type == CODING_EOL_UNDECIDED)
 -      coding->eol_type = system_eol_type;
 -      /* src_multibyte should be set to 1 _after_ a call to
 -       setup_coding_system, since it resets src_multibyte to
 -       zero.  */
        coding->src_multibyte = 1;
      }
    else
        /* For sending a unibyte text, character code conversion should
         not take place but EOL conversion should.  So, setup raw-text
         or one of the subsidiary if we have not yet done it.  */
 -      if (coding->type != coding_type_raw_text)
 +      if (CODING_REQUIRE_ENCODING (coding))
        {
          if (CODING_REQUIRE_FLUSHING (coding))
            {
              /* But, before changing the coding, we must flush out data.  */
              coding->mode |= CODING_MODE_LAST_BLOCK;
              send_process (proc, "", 0, Qt);
 +            coding->mode &= CODING_MODE_LAST_BLOCK;
            }
 +        setup_coding_system (raw_text_coding_system
 +                             (Vlast_coding_system_used),
 +                             coding);
          coding->src_multibyte = 0;
 -        setup_raw_text_coding_system (coding);
        }
      }
    coding->dst_multibyte = 0;
  
    if (CODING_REQUIRE_ENCODING (coding))
      {
 -      int require = encoding_buffer_size (coding, len);
 -      int from_byte = -1, from = -1, to = -1;
 -
 +      coding->dst_object = Qt;
        if (BUFFERP (object))
        {
 -        from_byte = BUF_PTR_BYTE_POS (XBUFFER (object), buf);
 -        from = buf_bytepos_to_charpos (XBUFFER (object), from_byte);
 -        to = buf_bytepos_to_charpos (XBUFFER (object), from_byte + len);
 +        int from_byte, from, to;
 +        int save_pt, save_pt_byte;
 +        struct buffer *cur = current_buffer;
 +
 +        set_buffer_internal (XBUFFER (object));
 +        save_pt = PT, save_pt_byte = PT_BYTE;
 +
 +        from_byte = PTR_BYTE_POS (buf);
 +        from = BYTE_TO_CHAR (from_byte);
 +        to = BYTE_TO_CHAR (from_byte + len);
 +        TEMP_SET_PT_BOTH (from, from_byte);
 +        encode_coding_object (coding, object, from, from_byte,
 +                              to, from_byte + len, Qt);
 +        TEMP_SET_PT_BOTH (save_pt, save_pt_byte);
 +        set_buffer_internal (cur);
        }
        else if (STRINGP (object))
        {
 -        from_byte = buf - SDATA (object);
 -        from = string_byte_to_char (object, from_byte);
 -        to =  string_byte_to_char (object, from_byte + len);
 +        encode_coding_string (coding, object, 1);
        }
 -
 -      if (coding->composing != COMPOSITION_DISABLED)
 +      else
        {
 -        if (from_byte >= 0)
 -          coding_save_composition (coding, from, to, object);
 -        else
 -          coding->composing = COMPOSITION_DISABLED;
 +        coding->dst_object = make_unibyte_string (buf, len);
 +        coding->produced = len;
        }
  
 -      if (SBYTES (p->encoding_buf) < require)
 -      p->encoding_buf = make_uninit_string (require);
 -
 -      if (from_byte >= 0)
 -      buf = (BUFFERP (object)
 -             ? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte)
 -             : SDATA (object) + from_byte);
 -
 -      object = p->encoding_buf;
 -      encode_coding (coding, (char *) buf, SDATA (object),
 -                   len, SBYTES (object));
 -      coding_free_composition_data (coding);
        len = coding->produced;
 -      buf = SDATA (object);
 +      buf = SDATA (coding->dst_object);
      }
  
  #ifdef VMS
@@@ -6386,7 -6411,7 +6392,7 @@@ sigchld_handler (signo
  
    while (1)
      {
-       register int pid;
+       register EMACS_INT pid;
        WAITTYPE w;
        Lisp_Object tail;
  
@@@ -6770,7 -6795,7 +6776,7 @@@ encode subprocess input.  */
      error ("Output file descriptor of %s closed", SDATA (p->name));
    Fcheck_coding_system (decoding);
    Fcheck_coding_system (encoding);
 -
 +  encoding = coding_inherit_eol_type (encoding, Qnil);
    p->decode_coding_system = decoding;
    p->encode_coding_system = encoding;
    setup_process_coding_systems (process);
@@@ -7158,7 -7183,7 +7164,7 @@@ The variable takes effect when `start-p
  
  #include "lisp.h"
  #include "systime.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "termopts.h"
  #include "sysselect.h"
diff --combined src/regex.c
index 396e55c6404acb082a0797e53e3f7d1a4d3a73f8,7784a3ae616d485f8efc3f884bdb2e9a3b27a0f2..177908cb751414aba3ff8ee2b313739d729d709f
@@@ -3,7 -3,7 +3,7 @@@
     internationalization features.)
  
     Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
  # define SYNTAX_ENTRY_VIA_PROPERTY
  
  # include "syntax.h"
 -# include "charset.h"
 +# include "character.h"
  # include "category.h"
  
  # ifdef malloc
  # define POS_AS_IN_BUFFER(p) ((p) + (NILP (re_match_object) || BUFFERP (re_match_object)))
  
  # define RE_MULTIBYTE_P(bufp) ((bufp)->multibyte)
 +# define RE_TARGET_MULTIBYTE_P(bufp) ((bufp)->target_multibyte)
  # define RE_STRING_CHAR(p, s) \
    (multibyte ? (STRING_CHAR (p, s)) : (*(p)))
  # define RE_STRING_CHAR_AND_LENGTH(p, s, len) \
    (multibyte ? (STRING_CHAR_AND_LENGTH (p, s, len)) : ((len) = 1, *(p)))
  
 -/* Set C a (possibly multibyte) character before P.  P points into a
 -   string which is the virtual concatenation of STR1 (which ends at
 -   END1) or STR2 (which ends at END2).  */
 -# define GET_CHAR_BEFORE_2(c, p, str1, end1, str2, end2)              \
 -  do {                                                                        \
 -    if (multibyte)                                                    \
 -       {                                                              \
 -       re_char *dtemp = (p) == (str2) ? (end1) : (p);                 \
 -       re_char *dlimit = ((p) > (str2) && (p) <= (end2)) ? (str2) : (str1); \
 -       re_char *d0 = dtemp;                                           \
 -       PREV_CHAR_BOUNDARY (d0, dlimit);                               \
 -       c = STRING_CHAR (d0, dtemp - d0);                              \
 -       }                                                              \
 -     else                                                             \
 -       (c = ((p) == (str2) ? (end1) : (p))[-1]);                      \
 +/* Set C a (possibly converted to multibyte) character before P.  P
 +   points into a string which is the virtual concatenation of STR1
 +   (which ends at END1) or STR2 (which ends at END2).  */
 +# define GET_CHAR_BEFORE_2(c, p, str1, end1, str2, end2)                   \
 +  do {                                                                             \
 +    if (multibyte)                                                         \
 +      {                                                                            \
 +      re_char *dtemp = (p) == (str2) ? (end1) : (p);                       \
 +      re_char *dlimit = ((p) > (str2) && (p) <= (end2)) ? (str2) : (str1); \
 +      while (dtemp-- > dlimit && !CHAR_HEAD_P (*dtemp));                   \
 +      c = STRING_CHAR (dtemp, (p) - dtemp);                                \
 +      }                                                                            \
 +    else                                                                   \
 +      {                                                                            \
 +      (c = ((p) == (str2) ? (end1) : (p))[-1]);                            \
 +      MAKE_CHAR_MULTIBYTE (c);                                             \
 +      }                                                                            \
    } while (0)
  
 +/* Set C a (possibly converted to multibyte) character at P, and set
 +   LEN to the byte length of that character.  */
 +# define GET_CHAR_AFTER(c, p, len)            \
 +  do {                                                \
 +    if (multibyte)                            \
 +      c = STRING_CHAR_AND_LENGTH (p, 0, len); \
 +    else                                      \
 +      {                                               \
 +      c = *p;                                 \
 +      len = 1;                                \
 +      MAKE_CHAR_MULTIBYTE (c);                \
 +      }                                               \
 +   } while (0)
  
  #else  /* not emacs */
  
@@@ -293,7 -277,6 +293,7 @@@ enum syntaxcode { Swhitespace = 0, Swor
  # define CHARSET_LEADING_CODE_BASE(c) 0
  # define MAX_MULTIBYTE_LENGTH 1
  # define RE_MULTIBYTE_P(x) 0
 +# define RE_TARGET_MULTIBYTE_P(x) 0
  # define WORD_BOUNDARY_P(c1, c2) (0)
  # define CHAR_HEAD_P(p) (1)
  # define SINGLE_BYTE_CHAR_P(c) (1)
  # define RE_STRING_CHAR_AND_LENGTH STRING_CHAR_AND_LENGTH
  # define GET_CHAR_BEFORE_2(c, p, str1, end1, str2, end2) \
    (c = ((p) == (str2) ? *((end1) - 1) : *((p) - 1)))
 +# define GET_CHAR_AFTER(c, p, len)    \
 +  (c = *p, len = 1)
  # define MAKE_CHAR(charset, c1, c2) (c1)
 +# define BYTE8_TO_CHAR(c) (c)
 +# define CHAR_BYTE8_P(c) (0)
 +# define MAKE_CHAR_MULTIBYTE(c) (c)
 +# define MAKE_CHAR_UNIBYTE(c) (c)
 +# define CHAR_LEADING_CODE(c) (c)
 +
  #endif /* not emacs */
  
  #ifndef RE_TRANSLATE
@@@ -521,7 -496,7 +521,7 @@@ init_syntax_once (
  #  ifdef __GNUC__
  #   define alloca __builtin_alloca
  #  else /* not __GNUC__ */
 -#   if HAVE_ALLOCA_H
 +#   ifdef HAVE_ALLOCA_H
  #    include <alloca.h>
  #   endif /* HAVE_ALLOCA_H */
  #  endif /* not __GNUC__ */
@@@ -1972,10 -1947,10 +1972,10 @@@ struct range_table_work_are
  
  #define EXTEND_RANGE_TABLE(work_area, n)                              \
    do {                                                                        \
 -    if (((work_area)->used + (n)) * sizeof (int) > (work_area)->allocated) \
 +    if (((work_area).used + (n)) * sizeof (int) > (work_area).allocated) \
        {                                                                       \
 -        extend_range_table_work_area (work_area);                     \
 -        if ((work_area)->table == 0)                                  \
 +        extend_range_table_work_area (&work_area);                    \
 +        if ((work_area).table == 0)                                   \
            return (REG_ESPACE);                                                \
        }                                                                       \
    } while (0)
  #define BIT_UPPER     0x10
  #define BIT_MULTIBYTE 0x20
  
 -/* Set a range START..END to WORK_AREA.
 -   The range is passed through TRANSLATE, so START and END
 -   should be untranslated.  */
 -#define SET_RANGE_TABLE_WORK_AREA(work_area, start, end)              \
 +/* Set a range (RANGE_START, RANGE_END) to WORK_AREA.  */
 +#define SET_RANGE_TABLE_WORK_AREA(work_area, range_start, range_end)  \
    do {                                                                        \
 -    int tem;                                                          \
 -    tem = set_image_of_range (&work_area, start, end, translate);     \
 -    if (tem > 0)                                                      \
 -      FREE_STACK_RETURN (tem);                                                \
 +    EXTEND_RANGE_TABLE ((work_area), 2);                              \
 +    (work_area).table[(work_area).used++] = (range_start);            \
 +    (work_area).table[(work_area).used++] = (range_end);              \
    } while (0)
  
  /* Free allocated memory for WORK_AREA.  */
  #define SET_LIST_BIT(c) (b[((c)) / BYTEWIDTH] |= 1 << ((c) % BYTEWIDTH))
  
  
 +#ifdef emacs
 +
 +/* Store characters in the rage range C0 to C1 in WORK_AREA while
 +   translating them and paying attention to the continuity of
 +   translated characters.
 +
 +   Implementation note: It is better to implement this fairly big
 +   macro by a function, but it's not that easy because macros called
 +   in this macro assume various local variables already declared.  */
 +
 +#define SETUP_MULTIBYTE_RANGE(work_area, c0, c1)                            \
 +  do {                                                                              \
 +    re_wchar_t c, t, t_last;                                                \
 +    int n;                                                                  \
 +                                                                            \
 +    c = (c0);                                                               \
 +    t_last = multibyte ? TRANSLATE (c) : TRANSLATE (MAKE_CHAR_MULTIBYTE (c)); \
 +    for (c++, n = 1; c <= (c1); c++, n++)                                   \
 +      {                                                                             \
 +      t = multibyte ? TRANSLATE (c) : TRANSLATE (MAKE_CHAR_MULTIBYTE (c));  \
 +      if (t_last + n == t)                                                  \
 +        continue;                                                           \
 +      SET_RANGE_TABLE_WORK_AREA ((work_area), t_last, t_last + n - 1);      \
 +      t_last = t;                                                           \
 +      n = 0;                                                                \
 +      }                                                                             \
 +    if (n > 0)                                                                      \
 +      SET_RANGE_TABLE_WORK_AREA ((work_area), t_last, t_last + n - 1);              \
 +  } while (0)
 +
 +#endif /* emacs */
 +
  /* Get the next unsigned number in the uncompiled pattern.  */
  #define GET_UNSIGNED_NUMBER(num)                                      \
    do {                                                                        \
@@@ -2172,7 -2118,6 +2172,7 @@@ extend_range_table_work_area (work_area
        = (int *) malloc (work_area->allocated);
  }
  
 +#if 0
  #ifdef emacs
  
  /* Carefully find the ranges of codes that are equivalent
@@@ -2405,7 -2350,6 +2405,7 @@@ set_image_of_range (work_area, start, e
  
    return -1;
  }
 +#endif        /* 0 */
  \f
  #ifndef MATCH_MAY_ALLOCATE
  
@@@ -2549,9 -2493,6 +2549,9 @@@ regex_compile (pattern, size, syntax, b
    /* If the object matched can contain multibyte characters.  */
    const boolean multibyte = RE_MULTIBYTE_P (bufp);
  
 +  /* If a target of matching can contain multibyte characters.  */
 +  const boolean target_multibyte = RE_TARGET_MULTIBYTE_P (bufp);
 +
    /* Nonzero if we have pushed down into a subpattern.  */
    int in_subpattern = 0;
  
                      break;
                  }
  
 -              /* What should we do for the character which is
 -                 greater than 0x7F, but not BASE_LEADING_CODE_P?
 -                 XXX */
 -
                /* See if we're at the beginning of a possible character
                   class.  */
  
                      {
                        re_wchar_t ch;
                        re_wctype_t cc;
 +                      int limit;
  
                        cc = re_wctype (str);
  
                           don't need to handle them for multibyte.
                           They are distinguished by a negative wctype.  */
  
 -                      if (multibyte)
 -                        SET_RANGE_TABLE_WORK_AREA_BIT (range_table_work,
 -                                                       re_wctype_to_bit (cc));
 +                      for (ch = 0; ch < 128; ++ch)
 +                        if (re_iswctype (btowc (ch), cc))
 +                          {
 +                            c = TRANSLATE (ch);
 +                            if (c < (1 << BYTEWIDTH))
 +                              SET_LIST_BIT (c);
 +                          }
  
 -                        for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
 +                      if (target_multibyte)
 +                        {
 +                          SET_RANGE_TABLE_WORK_AREA_BIT
 +                            (range_table_work, re_wctype_to_bit (cc));
 +                        }
 +                      else
                          {
 -                          int translated = TRANSLATE (ch);
 -                          if (translated < (1 << BYTEWIDTH)
 -                              && re_iswctype (btowc (ch), cc))
 -                            SET_LIST_BIT (translated);
 +                          for (ch = 0; ch < (1 << BYTEWIDTH); ++ch)
 +                            {
 +                              c = ch;
 +                              MAKE_CHAR_MULTIBYTE (c);
 +                              if (re_iswctype (btowc (c), cc))
 +                                {
 +                                  c = TRANSLATE (c);
 +                                  MAKE_CHAR_UNIBYTE (c);
 +                                  SET_LIST_BIT (c);
 +                                }
 +                            }
                          }
  
                        /* In most cases the matching rule for char classes
  
                    /* Fetch the character which ends the range. */
                    PATFETCH (c1);
 -
 -                  if (SINGLE_BYTE_CHAR_P (c))
 +                  if (c > c1)
                      {
 -                      if (! SINGLE_BYTE_CHAR_P (c1))
 -                        {
 -                          /* Handle a range starting with a
 -                             character of less than 256, and ending
 -                             with a character of not less than 256.
 -                             Split that into two ranges, the low one
 -                             ending at 0377, and the high one
 -                             starting at the smallest character in
 -                             the charset of C1 and ending at C1.  */
 -                          int charset = CHAR_CHARSET (c1);
 -                          re_wchar_t c2 = MAKE_CHAR (charset, 0, 0);
 -
 -                          SET_RANGE_TABLE_WORK_AREA (range_table_work,
 -                                                     c2, c1);
 -                          c1 = 0377;
 -                        }
 +                      if (syntax & RE_NO_EMPTY_RANGES)
 +                        FREE_STACK_RETURN (REG_ERANGEX);
 +                      /* Else, repeat the loop.  */
                      }
 -                  else if (!SAME_CHARSET_P (c, c1))
 -                    FREE_STACK_RETURN (REG_ERANGEX);
                  }
                else
                  /* Range from C to C. */
                  c1 = c;
  
 -              /* Set the range ... */
 -              if (SINGLE_BYTE_CHAR_P (c))
 -                /* ... into bitmap.  */
 +#ifndef emacs
 +              c = TRANSLATE (c);
 +              c1 = TRANSLATE (c1);
 +              /* Set the range into bitmap */
 +              for (; c <= c1; c++)
 +                SET_LIST_BIT (TRANSLATE (c));
 +#else  /* not emacs */
 +              if (target_multibyte)
                  {
 -                  re_wchar_t this_char;
 -                  re_wchar_t range_start = c, range_end = c1;
 -
 -                  /* If the start is after the end, the range is empty.  */
 -                  if (range_start > range_end)
 +                  if (c1 >= 128)
                      {
 -                      if (syntax & RE_NO_EMPTY_RANGES)
 -                        FREE_STACK_RETURN (REG_ERANGE);
 -                      /* Else, repeat the loop.  */
 +                      re_wchar_t c0 = MAX (c, 128);
 +
 +                      SETUP_MULTIBYTE_RANGE (range_table_work, c0, c1);
 +                      c1 = 127;
                      }
 -                  else
 +                  for (; c <= c1; c++)
 +                    SET_LIST_BIT (TRANSLATE (c));
 +                }
 +              else
 +                {
 +                  re_wchar_t c0;
 +
 +                  for (; c <= c1; c++)
                      {
 -                      for (this_char = range_start; this_char <= range_end;
 -                           this_char++)
 -                        {
 -                          int translated = TRANSLATE (this_char);
 -                          if (translated < (1 << BYTEWIDTH))
 -                            SET_LIST_BIT (translated);
 -                          else
 -                            SET_RANGE_TABLE_WORK_AREA
 -                              (range_table_work, translated, translated);
 -                        }
 +                      c0 = c;
 +                      if (! multibyte)
 +                        MAKE_CHAR_MULTIBYTE (c0);
 +                      c0 = TRANSLATE (c0);
 +                      MAKE_CHAR_UNIBYTE (c0);
 +                      SET_LIST_BIT (c0);
                      }
                  }
 -              else
 -                /* ... into range table.  */
 -                SET_RANGE_TABLE_WORK_AREA (range_table_work, c, c1);
 +#endif /* not emacs */
              }
  
            /* Discard any (non)matching list bytes that are all 0 at the
          {
            int len;
  
 +          if (! multibyte)
 +            MAKE_CHAR_MULTIBYTE (c);
            c = TRANSLATE (c);
 -          if (multibyte)
 -            len = CHAR_STRING (c, b);
 +          if (target_multibyte)
 +            {
 +              len = CHAR_STRING (c, b);
 +              b += len;
 +            }
            else
 -            *b = c, len = 1;
 -          b += len;
 +            {
 +              MAKE_CHAR_UNIBYTE (c);
 +              *b++ = c;
 +              len = 1;
 +            }
            (*pending_exact) += len;
          }
  
    /* We have succeeded; set the length of the buffer.  */
    bufp->used = b - bufp->buffer;
  
 +#ifdef emacs
 +  /* Now the buffer is adjusted for the multibyteness of a target.  */
 +  bufp->multibyte = bufp->target_multibyte;
 +#endif
 +
  #ifdef DEBUG
    if (debug > 0)
      {
@@@ -3964,11 -3892,16 +3964,11 @@@ analyse_first (p, pend, fastmap, multib
  
        case exactn:
          if (fastmap)
 -          {
 -            int c = RE_STRING_CHAR (p + 1, pend - p);
 -            /* When fast-scanning, the fastmap can be indexed either with
 -               a char (smaller than 256) or with the first byte of
 -               a char's byte sequence.  So we have to conservatively add
 -               both to the table.  */
 -            if (SINGLE_BYTE_CHAR_P (c))
 -              fastmap[c] = 1;
 -            fastmap[p[1]] = 1;
 -          }
 +          /* If multibyte is nonzero, the first byte of each
 +             character is an ASCII or a leading code.  Otherwise,
 +             each byte is a character.  Thus, this works in both
 +             cases. */
 +          fastmap[p[1]] = 1;
          break;
  
  
  
  
        case charset_not:
 -        /* Chars beyond end of bitmap are possible matches.
 -           All the single-byte codes can occur in multibyte buffers.
 -           So any that are not listed in the charset
 -           are possible matches, even in multibyte buffers.  */
          if (!fastmap) break;
 -        /* We don't need to mark LEADING_CODE_8_BIT_CONTROL specially
 -           because it will automatically be set when needed by virtue of
 -           being larger than the highest char of its charset (0xbf) but
 -           smaller than (1<<BYTEWIDTH).  */
 -        for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH;
 -             j < (1 << BYTEWIDTH); j++)
 -          fastmap[j] = 1;
 +        {
 +          /* Chars beyond end of bitmap are possible matches.  */
 +          /* In a multibyte case, the bitmap is used only for ASCII
 +             characters.  */
 +          int limit = multibyte ? 128 : (1 << BYTEWIDTH);
 +
 +          for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH;
 +               j < limit; j++)
 +            fastmap[j] = 1;
 +        }
 +
          /* Fallthrough */
        case charset:
          if (!fastmap) break;
          for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH - 1, p++;
               j >= 0; j--)
            if (!!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) ^ not)
 -            {
 -              fastmap[j] = 1;
 -#ifdef emacs
 -              if (j >= 0x80 && j < 0xa0)
 -                fastmap[LEADING_CODE_8_BIT_CONTROL] = 1;
 -#endif
 -            }
 +            fastmap[j] = 1;
  
          if ((not && multibyte)
 -            /* Any character set can possibly contain a character
 +            /* Any leading code can possibly start a character
                 which doesn't match the specified set of characters.  */
              || (CHARSET_RANGE_TABLE_EXISTS_P (&p[-2])
                  && CHARSET_RANGE_TABLE_BITS (&p[-2]) != 0))
            /* If we can match a character class, we can match
 -             any character set.  */
 +             any multibyte characters.  */
            {
 -          set_fastmap_for_multibyte_characters:
              if (match_any_multibyte_characters == false)
                {
 -                for (j = 0x80; j < 0xA0; j++) /* XXX */
 -                  if (BASE_LEADING_CODE_P (j))
 -                    fastmap[j] = 1;
 +                for (j = 0x80; j < (1 << BYTEWIDTH); j++)
 +                  fastmap[j] = 1;
                  match_any_multibyte_characters = true;
                }
            }
          else if (!not && CHARSET_RANGE_TABLE_EXISTS_P (&p[-2])
                   && match_any_multibyte_characters == false)
            {
 -            /* Set fastmap[I] 1 where I is a base leading code of each
 -               multibyte character in the range table. */
 +            /* Set fastmap[I] to 1 where I is a leading code of each
 +               multibyte characer in the range table. */
              int c, count;
 +            unsigned char lc1, lc2;
  
              /* Make P points the range table.  `+ 2' is to skip flag
                 bits for a character class.  */
              EXTRACT_NUMBER_AND_INCR (count, p);
              for (; count > 0; count--, p += 2 * 3) /* XXX */
                {
 -                /* Extract the start of each range.  */
 +                /* Extract the start and end of each range.  */
                  EXTRACT_CHARACTER (c, p);
 -                j = CHAR_CHARSET (c);
 -                fastmap[CHARSET_LEADING_CODE_BASE (j)] = 1;
 +                lc1 = CHAR_LEADING_CODE (c);
 +                p += 3;
 +                EXTRACT_CHARACTER (c, p);
 +                lc2 = CHAR_LEADING_CODE (c);
 +                for (j = lc1; j <= lc2; j++)
 +                  fastmap[j] = 1;
                }
            }
          break;
          if (!fastmap) break;
          not = (re_opcode_t)p[-1] == notcategoryspec;
          k = *p++;
 -        for (j = 0; j < (1 << BYTEWIDTH); j++)
 +        for (j = (multibyte ? 127 : (1 << BYTEWIDTH)); j >= 0; j--)
            if ((CHAR_HAS_CATEGORY (j, k)) ^ not)
              fastmap[j] = 1;
  
          if (multibyte)
 -          /* Any character set can possibly contain a character
 -             whose category is K (or not).  */
 -          goto set_fastmap_for_multibyte_characters;
 +          {
 +            /* Any character set can possibly contain a character
 +               whose category is K (or not).  */
 +            if (match_any_multibyte_characters == false)
 +              {
 +                for (j = 0x80; j < (1 << BYTEWIDTH); j++)
 +                  fastmap[j] = 1;
 +                match_any_multibyte_characters = true;
 +              }
 +          }
          break;
  
        /* All cases after this match the empty string.  These end with
@@@ -4329,8 -4258,8 +4329,8 @@@ re_search_2 (bufp, str1, size1, str2, s
    int total_size = size1 + size2;
    int endpos = startpos + range;
    boolean anchored_start;
 -
 -  /* Nonzero if we have to concern multibyte character.  */
 +  /* Nonzero if BUFP is setup for multibyte characters.  We are sure
 +     that it is the same as RE_TARGET_MULTIBYTE_P (bufp).  */
    const boolean multibyte = RE_MULTIBYTE_P (bufp);
  
    /* Check for out-of-range STARTPOS.  */
  
                        buf_ch = STRING_CHAR_AND_LENGTH (d, range - lim,
                                                         buf_charlen);
 -
                        buf_ch = RE_TRANSLATE (translate, buf_ch);
 -                      if (buf_ch >= 0400
 -                          || fastmap[buf_ch])
 +                      if (fastmap[CHAR_LEADING_CODE (buf_ch)])
                          break;
  
                        range -= buf_charlen;
                        d += buf_charlen;
                      }
                  else
 -                  {
 -                    /* Convert *d to integer to shut up GCC's
 -                       whining about comparison that is always
 -                       true.  */
 -                    int di = *d;
 -
 -                    while (range > lim
 -                           && !fastmap[RE_TRANSLATE (translate, di)])
 -                      {
 -                        di = *(++d);
 -                        range--;
 -                      }
 -                  }
 -              }
 -            else
 -              do
 -                {
 -                  re_char *d_start = d;
 -                  while (range > lim && !fastmap[*d])
 +                  while (range > lim)
                      {
 +                      buf_ch = *d;
 +                      MAKE_CHAR_MULTIBYTE (buf_ch);
 +                      buf_ch = RE_TRANSLATE (translate, buf_ch);
 +                      MAKE_CHAR_UNIBYTE (buf_ch);
 +                      if (fastmap[buf_ch])
 +                        break;
                        d++;
                        range--;
                      }
 -#ifdef emacs
 -                  if (multibyte && range > lim)
 +              }
 +            else
 +              {
 +                if (multibyte)
 +                  while (range > lim)
                      {
 -                      /* Check that we are at the beginning of a char.  */
 -                      int at_boundary;
 -                      AT_CHAR_BOUNDARY_P (at_boundary, d, d_start);
 -                      if (at_boundary)
 +                      int buf_charlen;
 +
 +                      buf_ch = STRING_CHAR_AND_LENGTH (d, range - lim,
 +                                                       buf_charlen);
 +                      if (fastmap[CHAR_LEADING_CODE (buf_ch)])
                          break;
 -                      else
 -                        { /* We have matched an internal byte of a char
 -                             rather than the leading byte, so it's a false
 -                             positive: we should keep scanning.  */
 -                          d++; range--;
 -                        }
 +                      range -= buf_charlen;
 +                      d += buf_charlen;
                      }
 -                  else
 -#endif
 -                    break;
 -                } while (1);
 -
 +                else
 +                  while (range > lim && !fastmap[*d])
 +                    {
 +                      d++;
 +                      range--;
 +                    }
 +              }
              startpos += irange - range;
            }
          else                          /* Searching backwards.  */
              int room = (startpos >= size1
                          ? size2 + size1 - startpos
                          : size1 - startpos);
 -            buf_ch = RE_STRING_CHAR (d, room);
 -            buf_ch = TRANSLATE (buf_ch);
 -
 -            if (! (buf_ch >= 0400
 -                   || fastmap[buf_ch]))
 -              goto advance;
 +            if (multibyte)
 +              {
 +                buf_ch = STRING_CHAR (d, room);
 +                buf_ch = TRANSLATE (buf_ch);
 +                if (! fastmap[CHAR_LEADING_CODE (buf_ch)])
 +                  goto advance;
 +              }
 +            else
 +              {
 +                if (! fastmap[TRANSLATE (*d)])
 +                  goto advance;
 +              }
            }
        }
  
@@@ -4783,7 -4718,7 +4783,7 @@@ mutually_exclusive_p (bufp, p1, p2
  
            /* Test if C is listed in charset (or charset_not)
               at `p1'.  */
 -          if (SINGLE_BYTE_CHAR_P (c))
 +          if (! multibyte || IS_REAL_ASCII (c))
              {
                if (c < CHARSET_BITMAP_SIZE (p1) * BYTEWIDTH
                    && p1[2 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
             size of bitmap table of P1 is extracted by
             using macro `CHARSET_BITMAP_SIZE'.
  
 -           Since we know that all the character listed in
 -           P2 is ASCII, it is enough to test only bitmap
 -           table of P1.  */
 +           In a multibyte case, we know that all the character
 +           listed in P2 is ASCII.  In a unibyte case, P1 has only a
 +           bitmap table.  So, in both cases, it is enough to test
 +           only the bitmap table of P1.  */
  
          if ((re_opcode_t) *p1 == charset)
            {
@@@ -4993,24 -4927,6 +4993,24 @@@ re_match_2 (bufp, string1, size1, strin
  }
  WEAK_ALIAS (__re_match_2, re_match_2)
  
 +#ifdef emacs
 +#define TRANSLATE_VIA_MULTIBYTE(c)    \
 +  do {                                        \
 +    if (multibyte)                    \
 +      (c) = TRANSLATE (c);            \
 +    else                              \
 +      {                                       \
 +      MAKE_CHAR_MULTIBYTE (c);        \
 +      (c) = TRANSLATE (c);            \
 +      MAKE_CHAR_UNIBYTE (c);          \
 +      }                                       \
 +  } while (0)
 +
 +#else
 +#define TRANSLATE_VIA_MULTIBYTE(c) ((c) = TRANSLATE (c))
 +#endif
 +
 +
  /* This is a separate function so that we can force an alloca cleanup
     afterwards.  */
  static int
@@@ -5047,11 -4963,10 +5047,11 @@@ re_match_2_internal (bufp, string1, siz
    re_char *p = bufp->buffer;
    re_char *pend = p + bufp->used;
  
 -  /* We use this to map every character in the string.  */
 +  /* We use this to map every character in the string.        */
    RE_TRANSLATE_TYPE translate = bufp->translate;
  
 -  /* Nonzero if we have to concern multibyte character.  */
 +  /* Nonzero if BUFP is setup for multibyte characters.  We are sure
 +     that it is the same as RE_TARGET_MULTIBYTE_P (bufp).  */
    const boolean multibyte = RE_MULTIBYTE_P (bufp);
  
    /* Failure point stack.  Each place that can handle a failure further
          /* Remember the start point to rollback upon failure.  */
          dfail = d;
  
 +#ifndef emacs
          /* This is written out as an if-else so we don't waste time
             testing `translate' inside the loop.  */
          if (RE_TRANSLATE_P (translate))
 -          {
 -            if (multibyte)
 -              do
 +          do
 +            {
 +              PREFETCH ();
 +              if (RE_TRANSLATE (translate, *d) != *p++)
                  {
 -                  int pat_charlen, buf_charlen;
 -                  unsigned int pat_ch, buf_ch;
 -
 -                  PREFETCH ();
 -                  pat_ch = STRING_CHAR_AND_LENGTH (p, pend - p, pat_charlen);
 -                  buf_ch = STRING_CHAR_AND_LENGTH (d, dend - d, buf_charlen);
 -
 -                  if (RE_TRANSLATE (translate, buf_ch)
 -                      != pat_ch)
 -                    {
 -                      d = dfail;
 -                      goto fail;
 -                    }
 -
 -                  p += pat_charlen;
 -                  d += buf_charlen;
 -                  mcnt -= pat_charlen;
 +                  d = dfail;
 +                  goto fail;
                  }
 -              while (mcnt > 0);
 -            else
 -              do
 +              d++;
 +            }
 +          while (--mcnt);
 +        else
 +          do
 +            {
 +              PREFETCH ();
 +              if (*d++ != *p++)
                  {
 -                  /* Avoid compiler whining about comparison being
 -                     always true.  */
 -                  int di;
 +                  d = dfail;
 +                  goto fail;
 +                }
 +            }
 +          while (--mcnt);
 +#else  /* emacs */
 +        /* The cost of testing `translate' is comparatively small.  */
 +        if (multibyte)
 +          do
 +            {
 +              int pat_charlen, buf_charlen;
 +              unsigned int pat_ch, buf_ch;
  
 -                  PREFETCH ();
 -                  di = *d;
 -                  if (RE_TRANSLATE (translate, di) != *p++)
 -                    {
 -                      d = dfail;
 -                      goto fail;
 -                    }
 -                  d++;
 +              PREFETCH ();
 +              pat_ch = STRING_CHAR_AND_LENGTH (p, pend - p, pat_charlen);
 +              buf_ch = STRING_CHAR_AND_LENGTH (d, dend - d, buf_charlen);
 +
 +              if (TRANSLATE (buf_ch) != pat_ch)
 +                {
 +                  d = dfail;
 +                  goto fail;
                  }
 -              while (--mcnt);
 -          }
 +
 +              p += pat_charlen;
 +              d += buf_charlen;
 +              mcnt -= pat_charlen;
 +            }
 +          while (mcnt > 0);
          else
 -          {
 -            do
 -              {
 -                PREFETCH ();
 -                if (*d++ != *p++)
 -                  {
 -                    d = dfail;
 -                    goto fail;
 -                  }
 -              }
 -            while (--mcnt);
 -          }
 +          do
 +            {
 +              unsigned int buf_ch;
 +
 +              PREFETCH ();
 +              buf_ch = *d++;
 +              TRANSLATE_VIA_MULTIBYTE (buf_ch);
 +              if (buf_ch != *p++)
 +                {
 +                  d = dfail;
 +                  goto fail;
 +                }
 +            }
 +          while (--mcnt);
 +#endif
          break;
  
  
  
            PREFETCH ();
            c = RE_STRING_CHAR_AND_LENGTH (d, dend - d, len);
 -          c = TRANSLATE (c); /* The character to match.  */
 +          TRANSLATE_VIA_MULTIBYTE (c); /* The character to match.  */
  
 -          if (SINGLE_BYTE_CHAR_P (c))
 +          if (! multibyte || IS_REAL_ASCII (c))
              {                 /* Lookup bitmap.  */
                /* Cast to `unsigned' instead of `unsigned char' in
                   case the bit list is a full 32 bytes long.  */
            }
          else
            {
 -            unsigned char c;
 +            unsigned c;
              GET_CHAR_BEFORE_2 (c, d, string1, end1, string2, end2);
              if (c == '\n')
                break;
                 is the character at D, and S2 is the syntax of C2.  */
              re_wchar_t c1, c2;
              int s1, s2;
 +            int dummy;
  #ifdef emacs
              int offset = PTR_TO_OFFSET (d - 1);
              int charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
              UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
  #endif
              PREFETCH_NOLIMIT ();
 -            c2 = RE_STRING_CHAR (d, dend - d);
 +            GET_CHAR_AFTER (c2, d, dummy);
              s2 = SYNTAX (c2);
  
              if (/* Case 2: Only one of S1 and S2 is Sword.  */
                 is the character at D, and S2 is the syntax of C2.  */
              re_wchar_t c1, c2;
              int s1, s2;
 +            int dummy;
  #ifdef emacs
              int offset = PTR_TO_OFFSET (d);
              int charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
              UPDATE_SYNTAX_TABLE (charpos);
  #endif
              PREFETCH ();
 -            c2 = RE_STRING_CHAR (d, dend - d);
 +            GET_CHAR_AFTER (c2, d, dummy);
              s2 = SYNTAX (c2);
  
              /* Case 2: S2 is not Sword. */
                 is the character at D, and S2 is the syntax of C2.  */
              re_wchar_t c1, c2;
              int s1, s2;
 +            int dummy;
  #ifdef emacs
              int offset = PTR_TO_OFFSET (d) - 1;
              int charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
              if (!AT_STRINGS_END (d))
                {
                  PREFETCH_NOLIMIT ();
 -                c2 = RE_STRING_CHAR (d, dend - d);
 +                GET_CHAR_AFTER (c2, d, dummy);
  #ifdef emacs
 -                UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
 +                UPDATE_SYNTAX_TABLE_FORWARD (charpos);
  #endif
                  s2 = SYNTAX (c2);
  
            int len;
            re_wchar_t c;
  
 -          c = RE_STRING_CHAR_AND_LENGTH (d, dend - d, len);
 -
 +          GET_CHAR_AFTER (c, d, len);
            if ((SYNTAX (c) != (enum syntaxcode) mcnt) ^ not)
              goto fail;
            d += len;
            int len;
            re_wchar_t c;
  
 -          c = RE_STRING_CHAR_AND_LENGTH (d, dend - d, len);
 -
 +          GET_CHAR_AFTER (c, d, len);
            if ((!CHAR_HAS_CATEGORY (c, mcnt)) ^ not)
              goto fail;
            d += len;
@@@ -6307,8 -6213,8 +6307,8 @@@ bcmp_translate (s1, s2, len, translate
        int p1_charlen, p2_charlen;
        re_wchar_t p1_ch, p2_ch;
  
 -      p1_ch = RE_STRING_CHAR_AND_LENGTH (p1, p1_end - p1, p1_charlen);
 -      p2_ch = RE_STRING_CHAR_AND_LENGTH (p2, p2_end - p2, p2_charlen);
 +      GET_CHAR_AFTER (p1_ch, p1, p1_charlen);
 +      GET_CHAR_AFTER (p2_ch, p2, p2_charlen);
  
        if (RE_TRANSLATE (translate, p1_ch)
          != RE_TRANSLATE (translate, p2_ch))
diff --combined src/regex.h
index e065c597d4981bbd675fad582e9064c131631045,dd57ba36f574024b93cc8ccba6d5202668266325..3f3d313397b1822bb4b6a85985cc2747d25a8c3d
@@@ -1,8 -1,9 +1,9 @@@
  /* Definitions for data structures and routines for the regular
     expression library, version 0.12.
  
-    Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 2000, 2002,
-                  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 2000, 2001,
+                  2002, 2003, 2004, 2005, 2006, 2007
+                  Free Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@@ -397,15 -398,9 +398,15 @@@ struct re_pattern_buffe
    unsigned used_syntax : 1;
  
  #ifdef emacs
 -  /* If true, multi-byte form in the `buffer' should be recognized as a
 -     multibyte character. */
 +  /* If true, multi-byte form in the regexp pattern should be
 +     recognized as a multibyte character.  When the pattern is
 +     compiled, this is set to the same value as target_multibyte
 +     below.  */
    unsigned multibyte : 1;
 +
 +  /* If true, multi-byte form in the target of match should be
 +     recognized as a multibyte character.  */
 +  unsigned target_multibyte : 1;
  #endif
  
  /* [[[end pattern_buffer]]] */
diff --combined src/search.c
index 4c4fa7931a1cece6b65180e7110f69d85795a1e9,abc28619199ea780ab4135f72d5642bbfa529911..2e4ddc3256d5369037fc590cd416155201bbb077
@@@ -1,6 -1,6 +1,6 @@@
  /* String search routines for GNU Emacs.
-    Copyright (C) 1985, 1986, 1987, 1993, 1994, 1997, 1998, 1999, 2002, 2003,
-                  2004, 2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1985, 1986, 1987, 1993, 1994, 1997, 1998, 1999, 2001, 2002,
+                  2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -25,7 -25,7 +25,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "syntax.h"
  #include "category.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "region-cache.h"
  #include "commands.h"
  #include "blockinput.h"
@@@ -115,8 -115,9 +115,8 @@@ matcher_overflow (
     subexpression bounds.
     POSIX is nonzero if we want full backtracking (POSIX style)
     for this pattern.  0 means backtrack only enough to get a valid match.
 -   MULTIBYTE is nonzero if we want to handle multibyte characters in
 -   PATTERN.  0 means all multibyte characters are recognized just as
 -   sequences of binary data.
 +   MULTIBYTE is nonzero iff a target of match is a multibyte buffer or
 +   string.
  
     The behavior also depends on Vsearch_spaces_regexp.  */
  
@@@ -129,14 -130,46 +129,14 @@@ compile_pattern_1 (cp, pattern, transla
       int posix;
       int multibyte;
  {
 -  unsigned char *raw_pattern;
 -  int raw_pattern_size;
    char *val;
    reg_syntax_t old;
  
 -  /* MULTIBYTE says whether the text to be searched is multibyte.
 -     We must convert PATTERN to match that, or we will not really
 -     find things right.  */
 -
 -  if (multibyte == STRING_MULTIBYTE (pattern))
 -    {
 -      raw_pattern = (unsigned char *) SDATA (pattern);
 -      raw_pattern_size = SBYTES (pattern);
 -    }
 -  else if (multibyte)
 -    {
 -      raw_pattern_size = count_size_as_multibyte (SDATA (pattern),
 -                                                SCHARS (pattern));
 -      raw_pattern = (unsigned char *) alloca (raw_pattern_size + 1);
 -      copy_text (SDATA (pattern), raw_pattern,
 -               SCHARS (pattern), 0, 1);
 -    }
 -  else
 -    {
 -      /* Converting multibyte to single-byte.
 -
 -       ??? Perhaps this conversion should be done in a special way
 -       by subtracting nonascii-insert-offset from each non-ASCII char,
 -       so that only the multibyte chars which really correspond to
 -       the chosen single-byte character set can possibly match.  */
 -      raw_pattern_size = SCHARS (pattern);
 -      raw_pattern = (unsigned char *) alloca (raw_pattern_size + 1);
 -      copy_text (SDATA (pattern), raw_pattern,
 -               SBYTES (pattern), 1, 0);
 -    }
 -
    cp->regexp = Qnil;
    cp->buf.translate = (! NILP (translate) ? translate : make_number (0));
    cp->posix = posix;
 -  cp->buf.multibyte = multibyte;
 +  cp->buf.multibyte = STRING_MULTIBYTE (pattern);
 +  cp->buf.target_multibyte = multibyte;
    cp->whitespace_regexp = Vsearch_spaces_regexp;
    /* rms: I think BLOCK_INPUT is not needed here any more,
       because regex.c defines malloc to call xmalloc.
    /*  BLOCK_INPUT;  */
    old = re_set_syntax (RE_SYNTAX_EMACS
                       | (posix ? 0 : RE_NO_POSIX_BACKTRACKING));
 -
    re_set_whitespace_regexp (NILP (Vsearch_spaces_regexp) ? NULL
                            : SDATA (Vsearch_spaces_regexp));
  
 -  val = (char *) re_compile_pattern ((char *)raw_pattern,
 -                                   raw_pattern_size, &cp->buf);
 +  val = (char *) re_compile_pattern ((char *) SDATA (pattern),
 +                                   SBYTES (pattern), &cp->buf);
  
    /* If the compiled pattern hard codes some of the contents of the
       syntax-table, it can only be reused with *this* syntax table.  */
@@@ -235,7 -269,7 +235,7 @@@ compile_pattern (pattern, regp, transla
          && !NILP (Fstring_equal (cp->regexp, pattern))
          && EQ (cp->buf.translate, (! NILP (translate) ? translate : make_number (0)))
          && cp->posix == posix
 -        && cp->buf.multibyte == multibyte
 +        && cp->buf.target_multibyte == multibyte
          && (EQ (cp->syntax_table, Qt)
              || EQ (cp->syntax_table, current_buffer->syntax_table))
          && !NILP (Fequal (cp->whitespace_regexp, Vsearch_spaces_regexp)))
@@@ -1182,7 -1216,7 +1182,7 @@@ search_buffer (string, pos, pos_byte, l
        unsigned char *base_pat;
        /* Set to positive if we find a non-ASCII char that need
         translation.  Otherwise set to zero later.  */
 -      int charset_base = -1;
 +      int char_base = -1;
        int boyer_moore_ok = 1;
  
        /* MULTIBYTE says whether the text to be searched is multibyte.
        /* Copy and optionally translate the pattern.  */
        len = raw_pattern_size;
        len_byte = raw_pattern_size_byte;
 -      patbuf = (unsigned char *) alloca (len_byte);
 +      patbuf = (unsigned char *) alloca (len * MAX_MULTIBYTE_LENGTH);
        pat = patbuf;
        base_pat = raw_pattern;
        if (multibyte)
                  if (c != inverse && boyer_moore_ok)
                    {
                      /* Check if all equivalents belong to the same
 -                       charset & row.  Note that the check of C
 -                       itself is done by the last iteration.  Note
 -                       also that we don't have to check ASCII
 -                       characters because boyer-moore search can
 -                       always handle their translation.  */
 -                    while (1)
 +                       group of characters.  Note that the check of C
 +                       itself is done by the last iteration.  */
 +                    int this_char_base = -1;
 +
 +                    while (boyer_moore_ok)
                        {
                          if (ASCII_BYTE_P (inverse))
                            {
 -                            if (charset_base > 0)
 +                            if (this_char_base > 0)
 +                              boyer_moore_ok = 0;
 +                            else
                                {
 -                                boyer_moore_ok = 0;
 -                                break;
 +                                this_char_base = 0;
 +                                if (char_base < 0)
 +                                  char_base = this_char_base;
                                }
 -                            charset_base = 0;
 -                          }
 -                        else if (SINGLE_BYTE_CHAR_P (inverse))
 -                          {
 -                            /* Boyer-moore search can't handle a
 -                               translation of an eight-bit
 -                               character.  */
 -                            boyer_moore_ok = 0;
 -                            break;
                            }
 -                        else if (charset_base < 0)
 -                          charset_base = inverse & ~CHAR_FIELD3_MASK;
 -                        else if ((inverse & ~CHAR_FIELD3_MASK)
 -                                 != charset_base)
 +                        else if (CHAR_BYTE8_P (inverse))
 +                          /* Boyer-moore search can't handle a
 +                             translation of an eight-bit
 +                             character.  */
 +                          boyer_moore_ok = 0;
 +                        else if (this_char_base < 0)
                            {
 -                            boyer_moore_ok = 0;
 -                            break;
 +                            this_char_base = inverse & ~0x3F;
 +                            if (char_base < 0)
 +                              char_base = this_char_base;
 +                            else if (char_base > 0
 +                                     && this_char_base != char_base)
 +                              boyer_moore_ok = 0;
                            }
 +                        else if ((inverse & ~0x3F) != this_char_base)
 +                          boyer_moore_ok = 0;
                          if (c == inverse)
                            break;
                          TRANSLATE (inverse, inverse_trt, inverse);
                        }
                    }
                }
 -            if (charset_base < 0)
 -              charset_base = 0;
 +            if (char_base < 0)
 +              char_base = 0;
  
              /* Store this character into the translated pattern.  */
              bcopy (str, pat, charlen);
        else
        {
          /* Unibyte buffer.  */
 -        charset_base = 0;
 +        char_base = 0;
          while (--len >= 0)
            {
              int c, translated;
        if (boyer_moore_ok)
        return boyer_moore (n, pat, len, len_byte, trt, inverse_trt,
                            pos, pos_byte, lim, lim_byte,
 -                          charset_base);
 +                          char_base);
        else
        return simple_search (n, pat, len, len_byte, trt,
                              pos, pos_byte, lim, lim_byte);
@@@ -1382,9 -1415,6 +1382,9 @@@ simple_search (n, pat, len, len_byte, t
  {
    int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
    int forward = n > 0;
 +  /* Number of buffer bytes matched.  Note that this may be different
 +     from len_byte in a multibyte buffer.  */
 +  int match_byte;
  
    if (lim > pos && multibyte)
      while (n > 0)
            int this_len = len;
            int this_len_byte = len_byte;
            unsigned char *p = pat;
 -          if (pos + len > lim)
 +          if (pos + len > lim || pos_byte + len_byte > lim_byte)
              goto stop;
  
            while (this_len > 0)
  
            if (this_len == 0)
              {
 +              match_byte = this_pos_byte - pos_byte;
                pos += len;
 -              pos_byte += len_byte;
 +              pos_byte += match_byte;
                break;
              }
  
  
            if (this_len == 0)
              {
 +              match_byte = len;
                pos += len;
                break;
              }
          {
            /* Try matching at position POS.  */
            int this_pos = pos - len;
 -          int this_pos_byte = pos_byte - len_byte;
 +          int this_pos_byte;
            int this_len = len;
            int this_len_byte = len_byte;
            unsigned char *p = pat;
  
 -          if (this_pos < lim || this_pos_byte < lim_byte)
 +          if (this_pos < lim || (pos_byte - len_byte) < lim_byte)
              goto stop;
 +          this_pos_byte = CHAR_TO_BYTE (this_pos);
 +          match_byte = pos_byte - this_pos_byte;
  
            while (this_len > 0)
              {
            if (this_len == 0)
              {
                pos -= len;
 -              pos_byte -= len_byte;
 +              pos_byte -= match_byte;
                break;
              }
  
            int this_len = len;
            unsigned char *p = pat;
  
 -          if (pos - len < lim)
 +          if (this_pos < lim)
              goto stop;
  
            while (this_len > 0)
  
            if (this_len == 0)
              {
 +              match_byte = len;
                pos -= len;
                break;
              }
    if (n == 0)
      {
        if (forward)
 -      set_search_regs ((multibyte ? pos_byte : pos) - len_byte, len_byte);
 +      set_search_regs ((multibyte ? pos_byte : pos) - match_byte, match_byte);
        else
 -      set_search_regs (multibyte ? pos_byte : pos, len_byte);
 +      set_search_regs (multibyte ? pos_byte : pos, match_byte);
  
        return pos;
      }
     have nontrivial translation are the same aside from the last byte.
     This makes it possible to translate just the last byte of a
     character, and do so after just a simple test of the context.
 -   CHARSET_BASE is nonzero iff there is such a non-ASCII character.
 +   CHAR_BASE is nonzero iff there is such a non-ASCII character.
  
     If that criterion is not satisfied, do not call this function.  */
  
  static int
  boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
 -           pos, pos_byte, lim, lim_byte, charset_base)
 +           pos, pos_byte, lim, lim_byte, char_base)
       int n;
       unsigned char *base_pat;
       int len, len_byte;
       Lisp_Object inverse_trt;
       int pos, pos_byte;
       int lim, lim_byte;
 -     int charset_base;
 +     int char_base;
  {
    int direction = ((n > 0) ? 1 : -1);
    register int dirlen;
  
    unsigned char simple_translate[0400];
    /* These are set to the preceding bytes of a byte to be translated
 -     if charset_base is nonzero.  As the maximum byte length of a
 -     multibyte character is 4, we have to check at most three previous
 +     if char_base is nonzero.  As the maximum byte length of a
 +     multibyte character is 5, we have to check at most four previous
       bytes.  */
    int translate_prev_byte1 = 0;
    int translate_prev_byte2 = 0;
    int translate_prev_byte3 = 0;
 +  int translate_prev_byte4 = 0;
  
  #ifdef C_ALLOCA
    int BM_tab_space[0400];
    for (i = 0; i < 0400; i++)
      simple_translate[i] = i;
  
 -  if (charset_base)
 +  if (char_base)
      {
 -      /* Setup translate_prev_byte1/2/3 from CHARSET_BASE.  Only a
 +      /* Setup translate_prev_byte1/2/3/4 from CHAR_BASE.  Only a
         byte following them are the target of translation.  */
 -      int sample_char = charset_base | 0x20;
        unsigned char str[MAX_MULTIBYTE_LENGTH];
 -      int len = CHAR_STRING (sample_char, str);
 +      int len = CHAR_STRING (char_base, str);
  
        translate_prev_byte1 = str[len - 2];
        if (len > 2)
        {
          translate_prev_byte2 = str[len - 3];
          if (len > 3)
 -          translate_prev_byte3 = str[len - 4];
 +          {
 +            translate_prev_byte3 = str[len - 4];
 +            if (len > 4)
 +              translate_prev_byte4 = str[len - 5];
 +          }
        }
      }
  
          /* If the byte currently looking at is the last of a
             character to check case-equivalents, set CH to that
             character.  An ASCII character and a non-ASCII character
 -           matching with CHARSET_BASE are to be checked.  */
 +           matching with CHAR_BASE are to be checked.  */
          int ch = -1;
  
          if (ASCII_BYTE_P (*ptr) || ! multibyte)
            ch = *ptr;
 -        else if (charset_base
 +        else if (char_base
                   && ((pat_end - ptr) == 1 || CHAR_HEAD_P (ptr[1])))
            {
              unsigned char *charstart = ptr - 1;
              while (! (CHAR_HEAD_P (*charstart)))
                charstart--;
              ch = STRING_CHAR (charstart, ptr - charstart + 1);
 -            if (charset_base != (ch & ~CHAR_FIELD3_MASK))
 +            if (char_base != (ch & ~0x3F))
                ch = -1;
            }
  
          if (ch >= 0400)
 -          j = ((unsigned char) ch) | 0200;
 +          j = (ch & 0x3F) | 0200;
          else
            j = *ptr;
  
                {
                  TRANSLATE (ch, inverse_trt, ch);
                  if (ch >= 0400)
 -                  j = ((unsigned char) ch) | 0200;
 +                  j = (ch & 0x3F) | 0200;
                  else
 -                  j = (unsigned char) ch;
 +                  j = ch;
  
                  /* For all the characters that map into CH,
                     set up simple_translate to map the last byte
@@@ -2059,7 -2080,7 +2059,7 @@@ wordify (string
      {
        int c;
  
 -      FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
 +      FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, string, i, i_byte);
  
        if (SYNTAX (c) != Sword)
        {
        int c;
        int i_byte_orig = i_byte;
  
 -      FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
 +      FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, string, i, i_byte);
  
        if (SYNTAX (c) == Sword)
        {
@@@ -2378,11 -2399,11 +2378,11 @@@ since only regular expressions have dis
        {
          if (NILP (string))
            {
 -            c = FETCH_CHAR (pos_byte);
 +            c = FETCH_CHAR_AS_MULTIBYTE (pos_byte);
              INC_BOTH (pos, pos_byte);
            }
          else
 -          FETCH_STRING_CHAR_ADVANCE (c, string, pos, pos_byte);
 +          FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, string, pos, pos_byte);
  
          if (LOWERCASEP (c))
            {
        Lisp_Object rev_tbl;
        int really_changed = 0;
  
 -      rev_tbl= (!buf_multibyte && CHAR_TABLE_P (Vnonascii_translation_table)
 -              ? Fchar_table_extra_slot (Vnonascii_translation_table,
 -                                        make_number (0))
 -              : Qnil);
 +      rev_tbl = Qnil;
  
        substed_alloc_size = length * 2 + 100;
        substed = (unsigned char *) xmalloc (substed_alloc_size + 1);
                {
                  FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, newtext,
                                                      pos, pos_byte);
 -                if (!buf_multibyte && !SINGLE_BYTE_CHAR_P (c))
 +                if (!buf_multibyte && !ASCII_CHAR_P (c))
                    c = multibyte_char_to_unibyte (c, rev_tbl);
                }
              else
diff --combined src/syntax.c
index d1ae3f6bd8c95cf5641fdc94965ea5317f2a5e66,a9e6dda81fe930a031be97636507092765c8f842..651406230325fb109461f6c2e5367f34f063c810
@@@ -1,6 -1,7 +1,7 @@@
  /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
-    Copyright (C) 1985, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2002,
-                  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1985, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2001,
+                  2002, 2003, 2004, 2005, 2006, 2007
+                  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -25,7 -26,7 +26,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "lisp.h"
  #include "commands.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "keymap.h"
  #include "regex.h"
  
@@@ -100,8 -101,7 +101,8 @@@ static int find_defun_start P_ ((int, i
  static int back_comment P_ ((EMACS_INT, EMACS_INT, EMACS_INT, int, int,
                             EMACS_INT *, EMACS_INT *));
  static int char_quoted P_ ((int, int));
 -static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object, int));
 +static Lisp_Object skip_chars P_ ((int, Lisp_Object, Lisp_Object, int));
 +static Lisp_Object skip_syntaxes P_ ((int, Lisp_Object, Lisp_Object));
  static Lisp_Object scan_lists P_ ((EMACS_INT, EMACS_INT, EMACS_INT, int));
  static void scan_sexps_forward P_ ((struct lisp_parse_state *,
                                    int, int, int, int,
@@@ -306,7 -306,7 +307,7 @@@ char_quoted (charpos, bytepos
        int c;
  
        UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
 -      c = FETCH_CHAR (bytepos);
 +      c = FETCH_CHAR_AS_MULTIBYTE (bytepos);
        code = SYNTAX (c);
        if (! (code == Scharquote || code == Sescape))
        break;
@@@ -398,11 -398,11 +399,11 @@@ find_defun_start (pos, pos_byte
  
        /* Open-paren at start of line means we may have found our
         defun-start.  */
 -      c = FETCH_CHAR (PT_BYTE);
 +      c = FETCH_CHAR_AS_MULTIBYTE (PT_BYTE);
        if (SYNTAX (c) == Sopen)
        {
          SETUP_SYNTAX_TABLE (PT + 1, -1);      /* Try again... */
 -        c = FETCH_CHAR (PT_BYTE);
 +        c = FETCH_CHAR_AS_MULTIBYTE (PT_BYTE);
          if (SYNTAX (c) == Sopen)
            break;
          /* Now fallback to the default value.  */
@@@ -523,7 -523,7 +524,7 @@@ back_comment (from, from_byte, stop, co
        UPDATE_SYNTAX_TABLE_BACKWARD (from);
  
        prev_syntax = syntax;
 -      c = FETCH_CHAR (from_byte);
 +      c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
        syntax = SYNTAX_WITH_FLAGS (c);
        code = SYNTAX (c);
  
          int next = from, next_byte = from_byte, next_c, next_syntax;
          DEC_BOTH (next, next_byte);
          UPDATE_SYNTAX_TABLE_BACKWARD (next);
 -        next_c = FETCH_CHAR (next_byte);
 +        next_c = FETCH_CHAR_AS_MULTIBYTE (next_byte);
          next_syntax = SYNTAX_WITH_FLAGS (next_c);
          if (((com2start || comnested)
               && SYNTAX_FLAGS_COMEND_SECOND (syntax)
@@@ -855,6 -855,29 +856,6 @@@ char syntax_code_spec[16] 
  static Lisp_Object Vsyntax_code_object;
  
  \f
 -/* Look up the value for CHARACTER in syntax table TABLE's parent
 -   and its parents.  SYNTAX_ENTRY calls this, when TABLE itself has nil
 -   for CHARACTER.  It's actually used only when not compiled with GCC.  */
 -
 -Lisp_Object
 -syntax_parent_lookup (table, character)
 -     Lisp_Object table;
 -     int character;
 -{
 -  Lisp_Object value;
 -
 -  while (1)
 -    {
 -      table = XCHAR_TABLE (table)->parent;
 -      if (NILP (table))
 -      return Qnil;
 -
 -      value = XCHAR_TABLE (table)->contents[character];
 -      if (!NILP (value))
 -      return value;
 -    }
 -}
 -
  DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
         doc: /* Return the syntax code of CHARACTER, described by a character.
  For example, if CHARACTER is a word constituent,
@@@ -973,8 -996,6 +974,8 @@@ DEFUN ("modify-syntax-entry", Fmodify_s
         doc: /* Set syntax for character CHAR according to string NEWENTRY.
  The syntax is changed only for table SYNTAX-TABLE, which defaults to
   the current buffer's syntax table.
 +CHAR may be a cons (MIN . MAX), in which case, syntaxes of all characters
 +in the range MIN and MAX are changed.
  The first character of NEWENTRY should be one of the following:
    Space or -  whitespace syntax.    w   word constituent.
    _           symbol constituent.   .   punctuation.
@@@ -1011,24 -1032,14 +1012,24 @@@ usage: (modify-syntax-entry CHAR NEWENT
       (c, newentry, syntax_table)
       Lisp_Object c, newentry, syntax_table;
  {
 -  CHECK_NUMBER (c);
 +  if (CONSP (c))
 +    {
 +      CHECK_CHARACTER_CAR (c);
 +      CHECK_CHARACTER_CDR (c);
 +    }
 +  else
 +    CHECK_CHARACTER (c);
  
    if (NILP (syntax_table))
      syntax_table = current_buffer->syntax_table;
    else
      check_syntax_table (syntax_table);
  
 -  SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), Fstring_to_syntax (newentry));
 +  newentry = Fstring_to_syntax (newentry);
 +  if (CONSP (c))
 +    SET_RAW_SYNTAX_ENTRY_RANGE (syntax_table, c, newentry);
 +  else
 +    SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), newentry);
  
    /* We clear the regexp cache, since character classes can now have
       different values from those in the compiled regexps.*/
@@@ -1187,10 -1198,6 +1188,10 @@@ DEFUN ("internal-describe-syntax-value"
  \f
  int parse_sexp_ignore_comments;
  
 +/* Char-table of functions that find the next or previous word
 +   boundary.  */
 +Lisp_Object Vfind_word_boundary_function_table;
 +
  /* Return the position across COUNT words from FROM.
     If that many words cannot be found before the end of the buffer, return 0.
     COUNT negative means scan backward and stop at word beginning.  */
@@@ -1204,7 -1211,6 +1205,7 @@@ scan_words (from, count
    register int from_byte = CHAR_TO_BYTE (from);
    register enum syntaxcode code;
    int ch0, ch1;
 +  Lisp_Object func, script, pos;
  
    immediate_quit = 1;
    QUIT;
              return 0;
            }
          UPDATE_SYNTAX_TABLE_FORWARD (from);
 -        ch0 = FETCH_CHAR (from_byte);
 +        ch0 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
          code = SYNTAX (ch0);
          INC_BOTH (from, from_byte);
          if (words_include_escapes
        }
        /* Now CH0 is a character which begins a word and FROM is the
           position of the next character.  */
 -      while (1)
 +      func = CHAR_TABLE_REF (Vfind_word_boundary_function_table, ch0);
 +      if (! NILP (Ffboundp (func)))
        {
 -        if (from == end) break;
 -        UPDATE_SYNTAX_TABLE_FORWARD (from);
 -        ch1 = FETCH_CHAR (from_byte);
 -        code = SYNTAX (ch1);
 -        if (!(words_include_escapes
 -              && (code == Sescape || code == Scharquote)))
 -          if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))
 -            break;
 -        INC_BOTH (from, from_byte);
 -        ch0 = ch1;
 +        pos = call2 (func, make_number (from - 1), make_number (end));
 +        if (INTEGERP (pos) && XINT (pos) > from)
 +          {
 +            from = XINT (pos);
 +            from_byte = CHAR_TO_BYTE (from);
 +          }
 +      }
 +      else
 +      {
 +        script = CHAR_TABLE_REF (Vchar_script_table, ch0);
 +        while (1)
 +          {
 +            if (from == end) break;
 +            UPDATE_SYNTAX_TABLE_FORWARD (from);
 +            ch1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
 +            code = SYNTAX (ch1);
 +            if ((code != Sword
 +                 && (! words_include_escapes
 +                     || (code != Sescape && code != Scharquote)))
 +                || ! EQ (CHAR_TABLE_REF (Vchar_script_table, ch1), script))
 +              break;
 +            INC_BOTH (from, from_byte);
 +            ch0 = ch1;
 +          }
        }
        count--;
      }
            }
          DEC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_BACKWARD (from);
 -        ch1 = FETCH_CHAR (from_byte);
 +        ch1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
          code = SYNTAX (ch1);
          if (words_include_escapes
              && (code == Sescape || code == Scharquote))
        }
        /* Now CH1 is a character which ends a word and FROM is the
           position of it.  */
 -      while (1)
 +      func = CHAR_TABLE_REF (Vfind_word_boundary_function_table, ch1);
 +      if (! NILP (Ffboundp (func)))
 +      {
 +        pos = call2 (func, make_number (from), make_number (beg));
 +        if (INTEGERP (pos) && XINT (pos) < from)
 +          {
 +            from = XINT (pos);
 +            from_byte = CHAR_TO_BYTE (from);
 +          }
 +      }
 +      else
        {
 -        int temp_byte;
 +        script = CHAR_TABLE_REF (Vchar_script_table, ch1);
 +        while (1)
 +          {
 +            int temp_byte;
  
 -        if (from == beg)
 -          break;
 -        temp_byte = dec_bytepos (from_byte);
 -        UPDATE_SYNTAX_TABLE_BACKWARD (from);
 -        ch0 = FETCH_CHAR (temp_byte);
 -        code = SYNTAX (ch0);
 -        if (!(words_include_escapes
 -              && (code == Sescape || code == Scharquote)))
 -          if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))
 -            break;
 -        DEC_BOTH (from, from_byte);
 -        ch1 = ch0;
 +            if (from == beg)
 +              break;
 +            temp_byte = dec_bytepos (from_byte);
 +            UPDATE_SYNTAX_TABLE_BACKWARD (from);
 +            ch0 = FETCH_CHAR_AS_MULTIBYTE (temp_byte);
 +            code = SYNTAX (ch0);
 +            if ((code != Sword
 +                 && (! words_include_escapes
 +                     || (code != Sescape && code != Scharquote)))
 +                || ! EQ (CHAR_TABLE_REF (Vchar_script_table, ch0), script))
 +              break;
 +            DEC_BOTH (from, from_byte);
 +            ch1 = ch0;
 +          }
        }
        count++;
      }
@@@ -1368,7 -1344,7 +1369,7 @@@ Returns the distance traveled, either z
       (string, lim)
       Lisp_Object string, lim;
  {
 -  return skip_chars (1, 0, string, lim, 1);
 +  return skip_chars (1, string, lim, 1);
  }
  
  DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
@@@ -1378,7 -1354,7 +1379,7 @@@ Returns the distance traveled, either z
       (string, lim)
       Lisp_Object string, lim;
  {
 -  return skip_chars (0, 0, string, lim, 1);
 +  return skip_chars (0, string, lim, 1);
  }
  
  DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,
@@@ -1390,7 -1366,7 +1391,7 @@@ This function returns the distance trav
       (syntax, lim)
       Lisp_Object syntax, lim;
  {
 -  return skip_chars (1, 1, syntax, lim, 0);
 +  return skip_syntaxes (1, syntax, lim);
  }
  
  DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,
@@@ -1402,27 -1378,25 +1403,27 @@@ This function returns the distance trav
       (syntax, lim)
       Lisp_Object syntax, lim;
  {
 -  return skip_chars (0, 1, syntax, lim, 0);
 +  return skip_syntaxes (0, syntax, lim);
  }
  
  static Lisp_Object
 -skip_chars (forwardp, syntaxp, string, lim, handle_iso_classes)
 -     int forwardp, syntaxp;
 +skip_chars (forwardp, string, lim, handle_iso_classes)
 +     int forwardp;
       Lisp_Object string, lim;
       int handle_iso_classes;
  {
    register unsigned int c;
    unsigned char fastmap[0400];
 -  /* If SYNTAXP is 0, STRING may contain multi-byte form of characters
 -     of which codes don't fit in FASTMAP.  In that case, set the
 -     ranges of characters in CHAR_RANGES.  */
 +  /* Store the ranges of non-ASCII characters.  */
    int *char_ranges;
    int n_char_ranges = 0;
    int negate = 0;
    register int i, i_byte;
 -  int multibyte = !NILP (current_buffer->enable_multibyte_characters);
 +  /* Set to 1 if the current buffer is multibyte and the region
 +     contains non-ASCII chars.  */
 +  int multibyte;
 +  /* Set to 1 if STRING is multibyte and it contains non-ASCII
 +     chars.  */
    int string_multibyte;
    int size_byte;
    const unsigned char *str;
    Lisp_Object iso_classes;
  
    CHECK_STRING (string);
 -  char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2);
 -  string_multibyte = STRING_MULTIBYTE (string);
 -  str = SDATA (string);
 -  size_byte = SBYTES (string);
    iso_classes = Qnil;
  
 -  /* Adjust the multibyteness of the string to that of the buffer.  */
 -  if (multibyte != string_multibyte)
 -    {
 -      int nbytes;
 -
 -      if (multibyte)
 -      nbytes = count_size_as_multibyte (SDATA (string),
 -                                        SCHARS (string));
 -      else
 -      nbytes = SCHARS (string);
 -      if (nbytes != size_byte)
 -      {
 -        unsigned char *tmp = (unsigned char *) alloca (nbytes);
 -        copy_text (SDATA (string), tmp, size_byte,
 -                   string_multibyte, multibyte);
 -        size_byte = nbytes;
 -        str = tmp;
 -      }
 -    }
 -
    if (NILP (lim))
      XSETINT (lim, forwardp ? ZV : BEGV);
    else
    if (XINT (lim) < BEGV)
      XSETFASTINT (lim, BEGV);
  
 +  multibyte = (!NILP (current_buffer->enable_multibyte_characters)
 +             && (XINT (lim) - PT != CHAR_TO_BYTE (XINT (lim)) - PT_BYTE));
 +  string_multibyte = SBYTES (string) > SCHARS (string);
 +
    bzero (fastmap, sizeof fastmap);
  
 -  i_byte = 0;
 +  str = SDATA (string);
 +  size_byte = SBYTES (string);
  
 +  i_byte = 0;
    if (i_byte < size_byte
        && SREF (string, 0) == '^')
      {
      }
  
    /* Find the characters specified and set their elements of fastmap.
 -     If syntaxp, each character counts as itself.
 -     Otherwise, handle backslashes and ranges specially.  */
 +     Handle backslashes and ranges specially.
  
 -  while (i_byte < size_byte)
 +     If STRING contains non-ASCII characters, setup char_ranges for
 +     them and use fastmap only for their leading codes.  */
 +
 +  if (! string_multibyte)
      {
 -      c = STRING_CHAR_AND_LENGTH (str + i_byte, size_byte - i_byte, len);
 -      i_byte += len;
 +      int string_has_eight_bit = 0;
  
 -      if (syntaxp)
 -      fastmap[syntax_spec_code[c & 0377]] = 1;
 -      else
 +      /* At first setup fastmap.  */
 +      while (i_byte < size_byte)
        {
 +        c = str[i_byte++];
 +
          if (handle_iso_classes && c == '['
              && i_byte < size_byte
 -            && STRING_CHAR (str + i_byte, size_byte - i_byte) == ':')
 +            && str[i_byte] == ':')
            {
              const unsigned char *class_beg = str + i_byte + 1;
              const unsigned char *class_end = class_beg;
              if (i_byte == size_byte)
                break;
  
 +            c = str[i_byte++];
 +          }
 +        /* Treat `-' as range character only if another character
 +           follows.  */
 +        if (i_byte + 1 < size_byte
 +            && str[i_byte] == '-')
 +          {
 +            unsigned int c2;
 +
 +            /* Skip over the dash.  */
 +            i_byte++;
 +
 +            /* Get the end of the range.  */
 +            c2 = str[i_byte++];
 +            if (c2 == '\\'
 +                && i_byte < size_byte)
 +              c2 = str[i_byte++];
 +
 +            if (c <= c2)
 +              {
 +                while (c <= c2)
 +                  fastmap[c++] = 1;
 +                if (! ASCII_CHAR_P (c2))
 +                  string_has_eight_bit = 1;
 +              }
 +          }
 +        else
 +          {
 +            fastmap[c] = 1;
 +            if (! ASCII_CHAR_P (c))
 +              string_has_eight_bit = 1;
 +          }
 +      }
 +
 +      /* If the current range is multibyte and STRING contains
 +       eight-bit chars, arrange fastmap and setup char_ranges for
 +       the corresponding multibyte chars.  */
 +      if (multibyte && string_has_eight_bit)
 +      {
 +        unsigned char fastmap2[0400];
 +        int range_start_byte, range_start_char;
 +
 +        bcopy (fastmap2 + 0200, fastmap + 0200, 0200);
 +        bzero (fastmap + 0200, 0200);
 +        /* We are sure that this loop stops.  */
 +        for (i = 0200; ! fastmap2[i]; i++);
 +        c = unibyte_char_to_multibyte (i);
 +        fastmap[CHAR_LEADING_CODE (c)] = 1;
 +        range_start_byte = i;
 +        range_start_char = c;
 +        char_ranges = (int *) alloca (sizeof (int) * 128 * 2);
 +        for (i = 129; i < 0400; i++)
 +          {
 +            c = unibyte_char_to_multibyte (i);
 +            fastmap[CHAR_LEADING_CODE (c)] = 1;
 +            if (i - range_start_byte != c - range_start_char)
 +              {
 +                char_ranges[n_char_ranges++] = range_start_char;
 +                char_ranges[n_char_ranges++] = ((i - 1 - range_start_byte)
 +                                                + range_start_char);
 +                range_start_byte = i;
 +                range_start_char = c;
 +              }
 +          }
 +        char_ranges[n_char_ranges++] = range_start_char;
 +        char_ranges[n_char_ranges++] = ((i - 1 - range_start_byte)
 +                                        + range_start_char);
 +      }
 +    }
 +  else                                /* STRING is multibyte */
 +    {
 +      char_ranges = (int *) alloca (sizeof (int) * SCHARS (string) * 2);
 +
 +      while (i_byte < size_byte)
 +      {
 +        unsigned char leading_code;
 +
 +        leading_code = str[i_byte];
 +        c = STRING_CHAR_AND_LENGTH (str + i_byte, size_byte-i_byte, len);
 +        i_byte += len;
 +
 +        if (handle_iso_classes && c == '['
 +            && i_byte < size_byte
 +            && STRING_CHAR (str + i_byte, size_byte - i_byte) == ':')
 +          {
 +            const unsigned char *class_beg = str + i_byte + 1;
 +            const unsigned char *class_end = class_beg;
 +            const unsigned char *class_limit = str + size_byte - 2;
 +            /* Leave room for the null.        */
 +            unsigned char class_name[CHAR_CLASS_MAX_LENGTH + 1];
 +            re_wctype_t cc;
 +
 +            if (class_limit - class_beg > CHAR_CLASS_MAX_LENGTH)
 +              class_limit = class_beg + CHAR_CLASS_MAX_LENGTH;
 +
 +            while (class_end < class_limit
 +                   && *class_end >= 'a' && *class_end <= 'z')
 +              class_end++;
 +
 +            if (class_end == class_beg
 +                || *class_end != ':' || class_end[1] != ']')
 +              goto not_a_class_name_multibyte;
 +
 +            bcopy (class_beg, class_name, class_end - class_beg);
 +            class_name[class_end - class_beg] = 0;
 +
 +            cc = re_wctype (class_name);
 +            if (cc == 0)
 +              error ("Invalid ISO C character class");
 +
 +            iso_classes = Fcons (make_number (cc), iso_classes);
 +
 +            i_byte = class_end + 2 - str;
 +            continue;
 +          }
 +
 +      not_a_class_name_multibyte:
 +        if (c == '\\')
 +          {
 +            if (i_byte == size_byte)
 +              break;
 +
 +            leading_code = str[i_byte];
              c = STRING_CHAR_AND_LENGTH (str + i_byte,
                                          size_byte - i_byte, len);
              i_byte += len;
              && str[i_byte] == '-')
            {
              unsigned int c2;
 +            unsigned char leading_code2;
  
              /* Skip over the dash.  */
              i_byte++;
  
              /* Get the end of the range.  */
 +            leading_code2 = str[i_byte];
              c2 = STRING_CHAR_AND_LENGTH (str + i_byte,
                                           size_byte - i_byte, len);
              i_byte += len;
  
 -            if (SINGLE_BYTE_CHAR_P (c))
 +            if (c2 == '\\'
 +                && i_byte < size_byte)
                {
 -                if (! SINGLE_BYTE_CHAR_P (c2))
 +                leading_code2 = str[i_byte];
 +                c2 =STRING_CHAR_AND_LENGTH (str + i_byte, size_byte-i_byte, len);
 +                i_byte += len;
 +              }
 +
 +            if (c > c2)
 +              continue;
 +            if (ASCII_CHAR_P (c))
 +              {
 +                while (c <= c2 && c < 0x80)
 +                  fastmap[c++] = 1;
 +                leading_code = CHAR_LEADING_CODE (c);
 +              }
 +            if (! ASCII_CHAR_P (c))
 +              {
 +                while (leading_code <= leading_code2)
 +                  fastmap[leading_code++] = 1;
 +                if (c <= c2)
                    {
 -                    /* Handle a range starting with a character of
 -                       less than 256, and ending with a character of
 -                       not less than 256.  Split that into two
 -                       ranges, the low one ending at 0377, and the
 -                       high one starting at the smallest character
 -                       in the charset of C2 and ending at C2.  */
 -                    int charset = CHAR_CHARSET (c2);
 -                    int c1 = MAKE_CHAR (charset, 0, 0);
 -
 -                    char_ranges[n_char_ranges++] = c1;
 +                    char_ranges[n_char_ranges++] = c;
                      char_ranges[n_char_ranges++] = c2;
 -                    c2 = 0377;
 -                  }
 -                while (c <= c2)
 -                  {
 -                    fastmap[c] = 1;
 -                    c++;
                    }
                }
 -            else if (c <= c2) /* Both C and C2 are multibyte char.  */
 -              {
 -                char_ranges[n_char_ranges++] = c;
 -                char_ranges[n_char_ranges++] = c2;
 -              }
            }
          else
            {
 -            if (SINGLE_BYTE_CHAR_P (c))
 +            if (ASCII_CHAR_P (c))
                fastmap[c] = 1;
              else
                {
 +                fastmap[leading_code] = 1;
                  char_ranges[n_char_ranges++] = c;
                  char_ranges[n_char_ranges++] = c;
                }
            }
        }
 +
 +      /* If the current range is unibyte and STRING contains non-ASCII
 +       chars, arrange fastmap for the corresponding unibyte
 +       chars.  */
 +
 +      if (! multibyte && n_char_ranges > 0)
 +      {
 +        bzero (fastmap + 0200, 0200);
 +        for (i = 0; i < n_char_ranges; i += 2)
 +          {
 +            int c1 = char_ranges[i];
 +            int c2 = char_ranges[i + 1];
 +
 +            for (; c1 <= c2; c1++)
 +              fastmap[CHAR_TO_BYTE8 (c1)] = 1;
 +          }
 +      }
      }
  
    /* If ^ was the first character, complement the fastmap.  */
    if (negate)
 -    for (i = 0; i < sizeof fastmap; i++)
 -      fastmap[i] ^= 1;
 +    {
 +      if (! multibyte)
 +      for (i = 0; i < sizeof fastmap; i++)
 +        fastmap[i] ^= 1;
 +      else
 +      {
 +        for (i = 0; i < 0200; i++)
 +          fastmap[i] ^= 1;
 +        /* All non-ASCII chars possibly match.  */
 +        for (; i < sizeof fastmap; i++)
 +          fastmap[i] = 1;
 +      }
 +    }
  
    {
      int start_point = PT;
        }
  
      immediate_quit = 1;
 -    if (syntaxp)
 +    if (forwardp)
        {
 -        SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1);
 -      if (forwardp)
 -        {
 -          if (multibyte)
 -            while (1)
 -              {
 -                int nbytes;
 +      if (multibyte)
 +        while (1)
 +          {
 +            int nbytes;
  
 -                if (p >= stop)
 -                  {
 -                    if (p >= endp)
 -                      break;
 -                    p = GAP_END_ADDR;
 -                    stop = endp;
 -                  }
 -                c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
 -                if (! fastmap[(int) SYNTAX (c)])
 +            if (p >= stop)
 +              {
 +                if (p >= endp)
                    break;
 -                p += nbytes, pos++, pos_byte += nbytes;
 -                UPDATE_SYNTAX_TABLE_FORWARD (pos);
 +                p = GAP_END_ADDR;
 +                stop = endp;
                }
 -          else
 -            while (1)
 +            c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
 +            if (! NILP (iso_classes) && in_classes (c, iso_classes))
                {
 -                if (p >= stop)
 -                  {
 -                    if (p >= endp)
 -                      break;
 -                    p = GAP_END_ADDR;
 -                    stop = endp;
 -                  }
 -                if (! fastmap[(int) SYNTAX (*p)])
 +                if (negate)
                    break;
 -                p++, pos++;
 -                UPDATE_SYNTAX_TABLE_FORWARD (pos);
 +                else
 +                  goto fwd_ok;
                }
 -        }
 -      else
 -        {
 -          if (multibyte)
 -            while (1)
 -              {
 -                unsigned char *prev_p;
 -                int nbytes;
  
 -                if (p <= stop)
 -                  {
 -                    if (p <= endp)
 -                      break;
 -                    p = GPT_ADDR;
 -                    stop = endp;
 -                  }
 -                prev_p = p;
 -                while (--p >= stop && ! CHAR_HEAD_P (*p));
 -                PARSE_MULTIBYTE_SEQ (p, MAX_MULTIBYTE_LENGTH, nbytes);
 -                if (prev_p - p > nbytes)
 -                  p = prev_p - 1, c = *p, nbytes = 1;
 -                else
 -                  c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
 -                pos--, pos_byte -= nbytes;
 -                UPDATE_SYNTAX_TABLE_BACKWARD (pos);
 -                if (! fastmap[(int) SYNTAX (c)])
 -                  {
 -                    pos++;
 -                    pos_byte += nbytes;
 +            if (! fastmap[*p])
 +              break;
 +            if (! ASCII_CHAR_P (c))
 +              {
 +                /* As we are looking at a multibyte character, we
 +                   must look up the character in the table
 +                   CHAR_RANGES.  If there's no data in the table,
 +                   that character is not what we want to skip.  */
 +
 +                /* The following code do the right thing even if
 +                   n_char_ranges is zero (i.e. no data in
 +                   CHAR_RANGES).  */
 +                for (i = 0; i < n_char_ranges; i += 2)
 +                  if (c >= char_ranges[i] && c <= char_ranges[i + 1])
                      break;
 -                  }
 +                if (!(negate ^ (i < n_char_ranges)))
 +                  break;
                }
 -          else
 -            while (1)
 +          fwd_ok:
 +            p += nbytes, pos++, pos_byte += nbytes;
 +          }
 +      else
 +        while (1)
 +          {
 +            if (p >= stop)
                {
 -                if (p <= stop)
 -                  {
 -                    if (p <= endp)
 -                      break;
 -                    p = GPT_ADDR;
 -                    stop = endp;
 -                  }
 -                if (! fastmap[(int) SYNTAX (p[-1])])
 +                if (p >= endp)
                    break;
 -                p--, pos--;
 -                UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
 +                p = GAP_END_ADDR;
 +                stop = endp;
                }
 -        }
 +
 +            if (!NILP (iso_classes) && in_classes (*p, iso_classes))
 +              {
 +                if (negate)
 +                  break;
 +                else
 +                  goto fwd_unibyte_ok;
 +              }
 +
 +            if (!fastmap[*p])
 +              break;
 +          fwd_unibyte_ok:
 +            p++, pos++, pos_byte++;
 +          }
        }
      else
        {
 -      if (forwardp)
 -        {
 -          if (multibyte)
 -            while (1)
 -              {
 -                int nbytes;
 -
 -                if (p >= stop)
 -                  {
 -                    if (p >= endp)
 -                      break;
 -                    p = GAP_END_ADDR;
 -                    stop = endp;
 -                  }
 -                c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
 +      if (multibyte)
 +        while (1)
 +          {
 +            unsigned char *prev_p;
  
 -                if (! NILP (iso_classes) && in_classes (c, iso_classes))
 -                  {
 -                    if (negate)
 -                      break;
 -                    else
 -                      goto fwd_ok;
 -                  }
 +            if (p <= stop)
 +              {
 +                if (p <= endp)
 +                  break;
 +                p = GPT_ADDR;
 +                stop = endp;
 +              }
 +            prev_p = p;
 +            while (--p >= stop && ! CHAR_HEAD_P (*p));
 +            c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
  
 -                if (SINGLE_BYTE_CHAR_P (c))
 -                  {
 -                    if (!fastmap[c])
 -                      break;
 -                  }
 +            if (! NILP (iso_classes) && in_classes (c, iso_classes))
 +              {
 +                if (negate)
 +                  break;
                  else
 -                  {
 -                    /* If we are looking at a multibyte character,
 -                       we must look up the character in the table
 -                       CHAR_RANGES.  If there's no data in the
 -                       table, that character is not what we want to
 -                       skip.  */
 -
 -                    /* The following code do the right thing even if
 -                       n_char_ranges is zero (i.e. no data in
 -                       CHAR_RANGES).  */
 -                    for (i = 0; i < n_char_ranges; i += 2)
 -                      if (c >= char_ranges[i] && c <= char_ranges[i + 1])
 -                        break;
 -                    if (!(negate ^ (i < n_char_ranges)))
 -                      break;
 -                  }
 -              fwd_ok:
 -                p += nbytes, pos++, pos_byte += nbytes;
 +                  goto back_ok;
                }
 -          else
 -            while (1)
 -              {
 -                if (p >= stop)
 -                  {
 -                    if (p >= endp)
 -                      break;
 -                    p = GAP_END_ADDR;
 -                    stop = endp;
 -                  }
 -
 -                if (!NILP (iso_classes) && in_classes (*p, iso_classes))
 -                  {
 -                    if (negate)
 -                      break;
 -                    else
 -                      goto fwd_unibyte_ok;
 -                  }
  
 -                if (!fastmap[*p])
 +            if (! fastmap[*p])
 +              break;
 +            if (! ASCII_CHAR_P (c))
 +              {
 +                /* See the comment in the previous similar code.  */
 +                for (i = 0; i < n_char_ranges; i += 2)
 +                  if (c >= char_ranges[i] && c <= char_ranges[i + 1])
 +                    break;
 +                if (!(negate ^ (i < n_char_ranges)))
                    break;
 -              fwd_unibyte_ok:
 -                p++, pos++;
                }
 -        }
 +          back_ok:
 +            pos--, pos_byte -= prev_p - p;
 +          }
        else
 -        {
 -          if (multibyte)
 -            while (1)
 +        while (1)
 +          {
 +            if (p <= stop)
                {
 -                unsigned char *prev_p;
 -                int nbytes;
 +                if (p <= endp)
 +                  break;
 +                p = GPT_ADDR;
 +                stop = endp;
 +              }
  
 -                if (p <= stop)
 -                  {
 -                    if (p <= endp)
 -                      break;
 -                    p = GPT_ADDR;
 -                    stop = endp;
 -                  }
 -                prev_p = p;
 -                while (--p >= stop && ! CHAR_HEAD_P (*p));
 -                PARSE_MULTIBYTE_SEQ (p, MAX_MULTIBYTE_LENGTH, nbytes);
 -                if (prev_p - p > nbytes)
 -                  p = prev_p - 1, c = *p, nbytes = 1;
 +            if (! NILP (iso_classes) && in_classes (p[-1], iso_classes))
 +              {
 +                if (negate)
 +                  break;
                  else
 -                  c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
 +                  goto back_unibyte_ok;
 +              }
  
 -                if (! NILP (iso_classes) && in_classes (c, iso_classes))
 -                  {
 -                    if (negate)
 -                      break;
 -                    else
 -                      goto back_ok;
 -                  }
 +            if (!fastmap[p[-1]])
 +              break;
 +          back_unibyte_ok:
 +            p--, pos--, pos_byte--;
 +          }
 +      }
  
 -                if (SINGLE_BYTE_CHAR_P (c))
 -                  {
 -                    if (!fastmap[c])
 -                      break;
 -                  }
 -                else
 -                  {
 -                    /* See the comment in the previous similar code.  */
 -                    for (i = 0; i < n_char_ranges; i += 2)
 -                      if (c >= char_ranges[i] && c <= char_ranges[i + 1])
 -                        break;
 -                    if (!(negate ^ (i < n_char_ranges)))
 -                      break;
 -                  }
 -              back_ok:
 -                pos--, pos_byte -= nbytes;
 -              }
 -          else
 -            while (1)
 -              {
 -                if (p <= stop)
 -                  {
 -                    if (p <= endp)
 -                      break;
 -                    p = GPT_ADDR;
 -                    stop = endp;
 -                  }
 +    SET_PT_BOTH (pos, pos_byte);
 +    immediate_quit = 0;
  
 -                if (! NILP (iso_classes) && in_classes (p[-1], iso_classes))
 -                  {
 -                    if (negate)
 -                      break;
 -                    else
 -                      goto back_unibyte_ok;
 -                  }
 +    return make_number (PT - start_point);
 +  }
 +}
  
 -                if (!fastmap[p[-1]])
 -                  break;
 -              back_unibyte_ok:
 -                p--, pos--;
 -              }
 -        }
 +
 +static Lisp_Object
 +skip_syntaxes (forwardp, string, lim)
 +     int forwardp;
 +     Lisp_Object string, lim;
 +{
 +  register unsigned int c;
 +  unsigned char fastmap[0400];
 +  int negate = 0;
 +  register int i, i_byte;
 +  int multibyte;
 +  int size_byte;
 +  unsigned char *str;
 +
 +  CHECK_STRING (string);
 +
 +  if (NILP (lim))
 +    XSETINT (lim, forwardp ? ZV : BEGV);
 +  else
 +    CHECK_NUMBER_COERCE_MARKER (lim);
 +
 +  /* In any case, don't allow scan outside bounds of buffer.  */
 +  if (XINT (lim) > ZV)
 +    XSETFASTINT (lim, ZV);
 +  if (XINT (lim) < BEGV)
 +    XSETFASTINT (lim, BEGV);
 +
 +  if (forwardp ? (PT >= XFASTINT (lim)) : (PT <= XFASTINT (lim)))
 +    return make_number (0);
 +
 +  multibyte = (!NILP (current_buffer->enable_multibyte_characters)
 +             && (XINT (lim) - PT != CHAR_TO_BYTE (XINT (lim)) - PT_BYTE));
 +
 +  bzero (fastmap, sizeof fastmap);
 +
 +  if (SBYTES (string) > SCHARS (string))
 +    /* As this is very rare case (syntax spec is ASCII only), don't
 +       consider efficiency.  */
 +    string = string_make_unibyte (string);
 +
 +  str = SDATA (string);
 +  size_byte = SBYTES (string);
 +
 +  i_byte = 0;
 +  if (i_byte < size_byte
 +      && SREF (string, 0) == '^')
 +    {
 +      negate = 1; i_byte++;
 +    }
 +
 +  /* Find the syntaxes specified and set their elements of fastmap.  */
 +
 +  while (i_byte < size_byte)
 +    {
 +      c = str[i_byte++];
 +      fastmap[syntax_spec_code[c]] = 1;
 +    }
 +
 +  /* If ^ was the first character, complement the fastmap.  */
 +  if (negate)
 +    for (i = 0; i < sizeof fastmap; i++)
 +      fastmap[i] ^= 1;
 +
 +  {
 +    int start_point = PT;
 +    int pos = PT;
 +    int pos_byte = PT_BYTE;
 +    unsigned char *p = PT_ADDR, *endp, *stop;
 +
 +    if (forwardp)
 +      {
 +      endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));
 +      stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp;
 +      }
 +    else
 +      {
 +      endp = CHAR_POS_ADDR (XINT (lim));
 +      stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp;
        }
  
 -#if 0 /* Not needed now that a position in mid-character
 -       cannot be specified in Lisp.  */
 -    if (multibyte
 -      /* INC_POS or DEC_POS might have moved POS over LIM.  */
 -      && (forwardp ? (pos > XINT (lim)) : (pos < XINT (lim))))
 -      pos = XINT (lim);
 -#endif
 +    immediate_quit = 1;
 +    SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1);
 +    if (forwardp)
 +      {
 +      if (multibyte)
 +        {
 +          while (1)
 +            {
 +              int nbytes;
 +
 +              if (p >= stop)
 +                {
 +                  if (p >= endp)
 +                    break;
 +                  p = GAP_END_ADDR;
 +                  stop = endp;
 +                }
 +              c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
 +              if (! fastmap[(int) SYNTAX (c)])
 +                break;
 +              p += nbytes, pos++, pos_byte += nbytes;
 +              UPDATE_SYNTAX_TABLE_FORWARD (pos);
 +            }
 +        }
 +      else
 +        {
 +          while (1)
 +            {
 +              if (p >= stop)
 +                {
 +                  if (p >= endp)
 +                    break;
 +                  p = GAP_END_ADDR;
 +                  stop = endp;
 +                }
 +              if (! fastmap[(int) SYNTAX (*p)])
 +                break;
 +              p++, pos++, pos_byte++;
 +              UPDATE_SYNTAX_TABLE_FORWARD (pos);
 +            }
 +        }
 +      }
 +    else
 +      {
 +      if (multibyte)
 +        {
 +          while (1)
 +            {
 +              unsigned char *prev_p;
  
 -    if (! multibyte)
 -      pos_byte = pos;
 +              if (p <= stop)
 +                {
 +                  if (p <= endp)
 +                    break;
 +                  p = GPT_ADDR;
 +                  stop = endp;
 +                }
 +              prev_p = p;
 +              while (--p >= stop && ! CHAR_HEAD_P (*p));
 +              c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
 +              if (! fastmap[(int) SYNTAX (c)])
 +                break;
 +              pos--, pos_byte -= prev_p - p;
 +              UPDATE_SYNTAX_TABLE_BACKWARD (pos);
 +            }
 +        }
 +      else
 +        {
 +          while (1)
 +            {
 +              if (p <= stop)
 +                {
 +                  if (p <= endp)
 +                    break;
 +                  p = GPT_ADDR;
 +                  stop = endp;
 +                }
 +              if (! fastmap[(int) SYNTAX (p[-1])])
 +                break;
 +              p--, pos--, pos_byte--;
 +              UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
 +            }
 +        }
 +      }
  
      SET_PT_BOTH (pos, pos_byte);
      immediate_quit = 0;
@@@ -2141,7 -1921,7 +2142,7 @@@ forw_comment (from, from_byte, stop, ne
          *bytepos_ptr = from_byte;
          return 0;
        }
 -      c = FETCH_CHAR (from_byte);
 +      c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
        syntax = SYNTAX_WITH_FLAGS (c);
        code = syntax & 0xff;
        if (code == Sendcomment
      forw_incomment:
        if (from < stop && SYNTAX_FLAGS_COMEND_FIRST (syntax)
          && SYNTAX_FLAGS_COMMENT_STYLE (syntax) == style
 -        && (c1 = FETCH_CHAR (from_byte),
 +        && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
              SYNTAX_COMEND_SECOND (c1))
          && ((SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||
               SYNTAX_COMMENT_NESTED (c1)) ? nesting > 0 : nesting < 0))
        if (nesting > 0
          && from < stop
          && SYNTAX_FLAGS_COMSTART_FIRST (syntax)
 -        && (c1 = FETCH_CHAR (from_byte),
 +        && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
              SYNTAX_COMMENT_STYLE (c1) == style
              && SYNTAX_COMSTART_SECOND (c1))
          && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||
@@@ -2254,7 -2034,7 +2255,7 @@@ between them, return t; otherwise retur
              immediate_quit = 0;
              return Qnil;
            }
 -        c = FETCH_CHAR (from_byte);
 +        c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
          code = SYNTAX (c);
          comstart_first = SYNTAX_COMSTART_FIRST (c);
          comnested = SYNTAX_COMMENT_NESTED (c);
          INC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_FORWARD (from);
          if (from < stop && comstart_first
 -            && (c1 = FETCH_CHAR (from_byte),
 +            && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
                  SYNTAX_COMSTART_SECOND (c1)))
            {
              /* We have encountered a comment start sequence and we
          DEC_BOTH (from, from_byte);
          /* char_quoted does UPDATE_SYNTAX_TABLE_BACKWARD (from).  */
          quoted = char_quoted (from, from_byte);
 -        c = FETCH_CHAR (from_byte);
 +        c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
          code = SYNTAX (c);
          comstyle = 0;
          comnested = SYNTAX_COMMENT_NESTED (c);
              code = Sendcomment;
              /* Calling char_quoted, above, set up global syntax position
                 at the new value of FROM.  */
 -            c1 = FETCH_CHAR (from_byte);
 +            c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
              comstyle = SYNTAX_COMMENT_STYLE (c1);
              comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
            }
                {
                  DEC_BOTH (from, from_byte);
                  UPDATE_SYNTAX_TABLE_BACKWARD (from);
 -                c = FETCH_CHAR (from_byte);
 +                c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
                  if (SYNTAX (c) == Scomment_fence
                      && !char_quoted (from, from_byte))
                    {
    return Qt;
  }
  \f
 -/* Return syntax code of character C if C is a single byte character
 +/* Return syntax code of character C if C is an ASCII character
     or `multibyte_symbol_p' is zero.  Otherwise, return Ssymbol.  */
  
 -#define SYNTAX_WITH_MULTIBYTE_CHECK(c)                        \
 -  ((SINGLE_BYTE_CHAR_P (c) || !multibyte_symbol_p)    \
 +#define SYNTAX_WITH_MULTIBYTE_CHECK(c)                \
 +  ((ASCII_CHAR_P (c) || !multibyte_symbol_p)  \
     ? SYNTAX (c) : Ssymbol)
  
  static Lisp_Object
@@@ -2465,7 -2245,7 +2466,7 @@@ scan_lists (from, count, depth, sexpfla
        {
          int comstart_first, prefix;
          UPDATE_SYNTAX_TABLE_FORWARD (from);
 -        c = FETCH_CHAR (from_byte);
 +        c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
          code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
          comstart_first = SYNTAX_COMSTART_FIRST (c);
          comnested = SYNTAX_COMMENT_NESTED (c);
          INC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_FORWARD (from);
          if (from < stop && comstart_first
 -            && (c = FETCH_CHAR (from_byte), SYNTAX_COMSTART_SECOND (c))
 +            && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte),
 +                SYNTAX_COMSTART_SECOND (c))
              && parse_sexp_ignore_comments)
            {
              /* we have encountered a comment start sequence and we
                 only a comment end of the same style actually ends
                 the comment section */
              code = Scomment;
 -            c1 = FETCH_CHAR (from_byte);
 +            c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
              comstyle = SYNTAX_COMMENT_STYLE (c1);
              comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
              INC_BOTH (from, from_byte);
                  UPDATE_SYNTAX_TABLE_FORWARD (from);
  
                  /* Some compilers can't handle this inside the switch.  */
 -                c = FETCH_CHAR (from_byte);
 +                c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
                  temp = SYNTAX_WITH_MULTIBYTE_CHECK (c);
                  switch (temp)
                    {
            case Smath:
              if (!sexpflag)
                break;
 -            if (from != stop && c == FETCH_CHAR (from_byte))
 +            if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (from_byte))
                {
                  INC_BOTH (from, from_byte);
                }
            case Sstring:
            case Sstring_fence:
              temp_pos = dec_bytepos (from_byte);
 -            stringterm = FETCH_CHAR (temp_pos);
 +            stringterm = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
              while (1)
                {
                  if (from >= stop) goto lose;
                  UPDATE_SYNTAX_TABLE_FORWARD (from);
 -                c = FETCH_CHAR (from_byte);
 +                c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
                  if (code == Sstring
                      ? (c == stringterm
                         && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
        {
          DEC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_BACKWARD (from);
 -        c = FETCH_CHAR (from_byte);
 +        c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
          code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
          if (depth == min_depth)
            last_good = from;
              DEC_BOTH (from, from_byte);
              UPDATE_SYNTAX_TABLE_BACKWARD (from);
              code = Sendcomment;
 -            c1 = FETCH_CHAR (from_byte);
 +            c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
              comstyle = SYNTAX_COMMENT_STYLE (c1);
              comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
            }
                  else
                    temp_pos--;
                  UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
 -                c1 = FETCH_CHAR (temp_pos);
 +                c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
                  temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
                  /* Don't allow comment-end to be quoted.  */
                  if (temp_code == Sendcomment)
                      temp_pos = dec_bytepos (temp_pos);
                      UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
                    }
 -                c1 = FETCH_CHAR (temp_pos);
 +                c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
                  temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
                  if (! (quoted || temp_code == Sword
                         || temp_code == Ssymbol
                break;
              temp_pos = dec_bytepos (from_byte);
              UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
 -            if (from != stop && c == FETCH_CHAR (temp_pos))
 +            if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (temp_pos))
                DEC_BOTH (from, from_byte);
              if (mathexit)
                {
                  DEC_BOTH (from, from_byte);
                  UPDATE_SYNTAX_TABLE_BACKWARD (from);
                  if (!char_quoted (from, from_byte)
 -                    && (c = FETCH_CHAR (from_byte),
 +                    && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte),
                          SYNTAX_WITH_MULTIBYTE_CHECK (c) == code))
                    break;
                }
              break;
  
            case Sstring:
 -            stringterm = FETCH_CHAR (from_byte);
 +            stringterm = FETCH_CHAR_AS_MULTIBYTE (from_byte);
              while (1)
                {
                  if (from == stop) goto lose;
                  DEC_BOTH (from, from_byte);
                  UPDATE_SYNTAX_TABLE_BACKWARD (from);
                  if (!char_quoted (from, from_byte)
 -                    && stringterm == (c = FETCH_CHAR (from_byte))
 +                    && (stringterm
 +                        == (c = FETCH_CHAR_AS_MULTIBYTE (from_byte)))
                      && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
                    break;
                }
@@@ -2872,7 -2650,7 +2873,7 @@@ This includes chars with "quote" or "pr
  
    while (!char_quoted (pos, pos_byte)
         /* Previous statement updates syntax table.  */
 -       && ((c = FETCH_CHAR (pos_byte), SYNTAX (c) == Squote)
 +       && ((c = FETCH_CHAR_AS_MULTIBYTE (pos_byte), SYNTAX (c) == Squote)
             || SYNTAX_PREFIX (c)))
      {
        opoint = pos;
@@@ -2900,8 -2678,7 +2901,8 @@@ scan_sexps_forward (stateptr, from, fro
                    stopbefore, oldstate, commentstop)
       struct lisp_parse_state *stateptr;
       register int from;
 -     int end, targetdepth, stopbefore, from_byte;
 +     int from_byte;
 +     int end, targetdepth, stopbefore;
       Lisp_Object oldstate;
       int commentstop;
  {
  #define INC_FROM                              \
  do { prev_from = from;                                \
       prev_from_byte = from_byte;              \
 -     temp = FETCH_CHAR (prev_from_byte);      \
 +     temp = FETCH_CHAR_AS_MULTIBYTE (prev_from_byte); \
       prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \
       INC_BOTH (from, from_byte);              \
       if (from < end)                          \
          while (from < end)
            {
              /* Some compilers can't handle this inside the switch.  */
 -            temp = FETCH_CHAR (from_byte);
 +            temp = FETCH_CHAR_AS_MULTIBYTE (from_byte);
              temp = SYNTAX (temp);
              switch (temp)
                {
          if (stopbefore) goto stop;  /* this arg means stop at sexp start */
          curlevel->last = prev_from;
          state.instring = (code == Sstring
 -                          ? (FETCH_CHAR (prev_from_byte))
 +                          ? (FETCH_CHAR_AS_MULTIBYTE (prev_from_byte))
                            : ST_STRING_STYLE);
          if (boundary_stop) goto done;
        startinstring:
                int c;
  
                if (from >= end) goto done;
 -              c = FETCH_CHAR (from_byte);
 +              c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
                /* Some compilers can't handle this inside the switch.  */
                temp = SYNTAX (c);
  
@@@ -3406,7 -3183,8 +3407,7 @@@ init_syntax_once (
  
    /* All multibyte characters have syntax `word' by default.  */
    temp = XVECTOR (Vsyntax_code_object)->contents[(int) Sword];
 -  for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
 -    XCHAR_TABLE (Vstandard_syntax_table)->contents[i] = temp;
 +  char_table_set_range (Vstandard_syntax_table, 0x80, MAX_CHAR, temp);
  }
  
  void
@@@ -3454,25 -3232,6 +3455,25 @@@ See the info node `(elisp)Syntax Proper
               doc: /* *Non-nil means an open paren in column 0 denotes the start of a defun.  */);
    open_paren_in_column_0_is_defun_start = 1;
  
 +
 +  DEFVAR_LISP ("find-word-boundary-function-table",
 +             &Vfind_word_boundary_function_table,
 +             doc: /*
 +Char table of functions to search for the word boundary.
 +Each function is called with two arguments; POS and LIMIT.
 +POS and LIMIT are character positions in the current buffer.
 +
 +If POS is less than LIMIT, POS is at the first character of a word,
 +and the return value of a function is a position after the last
 +character of that word.
 +
 +If POS is not less than LIMIT, POS is at the last character of a word,
 +and the return value of a function is a position at the first
 +character of that word.
 +
 +In both cases, LIMIT bounds the search. */);
 +  Vfind_word_boundary_function_table = Fmake_char_table (Qnil, Qnil);
 +
    defsubr (&Ssyntax_table_p);
    defsubr (&Ssyntax_table);
    defsubr (&Sstandard_syntax_table);
diff --combined src/syntax.h
index c7e67ebf355bc401f061520a4639b340637da5d5,f64aa0e132725f16b83eb02f5bdce3198f2a7ea6..2ff63678bd29eb54dd90e0aad5205ed5bd341b06
@@@ -1,6 -1,6 +1,6 @@@
  /* Declarations having to do with GNU Emacs syntax tables.
-    Copyright (C) 1985, 1993, 1994, 1997, 1998, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1985, 1993, 1994, 1997, 1998, 2001, 2002, 2003, 2004,
+                  2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -58,14 -58,37 +58,14 @@@ enum syntaxcod
  
  /* Set the syntax entry VAL for char C in table TABLE.  */
  
 -#define SET_RAW_SYNTAX_ENTRY(table, c, val)                           \
 -  ((((c) & 0xFF) == (c))                                              \
 -   ? (XCHAR_TABLE (table)->contents[(unsigned char) (c)] = (val))     \
 -   : Faset ((table), make_number (c), (val)))
 +#define SET_RAW_SYNTAX_ENTRY(table, c, val)   \
 +  CHAR_TABLE_SET ((table), c, (val))
  
 -/* Fetch the syntax entry for char C in syntax table TABLE.
 -   This macro is called only when C is less than CHAR_TABLE_ORDINARY_SLOTS.
 -   Do inheritance.  */
 +/* Set the syntax entry VAL for char-range RANGE in table TABLE.
 +   RANGE is a cons (FROM . TO) specifying the range of characters.  */
  
 -#ifdef __GNUC__
 -#define SYNTAX_ENTRY_FOLLOW_PARENT(table, c)                  \
 -  ({ Lisp_Object _syntax_tbl = (table);                               \
 -     Lisp_Object _syntax_temp = XCHAR_TABLE (_syntax_tbl)->contents[(c)]; \
 -     while (NILP (_syntax_temp))                              \
 -       {                                                      \
 -       _syntax_tbl = XCHAR_TABLE (_syntax_tbl)->parent;       \
 -       if (NILP (_syntax_tbl))                                \
 -         break;                                               \
 -       _syntax_temp = XCHAR_TABLE (_syntax_tbl)->contents[(c)]; \
 -       }                                                      \
 -     _syntax_temp; })
 -#else
 -extern Lisp_Object syntax_temp;
 -extern Lisp_Object syntax_parent_lookup P_ ((Lisp_Object, int));
 -
 -#define SYNTAX_ENTRY_FOLLOW_PARENT(table, c)          \
 -  (syntax_temp = XCHAR_TABLE (table)->contents[(c)],  \
 -   (NILP (syntax_temp)                                        \
 -    ? syntax_parent_lookup (table, (c))                       \
 -    : syntax_temp))
 -#endif
 +#define SET_RAW_SYNTAX_ENTRY_RANGE(table, range, val) \
 +  Fset_char_table_range ((table), (range), (val))
  
  /* SYNTAX_ENTRY fetches the information from the entry for character C
     in syntax table TABLE, or from globally kept data (gl_state).
  #  define CURRENT_SYNTAX_TABLE current_buffer->syntax_table
  #endif
  
 -#define SYNTAX_ENTRY_INT(c)                           \
 -  ((((c) & 0xFF) == (c))                              \
 -   ? SYNTAX_ENTRY_FOLLOW_PARENT (CURRENT_SYNTAX_TABLE,        \
 -                               (unsigned char) (c))   \
 -   : Faref (CURRENT_SYNTAX_TABLE,                     \
 -          make_number (c)))
 +#define SYNTAX_ENTRY_INT(c) CHAR_TABLE_REF (CURRENT_SYNTAX_TABLE, (c))
  
  /* Extract the information from the entry for character C
     in the current syntax table.  */
        ? XCDR (_syntax_temp)                                           \
        : Qnil); })
  #else
 +extern Lisp_Object syntax_temp;
  #define SYNTAX(c)                                                     \
    (syntax_temp = SYNTAX_ENTRY ((c)),                                  \
     (CONSP (syntax_temp)                                                       \
diff --combined src/term.c
index 7f25eb36328354ba8c148a6b605be65a734075e3,e407aec2fe1e12fcddbdf294f14f5f38a38b18fe..1ec904e79f36fbfa1a3734f61638a02983cee6a4
@@@ -1,6 -1,6 +1,6 @@@
  /* Terminal control module for terminals described by TERMCAP
     Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -29,11 -29,8 +29,11 @@@ Boston, MA 02110-1301, USA.  *
  #include "termchar.h"
  #include "termopts.h"
  #include "lisp.h"
 +#include "buffer.h"
 +#include "character.h"
  #include "charset.h"
  #include "coding.h"
 +#include "composite.h"
  #include "keyboard.h"
  #include "frame.h"
  #include "disptab.h"
@@@ -814,12 -811,10 +814,12 @@@ clear_end_of_line (first_unused_hpos
      }
  }
  \f
 -/* Buffer to store the source and result of code conversion for terminal.  */
 -static unsigned char *encode_terminal_buf;
 -/* Allocated size of the above buffer.  */
 -static int encode_terminal_bufsize;
 +/* Buffers to store the source and result of code conversion for terminal.  */
 +static unsigned char *encode_terminal_src;
 +static unsigned char *encode_terminal_dst;
 +/* Allocated sizes of the above buffers.  */
 +static int encode_terminal_src_size;
 +static int encode_terminal_dst_size;
  
  /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
     Set CODING->produced to the byte-length of the resulting byte
@@@ -837,73 -832,37 +837,73 @@@ encode_terminal_code (src, src_len, cod
    int nchars, nbytes, required;
    register int tlen = GLYPH_TABLE_LENGTH;
    register Lisp_Object *tbase = GLYPH_TABLE_BASE;
 +  Lisp_Object charset_list;
  
    /* Allocate sufficient size of buffer to store all characters in
       multibyte-form.  But, it may be enlarged on demand if
 -     Vglyph_table contains a string.  */
 +     Vglyph_table contains a string or a composite glyph is
 +     encountered.  */
    required = MAX_MULTIBYTE_LENGTH * src_len;
 -  if (encode_terminal_bufsize < required)
 +  if (encode_terminal_src_size < required)
      {
 -      if (encode_terminal_bufsize == 0)
 -      encode_terminal_buf = xmalloc (required);
 +      if (encode_terminal_src_size == 0)
 +      encode_terminal_src = xmalloc (required);
        else
 -      encode_terminal_buf = xrealloc (encode_terminal_buf, required);
 -      encode_terminal_bufsize = required;
 +      encode_terminal_src = xrealloc (encode_terminal_src, required);
 +      encode_terminal_src_size = required;
      }
  
 -  buf = encode_terminal_buf;
 +  charset_list = coding_charset_list (coding);
 +
 +  buf = encode_terminal_src;
    nchars = 0;
    while (src < src_end)
      {
 +      if (src->type == COMPOSITE_GLYPH)
 +      {
 +        struct composition *cmp = composition_table[src->u.cmp_id];
 +        int i;
 +
 +        nbytes = buf - encode_terminal_src;
 +        required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
 +
 +        if (encode_terminal_src_size < nbytes + required)
 +          {
 +            encode_terminal_src_size = nbytes + required;
 +            encode_terminal_src = xrealloc (encode_terminal_src,
 +                                            encode_terminal_src_size);
 +            buf = encode_terminal_src + nbytes;
 +          }
 +
 +        for (i = 0; i < cmp->glyph_len; i++)
 +          {
 +            int c = COMPOSITION_GLYPH (cmp, i);
 +            
 +            if (! char_charset (c, charset_list, NULL))
 +              break;
 +            buf += CHAR_STRING (c, buf);
 +            nchars++;
 +          }
 +        if (i == 0)
 +          {
 +            /* The first character of the composition is not encodable.  */
 +            *buf++ = '?';
 +            nchars++;
 +          }
 +      }
        /* We must skip glyphs to be padded for a wide character.  */
 -      if (! CHAR_GLYPH_PADDING_P (*src))
 +      else if (! CHAR_GLYPH_PADDING_P (*src))
        {
 +        int c;
 +        Lisp_Object string;
 +
 +        string = Qnil;
          g = GLYPH_FROM_CHAR_GLYPH (src[0]);
  
          if (g < 0 || g >= tlen)
            {
              /* This glyph doesn't has an entry in Vglyph_table.  */
 -            if (CHAR_VALID_P (src->u.ch, 0))
 -              buf += CHAR_STRING (src->u.ch, buf);
 -            else
 -              *buf++ = SPACEGLYPH;
 -            nchars++;
 +            c = src->u.ch;
            }
          else
            {
              GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
  
              if (GLYPH_SIMPLE_P (tbase, tlen, g))
 -              {
 -                int c = FAST_GLYPH_CHAR (g);
 +              /* We set the multi-byte form of a character in G
 +                 (that should be an ASCII character) at WORKBUF.  */
 +              c = FAST_GLYPH_CHAR (g);
 +            else
 +              /* We have a string in Vglyph_table.  */
 +              string = tbase[g];
 +          }
  
 -                if (CHAR_VALID_P (c, 0))
 -                  buf += CHAR_STRING (c, buf);
 -                else
 -                  *buf++ = SPACEGLYPH;
 +        if (NILP (string))
 +          {
 +            nbytes = buf - encode_terminal_src;
 +            if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH)
 +              {
 +                encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH;
 +                encode_terminal_src = xrealloc (encode_terminal_src,
 +                                                encode_terminal_src_size);
 +                buf = encode_terminal_src + nbytes;
 +              }
 +            if (char_charset (c, charset_list, NULL))
 +              {
 +                /* Store the multibyte form of C at BUF.  */
 +                buf += CHAR_STRING (c, buf);
                  nchars++;
                }
              else
                {
 -                /* We have a string in Vglyph_table.  */
 -                Lisp_Object string;
 -
 -                string = tbase[g];
 -                if (! STRING_MULTIBYTE (string))
 -                  string = string_to_multibyte (string);
 -                nbytes = buf - encode_terminal_buf;
 -                if (encode_terminal_bufsize < nbytes + SBYTES (string))
 +                /* C is not encodable.  */
 +                *buf++ = '?';
 +                nchars++;
 +                while (src + 1 < src_end && CHAR_GLYPH_PADDING_P (src[1]))
                    {
 -                    encode_terminal_bufsize = nbytes + SBYTES (string);
 -                    encode_terminal_buf = xrealloc (encode_terminal_buf,
 -                                                    encode_terminal_bufsize);
 -                    buf = encode_terminal_buf + nbytes;
 +                    *buf++ = '?';
 +                    nchars++;
 +                    src++;
                    }
 -                bcopy (SDATA (string), buf, SBYTES (string));
 -                buf += SBYTES (string);
 -                nchars += SCHARS (string);
                }
            }
 +        else
 +          {
 +            unsigned char *p = SDATA (string), *pend = p + SBYTES (string);
 +
 +            if (! STRING_MULTIBYTE (string))
 +              string = string_to_multibyte (string);
 +            nbytes = buf - encode_terminal_src;
 +            if (encode_terminal_src_size < nbytes + SBYTES (string))
 +              {
 +                encode_terminal_src_size = nbytes + SBYTES (string);
 +                encode_terminal_src = xrealloc (encode_terminal_src,
 +                                                encode_terminal_src_size);
 +                buf = encode_terminal_src + nbytes;
 +              }
 +            bcopy (SDATA (string), buf, SBYTES (string));
 +            buf += SBYTES (string);
 +            nchars += SCHARS (string);
 +          }
        }
        src++;
      }
  
 -  nbytes = buf - encode_terminal_buf;
 -  coding->src_multibyte = 1;
 -  coding->dst_multibyte = 0;
 -  if (SYMBOLP (coding->pre_write_conversion)
 -      && ! NILP (Ffboundp (coding->pre_write_conversion)))
 +  if (nchars == 0)
      {
 -      run_pre_write_conversin_on_c_str (&encode_terminal_buf,
 -                                      &encode_terminal_bufsize,
 -                                      nchars, nbytes, coding);
 -      nchars = coding->produced_char;
 -      nbytes = coding->produced;
 +      coding->produced = 0;
 +      return NULL;
      }
 -  required = nbytes + encoding_buffer_size (coding, nbytes);
 -  if (encode_terminal_bufsize < required)
 +
 +  nbytes = buf - encode_terminal_src;
 +  coding->source = encode_terminal_src;
 +  if (encode_terminal_dst_size == 0)
      {
 -      encode_terminal_bufsize = required;
 -      encode_terminal_buf = xrealloc (encode_terminal_buf, required);
 +      encode_terminal_dst_size = encode_terminal_src_size;
 +      encode_terminal_dst = xmalloc (encode_terminal_dst_size);
      }
 +  coding->destination = encode_terminal_dst;
 +  coding->dst_bytes = encode_terminal_dst_size;
 +  encode_coding_object (coding, Qnil, 0, 0, nchars, nbytes, Qnil);
 +  /* coding->destination may have been reallocated.  */
 +  encode_terminal_dst = coding->destination;
 +  encode_terminal_dst_size = coding->dst_bytes;
  
 -  encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes,
 -               nbytes, encode_terminal_bufsize - nbytes);
 -  return encode_terminal_buf + nbytes;
 +  return (encode_terminal_dst);
  }
  
 +
  void
  write_glyphs (string, len)
       register struct glyph *string;
       register int len;
  {
 +  int produced, consumed;
    struct frame *sf = XFRAME (selected_frame);
    struct frame *f = updating_frame ? updating_frame : sf;
    unsigned char *conversion_buffer;
@@@ -1705,14 -1638,11 +1705,14 @@@ term_get_fkeys_1 (
  #ifdef static
  #define append_glyph append_glyph_term
  #define produce_stretch_glyph produce_stretch_glyph_term
 +#define append_composite_glyph append_composite_glyph_term
 +#define produce_composite_glyph produce_composite_glyph_term
  #endif
  
  static void append_glyph P_ ((struct it *));
  static void produce_stretch_glyph P_ ((struct it *));
 -
 +static void append_composite_glyph P_ ((struct it *));
 +static void produce_composite_glyph P_ ((struct it *));
  
  /* Append glyphs to IT's glyph_row.  Called from produce_glyphs for
     terminal frames if IT->glyph_row != NULL.  IT->char_to_display is
@@@ -1773,8 -1703,6 +1773,8 @@@ produce_glyphs (it
       struct it *it;
  {
    /* If a hook is installed, let it do the work.  */
 +
 +  /* Nothing but characters are supported on terminal frames.  */
    xassert (it->what == IT_CHARACTER
           || it->what == IT_COMPOSITION
           || it->what == IT_STRETCH);
        goto done;
      }
  
 -  /* Nothing but characters are supported on terminal frames.  For a
 -     composition sequence, it->c is the first character of the
 -     sequence.  */
 -  xassert (it->what == IT_CHARACTER
 -         || it->what == IT_COMPOSITION);
 +  if (it->what == IT_COMPOSITION)
 +    {
 +      produce_composite_glyph (it);
 +      goto done;
 +    }
  
    /* Maybe translate single-byte characters to multibyte.  */
    it->char_to_display = it->c;
        it->pixel_width = nspaces;
        it->nglyphs = nspaces;
      }
 -  else if (SINGLE_BYTE_CHAR_P (it->c))
 +  else if (CHAR_BYTE8_P (it->c))
      {
        if (unibyte_display_via_language_environment
 -        && (it->c >= 0240
 -            || !NILP (Vnonascii_translation_table)))
 +        && (it->c >= 0240))
        {
 -        int charset;
 -
          it->char_to_display = unibyte_char_to_multibyte (it->c);
 -        charset = CHAR_CHARSET (it->char_to_display);
 -        it->pixel_width = CHARSET_WIDTH (charset);
 +        it->pixel_width = CHAR_WIDTH (it->char_to_display);
          it->nglyphs = it->pixel_width;
          if (it->glyph_row)
            append_glyph (it);
        }
        else
        {
 -        /* Coming here means that it->c is from display table, thus we
 -           must send the code as is to the terminal.  Although there's
 -           no way to know how many columns it occupies on a screen, it
 -           is a good assumption that a single byte code has 1-column
 -           width.  */
 +        /* Coming here means that it->c is from display table, thus
 +           we must send the raw 8-bit byte as is to the terminal.
 +           Although there's no way to know how many columns it
 +           occupies on a screen, it is a good assumption that a
 +           single byte code has 1-column width.  */
          it->pixel_width = it->nglyphs = 1;
          if (it->glyph_row)
            append_glyph (it);
      }
    else
      {
 -      /* A multi-byte character.  The display width is fixed for all
 -       characters of the set.  Some of the glyphs may have to be
 -       ignored because they are already displayed in a continued
 -       line.  */
 -      int charset = CHAR_CHARSET (it->c);
 -
 -      it->pixel_width = CHARSET_WIDTH (charset);
 +      it->pixel_width = CHAR_WIDTH (it->c);
        it->nglyphs = it->pixel_width;
  
        if (it->glyph_row)
@@@ -1948,57 -1886,6 +1948,57 @@@ produce_stretch_glyph (it
  }
  
  
 +/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
 +   Called from produce_composite_glyph for terminal frames if
 +   IT->glyph_row != NULL.  IT->face_id contains the character's
 +   face.  */
 +
 +static void
 +append_composite_glyph (it)
 +     struct it *it;
 +{
 +  struct glyph *glyph;
 +
 +  xassert (it->glyph_row);
 +  glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
 +  if (glyph < it->glyph_row->glyphs[1 + it->area])
 +    {
 +      glyph->type = COMPOSITE_GLYPH;
 +      glyph->pixel_width = it->pixel_width;
 +      glyph->u.cmp_id = it->cmp_id;
 +      glyph->face_id = it->face_id;
 +      glyph->padding_p = 0;
 +      glyph->charpos = CHARPOS (it->position);
 +      glyph->object = it->object;
 +
 +      ++it->glyph_row->used[it->area];
 +      ++glyph;
 +    }
 +}
 +
 +
 +/* Produce a composite glyph for iterator IT.  IT->cmp_id is the ID of
 +   the composition.  We simply produces components of the composition
 +   assuming that that the terminal has a capability to layout/render
 +   it correctly.  */
 +
 +static void
 +produce_composite_glyph (it)
 +     struct it *it;
 +{
 +  struct composition *cmp = composition_table[it->cmp_id];
 +  int c;
 +
 +  xassert (cmp->glyph_len > 0);
 +  c = COMPOSITION_GLYPH (cmp, 0);
 +  it->pixel_width = CHAR_WIDTH (it->c);
 +  it->nglyphs = 1;
 +
 +  if (it->glyph_row)
 +    append_composite_glyph (it);
 +}
 +
 +
  /* Get information about special display element WHAT in an
     environment described by IT.  WHAT is one of IT_TRUNCATION or
     IT_CONTINUATION.  Maybe produce glyphs for WHAT if IT has a
@@@ -2431,8 -2318,7 +2431,8 @@@ term_init (terminal_type
    int status;
    struct frame *sf = XFRAME (selected_frame);
  
 -  encode_terminal_bufsize = 0;
 +  encode_terminal_src_size = 0;
 +  encode_terminal_dst_size = 0;
  
  #ifdef WINDOWSNT
    initialize_w32_display ();
diff --combined src/w16select.c
index e77d4fca8061f077f2d4ba353b0f9204ced3edac,82619c15833aaa0a70aa720a4fa85045e5eb6f51..f73a12e528095f4ce63e3a77c21f524dfbaf6eb9
@@@ -1,6 -1,6 +1,6 @@@
  /* 16-bit Windows Selection processing for emacs on MS-Windows
     Copyright (C) 1996, 1997, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -39,7 -39,7 +39,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "frame.h"    /* Need this to get the X window of selected_frame */
  #include "blockinput.h"
  #include "buffer.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "composite.h"
  
diff --combined src/w32bdf.c
index fbdb7f4c373bc2e59b03914af4816158fafb7054,64ec2f7a3b0812b965fa324b75a62eb16d72d8f7..358415c6e42a72bd3c6c2362f10f1c720d96202b
@@@ -1,6 -1,6 +1,6 @@@
  /* Implementation of BDF font handling on the Microsoft W32 API.
-    Copyright (C) 1999, 2002, 2003, 2004, 2005,
-                  2006 Free Software Foundation, Inc.
+    Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005,
+                  2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -29,7 -29,7 +29,7 @@@ Boston, MA 02110-1301, USA.  *
  #endif
  
  #include "lisp.h"
 -#include "charset.h"
 +#include "character.h"
  #include "keyboard.h"
  #include "frame.h"
  #include "dispextern.h"
@@@ -202,7 -202,7 +202,7 @@@ set_bdf_font_info(bdffont *fontp
      else if (search_file_line("CHARSET_ENCODING", start, len,
                              (char **)&p, (char **)&q) == 1)
        {
 -        fontp->encoding = get_quoted_string(p, q);
 +      fontp->encoding = get_quoted_string(p, q);
        }
      else if (search_file_line("SLANT", start, len,
                              (char **)&p, (char **)&q) == 1)
@@@ -790,7 -790,7 +790,7 @@@ struct font_info *w32_load_bdf_font (st
         uses this font.  So, we set informatoin in fontp->encoding[1]
         which is never used by any charset.  If mapping can't be
         decided, set FONT_ENCODING_NOT_DECIDED.  */
 -    fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
 +    fontp->encoding_type = FONT_ENCODING_NOT_DECIDED;
      fontp->baseline_offset = bdf_font->yoffset;
      fontp->relative_compose = bdf_font->relative_compose;
      fontp->default_ascent = bdf_font->default_ascent;
diff --combined src/w32console.c
index b660d74f85203405299d845872e9fd190a4dbd79,d2f0e06a64ded8fa2b7a2a7fa5edcb277f1e8671..d9cef2baa0ca6af9f68ac7a19d674e24039c68aa
@@@ -1,6 -1,6 +1,6 @@@
  /* Terminal hooks for GNU Emacs on the Microsoft W32 API.
-    Copyright (C) 1992, 1999, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1992, 1999, 2001, 2002, 2003, 2004,
+                  2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -32,7 -32,7 +32,7 @@@ Boston, MA 02110-1301, USA
  #include <string.h>
  
  #include "lisp.h"
 -#include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "disptab.h"
  #include "termhooks.h"
diff --combined src/w32fns.c
index 29157dc356fd677677f2535fb9df03b7199f57f6,885ade0e4bbfcb2824788283357e10be7ac015d0..e7cafce29a600715a95341b8b6a5709cef7eaeae
@@@ -1,6 -1,6 +1,6 @@@
  /* Graphical user interface functions for the Microsoft W32 API.
     Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-                  2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -29,23 -29,22 +29,23 @@@ Boston, MA 02110-1301, USA.  *
  #include <errno.h>
  
  #include "lisp.h"
 -#include "charset.h"
 -#include "dispextern.h"
  #include "w32term.h"
 -#include "keyboard.h"
  #include "frame.h"
  #include "window.h"
  #include "buffer.h"
 -#include "fontset.h"
  #include "intervals.h"
 +#include "dispextern.h"
 +#include "keyboard.h"
  #include "blockinput.h"
  #include "epaths.h"
 -#include "w32heap.h"
 -#include "termhooks.h"
 +#include "character.h"
 +#include "charset.h"
  #include "coding.h"
  #include "ccl.h"
 +#include "fontset.h"
  #include "systime.h"
 +#include "termhooks.h"
 +#include "w32heap.h"
  
  #include "bitmaps/gray.xbm"
  
@@@ -4262,7 -4261,7 +4262,7 @@@ This function is an internal primitive-
        {
          tem = Fquery_fontset (font, Qnil);
          if (STRINGP (tem))
 -          font = x_new_fontset (f, SDATA (tem));
 +          font = x_new_fontset (f, tem);
          else
            font = x_new_font (f, SDATA (font));
        }
@@@ -4660,8 -4659,6 +4660,8 @@@ w32_load_system_font (f,fontname,size
        fontp->average_width = font->tm.tmAveCharWidth;
        }
  
 +
 +    fontp->charset = -1;
      charset = xlfd_charset_of_font (fontname);
  
    /* Cache the W32 codepage for a font.  This makes w32_encode_char
         (0:0x20..0x7F, 1:0xA0..0xFF,
         (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
         2:0xA020..0xFF7F).  For the moment, we don't know which charset
 -       uses this font.  So, we set information in fontp->encoding[1]
 +       uses this font.  So, we set information in fontp->encoding_type
         which is never used by any charset.  If mapping can't be
         decided, set FONT_ENCODING_NOT_DECIDED.  */
  
         type FONT_ENCODING_NOT_DECIDED.  */
      encoding = strrchr (fontp->name, '-');
      if (encoding && strnicmp (encoding+1, "sjis", 4) == 0)
 -      fontp->encoding[1] = 4;
 +      fontp->encoding_type = 4;
      else
 -      fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
 +      fontp->encoding_type = FONT_ENCODING_NOT_DECIDED;
  
      /* The following three values are set to 0 under W32, which is
         what they get set to if XGetFontProperty fails under X.  */
@@@ -4852,16 -4849,12 +4852,16 @@@ x_to_w32_charset (lpcs
    if (strncmp (lpcs, "*-#", 3) == 0)
      return atoi (lpcs + 3);
  
 +  /* All Windows fonts qualify as unicode.  */
 +  if (!strncmp (lpcs, "iso10646", 8))
 +    return DEFAULT_CHARSET;
 +
    /* Handle wildcards by ignoring them; eg. treat "big5*-*" as "big5".  */
    charset = alloca (len + 1);
    strcpy (charset, lpcs);
    lpcs = strchr (charset, '*');
    if (lpcs)
 -    *lpcs = 0;
 +    *lpcs = '\0';
  
    /* Look through w32-charset-info-alist for the character set.
       Format of each entry is
  
  
  static char *
 -w32_to_x_charset (fncharset)
 +w32_to_x_charset (fncharset, matching)
      int fncharset;
 +    char *matching;
  {
    static char buf[32];
    Lisp_Object charset_type;
 +  int match_len = 0;
 +
 +  if (matching)
 +    {
 +      /* If fully specified, accept it as it is.  Otherwise use a
 +       substring match. */
 +      char *wildcard = strchr (matching, '*');
 +      if (wildcard)
 +      *wildcard = '\0';
 +      else if (strchr (matching, '-'))
 +      return matching;
 +
 +      match_len = strlen (matching);
 +    }
  
    switch (fncharset)
      {
    {
      Lisp_Object rest;
      char * best_match = NULL;
 +    int matching_found = 0;
  
      /* Look through w32-charset-info-alist for the character set.
         Prefer ISO codepages, and prefer lower numbers in the ISO
              /* If we don't have a match already, then this is the
                 best.  */
              if (!best_match)
 -              best_match = x_charset;
 -            /* If this is an ISO codepage, and the best so far isn't,
 -               then this is better.  */
 -            else if (strnicmp (best_match, "iso", 3) != 0
 -                     && strnicmp (x_charset, "iso", 3) == 0)
 -              best_match = x_charset;
 +            {
 +              best_match = x_charset;
 +              if (matching && !strnicmp (x_charset, matching, match_len))
 +                matching_found = 1;
 +            }
 +          /* If we already found a match for MATCHING, then
 +             only consider other matches.  */
 +          else if (matching_found
 +                   && strnicmp (x_charset, matching, match_len))
 +            continue;
 +          /* If this matches what we want, and the best so far doesn't,
 +             then this is better.  */
 +          else if (!matching_found && matching
 +                   && !strnicmp (x_charset, matching, match_len))
 +            {
 +              best_match = x_charset;
 +              matching_found = 1;
 +            }
 +          /* If this is fully specified, and the best so far isn't,
 +             then this is better.  */
 +          else if ((!strchr (best_match, '-') && strchr (x_charset, '-'))
 +          /* If this is an ISO codepage, and the best so far isn't,
 +             then this is better, but only if it fully specifies the
 +             encoding.  */
 +              || (strnicmp (best_match, "iso", 3) != 0
 +                  && strnicmp (x_charset, "iso", 3) == 0
 +                  && strchr (x_charset, '-')))
 +              best_match = x_charset;
              /* If both are ISO8859 codepages, choose the one with the
                 lowest number in the encoding field.  */
              else if (strnicmp (best_match, "iso8859-", 8) == 0
          return buf;
        }
  
 -    strncpy(buf, best_match, 31);
 +    strncpy (buf, best_match, 31);
 +    /* If the charset is not fully specified, put -0 on the end.  */
 +    if (!strchr (best_match, '-'))
 +      {
 +      int pos = strlen (best_match);
 +      /* Charset specifiers shouldn't be very long.  If it is a made
 +         up one, truncating it should not do any harm since it isn't
 +         recognized anyway.  */
 +      if (pos > 29)
 +        pos = 29;
 +      strcpy (buf + pos, "-0");
 +      }
      buf[31] = '\0';
      return buf;
    }
@@@ -5228,8 -5172,7 +5228,8 @@@ w32_to_all_x_charsets (fncharset
    {
      Lisp_Object rest;
      /* Look through w32-charset-info-alist for the character set.
 -       Only return charsets for codepages which are installed.
 +       Only return fully specified charsets for codepages which are
 +       installed.
  
         Format of each entry in Vw32_charset_info_alist is
           (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
          w32_charset = XCAR (XCDR (this_entry));
          codepage = XCDR (XCDR (this_entry));
  
 +      if (!strchr (SDATA (x_charset), '-'))
 +        continue;
 +
          /* Look for Same charset and a valid codepage (or non-int
             which means ignore).  */
          if (EQ (w32_charset, charset_type)
@@@ -5285,6 -5225,9 +5285,6 @@@ w32_codepage_for_font (char *fontname
    Lisp_Object codepage, entry;
    char *charset_str, *charset, *end;
  
 -  if (NILP (Vw32_charset_info_alist))
 -    return CP_DEFAULT;
 -
    /* Extract charset part of font string.  */
    charset = xlfd_charset_of_font (fontname);
  
          *end = '\0';
        }
  
 +  if (!strcmp (charset, "iso10646"))
 +    return CP_UNICODE;
 +
 +  if (NILP (Vw32_charset_info_alist))
 +    return CP_DEFAULT;
 +
    entry = Fassoc (build_string(charset), Vw32_charset_info_alist);
    if (NILP (entry))
      return CP_UNKNOWN;
@@@ -5348,6 -5285,7 +5348,6 @@@ w32_to_x_font (lplogfont, lpxstr, len, 
    char *fontname_dash;
    int display_resy = (int) one_w32_display_info.resy;
    int display_resx = (int) one_w32_display_info.resx;
 -  int bufsz;
    struct coding_system coding;
  
    if (!lpxstr) abort ();
    coding.mode |= CODING_MODE_LAST_BLOCK;
    /* We explicitely disable composition handling because selection
       data should not contain any composition sequence.  */
 -  coding.composing = COMPOSITION_DISABLED;
 -  bufsz = decoding_buffer_size (&coding, LF_FACESIZE);
 +  coding.common_flags &= ~CODING_ANNOTATION_MASK;
 +
 +  coding.dst_bytes = LF_FACESIZE * 2;
 +  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes + 1);
 +  decode_coding_c_string (&coding, lplogfont->lfFaceName,
 +                        strlen(lplogfont->lfFaceName), Qnil);
 +  fontname = coding.destination;
  
 -  fontname = alloca(sizeof(*fontname) * bufsz);
 -  decode_coding (&coding, lplogfont->lfFaceName, fontname,
 -                 strlen(lplogfont->lfFaceName), bufsz - 1);
    *(fontname + coding.produced) = '\0';
  
    /* Replace dashes with underscores so the dashes are not
             ((lplogfont->lfPitchAndFamily & 0x3) == VARIABLE_PITCH)
               ? 'p' : 'c',                            /* spacing */
             width_pixels,                           /* avg width */
 -           specific_charset ? specific_charset
 -             : w32_to_x_charset (lplogfont->lfCharSet)
 +             w32_to_x_charset (lplogfont->lfCharSet, specific_charset)
               /* charset registry and encoding */
             );
  
@@@ -5498,24 -5435,26 +5498,24 @@@ x_to_w32_font (lpxstr, lplogfont
  
        if (fields > 0 && name[0] != '*')
          {
 -        int bufsize;
 -        unsigned char *buf;
 -
 +        Lisp_Object string = build_string (name);
            setup_coding_system
              (Fcheck_coding_system (Vlocale_coding_system), &coding);
 -        coding.src_multibyte = 1;
 -        coding.dst_multibyte = 0;
 -        /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
 -           encode_coding_iso2022 trying to dereference a null pointer.  */
 -        coding.composing = COMPOSITION_DISABLED;
 -        if (coding.type == coding_type_iso2022)
 -          coding.flags |= CODING_FLAG_ISO_SAFE;
 -        bufsize = encoding_buffer_size (&coding, strlen (name));
 -        buf = (unsigned char *) alloca (bufsize);
 -          coding.mode |= CODING_MODE_LAST_BLOCK;
 -          encode_coding (&coding, name, buf, strlen (name), bufsize);
 +          coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
 +        /* Disable composition/charset annotation.   */
 +        coding.common_flags &= ~CODING_ANNOTATION_MASK;
 +        coding.dst_bytes = SCHARS (string) * 2;
 +
 +        coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
 +          encode_coding_object (&coding, string, 0, 0,
 +                              SCHARS (string), SBYTES (string), Qnil);
          if (coding.produced >= LF_FACESIZE)
            coding.produced = LF_FACESIZE - 1;
 -        buf[coding.produced] = 0;
 -        strcpy (lplogfont->lfFaceName, buf);
 +
 +        coding.destination[coding.produced] = '\0';
 +
 +        strcpy (lplogfont->lfFaceName, coding.destination);
 +        xfree (coding.destination);
        }
        else
          {
@@@ -5893,17 -5832,14 +5893,17 @@@ enum_font_cb2 (lplf, lptm, FontType, lp
        if (charset
            && strncmp (charset, "*-*", 3) != 0
            && lpef->logfont.lfCharSet == DEFAULT_CHARSET
 -          && strcmp (charset, w32_to_x_charset (DEFAULT_CHARSET)) != 0)
 +          && strcmp (charset, w32_to_x_charset (DEFAULT_CHARSET, NULL)) != 0)
          return 1;
        }
  
      if (charset)
        charset_list = Fcons (build_string (charset), Qnil);
      else
 -      charset_list = w32_to_all_x_charsets (lplf->elfLogFont.lfCharSet);
 +      /* Always prefer unicode.  */
 +      charset_list
 +      = Fcons (build_string ("iso10646-1"),
 +               w32_to_all_x_charsets (lplf->elfLogFont.lfCharSet));
  
      /* Loop through the charsets.  */
      for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list))
        Lisp_Object this_charset = Fcar (charset_list);
        charset = SDATA (this_charset);
  
 +      enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
 +                                   charset, width);
 +
        /* List bold and italic variations if w32-enable-synthesized-fonts
           is non-nil and this is a plain font.  */
        if (w32_enable_synthesized_fonts
            && lplf->elfLogFont.lfWeight == FW_NORMAL
            && lplf->elfLogFont.lfItalic == FALSE)
          {
 -          enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
 -                                       charset, width);
            /* bold.  */
            lplf->elfLogFont.lfWeight = FW_BOLD;
            enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
            enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
                                         charset, width);
          }
 -      else
 -        enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
 -                                     charset, width);
        }
    }
  
@@@ -7340,7 -7278,7 +7340,7 @@@ x_create_tip_frame (dpyinfo, parms, tex
        {
        tem = Fquery_fontset (font, Qnil);
        if (STRINGP (tem))
 -        font = x_new_fontset (f, SDATA (tem));
 +        font = x_new_fontset (f, tem);
        else
          font = x_new_font (f, SDATA (font));
        }
@@@ -9064,7 -9002,6 +9064,7 @@@ versions of Windows) characters.  */)
    find_ccl_program_func = w32_find_ccl_program;
    query_font_func = w32_query_font;
    set_frame_fontset_func = x_set_font;
 +  get_font_repertory_func = x_get_font_repertory;
    check_window_system_func = check_w32;
  
  
diff --combined src/w32select.c
index 7b39494343493929b8e30fbb5c2be04c01821866,ad5d0e67f837c20782ace8e2c78bbfd503ebeef2..889e09a4a6c10aa31a274bc4661cec2e93eab4d2
@@@ -1,6 -1,6 +1,6 @@@
  /* Selection processing for Emacs on the Microsoft W32 API.
-    Copyright (C) 1993, 1994, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+    Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004,
+                  2005, 2006, 2007  Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -100,9 -100,6 +100,9 @@@ static void setup_config (void)
  static BOOL WINAPI enum_locale_callback (/*const*/ char* loc_string);
  static UINT cp_from_locale (LCID lcid, UINT format);
  static Lisp_Object coding_from_cp (UINT codepage);
 +static Lisp_Object validate_coding_system (Lisp_Object coding_system);
 +static void setup_windows_coding_system (Lisp_Object coding_system,
 +                                       struct coding_system * coding);
  
  
  /* A remnant from X11: Symbol for the CLIPBORD selection type.  Other
@@@ -216,36 -213,63 +216,36 @@@ convert_to_handle_as_ascii (void
  static HGLOBAL
  convert_to_handle_as_coded (Lisp_Object coding_system)
  {
 -  HGLOBAL htext = NULL, htext2;
 -  int nbytes;
 -  unsigned char *src;
 +  HGLOBAL htext;
    unsigned char *dst = NULL;
 -  int bufsize;
    struct coding_system coding;
 -  Lisp_Object string = Qnil;
  
    ONTRACE (fprintf (stderr, "convert_to_handle_as_coded: %s\n",       
                    SDATA (SYMBOL_NAME (coding_system))));
  
 -  setup_coding_system (Fcheck_coding_system (coding_system), &coding);
 -  coding.src_multibyte = 1;
 -  coding.dst_multibyte = 0;
 -  /* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
 -     encode_coding_iso2022 trying to dereference a null pointer.  */
 -  coding.composing = COMPOSITION_DISABLED;
 -  if (coding.type == coding_type_iso2022)
 -    coding.flags |= CODING_FLAG_ISO_SAFE;
 -  coding.mode |= CODING_MODE_LAST_BLOCK;
 -  /* Force DOS line-ends. */
 -  coding.eol_type = CODING_EOL_CRLF;
 -
 -  if (SYMBOLP (coding.pre_write_conversion)
 -      && !NILP (Ffboundp (coding.pre_write_conversion)))
 -    string = run_pre_post_conversion_on_str (current_text, &coding, 1);
 -  else
 -    string = current_text;
 -
 -  nbytes = SBYTES (string);
 -  src = SDATA (string);
 +  setup_windows_coding_system (coding_system, &coding);
 +  coding.dst_bytes = SBYTES(current_text) * 2;
 +  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
 +  encode_coding_object (&coding, current_text, 0, 0,
 +                      SCHARS (current_text), SBYTES (current_text), Qnil);
  
 -  bufsize = encoding_buffer_size (&coding, nbytes) +2;
 -  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bufsize);
 +  htext = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, coding.produced +2);
  
    if (htext != NULL)
      dst = (unsigned char *) GlobalLock (htext);
  
    if (dst != NULL)
      {
 -      encode_coding (&coding, src, dst, nbytes, bufsize-2);
 +      memcpy (dst, coding.destination, coding.produced);
        /* Add the string terminator.  Add two NULs in case we are
         producing Unicode here.  */
        dst[coding.produced] = dst[coding.produced+1] = '\0';
 -    }
 -
 -  if (dst != NULL)
 -    GlobalUnlock (htext);
  
 -  if (htext != NULL)
 -    {
 -      /* Shrink data block to actual size.  */
 -      htext2 = GlobalReAlloc (htext, coding.produced+2,
 -                            GMEM_MOVEABLE | GMEM_DDESHARE);
 -      if (htext2 != NULL) htext = htext2;
 +      GlobalUnlock (htext);
      }
  
 +  xfree (coding.destination);
 +
    return htext;
  }
  
@@@ -494,26 -518,17 +494,26 @@@ setup_config (void
    const char *cp;
    char *end;
    int slen;
 -  Lisp_Object new_coding_system;
 +  Lisp_Object coding_system;
 +  Lisp_Object dos_coding_system;
  
    CHECK_SYMBOL (Vselection_coding_system);
  
 -  /* Check if we have it cached */
 -  new_coding_system = NILP (Vnext_selection_coding_system) ?
 +  coding_system = NILP (Vnext_selection_coding_system) ?
      Vselection_coding_system : Vnext_selection_coding_system;
 +
 +  dos_coding_system = validate_coding_system (coding_system);
 +  if (NILP (dos_coding_system))
 +    Fsignal (Qerror,
 +           list2 (build_string ("Coding system is invalid or doesn't have "
 +                                "an eol variant for dos line ends"),
 +                  coding_system));
 +
 +  /* Check if we have it cached */
    if (!NILP (cfg_coding_system)
 -      && EQ (cfg_coding_system, new_coding_system))
 +      && EQ (cfg_coding_system, dos_coding_system))
      return;
 -  cfg_coding_system = new_coding_system;
 +  cfg_coding_system = dos_coding_system;
    
    /* Set some sensible fallbacks */
    cfg_codepage = ANSICP;
@@@ -622,61 -637,12 +622,61 @@@ coding_from_cp (UINT codepage
    char buffer[30];
    sprintf (buffer, "cp%d-dos", (int) codepage);
    return intern (buffer);
 -  /* We don't need to check that this coding system exists right here,
 -     because that is done when the coding system is actually
 -     instantiated, i.e. it is passed through Fcheck_coding_system()
 -     there.  */
 +  /* We don't need to check that this coding system actually exists
 +     right here, because that is done later for all coding systems
 +     used, regardless of where they originate.  */
  }
  
 +static Lisp_Object
 +validate_coding_system (Lisp_Object coding_system)
 +{
 +  Lisp_Object eol_type;
 +
 +  /* Make sure the input is valid. */
 +  if (NILP (Fcoding_system_p (coding_system)))
 +    return Qnil;
 +
 +  /* Make sure we use a DOS coding system as mandated by the system
 +     specs. */
 +  eol_type = Fcoding_system_eol_type (coding_system);
 +
 +  /* Already a DOS coding system? */
 +  if (EQ (eol_type, make_number (1)))
 +    return coding_system;
 +
 +  /* Get EOL_TYPE vector of the base of CODING_SYSTEM.  */
 +  if (!VECTORP (eol_type))
 +    {
 +      eol_type = Fcoding_system_eol_type (Fcoding_system_base (coding_system));
 +      if (!VECTORP (eol_type))
 +      return Qnil;
 +    }
 +
 +  return AREF (eol_type, 1);
 +}
 +
 +static void
 +setup_windows_coding_system (Lisp_Object coding_system,
 +                           struct coding_system * coding)
 +{
 +  memset (coding, 0, sizeof (*coding));
 +  setup_coding_system (coding_system, coding);
 +
 +  /* Unset CODING_ANNOTATE_COMPOSITION_MASK.  Previous code had
 +     comments about crashes in encode_coding_iso2022 trying to
 +     dereference a null pointer when composition was on.  Selection
 +     data should not contain any composition sequence on Windows.
 +
 +     CODING_ANNOTATION_MASK also includes
 +     CODING_ANNOTATE_DIRECTION_MASK and CODING_ANNOTATE_CHARSET_MASK,
 +     which both apply to ISO6429 only.  We don't know if these really
 +     need to be unset on Windows, but it probably doesn't hurt
 +     either.  */
 +  coding->mode &= ~CODING_ANNOTATION_MASK;
 +  coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
 +}
 +
 +
  
  DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data,
         Sw32_set_clipboard_data, 1, 2, 0,
@@@ -881,9 -847,10 +881,9 @@@ DEFUN ("w32-get-clipboard-data", Fw32_g
  
      if (require_decoding)
        {
 -      int bufsize;
 -      unsigned char *buf;
        struct coding_system coding;
        Lisp_Object coding_system = Qnil;
 +      Lisp_Object dos_coding_system;
        
        /* `next-selection-coding-system' should override everything,
           even when the locale passed by the system disagrees.  The
          coding_system = Vselection_coding_system;
        Vnext_selection_coding_system = Qnil;
  
 -      setup_coding_system (Fcheck_coding_system (coding_system), &coding);
 -      coding.src_multibyte = 0;
 -      coding.dst_multibyte = 1;
 -      coding.mode |= CODING_MODE_LAST_BLOCK;
 -      /* We explicitely disable composition handling because
 -         selection data should not contain any composition
 -         sequence.  */
 -      coding.composing = COMPOSITION_DISABLED;
 -      /* Force DOS line-ends. */
 -      coding.eol_type = CODING_EOL_CRLF;
 -
 -      bufsize = decoding_buffer_size (&coding, nbytes);
 -      buf = (unsigned char *) xmalloc (bufsize);
 -      decode_coding (&coding, src, buf, nbytes, bufsize);
 -      Vlast_coding_system_used = coding.symbol;
 -        ret = make_string_from_bytes ((char *) buf,
 -                                      coding.produced_char, coding.produced);
 -      xfree (buf);
 -      if (SYMBOLP (coding.post_read_conversion)
 -          && !NILP (Ffboundp (coding.post_read_conversion)))
 -        ret = run_pre_post_conversion_on_str (ret, &coding, 0);
 +      dos_coding_system = validate_coding_system (coding_system);
 +      if (!NILP (dos_coding_system))
 +        {
 +          setup_windows_coding_system (dos_coding_system, &coding);
 +          coding.source = src;
 +          decode_coding_object (&coding, Qnil, 0, 0, nbytes, nbytes, Qt);
 +          ret = coding.dst_object;
 +
 +          Vlast_coding_system_used = CODING_ID_NAME (coding.id);
 +        }
        }
      else
        {
@@@ -1039,11 -1017,10 +1039,11 @@@ and t is the same as `SECONDARY'.  */
      {
        Lisp_Object val = Qnil;
  
 +      setup_config ();
 +
        if (OpenClipboard (NULL))
        {
          UINT format = 0;
 -        setup_config ();
          while ((format = EnumClipboardFormats (format)))
            /* Check CF_TEXT in addition to cfg_clipboard_type,
               because we can fall back on that if CF_UNICODETEXT is
diff --combined src/w32term.c
index 992bbc76aada6f96aa0cbd213b0fffac5b8aeed2,58ea99ff46c3c654b3ff6c6c80a04e812bb5ff0f..e488e4eeebca9201249c6caa55f794319d09f1d3
@@@ -1,6 -1,6 +1,6 @@@
  /* Implementation of GUI terminal on the Microsoft W32 API.
     Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -24,21 -24,25 +24,21 @@@ Boston, MA 02110-1301, USA.  *
  #include <stdio.h>
  #include <stdlib.h>
  #include "lisp.h"
 -#include "charset.h"
  #include "blockinput.h"
 -
 -#include "w32heap.h"
  #include "w32term.h"
 -#include "w32bdf.h"
 -#include <shellapi.h>
  
  #include "systty.h"
  #include "systime.h"
 -#include "atimer.h"
 -#include "keymap.h"
  
  #include <ctype.h>
  #include <errno.h>
  #include <setjmp.h>
  #include <sys/stat.h>
  
 -#include "keyboard.h"
 +#include "charset.h"
 +#include "character.h"
 +#include "coding.h"
 +#include "ccl.h"
  #include "frame.h"
  #include "dispextern.h"
  #include "fontset.h"
  #include "disptab.h"
  #include "buffer.h"
  #include "window.h"
 +#include "keyboard.h"
  #include "intervals.h"
 -#include "composite.h"
 -#include "coding.h"
 +#include "process.h"
 +#include "atimer.h"
 +#include "keymap.h"
 +
 +#include "w32heap.h"
 +#include "w32bdf.h"
 +#include <shellapi.h>
  
  #define abs(x)        ((x) < 0 ? -(x) : (x))
  
@@@ -122,31 -120,6 +122,31 @@@ struct w32_display_info *x_display_list
     FONT-LIST-CACHE records previous values returned by x-list-fonts.  */
  Lisp_Object w32_display_name_list;
  
 +
 +#ifndef GLYPHSET
 +/* Pre Windows 2000, this was not available, but define it here so
 +   that Emacs compiled on such a platform will run on newer versions.  */
 +
 +typedef struct tagWCRANGE
 +{
 +  WCHAR wcLow;
 +  USHORT cGlyphs;
 +} WCRANGE;
 +
 +typedef struct tagGLYPHSET 
 +{
 +  DWORD cbThis;
 +  DWORD flAccel;
 +  DWORD cGlyphsSupported;
 +  DWORD cRanges;
 +  WCRANGE ranges[1];
 +} GLYPHSET;  
 +
 +#endif
 +
 +/* Dynamic linking to GetFontUnicodeRanges (not available on 95, 98, ME).  */
 +DWORD (PASCAL *pfnGetFontUnicodeRanges) (HDC device, GLYPHSET *ranges);
 +
  /* Frame being updated by update_frame.  This is declared in term.c.
     This is set by update_begin and looked at by all the
     w32 functions.  It is zero while not inside an update.
@@@ -848,8 -821,7 +848,8 @@@ w32_reset_terminal_modes (void
  /* Function prototypes of this page.  */
  
  XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
 -static int w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
 +static int w32_encode_char P_ ((int, wchar_t *, struct font_info *,
 +                              struct charset *, int *));
  
  
  /* Get metrics of character CHAR2B in FONT.  Value is always non-null.
@@@ -1113,13 -1085,13 +1113,13 @@@ w32_use_unicode_for_codepage (codepage
     the two-byte form of C.  Encoding is returned in *CHAR2B.  */
  
  static int /* enum w32_char_font_type */
 -w32_encode_char (c, char2b, font_info, two_byte_p)
 +w32_encode_char (c, char2b, font_info, charset, two_byte_p)
       int c;
       wchar_t *char2b;
       struct font_info *font_info;
 +     struct charset *charset;
       int * two_byte_p;
  {
 -  int charset = CHAR_CHARSET (c);
    int codepage;
    int unicode_p = 0;
    int internal_two_byte_p = 0;
    XFontStruct *font = font_info->font;
  
    internal_two_byte_p = w32_font_is_double_byte (font);
 +  codepage = font_info->codepage;
 +
 +  /* If font can output unicode, use the original unicode character.  */
 +  if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
 +       && c >= 0x100)
 +    {
 +      *char2b = c;
 +      unicode_p = 1;
 +      internal_two_byte_p = 1;
 +    }
  
    /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
       This may be either a program in a special encoder language or a
       fixed encoding.  */
 -  if (font_info->font_encoder)
 +  else if (font_info->font_encoder)
      {
        /* It's a program.  */
        struct ccl_program *ccl = font_info->font_encoder;
  
        if (CHARSET_DIMENSION (charset) == 1)
        {
 -        ccl->reg[0] = charset;
 +        ccl->reg[0] = CHARSET_ID (charset);
          ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
          ccl->reg[2] = -1;
        }
        else
        {
 -        ccl->reg[0] = charset;
 +        ccl->reg[0] = CHARSET_ID (charset);
          ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
          ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
        }
  
 -      ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
 +      ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
  
        /* We assume that MSBs are appropriately set/reset by CCL
         program.  */
        else
        STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
      }
 -  else if (font_info->encoding[charset])
 +  else if (font_info->encoding_type)
      {
        /* Fixed encoding scheme.  See fontset.h for the meaning of the
         encoding numbers.  */
 -      int enc = font_info->encoding[charset];
 +      unsigned char enc = font_info->encoding_type;
  
        if ((enc == 1 || enc == 2)
          && CHARSET_DIMENSION (charset) == 2)
        STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b) | 0x80, XCHAR2B_BYTE2 (char2b));
  
 -      if (enc == 1 || enc == 3
 -          || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
 +      if (enc == 1 || enc == 3          || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
        STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b) | 0x80);
        else if (enc == 4)
          {
 -          int sjis1, sjis2;
 +          int code = (int) (*char2b);
  
 -          ENCODE_SJIS (XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b),
 -                       sjis1, sjis2);
 -          STORE_XCHAR2B (char2b, sjis1, sjis2);
 +        JIS_TO_SJIS (code);
 +          STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
          }
      }
 -  codepage = font_info->codepage;
 -
 -  /* If charset is not ASCII or Latin-1, may need to move it into
 -     Unicode space.  */
 -  if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
 -       && charset != CHARSET_ASCII && charset != charset_latin_iso8859_1
 -       && charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC)
 -    {
 -      char temp[3];
 -      temp[0] = XCHAR2B_BYTE1 (char2b);
 -      temp[1] = XCHAR2B_BYTE2 (char2b);
 -      temp[2] = '\0';
 -      if (codepage != CP_UNICODE)
 -        {
 -          if (temp[0])
 -            MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
 -          else
 -            MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
 -        }
 -      unicode_p = 1;
 -      internal_two_byte_p = 1;
 -    }
  
    if (two_byte_p)
      *two_byte_p = internal_two_byte_p;
  }
  
  
 +/* Return a char-table whose elements are t if the font FONT_INFO
 +   contains a glyph for the corresponding character, and nil if not.
 +
 +   Fixme: For the moment, this function works only for fonts whose
 +   glyph encoding is the same as Unicode (e.g. ISO10646-1 fonts).  */
 +
 +Lisp_Object
 +x_get_font_repertory (f, font_info)
 +     FRAME_PTR f;
 +     struct font_info *font_info;
 +{
 +  XFontStruct *font = (XFontStruct *) font_info->font;
 +  Lisp_Object table;
 +  int min_byte1, max_byte1, min_byte2, max_byte2;
 +
 +  table = Fmake_char_table (Qnil, Qnil);
 +
 +  if (!font->bdf && pfnGetFontUnicodeRanges)
 +    {
 +      GLYPHSET *glyphset;
 +      DWORD glyphset_size;
 +      HDC display = get_frame_dc (f);
 +      HFONT prev_font;
 +      int i;
 +
 +      prev_font = SelectObject (display, font->hfont);
 +
 +      /* First call GetFontUnicodeRanges to find out how big a structure
 +       we need.  */
 +      glyphset_size = pfnGetFontUnicodeRanges (display, NULL);
 +      if (glyphset_size)
 +      {
 +        glyphset = (GLYPHSET *) alloca (glyphset_size);
 +        glyphset->cbThis = glyphset_size;
 +
 +        /* Now call it again to get the ranges.  */
 +        glyphset_size = pfnGetFontUnicodeRanges (display, glyphset);
 +
 +        if (glyphset_size)
 +          {
 +            /* Store the ranges in TABLE.  */
 +            for (i = 0; i < glyphset->cRanges; i++)
 +              {
 +                int from = glyphset->ranges[i].wcLow;
 +                int to = from + glyphset->ranges[i].cGlyphs - 1;
 +                char_table_set_range (table, from, to, Qt);
 +              }
 +          }
 +      }
 +
 +      SelectObject (display, prev_font);
 +      release_frame_dc (f, display);
 +
 +      /* If we got the information we wanted above, then return it.  */
 +      if (glyphset_size)
 +      return table;
 +    }
 +
 +#if 0 /* TODO: Convert to work on Windows so BDF and older platforms work.  */
 +  /* When GetFontUnicodeRanges is not available or does not work,
 +     work it out manually.  */
 +  min_byte1 = font->min_byte1;
 +  max_byte1 = font->max_byte1;
 +  min_byte2 = font->min_char_or_byte2;
 +  max_byte2 = font->max_char_or_byte2;
 +  if (min_byte1 == 0 && max_byte1 == 0)
 +    {
 +      if (! font->per_char || font->all_chars_exist == True)
 +      char_table_set_range (table, min_byte2, max_byte2, Qt);
 +      else
 +      {
 +        XCharStruct *pcm = font->per_char;
 +        int from = -1;
 +        int i;
 +
 +        for (i = min_byte2; i <= max_byte2; i++, pcm++)
 +          {
 +            if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
 +              {
 +                if (from >= 0)
 +                  {
 +                    char_table_set_range (table, from, i - 1, Qt);
 +                    from = -1;
 +                  }
 +              }
 +            else if (from < 0)
 +              from = i;
 +          }
 +        if (from >= 0)
 +          char_table_set_range (table, from, i - 1, Qt);
 +      }
 +    }
 +  else
 +    {
 +      if (! font->per_char || font->all_chars_exist == True)
 +      {
 +        int i;
 +
 +        for (i = min_byte1; i <= max_byte1; i++)
 +          char_table_set_range (table,
 +                                (i << 8) | min_byte2, (i << 8) | max_byte2,
 +                                Qt);
 +      }
 +      else
 +      {
 +        XCharStruct *pcm = font->per_char;
 +        int i;
 +
 +        for (i = min_byte1; i <= max_byte1; i++)
 +          {
 +            int from = -1;
 +            int j;
 +
 +            for (j = min_byte2; j <= max_byte2; j++, pcm++)
 +              {
 +                if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
 +                  {
 +                    if (from >= 0)
 +                      {
 +                        char_table_set_range (table, (i << 8) | from,
 +                                              (i << 8) | (j - 1), Qt);
 +                        from = -1;
 +                      }
 +                  }
 +                else if (from < 0)
 +                  from = j;
 +              }
 +            if (from >= 0)
 +              char_table_set_range (table, (i << 8) | from,
 +                                    (i << 8) | (j - 1), Qt);
 +          }
 +      }
 +    }
 +#endif
 +  return table;
 +}
 +
  \f
  /***********************************************************************
                            Glyph display
@@@ -1471,9 -1320,9 +1471,9 @@@ x_set_mouse_face_gc (s
      face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
  
    if (s->first_glyph->type == CHAR_GLYPH)
 -    face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
 +    face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
    else
 -    face_id = FACE_FOR_CHAR (s->f, face, 0);
 +    face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
    s->face = FACE_FROM_ID (s->f, face_id);
    PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
  
@@@ -5382,16 -5231,11 +5382,16 @@@ x_new_font (f, fontname
       register char *fontname;
  {
    struct font_info *fontp
 -    = FS_LOAD_FONT (f, 0, fontname, -1);
 +    = FS_LOAD_FONT (f, fontname);
  
    if (!fontp)
      return Qnil;
  
 +  if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
 +    /* This font is already set in frame F.  There's nothing more to
 +       do.  */
 +    return build_string (fontp->full_name);
 +
    FRAME_FONT (f) = (XFontStruct *) (fontp->font);
    FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
    FRAME_FONTSET (f) = -1;
    return build_string (fontp->full_name);
  }
  \f
 -/* Give frame F the fontset named FONTSETNAME as its default font, and
 -   return the full name of that fontset.  FONTSETNAME may be a wildcard
 -   pattern; in that case, we choose some fontset that fits the pattern.
 -   The return value shows which fontset we chose.  */
 +/* Give frame F the fontset named FONTSETNAME as its default fontset,
 +   and return the full name of that fontset.  FONTSETNAME may be a
 +   wildcard pattern; in that case, we choose some fontset that fits
 +   the pattern.  FONTSETNAME may be a font name for ASCII characters;
 +   in that case, we create a fontset from that font name.
 +
 +   The return value shows which fontset we chose.
 +   If FONTSETNAME specifies the default fontset, return Qt.
 +   If an ASCII font in the specified fontset can't be loaded, return
 +   Qnil.  */
  
  Lisp_Object
  x_new_fontset (f, fontsetname)
       struct frame *f;
 -     char *fontsetname;
 +     Lisp_Object fontsetname;
  {
 -  int fontset = fs_query_fontset (build_string (fontsetname), 0);
 +  int fontset = fs_query_fontset (fontsetname, 0);
    Lisp_Object result;
  
 -  if (fontset < 0)
 -    return Qnil;
 -
 -  if (FRAME_FONTSET (f) == fontset)
 +  if (fontset > 0 && FRAME_FONTSET(f) == fontset)
      /* This fontset is already set in frame F.  There's nothing more
         to do.  */
      return fontset_name (fontset);
 +  else if (fontset == 0)
 +    /* The default fontset can't be the default font.   */
 +    return Qt;
  
 -  result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 +  if (fontset > 0)
 +    result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 +  else
 +    result = x_new_font (f, SDATA (fontsetname));
  
    if (!STRINGP (result))
      /* Can't load ASCII font.  */
      return Qnil;
  
 +  if (fontset < 0)
 +    fontset = new_fontset_from_font_name (result);
 +
    /* Since x_new_font doesn't update any fontset information, do it now.  */
    FRAME_FONTSET(f) = fontset;
  
 -  return build_string (fontsetname);
 +  return fontset_name (fontset);
  }
  
  \f
@@@ -6573,22 -6405,13 +6573,22 @@@ w32_initialize (
    AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
  #endif
  
 -  /* Load system settings.  */
 +  /* Dynamically link to optional system components.  */
    {
      UINT smoothing_type;
      BOOL smoothing_enabled;
  
 -    /* If using proportional scroll bars, ensure handle is at least 5 pixels;
 -       otherwise use the fixed height.  */
 +    HANDLE gdi_lib = LoadLibrary ("gdi32.dll");
 +
 +#define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn)
 +
 +    LOAD_PROC (gdi_lib, GetFontUnicodeRanges);
 +    
 +#undef LOAD_PROC
 +
 +    FreeLibrary (gdi_lib);
 +
 +    /* Ensure scrollbar handle is at least 5 pixels.  */
      vertical_scroll_bar_min_handle = 5;
  
      /* For either kind of scroll bar, take account of the arrows; these
diff --combined src/w32term.h
index c9d7fc375ac788d09becdef90c35847c7d600e3c,9d034f56f5b9c86e405ca4e9c56a4a8902707d2d..c1ad423ca67bb9e3424036466496e72316699829
@@@ -1,6 -1,6 +1,6 @@@
  /* Definitions and headers for communication on the Microsoft W32 API.
     Copyright (C) 1995, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -260,8 -260,6 +260,8 @@@ extern Lisp_Object w32_list_fonts P_ ((
  extern struct font_info *w32_get_font_info (), *w32_query_font ();
  extern void w32_cache_char_metrics (XFontStruct *font);
  extern void w32_find_ccl_program();
 +extern Lisp_Object x_get_font_repertory P_ ((struct frame *,
 +                                           struct font_info *));
  \f
  #define PIX_TYPE COLORREF
  
diff --combined src/window.c
index 5bd57496180157676008c53405c305ea5bb102d8,0fa22675fdcf47b93205430c0c1c9d4b5f2eacc8..17643ed874f92cdc65536373f6a90ef4fb2941ed
@@@ -1,7 -1,7 +1,7 @@@
  /* Window creation, deletion and examination for GNU Emacs.
     Does not include redisplay.
     Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-                  2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -1182,7 -1182,8 +1182,8 @@@ if it isn't already recorded.  */
  
    if (! NILP (update)
        && ! (! NILP (w->window_end_valid)
-           && XFASTINT (w->last_modified) >= BUF_MODIFF (b))
+           && XFASTINT (w->last_modified) >= BUF_MODIFF (b)
+           && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (b))
        && !noninteractive)
      {
        struct text_pos startp;
@@@ -3265,10 -3266,6 +3266,6 @@@ set_window_buffer (window, buffer, run_
    struct window *w = XWINDOW (window);
    struct buffer *b = XBUFFER (buffer);
    int count = SPECPDL_INDEX ();
- #ifdef HAVE_WINDOW_SYSTEM
-   struct frame *f = XFRAME (w->frame);
-   Display_Info *dpyinfo;
- #endif
  
    w->buffer = buffer;
  
        call1 (Vrun_hooks, Qwindow_configuration_change_hook);
      }
  
- #ifdef HAVE_WINDOW_SYSTEM
-   BLOCK_INPUT;
-   if (f && FRAME_X_OUTPUT (f)
-       && (dpyinfo = FRAME_X_DISPLAY_INFO (f))
-       && EQ (window, dpyinfo->mouse_face_window))
-     clear_mouse_face (dpyinfo);
-   UNBLOCK_INPUT;
- #endif
    unbind_to (count, Qnil);
  }
  
@@@ -3743,7 -3731,7 +3731,7 @@@ displayed.  */
        window = Fsplit_window (window, Qnil, Qnil);
        else
        {
 -        Lisp_Object upper, lower, other;
 +        Lisp_Object upper, other;
  
          window = Fget_lru_window (frames, Qt);
          /* If the LRU window is selected, and big enough,
            window = Fframe_selected_window (call0 (Vpop_up_frame_function));
          /* If window appears above or below another,
             even out their heights.  */
 -        other = upper = lower = Qnil;
 +        other = upper = Qnil;
          if (!NILP (XWINDOW (window)->prev))
 -          other = upper = XWINDOW (window)->prev, lower = window;
 +          other = upper = XWINDOW (window)->prev;
          if (!NILP (XWINDOW (window)->next))
 -          other = lower = XWINDOW (window)->next, upper = window;
 +          other = XWINDOW (window)->next, upper = window;
          if (!NILP (other)
              && !NILP (Veven_window_heights)
              /* Check that OTHER and WINDOW are vertically arrayed.  */
diff --combined src/xdisp.c
index 07df06785ad670e5dbde68f0f046e3018db2ffdc,b018735c3c6e760de337c8547514a48970b8a95a..5a78dd48c10cf8dc3c877d889b2dc784014b5782
@@@ -1,7 -1,7 +1,7 @@@
  /* Display generation from window structure and buffer text.
     Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                   1997, 1998, 1999, 2000, 2001, 2002, 2003,
-                  2004, 2005, 2006 Free Software Foundation, Inc.
+                  2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -177,7 -177,6 +177,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "termchar.h"
  #include "dispextern.h"
  #include "buffer.h"
 +#include "character.h"
  #include "charset.h"
  #include "indent.h"
  #include "commands.h"
  #include "macterm.h"
  #endif
  
 +#ifdef HAVE_WINDOW_SYSTEM
 +#ifdef USE_FONT_BACKEND
 +#include "font.h"
 +#endif        /* USE_FONT_BACKEND */
 +#endif        /* HAVE_WINDOW_SYSTEM */
 +
  #ifndef FRAME_X_OUTPUT
  #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
  #endif
@@@ -760,7 -753,6 +760,7 @@@ static enum prop_handled handle_display
  static enum prop_handled handle_composition_prop P_ ((struct it *));
  static enum prop_handled handle_overlay_change P_ ((struct it *));
  static enum prop_handled handle_fontified_prop P_ ((struct it *));
 +static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
  
  /* Properties handled by iterators.  */
  
@@@ -772,7 -764,6 +772,7 @@@ static struct props it_props[] 
    {&Qface,            FACE_PROP_IDX,          handle_face_prop},
    {&Qdisplay,         DISPLAY_PROP_IDX,       handle_display_prop},
    {&Qinvisible,               INVISIBLE_PROP_IDX,     handle_invisible_prop},
 +  {&Qauto_composed,   AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
    {&Qcomposition,     COMPOSITION_PROP_IDX,   handle_composition_prop},
    {NULL,              0,                      NULL}
  };
@@@ -3513,7 -3504,7 +3513,7 @@@ face_before_or_after_it_pos (it, before
          struct face *face = FACE_FROM_ID (it->f, face_id);
  
          c = string_char_and_length (p, rest, &len);
 -        face_id = FACE_FOR_CHAR (it->f, face, c);
 +        face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
        }
      }
    else
        {
          int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
          struct face *face = FACE_FROM_ID (it->f, face_id);
 -        face_id = FACE_FOR_CHAR (it->f, face, c);
 +        face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
        }
      }
  
@@@ -4127,7 -4118,7 +4127,7 @@@ handle_single_display_spec (it, spec, o
        {
          Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
          int face_id2 = lookup_derived_face (it->f, face_name,
 -                                            'A', FRINGE_FACE_ID, 0);
 +                                            FRINGE_FACE_ID, 0);
          if (face_id2 >= 0)
            face_id = face_id2;
        }
@@@ -4478,117 -4469,6 +4478,117 @@@ string_buffer_position (w, string, arou
                        `composition' property
   ***********************************************************************/
  
 +static enum prop_handled
 +handle_auto_composed_prop (it)
 +     struct it *it;
 +{
 +  enum prop_handled handled = HANDLED_NORMALLY;
 +
 +  if (FUNCTIONP (Vauto_composition_function))
 +    {
 +      Lisp_Object val;
 +      EMACS_INT pos, this_pos;
 +
 +      if (STRINGP (it->string))
 +      pos = IT_STRING_CHARPOS (*it);
 +      else
 +      pos = IT_CHARPOS (*it);
 +      this_pos = pos;
 +
 +      val =Fget_char_property (make_number (pos), Qauto_composed, it->string);
 +      if (! NILP (val))
 +      {
 +        Lisp_Object limit = Qnil, next;
 +        
 +        /* As Fnext_single_char_property_change is very slow, we
 +           limit the search to the current line.  */
 +        if (STRINGP (it->string))
 +          limit = make_number (SCHARS (it->string));
 +        else
 +          limit = make_number (find_next_newline_no_quit (pos, 1));
 +
 +        next = (Fnext_single_property_change
 +                (make_number (pos), Qauto_composed, it->string, limit));
 +        if (XINT (next) < XINT (limit))
 +          {
 +            /* The current point is auto-composed, but there exist
 +               characters not yet composed beyond the auto-composed
 +               region.  There's a possiblity that the last
 +               characters in the region may be newly composed.  */
 +            int charpos = XINT (next) - 1, bytepos, c;
 +
 +            if (STRINGP (it->string))
 +              {
 +                bytepos = string_char_to_byte (it->string, charpos);
 +                c = SDATA (it->string)[bytepos];
 +              }
 +            else
 +              {
 +                bytepos = CHAR_TO_BYTE (charpos);
 +                c = FETCH_BYTE (bytepos);
 +              }
 +            if (c != '\n')
 +              /* If the last character is not newline, it may be
 +                 composed with the following characters.  */
 +              val = Qnil, pos = charpos + 1;
 +          }
 +      }
 +      if (NILP (val))
 +      {
 +        int count = SPECPDL_INDEX ();
 +        Lisp_Object args[4];
 +
 +        args[0] = Vauto_composition_function;
 +        specbind (Qauto_composition_function, Qnil);
 +        args[1] = make_number (pos);
 +        args[2] = it->string;
 +#ifdef USE_FONT_BACKEND
 +        if (enable_font_backend)
 +          {
 +            struct face *face = FACE_FROM_ID (it->f, it->face_id);
 +            int c;
 +
 +            if (STRINGP (it->string))
 +              {
 +                EMACS_INT pos_byte = IT_STRING_BYTEPOS (*it);
 +                const unsigned char *s = SDATA (it->string) + pos_byte;
 +
 +                if (STRING_MULTIBYTE (it->string))
 +                  it->c = STRING_CHAR (s, 0);
 +                else
 +                  it->c = *s;
 +              }
 +            else
 +              {
 +                EMACS_INT pos_byte = IT_BYTEPOS (*it);
 +
 +                it->c = FETCH_CHAR (pos_byte);
 +              }
 +            args[3] = font_at (it->c, this_pos, face, it->w, it->string);
 +          }
 +        else
 +#endif        /* USE_FONT_BACKEND */
 +          args[3] = Qnil;
 +        safe_call (4, args);
 +        unbind_to (count, Qnil);
 +
 +        if (this_pos == pos)
 +          {
 +            val = Fget_char_property (args[1], Qauto_composed, it->string);
 +            /* Return HANDLED_RECOMPUTE_PROPS only if function composed
 +               something.  This avoids an endless loop if they failed to
 +               fontify the text for which reason ever.  */
 +            if (! NILP (val))
 +              handled = HANDLED_RECOMPUTE_PROPS;
 +          }
 +        else
 +          handled = HANDLED_RECOMPUTE_PROPS;
 +      }
 +    }
 +
 +  return handled;
 +}
 +
  /* Set up iterator IT from `composition' property at its current
     position.  Called from handle_stop.  */
  
@@@ -4597,7 -4477,7 +4597,7 @@@ handle_composition_prop (it
       struct it *it;
  {
    Lisp_Object prop, string;
 -  int pos, pos_byte, end;
 +  EMACS_INT pos, pos_byte, start, end;
    enum prop_handled handled = HANDLED_NORMALLY;
  
    if (STRINGP (it->string))
    /* If there's a valid composition and point is not inside of the
       composition (in the case that the composition is from the current
       buffer), draw a glyph composed from the composition components.  */
 -  if (find_composition (pos, -1, &pos, &end, &prop, string)
 -      && COMPOSITION_VALID_P (pos, end, prop)
 -      && (STRINGP (it->string) || (PT <= pos || PT >= end)))
 +  if (find_composition (pos, -1, &start, &end, &prop, string)
 +      && COMPOSITION_VALID_P (start, end, prop)
 +      && (STRINGP (it->string) || (PT <= start || PT >= end)))
      {
 -      int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
 +      int id;
 +
 +      if (start != pos)
 +      {
 +        if (STRINGP (it->string))
 +          pos_byte = string_char_to_byte (it->string, start);
 +        else
 +          pos_byte = CHAR_TO_BYTE (start);
 +      }
 +      id = get_composition_id (start, pos_byte, end - start, prop, string);
  
        if (id >= 0)
        {
          it->method = GET_FROM_COMPOSITION;
          it->cmp_id = id;
          it->cmp_len = COMPOSITION_LENGTH (prop);
 -        /* For a terminal, draw only the first character of the
 -             components.  */
 -        it->c = COMPOSITION_GLYPH (composition_table[id], 0);
 +        /* For a terminal, draw only the first (non-TAB) character
 +           of the components.  */
 +#ifdef USE_FONT_BACKEND
 +        if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
 +          {
 +            Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
 +                                         ->key_and_value,
 +                                         cmp->hash_index * 2);
 +
 +            it->c = XINT (LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, 0)));
 +          }
 +        else
 +#endif /* USE_FONT_BACKEND */
 +          {
 +            int i;
 +
 +            for (i = 0; i < cmp->glyph_len; i++)
 +              if ((it->c = COMPOSITION_GLYPH (composition_table[id], i))
 +                  != '\t')
 +                break;
 +          }
 +        if (it->c == '\t')
 +          it->c = ' ';
          it->len = (STRINGP (it->string)
                     ? string_char_to_byte (it->string, end)
                     : CHAR_TO_BYTE (end)) - pos_byte;
@@@ -5697,26 -5548,31 +5697,26 @@@ get_next_display_element (it
             the translation.  This could easily be changed but I
             don't believe that it is worth doing.
  
 -           If it->multibyte_p is nonzero, eight-bit characters and
 -           non-printable multibyte characters are also translated to
 -           octal form.
 +           If it->multibyte_p is nonzero, non-printable non-ASCII
 +           characters are also translated to octal form.
  
             If it->multibyte_p is zero, eight-bit characters that
             don't have corresponding multibyte char code are also
             translated to octal form.  */
          else if ((it->c < ' '
 -                  && (it->area != TEXT_AREA
 -                      /* In mode line, treat \n like other crl chars.  */
 -                      || (it->c != '\t'
 -                          && it->glyph_row && it->glyph_row->mode_line_p)
 -                      || (it->c != '\n' && it->c != '\t')))
 -                 || (it->multibyte_p
 -                     ? ((it->c >= 127
 -                         && it->len == 1)
 -                        || !CHAR_PRINTABLE_P (it->c)
 +                  ? (it->area != TEXT_AREA
 +                     /* In mode line, treat \n, \t like other crl chars.  */
 +                     || (it->c != '\t'
 +                         && it->glyph_row && it->glyph_row->mode_line_p)
 +                     || (it->c != '\n' && it->c != '\t'))
 +                  : (it->multibyte_p
 +                     ? (!CHAR_PRINTABLE_P (it->c)
                          || (!NILP (Vnobreak_char_display)
 -                            && (it->c == 0x8a0 || it->c == 0x8ad
 -                                || it->c == 0x920 || it->c == 0x92d
 -                                || it->c == 0xe20 || it->c == 0xe2d
 -                                || it->c == 0xf20 || it->c == 0xf2d)))
 +                            && (it->c == 0xA0 /* NO-BREAK SPACE */
 +                                || it->c == 0xAD /* SOFT HYPHEN */)))
                       : (it->c >= 127
 -                        && (!unibyte_display_via_language_environment
 -                            || it->c == unibyte_char_to_multibyte (it->c)))))
 +                        && (! unibyte_display_via_language_environment
 +                            || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
            {
              /* IT->c is a control character which must be displayed
                 either as '\003' or as `^C' where the '\\' and '^'
                 highlighting.  */
  
              if (EQ (Vnobreak_char_display, Qt)
 -                && (it->c == 0x8a0 || it->c == 0x920
 -                    || it->c == 0xe20 || it->c == 0xf20))
 +                && it->c == 0xA0)
                {
                  /* Merge the no-break-space face into the current face.  */
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
                 highlighting.  */
  
              if (EQ (Vnobreak_char_display, Qt)
 -                && (it->c == 0x8ad || it->c == 0x92d
 -                    || it->c == 0xe2d || it->c == 0xf2d))
 +                && it->c == 0xAD)
                {
                  g = it->c = '-';
                  XSETINT (it->ctl_chars[0], g);
              /* Handle non-break space and soft hyphen
                 with the escape glyph.  */
  
 -            if (it->c == 0x8a0 || it->c == 0x8ad
 -                || it->c == 0x920 || it->c == 0x92d
 -                || it->c == 0xe20 || it->c == 0xe2d
 -                || it->c == 0xf20 || it->c == 0xf2d)
 +            if (it->c == 0xA0 || it->c == 0xAD)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
 -                g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
 +                g = it->c = (it->c == 0xA0 ? ' ' : '-');
                  XSETINT (it->ctl_chars[1], g);
                  ctl_len = 2;
                  goto display_control;
                int i;
  
                /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
 -              if (SINGLE_BYTE_CHAR_P (it->c))
 -                str[0] = it->c, len = 1;
 +              if (CHAR_BYTE8_P (it->c))
 +                {
 +                  str[0] = CHAR_TO_BYTE8 (it->c);
 +                  len = 1;
 +                }
 +              else if (it->c < 256)
 +                {
 +                  str[0] = it->c;
 +                  len = 1;
 +                }
                else
                  {
 -                  len = CHAR_STRING_NO_SIGNAL (it->c, str);
 -                  if (len < 0)
 -                    {
 -                      /* It's an invalid character, which shouldn't
 -                         happen actually, but due to bugs it may
 -                         happen.  Let's print the char as is, there's
 -                         not much meaningful we can do with it.  */
 -                        str[0] = it->c;
 -                        str[1] = it->c >> 8;
 -                        str[2] = it->c >> 16;
 -                        str[3] = it->c >> 24;
 -                        len = 4;
 -                      }
 +                  /* It's an invalid character, which shouldn't
 +                     happen actually, but due to bugs it may
 +                     happen.  Let's print the char as is, there's
 +                     not much meaningful we can do with it.  */
 +                    str[0] = it->c;
 +                    str[1] = it->c >> 8;
 +                    str[2] = it->c >> 16;
 +                    str[3] = it->c >> 24;
 +                    len = 4;
                    }
  
                for (i = 0; i < len; i++)
              goto get_next;
            }
        }
 +    }
  
 -      /* Adjust face id for a multibyte character.  There are no
 -         multibyte character in unibyte text.  */
 -      if (it->multibyte_p
 -        && success_p
 -        && FRAME_WINDOW_P (it->f))
 -      {
 -        struct face *face = FACE_FROM_ID (it->f, it->face_id);
 -        it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
 -      }
 +  /* Adjust face id for a multibyte character.  There are no multibyte
 +     character in unibyte text.  */
 +  if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
 +      && it->multibyte_p
 +      && success_p
 +      && FRAME_WINDOW_P (it->f))
 +    {
 +      struct face *face = FACE_FROM_ID (it->f, it->face_id);
 +      int pos = (it->s ? -1
 +               : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
 +               : IT_CHARPOS (*it));
 +        
 +      it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
      }
  
    /* Is this character the last one of a run of characters with
@@@ -6917,16 -6769,6 +6917,16 @@@ move_it_to (it, to_charpos, to_x, to_y
             the line.  */
          if (skip == MOVE_X_REACHED)
            {
 +            /* Wait!  We can conclude that TO_Y is in the line if
 +               the already scanned glyphs make the line tall enough
 +               because further scanning doesn't make it shorter.  */
 +            line_height = it->max_ascent + it->max_descent;
 +            if (to_y >= it->current_y
 +                && to_y < it->current_y + line_height)
 +              {
 +                reached = 6;
 +                break;
 +              }
              it_backup = *it;
              TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
              skip2 = move_it_in_display_line_to (it, to_charpos, -1,
@@@ -7459,7 -7301,7 +7459,7 @@@ message_dolog (m, nbytes, nlflag, multi
          for (i = 0; i < nbytes; i += char_bytes)
            {
              c = string_char_and_length (m + i, nbytes - i, &char_bytes);
 -            work[0] = (SINGLE_BYTE_CHAR_P (c)
 +            work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
              insert_1_both (work, 1, 1, 1, 0, 0);
             for the *Message* buffer.  */
          for (i = 0; i < nbytes; i++)
            {
 -            c = unibyte_char_to_multibyte (msg[i]);
 +            c = msg[i];
 +            c = unibyte_char_to_multibyte (c);
              char_bytes = CHAR_STRING (c, str);
              insert_1_both (str, 1, char_bytes, 1, 0, 0);
            }
@@@ -8747,7 -8588,7 +8747,7 @@@ set_message_1 (a1, a2, nbytes, multibyt
          for (i = 0; i < nbytes; i += n)
            {
              c = string_char_and_length (s + i, nbytes - i, &n);
 -            work[0] = (SINGLE_BYTE_CHAR_P (c)
 +            work[0] = (ASCII_CHAR_P (c)
                         ? c
                         : multibyte_char_to_unibyte (c, Qnil));
              insert_1_both (work, 1, 1, 1, 0, 0);
          /* Convert a single-byte string to multibyte.  */
          for (i = 0; i < nbytes; i++)
            {
 -            c = unibyte_char_to_multibyte (msg[i]);
 +            c = msg[i];
 +            c = unibyte_char_to_multibyte (c);
              n = CHAR_STRING (c, str);
              insert_1_both (str, 1, n, 1, 0, 0);
            }
@@@ -10862,7 -10702,7 +10862,7 @@@ check_point_in_composition (prev_buf, p
       struct buffer *prev_buf, *buf;
       int prev_pt, pt;
  {
 -  int start, end;
 +  EMACS_INT start, end;
    Lisp_Object prop;
    Lisp_Object buffer;
  
@@@ -11864,24 -11704,35 +11864,24 @@@ disp_char_vector (dp, c
       struct Lisp_Char_Table *dp;
       int c;
  {
 -  int code[4], i;
    Lisp_Object val;
  
 -  if (SINGLE_BYTE_CHAR_P (c))
 -    return (dp->contents[c]);
 -
 -  SPLIT_CHAR (c, code[0], code[1], code[2]);
 -  if (code[1] < 32)
 -    code[1] = -1;
 -  else if (code[2] < 32)
 -    code[2] = -1;
 -
 -  /* Here, the possible range of code[0] (== charset ID) is
 -     128..max_charset.  Since the top level char table contains data
 -     for multibyte characters after 256th element, we must increment
 -     code[0] by 128 to get a correct index.  */
 -  code[0] += 128;
 -  code[3] = -1;               /* anchor */
 -
 -  for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
 +  if (ASCII_CHAR_P (c))
      {
 -      val = dp->contents[code[i]];
 -      if (!SUB_CHAR_TABLE_P (val))
 -      return (NILP (val) ? dp->defalt : val);
 +      val = dp->ascii;
 +      if (SUB_CHAR_TABLE_P (val))
 +      val = XSUB_CHAR_TABLE (val)->contents[c];
      }
 +  else
 +    {
 +      Lisp_Object table;
  
 -  /* Here, val is a sub char table.  We return the default value of
 -     it.  */
 -  return (dp->defalt);
 +      XSETCHAR_TABLE (table, dp);
 +      val = char_table_ref (table, c);
 +    }
 +  if (NILP (val))
 +    val = dp->defalt;
 +  return val;
  }
  
  
@@@ -13687,6 -13538,7 +13687,7 @@@ try_window (window, pos, check_margins
    struct window *w = XWINDOW (window);
    struct it it;
    struct glyph_row *last_text_row = NULL;
+   struct frame *f = XFRAME (w->frame);
  
    /* Make POS the new window start.  */
    set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
@@@ -15799,7 -15651,7 +15800,7 @@@ append_space_for_newline (it, default_f
          else if (it->face_before_selective_p)
            it->face_id = it->saved_face_id;
          face = FACE_FROM_ID (it->f, it->face_id);
 -        it->face_id = FACE_FOR_CHAR (it->f, face, 0);
 +        it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
  
          PRODUCE_GLYPHS (it);
  
@@@ -15859,9 -15711,9 +15860,9 @@@ extend_face_to_end_of_line (it
           ASCII face.  This will be automatically undone the next time
           get_next_display_element returns a multibyte character.  Note
           that the character will always be single byte in unibyte text.  */
 -  if (!SINGLE_BYTE_CHAR_P (it->c))
 +  if (!ASCII_CHAR_P (it->c))
      {
 -      it->face_id = FACE_FOR_CHAR (f, face, 0);
 +      it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
      }
  
    if (FRAME_WINDOW_P (f))
@@@ -15967,7 -15819,7 +15968,7 @@@ highlight_trailing_whitespace (f, row
                  && glyph->u.ch == ' '))
          && trailing_whitespace_p (glyph->charpos))
        {
 -        int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
 +        int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
          if (face_id < 0)
            return;
  
@@@ -17470,7 -17322,7 +17471,7 @@@ are the selected window and the window'
      {
        if (EQ (face, Qt))
        face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
 -      face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
 +      face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
      }
  
    if (face_id < 0)
@@@ -17693,7 -17545,7 +17694,7 @@@ decode_mode_spec_coding (coding_system
    /* The EOL conversion we are using.  */
    Lisp_Object eoltype;
  
 -  val = Fget (coding_system, Qcoding_system);
 +  val = CODING_SYSTEM_SPEC (coding_system);
    eoltype = Qnil;
  
    if (!VECTORP (val))         /* Not yet decided.  */
      }
    else
      {
 +      Lisp_Object attrs;
        Lisp_Object eolvalue;
  
 -      eolvalue = Fget (coding_system, Qeol_type);
 +      attrs = AREF (val, 0);
 +      eolvalue = AREF (val, 2);
  
        if (multibyte)
 -      *buf++ = XFASTINT (AREF (val, 1));
 +      *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
  
        if (eol_flag)
        {
            eoltype = eol_mnemonic_undecided;
          else if (VECTORP (eolvalue)) /* Not yet decided.  */
            eoltype = eol_mnemonic_undecided;
 -        else                  /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
 -          eoltype = (XFASTINT (eolvalue) == 0
 +        else                  /* eolvalue is Qunix, Qdos, or Qmac.  */
 +          eoltype = (EQ (eolvalue, Qunix)
                       ? eol_mnemonic_unix
 -                     : (XFASTINT (eolvalue) == 1
 +                     : (EQ (eolvalue, Qdos) == 1
                          ? eol_mnemonic_dos : eol_mnemonic_mac));
        }
      }
          eol_str = SDATA (eoltype);
          eol_str_len = SBYTES (eoltype);
        }
 -      else if (INTEGERP (eoltype)
 -             && CHAR_VALID_P (XINT (eoltype), 0))
 +      else if (CHARACTERP (eoltype))
        {
          unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
          eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
@@@ -18133,10 -17984,8 +18134,10 @@@ decode_mode_spec (w, c, field_width, pr
          {
            /* No need to mention EOL here--the terminal never needs
               to do EOL conversion.  */
 -          p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
 -          p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
 +          p = decode_mode_spec_coding (CODING_ID_NAME (keyboard_coding.id),
 +                                       p, 0);
 +          p = decode_mode_spec_coding (CODING_ID_NAME (terminal_coding.id),
 +                                       p, 0);
          }
        p = decode_mode_spec_coding (b->buffer_file_coding_system,
                                     p, eol_flag);
@@@ -18408,7 -18257,7 +18409,7 @@@ display_string (string, lisp_string, fa
                }
              break;
            }
 -        else if (x + glyph->pixel_width > it->first_visible_x)
 +        else if (x + glyph->pixel_width >= it->first_visible_x)
            {
              /* Glyph is at least partially visible.  */
              ++it->hpos;
@@@ -18936,80 -18785,6 +18937,80 @@@ append_glyph_string (head, tail, s
  }
  
  
 +/* Get face and two-byte form of character C in face FACE_ID on frame
 +   F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
 +   means we want to display multibyte text.  DISPLAY_P non-zero means
 +   make sure that X resources for the face returned are allocated.
 +   Value is a pointer to a realized face that is ready for display if
 +   DISPLAY_P is non-zero.  */
 +
 +static INLINE struct face *
 +get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
 +     struct frame *f;
 +     int c, face_id;
 +     XChar2b *char2b;
 +     int multibyte_p, display_p;
 +{
 +  struct face *face = FACE_FROM_ID (f, face_id);
 +
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      struct font *font = (struct font *) face->font_info;
 +
 +      if (font)
 +      {
 +        unsigned code = font->driver->encode_char (font, c);
 +
 +        if (code != FONT_INVALID_CODE)
 +          STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
 +        else
 +          STORE_XCHAR2B (char2b, 0, 0);
 +      }
 +    }
 +  else
 +#endif        /* USE_FONT_BACKEND */
 +  if (!multibyte_p)
 +    {
 +      /* Unibyte case.  We don't have to encode, but we have to make
 +       sure to use a face suitable for unibyte.  */
 +      STORE_XCHAR2B (char2b, 0, c);
 +      face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
 +      face = FACE_FROM_ID (f, face_id);
 +    }
 +  else if (c < 128)
 +    {
 +      /* Case of ASCII in a face known to fit ASCII.  */
 +      STORE_XCHAR2B (char2b, 0, c);
 +    }
 +  else if (face->font != NULL)
 +    {
 +      struct font_info *font_info
 +      = FONT_INFO_FROM_ID (f, face->font_info_id);
 +      struct charset *charset = CHARSET_FROM_ID (font_info->charset);
 +      unsigned code = ENCODE_CHAR (charset, c);
 +
 +      if (CHARSET_DIMENSION (charset) == 1)
 +      STORE_XCHAR2B (char2b, 0, code);
 +      else
 +      STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
 +       /* Maybe encode the character in *CHAR2B.  */
 +      rif->encode_char (c, char2b, font_info, charset, NULL);
 +    }
 +
 +  /* Make sure X resources of the face are allocated.  */
 +#ifdef HAVE_X_WINDOWS
 +  if (display_p)
 +#endif
 +    {
 +      xassert (face != NULL);
 +      PREPARE_FACE_FOR_DISPLAY (f, face);
 +    }
 +
 +  return face;
 +}
 +
 +
  /* Get face and two-byte form of character glyph GLYPH on frame F.
     The encoding of GLYPH->u.ch is returned in *CHAR2B.  Value is
     a pointer to a realized face that is ready for display.  */
@@@ -19029,23 -18804,6 +19030,23 @@@ get_glyph_face_and_encoding (f, glyph, 
    if (two_byte_p)
      *two_byte_p = 0;
  
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      struct font *font = (struct font *) face->font_info;
 +
 +      if (font)
 +      {
 +        unsigned code = font->driver->encode_char (font, glyph->u.ch);
 +
 +        if (code != FONT_INVALID_CODE)
 +          STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
 +        else
 +          STORE_XCHAR2B (char2b, 0, code);
 +      }
 +    }
 +  else
 +#endif        /* USE_FONT_BACKEND */
    if (!glyph->multibyte_p)
      {
        /* Unibyte case.  We don't have to encode, but we have to make
      }
    else
      {
 -      int c1, c2, charset;
 +      struct font_info *font_info
 +      = FONT_INFO_FROM_ID (f, face->font_info_id);
 +      if (font_info)
 +      {
 +        struct charset *charset = CHARSET_FROM_ID (font_info->charset);
 +        unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
  
 -      /* Split characters into bytes.  If c2 is -1 afterwards, C is
 -       really a one-byte character so that byte1 is zero.  */
 -      SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
 -      if (c2 > 0)
 -      STORE_XCHAR2B (char2b, c1, c2);
 -      else
 -      STORE_XCHAR2B (char2b, 0, c1);
 +        if (CHARSET_DIMENSION (charset) == 1)
 +          STORE_XCHAR2B (char2b, 0, code);
 +        else
 +          STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
  
 -      /* Maybe encode the character in *CHAR2B.  */
 -      if (charset != CHARSET_ASCII)
 -      {
 -        struct font_info *font_info
 -          = FONT_INFO_FROM_ID (f, face->font_info_id);
 -        if (font_info)
 -          glyph->font_type
 -            = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
 +        /* Maybe encode the character in *CHAR2B.  */
 +        if (CHARSET_ID (charset) != charset_ascii)
 +          {
 +            glyph->font_type
 +              = rif->encode_char (glyph->u.ch, char2b, font_info, charset,
 +                                  two_byte_p);
 +          }
        }
      }
  
  
  /* Fill glyph string S with composition components specified by S->cmp.
  
 -   FACES is an array of faces for all components of this composition.
 +   BASE_FACE is the base face of the composition.
     S->gidx is the index of the first component for S.
  
     OVERLAPS non-zero means S should draw the foreground only, and use
     Value is the index of a component not in S.  */
  
  static int
 -fill_composite_glyph_string (s, faces, overlaps)
 +fill_composite_glyph_string (s, base_face, overlaps)
       struct glyph_string *s;
 -     struct face **faces;
 +     struct face *base_face;
       int overlaps;
  {
    int i;
  
    s->for_overlaps = overlaps;
  
 -  s->face = faces[s->gidx];
 -  s->font = s->face->font;
 -  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend && s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
 +    {
 +      Lisp_Object gstring
 +      = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
 +              s->cmp->hash_index * 2);
  
 -  /* For all glyphs of this composition, starting at the offset
 -     S->gidx, until we reach the end of the definition or encounter a
 -     glyph that requires the different face, add it to S.  */
 -  ++s->nchars;
 -  for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
 -    ++s->nchars;
 +      s->face = base_face;
 +      s->font_info = s->cmp->font;
 +      s->font = s->font_info->font;
 +      for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
 +      {
 +        Lisp_Object g = LGSTRING_GLYPH (gstring, i);
 +        unsigned code;
  
 -  /* All glyph strings for the same composition has the same width,
 -     i.e. the width set for the first component of the composition.  */
 +        if (NILP (LGLYPH_FROM (g)))
 +          break;
 +        code = XUINT (LGLYPH_CODE (g));
 +        STORE_XCHAR2B (s->char2b + i, code >> 8, code & 0xFF);
 +      }
 +      s->width = s->cmp->pixel_width;
 +    }
 +  else
 +#endif        /* USE_FONT_BACKEND */
 +    {
 +      /* For all glyphs of this composition, starting at the offset
 +       S->gidx, until we reach the end of the definition or encounter a
 +       glyph that requires the different face, add it to S.  */
 +      struct face *face;
  
 -  s->width = s->first_glyph->pixel_width;
 +      s->face = NULL;
 +      s->font = NULL;
 +      s->font_info = NULL;
 +      for (i = s->gidx; i < s->cmp->glyph_len; i++)
 +      {
 +        int c = COMPOSITION_GLYPH (s->cmp, i);
 +
 +        if (c != '\t')
 +          {
 +            int face_id = FACE_FOR_CHAR (s->f, base_face, c, -1, Qnil);
 +
 +            face = get_char_face_and_encoding (s->f, c, face_id,
 +                                               s->char2b + i, 1, 1);
 +            if (face)
 +              {
 +                if (! s->face)
 +                  {
 +                    s->face = face;
 +                    s->font = s->face->font;
 +                    s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
 +                  }
 +                else if (s->face != face)
 +                  break;
 +              }
 +          }
 +        ++s->nchars;
 +      }
 +
 +      /* All glyph strings for the same composition has the same width,
 +       i.e. the width set for the first component of the composition.  */
 +      s->width = s->first_glyph->pixel_width;
 +    }
  
    /* If the specified font could not be loaded, use the frame's
       default font, but record the fact that we couldn't load it in
    /* Adjust base line for subscript/superscript text.  */
    s->ybase += s->first_glyph->voffset;
  
 -  xassert (s->face && s->face->gc);
 -
    /* This glyph string must always be drawn with 16-bit functions.  */
    s->two_byte_p = 1;
  
@@@ -19243,7 -18955,7 +19244,7 @@@ fill_glyph_string (s, face_id, start, e
      }
  
    s->font = s->face->font;
 -  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
 +  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
  
    /* If the specified font could not be loaded, use the frame's font,
       but record the fact that we couldn't load it in
@@@ -19307,7 -19019,7 +19308,7 @@@ fill_stretch_glyph_string (s, row, area
    face_id = glyph->face_id;
    s->face = FACE_FROM_ID (s->f, face_id);
    s->font = s->face->font;
 -  s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
 +  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
    s->width = glyph->pixel_width;
    s->nchars = 1;
    voffset = glyph->voffset;
    return glyph - s->row->glyphs[s->area];
  }
  
 +static XCharStruct *
 +get_per_char_metric (font, font_info, char2b, font_type)
 +     XFontStruct *font;
 +     struct font_info *font_info;
 +     XChar2b *char2b;
 +     int font_type;
 +{
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      static XCharStruct pcm_value;
 +      unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
 +      struct font *fontp;
 +      struct font_metrics metrics;
 +
 +      if (! font_info || code == FONT_INVALID_CODE)
 +      return NULL;
 +      fontp = (struct font *) font_info;
 +      fontp->driver->text_extents (fontp, &code, 1, &metrics);
 +      pcm_value.lbearing = metrics.lbearing;
 +      pcm_value.rbearing = metrics.rbearing;
 +      pcm_value.ascent = metrics.ascent;
 +      pcm_value.descent = metrics.descent;
 +      pcm_value.width = metrics.width;
 +      return &pcm_value;
 +    }
 +#endif        /* USE_FONT_BACKEND */
 +  return rif->per_char_metric (font, char2b, font_type);
 +}
  
  /* EXPORT for RIF:
     Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
@@@ -19382,9 -19065,9 +19383,9 @@@ x_get_glyph_overhangs (glyph, f, left, 
  
        face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
        font = face->font;
 -      font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
 +      font_info = FONT_INFO_FROM_FACE (f, face);
        if (font  /* ++KFS: Should this be font_info ?  */
 -        && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
 +        && (pcm = get_per_char_metric (font, font_info, &char2b, glyph->font_type)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
            *left = -pcm->lbearing;
        }
      }
 +  else if (glyph->type == COMPOSITE_GLYPH)
 +    {
 +      struct composition *cmp = composition_table[glyph->u.cmp_id];
 +
 +      *right = cmp->rbearing - cmp->pixel_width;
 +      *left = - cmp->lbearing;
 +    }
  }
  
  
@@@ -19512,6 -19188,70 +19513,6 @@@ right_overwriting (s
  }
  
  
 -/* Get face and two-byte form of character C in face FACE_ID on frame
 -   F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
 -   means we want to display multibyte text.  DISPLAY_P non-zero means
 -   make sure that X resources for the face returned are allocated.
 -   Value is a pointer to a realized face that is ready for display if
 -   DISPLAY_P is non-zero.  */
 -
 -static INLINE struct face *
 -get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
 -     struct frame *f;
 -     int c, face_id;
 -     XChar2b *char2b;
 -     int multibyte_p, display_p;
 -{
 -  struct face *face = FACE_FROM_ID (f, face_id);
 -
 -  if (!multibyte_p)
 -    {
 -      /* Unibyte case.  We don't have to encode, but we have to make
 -       sure to use a face suitable for unibyte.  */
 -      STORE_XCHAR2B (char2b, 0, c);
 -      face_id = FACE_FOR_CHAR (f, face, c);
 -      face = FACE_FROM_ID (f, face_id);
 -    }
 -  else if (c < 128)
 -    {
 -      /* Case of ASCII in a face known to fit ASCII.  */
 -      STORE_XCHAR2B (char2b, 0, c);
 -    }
 -  else
 -    {
 -      int c1, c2, charset;
 -
 -      /* Split characters into bytes.  If c2 is -1 afterwards, C is
 -       really a one-byte character so that byte1 is zero.  */
 -      SPLIT_CHAR (c, charset, c1, c2);
 -      if (c2 > 0)
 -      STORE_XCHAR2B (char2b, c1, c2);
 -      else
 -      STORE_XCHAR2B (char2b, 0, c1);
 -
 -      /* Maybe encode the character in *CHAR2B.  */
 -      if (face->font != NULL)
 -      {
 -        struct font_info *font_info
 -          = FONT_INFO_FROM_ID (f, face->font_info_id);
 -        if (font_info)
 -          rif->encode_char (c, char2b, font_info, 0);
 -      }
 -    }
 -
 -  /* Make sure X resources of the face are allocated.  */
 -#ifdef HAVE_X_WINDOWS
 -  if (display_p)
 -#endif
 -    {
 -      xassert (face != NULL);
 -      PREPARE_FACE_FOR_DISPLAY (f, face);
 -    }
 -
 -  return face;
 -}
 -
 -
  /* Set background width of glyph string S.  START is the index of the
     first glyph following S.  LAST_X is the right-most x-position + 1
     in the drawing area.  */
@@@ -19651,9 -19391,10 +19652,9 @@@ compute_overhangs_and_x (s, x, backward
  #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)          \
       do                                                                          \
         {                                                                 \
 -       int c, face_id;                                                   \
 +       int face_id;                                                      \
         XChar2b *char2b;                                                  \
                                                                           \
 -       c = (row)->glyphs[area][START].u.ch;                              \
         face_id = (row)->glyphs[area][START].face_id;                     \
                                                                           \
         s = (struct glyph_string *) alloca (sizeof *s);                   \
     x-position of the drawing area.  */
  
  #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
 -  do {                                                                          \
 -    int cmp_id = (row)->glyphs[area][START].u.cmp_id;                   \
 -    int face_id = (row)->glyphs[area][START].face_id;                   \
 -    struct face *base_face = FACE_FROM_ID (f, face_id);                         \
 -    struct composition *cmp = composition_table[cmp_id];                \
 -    int glyph_len = cmp->glyph_len;                                     \
 -    XChar2b *char2b;                                                    \
 -    struct face **faces;                                                \
 -    struct glyph_string *first_s = NULL;                                \
 -    int n;                                                              \
 -                                                                        \
 -    base_face = base_face->ascii_face;                                          \
 -    char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);                 \
 -    faces = (struct face **) alloca ((sizeof *faces) * glyph_len);      \
 -    /* At first, fill in `char2b' and `faces'.  */                      \
 -    for (n = 0; n < glyph_len; n++)                                     \
 -      {                                                                         \
 -      int c = COMPOSITION_GLYPH (cmp, n);                               \
 -      int this_face_id = FACE_FOR_CHAR (f, base_face, c);               \
 -      faces[n] = FACE_FROM_ID (f, this_face_id);                        \
 -      get_char_face_and_encoding (f, c, this_face_id,                   \
 -                                  char2b + n, 1, 1);                    \
 -      }                                                                         \
 -                                                                        \
 -    /* Make glyph_strings for each glyph sequence that is drawable by   \
 -       the same face, and append them to HEAD/TAIL.  */                         \
 -    for (n = 0; n < cmp->glyph_len;)                                    \
 -      {                                                                         \
 -      s = (struct glyph_string *) alloca (sizeof *s);                   \
 -      INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL);       \
 -      append_glyph_string (&(HEAD), &(TAIL), s);                        \
 -      s->cmp = cmp;                                                     \
 -      s->gidx = n;                                                      \
 -      s->x = (X);                                                       \
 -                                                                        \
 -      if (n == 0)                                                       \
 -        first_s = s;                                                    \
 -                                                                        \
 -      n = fill_composite_glyph_string (s, faces, overlaps);             \
 -      }                                                                         \
 -                                                                        \
 -    ++START;                                                            \
 -    s = first_s;                                                        \
 +  do {                                                                            \
 +    int face_id = (row)->glyphs[area][START].face_id;                     \
 +    struct face *base_face = FACE_FROM_ID (f, face_id);                           \
 +    int cmp_id = (row)->glyphs[area][START].u.cmp_id;                     \
 +    struct composition *cmp = composition_table[cmp_id];                  \
 +    XChar2b *char2b;                                                      \
 +    struct glyph_string *first_s;                                         \
 +    int n;                                                                \
 +                                                                          \
 +    char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len);      \
 +    base_face = base_face->ascii_face;                                            \
 +                                                                          \
 +    /* Make glyph_strings for each glyph sequence that is drawable by     \
 +       the same face, and append them to HEAD/TAIL.  */                           \
 +    for (n = 0; n < cmp->glyph_len;)                                      \
 +      {                                                                           \
 +      s = (struct glyph_string *) alloca (sizeof *s);                     \
 +      INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);             \
 +      append_glyph_string (&(HEAD), &(TAIL), s);                          \
 +      s->cmp = cmp;                                                       \
 +      s->gidx = n;                                                        \
 +      s->x = (X);                                                         \
 +      if (n == 0)                                                         \
 +        first_s = s;                                                      \
 +      n = fill_composite_glyph_string (s, base_face, overlaps);           \
 +      }                                                                           \
 +                                                                          \
 +    ++START;                                                              \
 +    s = first_s;                                                          \
    } while (0)
  
  
                 abort ();                                                 \
               }                                                           \
                                                                           \
 -             set_glyph_string_background_width (s, START, LAST_X);       \
 -           (X) += s->width;                                              \
 +           if (s)                                                        \
 +             {                                                           \
 +               set_glyph_string_background_width (s, START, LAST_X);     \
 +               (X) += s->width;                                          \
 +             }                                                           \
              }                                                            \
         }                                                                 \
       while (0)
@@@ -19789,7 -19541,7 +19790,7 @@@ draw_glyphs (w, x, row, area, start, en
       int x;
       struct glyph_row *row;
       enum glyph_row_area area;
 -     int start, end;
 +     EMACS_INT start, end;
       enum draw_glyphs_face hl;
       int overlaps;
  {
        if (i >= 0)
        {
          clip_tail = tail;
 +        i++;                  /* We must include the Ith glyph.  */
          BUILD_GLYPH_STRINGS (end, i, h, t,
                               DRAW_NORMAL_TEXT, x, last_x);
          for (s = h; s; s = s->next)
@@@ -20499,7 -20250,7 +20500,7 @@@ calc_line_height_property (it, val, fon
        struct face *face;
        struct font_info *font_info;
  
 -      face_id = lookup_named_face (it->f, face_name, ' ', 0);
 +      face_id = lookup_named_face (it->f, face_name, 0);
        if (face_id < 0)
        return make_number (-1);
  
        if (font == NULL)
        return make_number (-1);
  
 -      font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
 +      font_info = FONT_INFO_FROM_FACE (it->f, face);
        boff = font_info->baseline_offset;
        if (font_info->vertical_centering)
        boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
@@@ -20572,17 -20323,23 +20573,17 @@@ x_produce_glyphs (it
        /* Maybe translate single-byte characters to multibyte, or the
         other way.  */
        it->char_to_display = it->c;
 -      if (!ASCII_BYTE_P (it->c))
 +      if (!ASCII_BYTE_P (it->c)
 +        && ! it->multibyte_p)
        {
 -        if (unibyte_display_via_language_environment
 -            && SINGLE_BYTE_CHAR_P (it->c)
 -            && (it->c >= 0240
 -                || !NILP (Vnonascii_translation_table)))
 +        if (SINGLE_BYTE_CHAR_P (it->c)
 +            && unibyte_display_via_language_environment)
 +          it->char_to_display = unibyte_char_to_multibyte (it->c);
 +        if (! SINGLE_BYTE_CHAR_P (it->char_to_display))
            {
 -            it->char_to_display = unibyte_char_to_multibyte (it->c);
              it->multibyte_p = 1;
 -            it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
 -            face = FACE_FROM_ID (it->f, it->face_id);
 -          }
 -        else if (!SINGLE_BYTE_CHAR_P (it->c)
 -                 && !it->multibyte_p)
 -          {
 -            it->multibyte_p = 1;
 -            it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
 +            it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
 +                                         -1, Qnil);
              face = FACE_FROM_ID (it->f, it->face_id);
            }
        }
        }
        else
        {
 -        font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
 +        font_info = FONT_INFO_FROM_FACE (it->f, face);
          boff = font_info->baseline_offset;
          if (font_info->vertical_centering)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
  
          it->nglyphs = 1;
  
 -        pcm = rif->per_char_metric (font, &char2b,
 +        pcm = get_per_char_metric (font, font_info, &char2b,
                                      FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
  
          if (it->override_ascent >= 0)
  
          /* If we found a font, this font should give us the right
             metrics.  If we didn't find a font, use the frame's
 -           default font and calculate the width of the character
 -           from the charset width; this is what old redisplay code
 -           did.  */
 +           default font and calculate the width of the character by
 +           multiplying the width of font by the width of the
 +           character.  */
  
 -        pcm = rif->per_char_metric (font, &char2b,
 +        pcm = get_per_char_metric (font, font_info, &char2b,
                                      FONT_TYPE_FOR_MULTIBYTE (font, it->c));
  
          if (font_not_found_p || !pcm)
            {
 -            int charset = CHAR_CHARSET (it->char_to_display);
 -
              it->glyph_not_available_p = 1;
              it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
 -                               * CHARSET_WIDTH (charset));
 +                               * CHAR_WIDTH (it->char_to_display));
              it->phys_ascent = FONT_BASE (font) + boff;
              it->phys_descent = FONT_DESCENT (font) - boff;
            }
    else if (it->what == IT_COMPOSITION)
      {
        /* Note: A composition is represented as one glyph in the
 -       glyph matrix.  There are no padding glyphs.  */
 -      XChar2b char2b;
 -      XFontStruct *font;
 +       glyph matrix.  There are no padding glyphs.
 +
 +       Important is that pixel_width, ascent, and descent are the
 +       values of what is drawn by draw_glyphs (i.e. the values of
 +       the overall glyphs composed).  */
        struct face *face = FACE_FROM_ID (it->f, it->face_id);
 -      XCharStruct *pcm;
 -      int font_not_found_p;
 -      struct font_info *font_info;
        int boff;                       /* baseline offset */
        struct composition *cmp = composition_table[it->cmp_id];
 +      int glyph_len = cmp->glyph_len;
 +      XFontStruct *font = face->font;
  
 -      /* Maybe translate single-byte characters to multibyte.  */
 -      it->char_to_display = it->c;
 -      if (unibyte_display_via_language_environment
 -        && SINGLE_BYTE_CHAR_P (it->c)
 -        && (it->c >= 0240
 -            || (it->c >= 0200
 -                && !NILP (Vnonascii_translation_table))))
 -      {
 -        it->char_to_display = unibyte_char_to_multibyte (it->c);
 -      }
 -
 -      /* Get face and font to use.  Encode IT->char_to_display.  */
 -      it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
 -      face = FACE_FROM_ID (it->f, it->face_id);
 -      get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
 -                                &char2b, it->multibyte_p, 0);
 -      font = face->font;
 +      it->nglyphs = 1;
  
 -      /* When no suitable font found, use the default font.  */
 -      font_not_found_p = font == NULL;
 -      if (font_not_found_p)
 +#ifdef USE_FONT_BACKEND
 +      if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
        {
 -        font = FRAME_FONT (it->f);
 -        boff = FRAME_BASELINE_OFFSET (it->f);
 -        font_info = NULL;
 +        if (! cmp->font || cmp->font != font)
 +          font_prepare_composition (cmp);
        }
        else
 -      {
 -        font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
 -        boff = font_info->baseline_offset;
 -        if (font_info->vertical_centering)
 -          boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
 -      }
 -
 -      /* There are no padding glyphs, so there is only one glyph to
 -       produce for the composition.  Important is that pixel_width,
 -       ascent and descent are the values of what is drawn by
 -       draw_glyphs (i.e. the values of the overall glyphs composed).  */
 -      it->nglyphs = 1;
 -
 +#endif        /* USE_FONT_BACKEND */
        /* If we have not yet calculated pixel size data of glyphs of
         the composition for the current face font, calculate them
         now.  Theoretically, we have to check all fonts for the
         glyphs, but that requires much time and memory space.  So,
         here we check only the font of the first glyph.  This leads
 -       to incorrect display very rarely, and C-l (recenter) can
 -       correct the display anyway.  */
 -      if (cmp->font != (void *) font)
 -      {
 -        /* Ascent and descent of the font of the first character of
 -           this composition (adjusted by baseline offset).  Ascent
 -           and descent of overall glyphs should not be less than
 -           them respectively.  */
 -        int font_ascent = FONT_BASE (font) + boff;
 -        int font_descent = FONT_DESCENT (font) - boff;
 +       to incorrect display, but it's very rare, and C-l (recenter)
 +       can correct the display anyway.  */
 +      if (! cmp->font || cmp->font != font)
 +      {
 +        /* Ascent and descent of the font of the first character
 +           of this composition (adjusted by baseline offset).
 +           Ascent and descent of overall glyphs should not be less
 +           than them respectively.  */
 +        int font_ascent, font_descent, font_height;
          /* Bounding box of the overall glyphs.  */
          int leftmost, rightmost, lowest, highest;
 +        int lbearing, rbearing;
          int i, width, ascent, descent;
 +        int left_padded = 0, right_padded = 0;
 +        int face_id;
 +        int c;
 +        XChar2b char2b;
 +        XCharStruct *pcm;
 +        int font_not_found_p;
 +        struct font_info *font_info;
 +        int pos;
 +
 +        for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
 +          if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
 +            break;
 +        if (glyph_len < cmp->glyph_len)
 +          right_padded = 1;
 +        for (i = 0; i < glyph_len; i++)
 +          {
 +            if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
 +              break;
 +            cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
 +          }
 +        if (i > 0)
 +          left_padded = 1;
 +
 +        pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
 +               : IT_CHARPOS (*it));
 +        /* When no suitable font found, use the default font.  */
 +        font_not_found_p = font == NULL;
 +        if (font_not_found_p)
 +          {
 +            face = face->ascii_face;
 +            font = face->font;
 +          }
 +        font_info = FONT_INFO_FROM_FACE (it->f, face);
 +        boff = font_info->baseline_offset;
 +        if (font_info->vertical_centering)
 +          boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
 +        font_ascent = FONT_BASE (font) + boff;
 +        font_descent = FONT_DESCENT (font) - boff;
 +        font_height = FONT_HEIGHT (font);
  
          cmp->font = (void *) font;
  
 +        pcm = NULL;
 +        if (! font_not_found_p)
 +          {
 +            get_char_face_and_encoding (it->f, c, it->face_id,
 +                                        &char2b, it->multibyte_p, 0);
 +            pcm = get_per_char_metric (font, font_info, &char2b,
 +                                       FONT_TYPE_FOR_MULTIBYTE (font, c));
 +          }
 +
          /* Initialize the bounding box.  */
 -        if (font_info
 -            && (pcm = rif->per_char_metric (font, &char2b,
 -                                            FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
 +        if (pcm)
            {
              width = pcm->width;
              ascent = pcm->ascent;
              descent = pcm->descent;
 +            lbearing = pcm->lbearing;
 +            rbearing = pcm->rbearing;
            }
          else
            {
              width = FONT_WIDTH (font);
              ascent = FONT_BASE (font);
              descent = FONT_DESCENT (font);
 +            lbearing = 0;
 +            rbearing = width;
            }
  
          rightmost = width;
 +        leftmost = 0;
          lowest = - descent + boff;
          highest = ascent + boff;
 -        leftmost = 0;
  
 -        if (font_info
 +        if (! font_not_found_p
              && font_info->default_ascent
              && CHAR_TABLE_P (Vuse_default_ascent)
              && !NILP (Faref (Vuse_default_ascent,
            highest = font_info->default_ascent + boff;
  
          /* Draw the first glyph at the normal position.  It may be
 -           shifted to right later if some other glyphs are drawn at
 -           the left.  */
 -        cmp->offsets[0] = 0;
 -        cmp->offsets[1] = boff;
 +           shifted to right later if some other glyphs are drawn
 +           at the left.  */
 +        cmp->offsets[i * 2] = 0;
 +        cmp->offsets[i * 2 + 1] = boff;
 +        cmp->lbearing = lbearing;
 +        cmp->rbearing = rbearing;
  
          /* Set cmp->offsets for the remaining glyphs.  */
 -        for (i = 1; i < cmp->glyph_len; i++)
 +        for (i++; i < glyph_len; i++)
            {
              int left, right, btm, top;
              int ch = COMPOSITION_GLYPH (cmp, i);
 -            int face_id = FACE_FOR_CHAR (it->f, face, ch);
 +            int face_id;
 +            struct face *this_face;
 +            int this_boff;
 +
 +            if (ch == '\t')
 +              ch = ' ';
 +            face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
 +            this_face = FACE_FROM_ID (it->f, face_id);
 +            font = this_face->font;
  
 -            face = FACE_FROM_ID (it->f, face_id);
 -            get_char_face_and_encoding (it->f, ch, face->id,
 -                                        &char2b, it->multibyte_p, 0);
 -            font = face->font;
              if (font == NULL)
 -              {
 -                font = FRAME_FONT (it->f);
 -                boff = FRAME_BASELINE_OFFSET (it->f);
 -                font_info = NULL;
 -              }
 +              pcm = NULL;
              else
                {
 -                font_info
 -                  = FONT_INFO_FROM_ID (it->f, face->font_info_id);
 -                boff = font_info->baseline_offset;
 +                font_info = FONT_INFO_FROM_FACE (it->f, this_face);
 +                this_boff = font_info->baseline_offset;
                  if (font_info->vertical_centering)
 -                  boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
 +                  this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
 +                get_char_face_and_encoding (it->f, ch, face_id,
 +                                            &char2b, it->multibyte_p, 0);
 +                pcm = get_per_char_metric (font, font_info, &char2b,
 +                                           FONT_TYPE_FOR_MULTIBYTE (font,
 +                                                                    ch));
                }
 -
 -            if (font_info
 -                && (pcm = rif->per_char_metric (font, &char2b,
 -                                                FONT_TYPE_FOR_MULTIBYTE (font, ch))))
 +            if (! pcm)
 +              cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
 +            else
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
                  descent = pcm->descent;
 -              }
 -            else
 -              {
 -                width = FONT_WIDTH (font);
 -                ascent = 1;
 -                descent = 0;
 -              }
 +                lbearing = pcm->lbearing;
 +                rbearing = pcm->rbearing;
 +                if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
 +                  {
 +                    /* Relative composition with or without
 +                       alternate chars.  */
 +                    left = (leftmost + rightmost - width) / 2;
 +                    btm = - descent + boff;
 +                    if (font_info->relative_compose
 +                        && (! CHAR_TABLE_P (Vignore_relative_composition)
 +                            || NILP (Faref (Vignore_relative_composition,
 +                                            make_number (ch)))))
 +                      {
  
 -            if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
 -              {
 -                /* Relative composition with or without
 -                   alternate chars.  */
 -                left = (leftmost + rightmost - width) / 2;
 -                btm = - descent + boff;
 -                if (font_info && font_info->relative_compose
 -                    && (! CHAR_TABLE_P (Vignore_relative_composition)
 -                        || NILP (Faref (Vignore_relative_composition,
 -                                        make_number (ch)))))
 +                        if (- descent >= font_info->relative_compose)
 +                          /* One extra pixel between two glyphs.  */
 +                          btm = highest + 1;
 +                        else if (ascent <= 0)
 +                          /* One extra pixel between two glyphs.  */
 +                          btm = lowest - 1 - ascent - descent;
 +                      }
 +                  }
 +                else
                    {
 +                    /* A composition rule is specified by an integer
 +                       value that encodes global and new reference
 +                       points (GREF and NREF).  GREF and NREF are
 +                       specified by numbers as below:
 +
 +                       0---1---2 -- ascent
 +                       |       |
 +                       |       |
 +                       |       |
 +                       9--10--11 -- center
 +                       |       |
 +                       ---3---4---5--- baseline
 +                       |       |
 +                       6---7---8 -- descent
 +                    */
 +                    int rule = COMPOSITION_RULE (cmp, i);
 +                    int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
 +
 +                    COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
 +                    grefx = gref % 3, nrefx = nref % 3;
 +                    grefy = gref / 3, nrefy = nref / 3;
 +                    if (xoff)
 +                      xoff = font_height * (xoff - 128) / 256;
 +                    if (yoff)
 +                      yoff = font_height * (yoff - 128) / 256;
 +
 +                    left = (leftmost
 +                            + grefx * (rightmost - leftmost) / 2
 +                            - nrefx * width / 2
 +                            + xoff);
 +                
 +                    btm = ((grefy == 0 ? highest
 +                            : grefy == 1 ? 0
 +                            : grefy == 2 ? lowest
 +                            : (highest + lowest) / 2)
 +                           - (nrefy == 0 ? ascent + descent
 +                              : nrefy == 1 ? descent - boff
 +                              : nrefy == 2 ? 0
 +                              : (ascent + descent) / 2)
 +                           + yoff);
 +                  }
 +
 +                cmp->offsets[i * 2] = left;
 +                cmp->offsets[i * 2 + 1] = btm + descent;
  
 -                    if (- descent >= font_info->relative_compose)
 -                      /* One extra pixel between two glyphs.  */
 -                      btm = highest + 1;
 -                    else if (ascent <= 0)
 -                      /* One extra pixel between two glyphs.  */
 -                      btm = lowest - 1 - ascent - descent;
 +                /* Update the bounding box of the overall glyphs. */
 +                if (width > 0)
 +                  {
 +                    right = left + width;
 +                    if (left < leftmost)
 +                      leftmost = left;
 +                    if (right > rightmost)
 +                      rightmost = right;
                    }
 +                top = btm + descent + ascent;
 +                if (top > highest)
 +                  highest = top;
 +                if (btm < lowest)
 +                  lowest = btm;
 +
 +                if (cmp->lbearing > left + lbearing)
 +                  cmp->lbearing = left + lbearing;
 +                if (cmp->rbearing < left + rbearing)
 +                  cmp->rbearing = left + rbearing;
                }
 -            else
 -              {
 -                /* A composition rule is specified by an integer
 -                   value that encodes global and new reference
 -                   points (GREF and NREF).  GREF and NREF are
 -                   specified by numbers as below:
 -
 -                      0---1---2 -- ascent
 -                      |       |
 -                      |       |
 -                      |       |
 -                      9--10--11 -- center
 -                      |       |
 -                   ---3---4---5--- baseline
 -                      |       |
 -                      6---7---8 -- descent
 -                */
 -                int rule = COMPOSITION_RULE (cmp, i);
 -                int gref, nref, grefx, grefy, nrefx, nrefy;
 -
 -                COMPOSITION_DECODE_RULE (rule, gref, nref);
 -                grefx = gref % 3, nrefx = nref % 3;
 -                grefy = gref / 3, nrefy = nref / 3;
 -
 -                left = (leftmost
 -                        + grefx * (rightmost - leftmost) / 2
 -                        - nrefx * width / 2);
 -                btm = ((grefy == 0 ? highest
 -                        : grefy == 1 ? 0
 -                        : grefy == 2 ? lowest
 -                        : (highest + lowest) / 2)
 -                       - (nrefy == 0 ? ascent + descent
 -                          : nrefy == 1 ? descent - boff
 -                          : nrefy == 2 ? 0
 -                          : (ascent + descent) / 2));
 -              }
 -
 -            cmp->offsets[i * 2] = left;
 -            cmp->offsets[i * 2 + 1] = btm + descent;
 -
 -            /* Update the bounding box of the overall glyphs. */
 -            right = left + width;
 -            top = btm + descent + ascent;
 -            if (left < leftmost)
 -              leftmost = left;
 -            if (right > rightmost)
 -              rightmost = right;
 -            if (top > highest)
 -              highest = top;
 -            if (btm < lowest)
 -              lowest = btm;
            }
  
          /* If there are glyphs whose x-offsets are negative,
              for (i = 0; i < cmp->glyph_len; i++)
                cmp->offsets[i * 2] -= leftmost;
              rightmost -= leftmost;
 +            cmp->lbearing -= leftmost;
 +            cmp->rbearing -= leftmost;
 +          }
 +
 +        if (left_padded && cmp->lbearing < 0)
 +          {
 +            for (i = 0; i < cmp->glyph_len; i++)
 +              cmp->offsets[i * 2] -= cmp->lbearing;
 +            rightmost -= cmp->lbearing;
 +            cmp->rbearing -= cmp->lbearing;
 +            cmp->lbearing = 0;
 +          }
 +        if (right_padded && rightmost < cmp->rbearing)
 +          {
 +            rightmost = cmp->rbearing;
            }
  
          cmp->pixel_width = rightmost;
            cmp->descent = font_descent;
        }
  
 +      if (it->glyph_row
 +        && (cmp->lbearing < 0
 +            || cmp->rbearing > cmp->pixel_width))
 +      it->glyph_row->contains_overlapping_glyphs_p = 1;
 +
        it->pixel_width = cmp->pixel_width;
        it->ascent = it->phys_ascent = cmp->ascent;
        it->descent = it->phys_descent = cmp->descent;
@@@ -21308,8 -21011,7 +21309,8 @@@ x_insert_glyphs (start, len
    int line_height, shift_by_width, shifted_region_width;
    struct glyph_row *row;
    struct glyph *glyph;
 -  int frame_x, frame_y, hpos;
 +  int frame_x, frame_y;
 +  EMACS_INT hpos;
  
    xassert (updated_window && updated_row);
    BLOCK_INPUT;
@@@ -22259,7 -21961,7 +22260,7 @@@ cursor_in_mouse_face_p (w
  static int
  fast_find_position (w, charpos, hpos, vpos, x, y, stop)
       struct window *w;
 -     int charpos;
 +     EMACS_INT charpos;
       int *hpos, *vpos, *x, *y;
       Lisp_Object stop;
  {
  static int
  fast_find_position (w, pos, hpos, vpos, x, y, stop)
       struct window *w;
 -     int pos;
 +     EMACS_INT pos;
       int *hpos, *vpos, *x, *y;
       Lisp_Object stop;
  {
  static int
  fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
       struct window *w;
 -     int pos;
 +     EMACS_INT pos;
       Lisp_Object object;
       int *hpos, *vpos, *x, *y;
       int right_p;
diff --combined src/xfaces.c
index 9c8f02d690261148e9173dd81b48ea50536b67f3,46a95feeb452d48e54660fc4372b0fb151631610..d10dec235acf398988f6d5e4bc750d4110f740a3
@@@ -1,6 -1,6 +1,6 @@@
  /* xfaces.c -- "Face" primitives.
     Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -56,7 -56,7 +56,7 @@@ Boston, MA 02110-1301, USA.  *
     13. Whether or not a box should be drawn around characters, the box
     type, and, for simple boxes, in what color.
  
 -   14. Font or fontset pattern, or nil.  This is a special attribute.
 +   14. Font pattern, or nil.  This is a special attribute.
     When this attribute is specified, the face uses a font opened by
     that pattern as is.  In addition, all the other font-related
     attributes (1st thru 5th) are generated from the opened font name.
@@@ -72,8 -72,6 +72,8 @@@
     and is used to ensure that a font specified on the command line,
     for example, can be matched exactly.
  
 +   17. A fontset name.
 +
     Faces are frame-local by nature because Emacs allows to define the
     same named face (face names are symbols) differently for different
     frames.  Each frame has an alist of face definitions for all named
     is realized, it inherits (thus shares) a fontset of an ASCII face
     that has the same attributes other than font-related ones.
  
 -   Thus, all realized face have a realized fontset.
 +   Thus, all realized faces have a realized fontset.
  
  
     Unibyte text.
  #include <sys/stat.h>
  
  #include "lisp.h"
 +#include "character.h"
  #include "charset.h"
  #include "keyboard.h"
  #include "frame.h"
  #include "window.h"
  #include "intervals.h"
  
 +#ifdef HAVE_WINDOW_SYSTEM
 +#ifdef USE_FONT_BACKEND
 +#include "font.h"
 +#endif        /* USE_FONT_BACKEND */
 +#endif        /* HAVE_WINDOW_SYSTEM */
 +
  #ifdef HAVE_X_WINDOWS
  
  /* Compensate for a bug in Xos.h on some systems, on which it requires
@@@ -313,7 -304,6 +313,7 @@@ Lisp_Object QCinverse_video, QCforegrou
  Lisp_Object QCwidth, QCfont, QCbold, QCitalic;
  Lisp_Object QCreverse_video;
  Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
 +Lisp_Object QCfontset;
  
  /* Symbols used for attribute values.  */
  
@@@ -497,7 -487,7 +497,7 @@@ static int get_lface_attributes P_ ((st
  static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
  static unsigned char *xstrlwr P_ ((unsigned char *));
  static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
 -static void load_face_font P_ ((struct frame *, struct face *, int));
 +static void load_face_font P_ ((struct frame *, struct face *));
  static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
  static void free_face_colors P_ ((struct frame *, struct face *));
  static int face_color_gray_p P_ ((struct frame *, char *));
@@@ -510,17 -500,18 +510,17 @@@ static int font_list_1 P_ ((struct fram
                            Lisp_Object, struct font_name **));
  static int font_list P_ ((struct frame *, Lisp_Object, Lisp_Object,
                          Lisp_Object, struct font_name **));
 -static int try_font_list P_ ((struct frame *, Lisp_Object *,
 -                            Lisp_Object, Lisp_Object, struct font_name **,
 -                            int));
 +static int try_font_list P_ ((struct frame *, Lisp_Object,
 +                            Lisp_Object, Lisp_Object, struct font_name **));
  static int try_alternative_families P_ ((struct frame *f, Lisp_Object,
                                         Lisp_Object, struct font_name **));
  static int cmp_font_names P_ ((const void *, const void *));
 -static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *, int,
 -                                    struct face *, int));
 -static struct face *realize_x_face P_ ((struct face_cache *,
 -                                      Lisp_Object *, int, struct face *));
 -static struct face *realize_tty_face P_ ((struct face_cache *,
 -                                        Lisp_Object *, int));
 +static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *,
 +                                    int));
 +static struct face *realize_non_ascii_face P_ ((struct frame *, int,
 +                                              struct face *));
 +static struct face *realize_x_face P_ ((struct face_cache *, Lisp_Object *));
 +static struct face *realize_tty_face P_ ((struct face_cache *, Lisp_Object *));
  static int realize_basic_faces P_ ((struct frame *));
  static int realize_default_face P_ ((struct frame *));
  static void realize_named_face P_ ((struct frame *, Lisp_Object, int));
@@@ -530,22 -521,23 +530,22 @@@ static unsigned hash_string_case_insens
  static unsigned lface_hash P_ ((Lisp_Object *));
  static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
  static struct face_cache *make_face_cache P_ ((struct frame *));
 -static void free_realized_face P_ ((struct frame *, struct face *));
  static void clear_face_gcs P_ ((struct face_cache *));
  static void free_face_cache P_ ((struct face_cache *));
  static int face_numeric_weight P_ ((Lisp_Object));
  static int face_numeric_slant P_ ((Lisp_Object));
  static int face_numeric_swidth P_ ((Lisp_Object));
  static int face_fontset P_ ((Lisp_Object *));
 -static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int, int, int*));
  static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*,
                                    struct named_merge_point *));
  static int merge_face_ref P_ ((struct frame *, Lisp_Object, Lisp_Object *,
                               int, struct named_merge_point *));
  static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
                                         Lisp_Object, int, int));
 +static void set_lface_from_font_and_fontset P_ ((struct frame *, Lisp_Object,
 +                                               Lisp_Object, int, int));
  static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
  static struct face *make_realized_face P_ ((Lisp_Object *));
 -static void free_realized_faces P_ ((struct face_cache *));
  static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
                                     struct font_name *, int, int, int *));
  static void cache_face P_ ((struct face_cache *, struct face *, unsigned));
@@@ -984,9 -976,6 +984,9 @@@ clear_face_cache (clear_fonts_p
      {
        struct x_display_info *dpyinfo;
  
 +#ifdef USE_FONT_BACKEND
 +      if (! enable_font_backend)
 +#endif        /* USE_FONT_BACKEND */
        /* Fonts are common for frames on one display, i.e. on
         one X screen.  */
        for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
@@@ -1233,32 -1222,30 +1233,32 @@@ load_pixmap (f, name, w_ptr, h_ptr
  
  #ifdef HAVE_WINDOW_SYSTEM
  
 -/* Load font of face FACE which is used on frame F to display
 -   character C.  The name of the font to load is determined by lface
 -   and fontset of FACE.  */
 +/* Load font of face FACE which is used on frame F to display ASCII
 +   characters.  The name of the font to load is determined by lface.  */
  
  static void
 -load_face_font (f, face, c)
 +load_face_font (f, face)
       struct frame *f;
       struct face *face;
 -     int c;
  {
    struct font_info *font_info = NULL;
    char *font_name;
    int needs_overstrike;
  
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    abort ();
 +#endif        /* USE_FONT_BACKEND */
    face->font_info_id = -1;
    face->font = NULL;
 +  face->font_name = NULL;
  
 -  font_name = choose_face_font (f, face->lface, face->fontset, c,
 -                              &needs_overstrike);
 +  font_name = choose_face_font (f, face->lface, Qnil, &needs_overstrike);
    if (!font_name)
      return;
  
    BLOCK_INPUT;
 -  font_info = FS_LOAD_FACE_FONT (f, c, font_name, face);
 +  font_info = FS_LOAD_FONT (f, font_name);
    UNBLOCK_INPUT;
  
    if (font_info)
@@@ -1397,7 -1384,7 +1397,7 @@@ tty_defined_color (f, color_name, color
    color_def->green = 0;
  
    if (*color_name)
 -    status = tty_lookup_color (f, build_string (color_name), color_def, 0);
 +    status = tty_lookup_color (f, build_string (color_name), color_def, NULL);
  
    if (color_def->pixel == FACE_TTY_DEFAULT_COLOR && *color_name)
      {
@@@ -2145,7 -2132,7 +2145,7 @@@ face_value (table, dim, symbol
  static INLINE int
  face_numeric_value (table, dim, symbol)
       struct table_entry *table;
 -     int dim;
 +     size_t dim;
       Lisp_Object symbol;
  {
    struct table_entry *p = face_value (table, dim, symbol);
@@@ -2186,117 -2173,9 +2186,117 @@@ face_numeric_swidth (width
    return face_numeric_value (swidth_table, DIM (swidth_table), width);
  }
  
 -
  #ifdef HAVE_WINDOW_SYSTEM
  
 +#ifdef USE_FONT_BACKEND
 +static INLINE Lisp_Object
 +face_symbolic_value (table, dim, font_prop)
 +     struct table_entry *table;
 +     int dim;
 +     Lisp_Object font_prop;
 +{
 +  struct table_entry *p;
 +  char *s = SDATA (SYMBOL_NAME (font_prop));
 +  int low, mid, high, cmp;
 +
 +  low = 0;
 +  high = dim - 1;
 +
 +  while (low <= high)
 +    {
 +      mid = (low + high) / 2;
 +      cmp = strcmp (table[mid].name, s);
 +
 +      if (cmp < 0)
 +      low = mid + 1;
 +      else if (cmp > 0)
 +      high = mid - 1;
 +      else
 +      return *table[mid].symbol;
 +    }
 +
 +  return Qnil;
 +}
 +
 +static INLINE Lisp_Object
 +face_symbolic_weight (weight)
 +     Lisp_Object weight;
 +{
 +  return face_symbolic_value (weight_table, DIM (weight_table), weight);
 +}
 +
 +static INLINE Lisp_Object
 +face_symbolic_slant (slant)
 +     Lisp_Object slant;
 +{
 +  return face_symbolic_value (slant_table, DIM (slant_table), slant);
 +}
 +
 +static INLINE Lisp_Object
 +face_symbolic_swidth (width)
 +     Lisp_Object width;
 +{
 +  return face_symbolic_value (swidth_table, DIM (swidth_table), width);
 +}
 +#endif        /* USE_FONT_BACKEND */
 +
 +Lisp_Object
 +split_font_name_into_vector (fontname)
 +     Lisp_Object fontname;
 +{
 +  struct font_name font;
 +  Lisp_Object vec;
 +  int i;
 +
 +  font.name = LSTRDUPA (fontname);
 +  if (! split_font_name (NULL, &font, 0))
 +    return Qnil;
 +  vec = Fmake_vector (make_number (XLFD_LAST), Qnil);
 +  for (i = 0; i < XLFD_LAST; i++)
 +    if (font.fields[i][0] != '*')
 +      ASET (vec, i, build_string (font.fields[i]));
 +  return vec;
 +}
 +
 +Lisp_Object
 +build_font_name_from_vector (vec)
 +     Lisp_Object vec;
 +{
 +  struct font_name font;
 +  Lisp_Object fontname;
 +  char *p;
 +  int i;
 +
 +  for (i = 0; i < XLFD_LAST; i++)
 +    {
 +      font.fields[i] = (NILP (AREF (vec, i))
 +                      ? "*" : (char *) SDATA (AREF (vec, i)));
 +      if ((i == XLFD_FAMILY || i == XLFD_REGISTRY)
 +        && (p = strchr (font.fields[i], '-')))
 +      {
 +        char *p1 = STRDUPA (font.fields[i]);
 +
 +        p1[p - font.fields[i]] = '\0';
 +        if (i == XLFD_FAMILY)
 +          {
 +            font.fields[XLFD_FOUNDRY] = p1;
 +            font.fields[XLFD_FAMILY] = p + 1;
 +          }
 +        else
 +          {
 +            font.fields[XLFD_REGISTRY] = p1;
 +            font.fields[XLFD_ENCODING] = p + 1;
 +            break;
 +          }
 +      }
 +    }
 +
 +  p = build_font_name (&font);
 +  fontname = build_string (p);
 +  xfree (p);
 +  return fontname;
 +}
 +
  /* Return non-zero if FONT is the name of a fixed-pitch font.  */
  
  static INLINE int
@@@ -2319,9 -2198,7 +2319,9 @@@ xlfd_fixed_p (font
     72dpi versions, only.)
  
     Value is the real point size of FONT on frame F, or 0 if it cannot
 -   be determined.  */
 +   be determined.
 +
 +   By side effect, set FONT->numeric[XLFD_PIXEL_SIZE].  */
  
  static INLINE int
  xlfd_point_size (f, font)
    else
      pixel = atoi (pixel_field);
  
 +  font->numeric[XLFD_PIXEL_SIZE] = pixel;
    if (pixel == 0)
      real_pt = 0;
    else
@@@ -2847,12 -2723,12 +2847,12 @@@ cmp_font_names (a, b
  }
  
  
 -/* Get a sorted list of fonts of family FAMILY on frame F.  If PATTERN
 -   is non-nil list fonts matching that pattern.  Otherwise, if
 -   REGISTRY is non-nil return only fonts with that registry, otherwise
 -   return fonts of any registry.  Set *FONTS to a vector of font_name
 -   structures allocated from the heap containing the fonts found.
 -   Value is the number of fonts found.  */
 +/* Get a sorted list of fonts matching PATTERN on frame F.  If PATTERN
 +   is nil, list fonts matching FAMILY and REGISTRY.  FAMILY is a
 +   family name string or nil.  REGISTRY is a registry name string.
 +   Set *FONTS to a vector of font_name structures allocated from the
 +   heap containing the fonts found.  Value is the number of fonts
 +   found.  */
  
  static int
  font_list_1 (f, pattern, family, registry, fonts)
@@@ -2913,11 -2789,10 +2913,11 @@@ concat_font_list (fonts1, nfonts1, font
  
  /* Get a sorted list of fonts of family FAMILY on frame F.
  
 -   If PATTERN is non-nil list fonts matching that pattern.
 +   If PATTERN is non-nil, list fonts matching that pattern.
  
 -   If REGISTRY is non-nil, return fonts with that registry and the
 -   alternative registries from Vface_alternative_font_registry_alist.
 +   If REGISTRY is non-nil, it is a list of registry (and encoding)
 +   names.  Return fonts with those registries and the alternative
 +   registries from Vface_alternative_font_registry_alist.
  
     If REGISTRY is nil return fonts of any registry.
  
@@@ -2931,37 -2806,35 +2931,37 @@@ font_list (f, pattern, family, registry
       Lisp_Object pattern, family, registry;
       struct font_name **fonts;
  {
 -  int nfonts = font_list_1 (f, pattern, family, registry, fonts);
 +  int nfonts;
 +  int reg_prio;
 +  int i;
  
 -  if (!NILP (registry)
 -      && CONSP (Vface_alternative_font_registry_alist))
 +  if (NILP (registry))
 +    return font_list_1 (f, pattern, family, registry, fonts);
 +
 +  for (reg_prio = 0, nfonts = 0; CONSP (registry); registry = XCDR (registry))
      {
 -      Lisp_Object alter;
 +      Lisp_Object elt, alter;
 +      int nfonts2;
 +      struct font_name *fonts2;
  
 -      alter = Fassoc (registry, Vface_alternative_font_registry_alist);
 -      if (CONSP (alter))
 +      elt = XCAR (registry);
 +      alter = Fassoc (elt, Vface_alternative_font_registry_alist);
 +      if (NILP (alter))
 +      alter = Fcons (elt, Qnil);
 +      for (; CONSP (alter); alter = XCDR (alter), reg_prio++)
        {
 -        int reg_prio, i;
 -
 -        for (alter = XCDR (alter), reg_prio = 1;
 -             CONSP (alter);
 -             alter = XCDR (alter), reg_prio++)
 -          if (STRINGP (XCAR (alter)))
 -            {
 -              int nfonts2;
 -              struct font_name *fonts2;
 -
 -              nfonts2 = font_list_1 (f, pattern, family, XCAR (alter),
 -                                     &fonts2);
 +        nfonts2 = font_list_1 (f, pattern, family, XCAR (alter), &fonts2);
 +        if (nfonts2 > 0)
 +          {
 +            if (reg_prio > 0)
                for (i = 0; i < nfonts2; i++)
                  fonts2[i].registry_priority = reg_prio;
 -              *fonts = (nfonts > 0
 -                        ? concat_font_list (*fonts, nfonts, fonts2, nfonts2)
 -                        : fonts2);
 -              nfonts += nfonts2;
 -            }
 +            if (nfonts > 0)
 +              *fonts = concat_font_list (*fonts, nfonts, fonts2, nfonts2);
 +            else
 +              *fonts = fonts2;
 +            nfonts += nfonts2;
 +          }
        }
      }
  
@@@ -3143,7 -3016,7 +3143,7 @@@ the WIDTH times as wide as FACE on FRAM
      {
        /* This is of limited utility since it works with character
         widths.  Keep it for compatibility.  --gerd.  */
 -      int face_id = lookup_named_face (f, face, 0, 0);
 +      int face_id = lookup_named_face (f, face, 0);
        struct face *face = (face_id < 0
                           ? NULL
                           : FACE_FROM_ID (f, face_id));
  #define LFACE_FONT(LFACE)         AREF ((LFACE), LFACE_FONT_INDEX)
  #define LFACE_INHERIT(LFACE)      AREF ((LFACE), LFACE_INHERIT_INDEX)
  #define LFACE_AVGWIDTH(LFACE)     AREF ((LFACE), LFACE_AVGWIDTH_INDEX)
 +#define LFACE_FONTSET(LFACE)      AREF ((LFACE), LFACE_FONTSET_INDEX)
  
  /* Non-zero if LFACE is a Lisp face.  A Lisp face is a vector of size
     LFACE_VECTOR_SIZE which has the symbol `face' in slot 0.  */
@@@ -3281,12 -3153,7 +3281,12 @@@ check_lface_attrs (attrs
    xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
           || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
           || NILP (attrs[LFACE_FONT_INDEX])
 +#ifdef USE_FONT_BACKEND
 +         || FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])
 +#endif        /* USE_FONT_BACKEND */
           || STRINGP (attrs[LFACE_FONT_INDEX]));
 +  xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
 +         || STRINGP (attrs[LFACE_FONTSET_INDEX]));
  #endif
  }
  
@@@ -3478,7 -3345,7 +3478,7 @@@ lface_fully_specified_p (attrs
  
    for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
      if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
 -      && i != LFACE_AVGWIDTH_INDEX)
 +      && i != LFACE_AVGWIDTH_INDEX && i != LFACE_FONTSET_INDEX)
        if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i]))
  #ifdef MAC_OS
          /* MAC_TODO: No stipple support on Mac OS yet, this index is
@@@ -3522,15 -3389,8 +3522,15 @@@ set_lface_from_font_name (f, lface, fon
  
    /* If FONTNAME is actually a fontset name, get ASCII font name of it.  */
    fontset = fs_query_fontset (fontname, 0);
 -  if (fontset >= 0)
 +
 +  if (fontset > 0)
      font_name = SDATA (fontset_ascii (fontset));
 +  else if (fontset == 0)
 +    {
 +      if (may_fail_p)
 +      return 0;
 +      abort ();
 +    }
  
    /* Check if FONT_NAME is surely available on the system.  Usually
       FONT_NAME is already cached for the frame F and FS_LOAD_FONT
       caching it now is not futail because we anyway load the font
       later.  */
    BLOCK_INPUT;
 -  font_info = FS_LOAD_FONT (f, 0, font_name, -1);
 +  font_info = FS_LOAD_FONT (f, font_name);
    UNBLOCK_INPUT;
  
    if (!font_info)
      LFACE_SLANT (lface)
        = have_xlfd_p ? xlfd_symbolic_slant (&font) : Qnormal;
  
 -  LFACE_FONT (lface) = fontname;
 -
 +  if (fontset > 0)
 +    {
 +      LFACE_FONT (lface) = build_string (font_info->full_name);
 +      LFACE_FONTSET (lface) = fontset_name (fontset);
 +    }
 +  else
 +    {
 +      LFACE_FONT (lface) = fontname;
 +      fontset
 +      = new_fontset_from_font_name (build_string (font_info->full_name));
 +      LFACE_FONTSET (lface) = fontset_name (fontset);
 +    }
    return 1;
  }
  
 +#ifdef USE_FONT_BACKEND
 +/* Set font-related attributes of Lisp face LFACE from FONT-OBJECT and
 +   FONTSET.  If FORCE_P is zero, set only unspecified attributes of
 +   LFACE.  The exceptions are `font' and `fontset' attributes.  They
 +   are set regardless of FORCE_P.  */
 +
 +static void
 +set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p)
 +     struct frame *f;
 +     Lisp_Object lface, font_object;
 +     int fontset;
 +     int force_p;
 +{
 +  struct font *font = XSAVE_VALUE (font_object)->pointer;
 +  Lisp_Object entity = font->entity;
 +  Lisp_Object val;
 +
 +  /* Set attributes only if unspecified, otherwise face defaults for
 +     new frames would never take effect.  If the font doesn't have a
 +     specific property, set a normal value for that.  */
 +
 +  if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
 +    {
 +      Lisp_Object foundry = AREF (entity, FONT_FOUNDRY_INDEX);
 +      Lisp_Object family = AREF (entity, FONT_FAMILY_INDEX);
 +
 +      if (! NILP (foundry))
 +      {
 +        if (! NILP (family))
 +          val = concat3 (SYMBOL_NAME (foundry), build_string ("-"),
 +                         SYMBOL_NAME (family));
 +        else
 +          val = concat2 (SYMBOL_NAME (foundry), build_string ("-*"));
 +      }
 +      else
 +      {
 +        if (! NILP (family))
 +          val = SYMBOL_NAME (family);
 +        else
 +          val = build_string ("*");
 +      }
 +      LFACE_FAMILY (lface) = val;
 +    }
 +
 +  if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
 +    {
 +      int pt = pixel_point_size (f, font->pixel_size * 10);
 +
 +      xassert (pt > 0);
 +      LFACE_HEIGHT (lface) = make_number (pt);
 +    }
 +
 +  if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
 +    LFACE_AVGWIDTH (lface) = make_number (font->font.average_width);
 +
 +  if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
 +    {
 +      Lisp_Object weight = font_symbolic_weight (entity);
 +
 +      val = NILP (weight) ? Qnormal : face_symbolic_weight (weight);
 +      LFACE_WEIGHT (lface) = ! NILP (val) ? val : weight;
 +    }
 +  if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
 +    {
 +      Lisp_Object slant = font_symbolic_slant (entity);
 +
 +      val = NILP (slant) ? Qnormal : face_symbolic_slant (slant);
 +      LFACE_SLANT (lface) = ! NILP (val) ? val : slant;
 +    }
 +  if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
 +    {
 +      Lisp_Object width = font_symbolic_width (entity);
 +
 +      val = NILP (width) ? Qnormal : face_symbolic_swidth (width);
 +      LFACE_SWIDTH (lface) = ! NILP (val) ? val : width;
 +    }
 +
 +  LFACE_FONT (lface) = font_object;
 +  LFACE_FONTSET (lface) = fontset_name (fontset);
 +}
 +#endif        /* USE_FONT_BACKEND */
 +
  #endif /* HAVE_WINDOW_SYSTEM */
  
  
@@@ -4519,7 -4287,7 +4519,7 @@@ FRAME 0 means change the face on all fr
        LFACE_SWIDTH (lface) = value;
        font_related_attr_p = 1;
      }
 -  else if (EQ (attr, QCfont))
 +  else if (EQ (attr, QCfont) || EQ (attr, QCfontset))
      {
  #ifdef HAVE_WINDOW_SYSTEM
        if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
          else
            f = check_x_frame (frame);
  
 +#ifdef USE_FONT_BACKEND
 +        if (enable_font_backend
 +            && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
 +          {
 +            int fontset;
 +
 +            if (EQ (attr, QCfontset))
 +              {
 +                Lisp_Object fontset_name = Fquery_fontset (value, Qnil);
 +
 +                if (NILP (fontset_name))
 +                  signal_error ("Invalid fontset name", value);
 +                LFACE_FONTSET (lface) = value;
 +              }
 +            else
 +              {
 +                Lisp_Object font_object;
 +
 +                if (FONT_OBJECT_P (value))
 +                  {
 +                    font_object = value;
 +                    fontset = FRAME_FONTSET (f);
 +                  }
 +                else
 +                  {
 +                    CHECK_STRING (value);
 +
 +                    fontset = fs_query_fontset (value, 0);
 +                    if (fontset >= 0)
 +                      value = fontset_ascii (fontset);
 +                    else
 +                      fontset = FRAME_FONTSET (f);
 +                    font_object = font_open_by_name (f, SDATA (value));
 +                    if (NILP (font_object))
 +                      signal_error ("Invalid font", value);
 +                  }
 +                set_lface_from_font_and_fontset (f, lface, font_object,
 +                                                 fontset, 1);
 +              }
 +          }
 +        else
 +#endif        /* USE_FONT_BACKEND */
          if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
            {
              CHECK_STRING (value);
              tmp = Fquery_fontset (value, Qnil);
              if (!NILP (tmp))
                value = tmp;
 +            else if (EQ (attr, QCfontset))
 +              signal_error ("Invalid fontset name", value);
  
 -            if (!set_lface_from_font_name (f, lface, value, 1, 1))
 -              signal_error ("Invalid font or fontset name", value);
 +            if (EQ (attr, QCfont))
 +              {
 +                if (!set_lface_from_font_name (f, lface, value, 1, 1))
 +                  signal_error ("Invalid font or fontset name", value);
 +              }
 +            else
 +              LFACE_FONTSET (lface) = value;
            }
  
          font_attr_p = 1;
    if (!EQ (frame, Qt)
        && NILP (Fget (face, Qface_no_inherit))
        && (EQ (attr, QCfont)
 +        || EQ (attr, QCfontset)
          || NILP (Fequal (old_value, value))))
      {
        ++face_change_count;
  #ifdef HAVE_WINDOW_SYSTEM
  
  /* Set the `font' frame parameter of FRAME determined from `default'
 -   face attributes LFACE.  If a face or fontset name is explicitely
 +   face attributes LFACE.  If a font name is explicitely
     specfied in LFACE, use it as is.  Otherwise, determine a font name
     from the other font-related atrributes of LFACE.  In that case, if
     there's no matching font, signals an error.  */
@@@ -4772,29 -4490,12 +4772,29 @@@ set_font_frame_param (frame, lface
  
        if (STRINGP (LFACE_FONT (lface)))
        font_name = LFACE_FONT (lface);
 +#ifdef USE_FONT_BACKEND
 +      else if (enable_font_backend)
 +      {
 +        /* We set FONT_NAME to a font-object.  */
 +        if (FONT_OBJECT_P (LFACE_FONT (lface)))
 +          font_name = LFACE_FONT (lface);
 +        else
 +          {
 +            font_name = font_find_for_lface (f, &AREF (lface, 0), Qnil);
 +            if (NILP (font_name))
 +              error ("No font matches the specified attribute");
 +            font_name = font_open_for_lface (f, &AREF (lface, 0), font_name);
 +            if (NILP (font_name))
 +              error ("No font matches the specified attribute");
 +          }
 +      }
 +#endif
        else
        {
          /* Choose a font name that reflects LFACE's attributes and has
             the registry and encoding pattern specified in the default
             fontset (3rd arg: -1) for ASCII characters (4th arg: 0).  */
 -        font = choose_face_font (f, XVECTOR (lface)->contents, -1, 0, 0);
 +        font = choose_face_font (f, XVECTOR (lface)->contents, Qnil, NULL);
          if (!font)
            error ("No font matches the specified attribute");
          font_name = build_string (font);
@@@ -5177,8 -4878,6 +5177,8 @@@ frames).  If FRAME is omitted or nil, u
      value = LFACE_INHERIT (lface);
    else if (EQ (keyword, QCfont))
      value = LFACE_FONT (lface);
 +  else if (EQ (keyword, QCfontset))
 +    value = LFACE_FONTSET (lface);
    else
      signal_error ("Invalid face attribute name", keyword);
  
@@@ -5283,18 -4982,15 +5283,18 @@@ Default face attributes override any lo
     return fonts with the same size as the font of a face.  This is
     done in fontset.el.  */
  
 -DEFUN ("face-font", Fface_font, Sface_font, 1, 2, 0,
 +DEFUN ("face-font", Fface_font, Sface_font, 1, 3, 0,
         doc: /* Return the font name of face FACE, or nil if it is unspecified.
 +The font name is, by default, for ASCII characters.
  If the optional argument FRAME is given, report on face FACE in that frame.
  If FRAME is t, report on the defaults for face FACE (for new frames).
    The font default for a face is either nil, or a list
    of the form (bold), (italic) or (bold italic).
 -If FRAME is omitted or nil, use the selected frame.  */)
 -     (face, frame)
 -     Lisp_Object face, frame;
 +If FRAME is omitted or nil, use the selected frame.  And, in this case,
 +if the optional third argument CHARACTER is given,
 +return the font name used for CHARACTER.  */)
 +     (face, frame, character)
 +     Lisp_Object face, frame, character;
  {
    if (EQ (frame, Qt))
      {
    else
      {
        struct frame *f = frame_or_selected_frame (frame, 1);
 -      int face_id = lookup_named_face (f, face, 0, 1);
 +      int face_id = lookup_named_face (f, face, 1);
        struct face *face = FACE_FROM_ID (f, face_id);
 -      return face ? build_string (face->font_name) : Qnil;
 +
 +      if (! face)
 +      return Qnil;
 +#ifdef HAVE_WINDOW_SYSTEM
 +      if (FRAME_WINDOW_P (f) && !NILP (character))
 +      {
 +        CHECK_CHARACTER (character);
 +        face_id = FACE_FOR_CHAR (f, face, XINT (character), -1, Qnil);
 +        face = FACE_FROM_ID (f, face_id);
 +        return (face->font && face->font_name
 +                ? build_string (face->font_name)
 +                : Qnil);
 +      }
 +#endif
 +      return build_string (face->font_name);
      }
  }
  
@@@ -5493,8 -5175,8 +5493,8 @@@ lface_hash (v
  
  /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
     considering charsets/registries).  They do if they specify the same
 -   family, point size, weight, width, slant, and fontset.  Both LFACE1
 -   and LFACE2 must be fully-specified.  */
 +   family, point size, weight, width, slant, font, and fontset.  Both
 +   LFACE1 and LFACE2 must be fully-specified.  */
  
  static INLINE int
  lface_same_font_attributes_p (lface1, lface2)
          && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
              || (STRINGP (lface1[LFACE_FONT_INDEX])
                  && STRINGP (lface2[LFACE_FONT_INDEX])
 -                && xstricmp (SDATA (lface1[LFACE_FONT_INDEX]),
 -                             SDATA (lface2[LFACE_FONT_INDEX])))));
 +                && ! xstricmp (SDATA (lface1[LFACE_FONT_INDEX]),
 +                               SDATA (lface2[LFACE_FONT_INDEX]))))
 +        && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
 +            || (STRINGP (lface1[LFACE_FONTSET_INDEX])
 +                && STRINGP (lface2[LFACE_FONTSET_INDEX])
 +                && ! xstricmp (SDATA (lface1[LFACE_FONTSET_INDEX]),
 +                               SDATA (lface2[LFACE_FONTSET_INDEX]))))
 +        );
  }
  
  
@@@ -5546,7 -5222,7 +5546,7 @@@ make_realized_face (attr
  /* Free realized face FACE, including its X resources.  FACE may
     be null.  */
  
 -static void
 +void
  free_realized_face (f, face)
       struct frame *f;
       struct face *face;
            free_face_fontset (f, face);
          if (face->gc)
            {
 +#ifdef USE_FONT_BACKEND
 +            if (enable_font_backend && face->font_info)
 +              font_done_for_face (f, face);
 +#endif        /* USE_FONT_BACKEND */
              x_free_gc (f, face->gc);
              face->gc = 0;
            }
@@@ -5626,10 -5298,6 +5626,10 @@@ prepare_face_for_display (f, face
        }
  #endif
        face->gc = x_create_gc (f, mask, &xgcv);
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend && face->font)
 +      font_prepare_for_face (f, face);
 +#endif        /* USE_FONT_BACKEND */
        UNBLOCK_INPUT;
      }
  #endif /* HAVE_WINDOW_SYSTEM */
@@@ -5736,10 -5404,6 +5736,10 @@@ clear_face_gcs (c
          struct face *face = c->faces_by_id[i];
          if (face && face->gc)
            {
 +#ifdef USE_FONT_BACKEND
 +            if (enable_font_backend && face->font_info)
 +              font_done_for_face (c->f, face);
 +#endif        /* USE_FONT_BACKEND */
              x_free_gc (c->f, face->gc);
              face->gc = 0;
            }
@@@ -5793,10 -5457,11 +5793,10 @@@ free_realized_faces (c
  }
  
  
 -/* Free all faces realized for multibyte characters on frame F that
 -   has FONTSET.  */
 +/* Free all realized faces that are using FONTSET on frame F.  */
  
  void
 -free_realized_multibyte_face (f, fontset)
 +free_realized_faces_for_fontset (f, fontset)
       struct frame *f;
       int fontset;
  {
      {
        face = cache->faces_by_id[i];
        if (face
 -        && face != face->ascii_face
          && face->fontset == fontset)
        {
          uncache_face (cache, face);
@@@ -5870,11 -5536,10 +5870,11 @@@ free_face_cache (c
  
  
  /* Cache realized face FACE in face cache C.  HASH is the hash value
 -   of FACE.  If FACE->fontset >= 0, add the new face to the end of the
 -   collision list of the face hash table of C.  This is done because
 -   otherwise lookup_face would find FACE for every character, even if
 -   faces with the same attributes but for specific characters exist.  */
 +   of FACE.  If FACE is for ASCII characters (i.e. FACE->ascii_face ==
 +   FACE), insert the new face to the beginning of the collision list
 +   of the face hash table of C.  Otherwise, add the new face to the
 +   end of the collision list.  This way, lookup_face can quickly find
 +   that a requested face is not cached.  */
  
  static void
  cache_face (c, face, hash)
  
    face->hash = hash;
  
 -  if (face->fontset >= 0)
 +  if (face->ascii_face != face)
      {
        struct face *last = c->buckets[i];
        if (last)
@@@ -5978,14 -5643,17 +5978,14 @@@ uncache_face (c, face
  
  
  /* Look up a realized face with face attributes ATTR in the face cache
 -   of frame F.  The face will be used to display character C.  Value
 -   is the ID of the face found.  If no suitable face is found, realize
 -   a new one.  In that case, if C is a multibyte character, BASE_FACE
 -   is a face that has the same attributes.  */
 +   of frame F.  The face will be used to display ASCII characters.
 +   Value is the ID of the face found.  If no suitable face is found,
 +   realize a new one.  */
  
  INLINE int
 -lookup_face (f, attr, c, base_face)
 +lookup_face (f, attr)
       struct frame *f;
       Lisp_Object *attr;
 -     int c;
 -     struct face *base_face;
  {
    struct face_cache *cache = FRAME_FACE_CACHE (f);
    unsigned hash;
    i = hash % FACE_CACHE_BUCKETS_SIZE;
  
    for (face = cache->buckets[i]; face; face = face->next)
 -    if (face->hash == hash
 -      && (!FRAME_WINDOW_P (f)
 -          || FACE_SUITABLE_FOR_CHAR_P (face, c))
 -      && lface_equal_p (face->lface, attr))
 -      break;
 +    {
 +      if (face->ascii_face != face)
 +      {
 +        /* There's no more ASCII face.  */
 +        face = NULL;
 +        break;
 +      }
 +      if (face->hash == hash
 +        && lface_equal_p (face->lface, attr))
 +      break;
 +    }
  
    /* If not found, realize a new face.  */
    if (face == NULL)
 -    face = realize_face (cache, attr, c, base_face, -1);
 +    face = realize_face (cache, attr, -1);
  
  #if GLYPH_DEBUG
    xassert (face == FACE_FROM_ID (f, face->id));
 +#endif /* GLYPH_DEBUG */
  
 -/* When this function is called from face_for_char (in this case, C is
 -   a multibyte character), a fontset of a face returned by
 -   realize_face is not yet set, i.e. FACE_SUITABLE_FOR_CHAR_P (FACE,
 -   C) is not sutisfied.  The fontset is set for this face by
 -   face_for_char later.  */
 -#if 0
 -  if (FRAME_WINDOW_P (f))
 -    xassert (FACE_SUITABLE_FOR_CHAR_P (face, c));
 -#endif
 +  return face->id;
 +}
 +
 +#ifdef HAVE_WINDOW_SYSTEM
 +/* Look up a realized face that has the same attributes as BASE_FACE
 +   except for the font in the face cache of frame F.  If FONT_ID is
 +   not negative, it is an ID number of an already opened font that is
 +   used by the face.  If FONT_ID is negative, the face has no font.
 +   Value is the ID of the face found.  If no suitable face is found,
 +   realize a new one.  */
 +
 +int
 +lookup_non_ascii_face (f, font_id, base_face)
 +     struct frame *f;
 +     int font_id;
 +     struct face *base_face;
 +{
 +  struct face_cache *cache = FRAME_FACE_CACHE (f);
 +  unsigned hash;
 +  int i;
 +  struct face *face;
 +
 +  xassert (cache != NULL);
 +  base_face = base_face->ascii_face;
 +  hash = lface_hash (base_face->lface);
 +  i = hash % FACE_CACHE_BUCKETS_SIZE;
 +
 +  for (face = cache->buckets[i]; face; face = face->next)
 +    {
 +      if (face->ascii_face == face)
 +      continue;
 +      if (face->ascii_face == base_face
 +        && face->font_info_id == font_id)
 +      break;
 +    }
 +
 +  /* If not found, realize a new face.  */
 +  if (face == NULL)
 +    face = realize_non_ascii_face (f, font_id, base_face);
 +
 +#if GLYPH_DEBUG
 +  xassert (face == FACE_FROM_ID (f, face->id));
  #endif /* GLYPH_DEBUG */
  
    return face->id;
  }
  
 +#ifdef USE_FONT_BACKEND
 +int
 +face_for_font (f, font, base_face)
 +     struct frame *f;
 +     struct font *font;
 +     struct face *base_face;
 +{
 +  struct face_cache *cache = FRAME_FACE_CACHE (f);
 +  unsigned hash;
 +  int i;
 +  struct face *face;
 +
 +  xassert (cache != NULL);
 +  base_face = base_face->ascii_face;
 +  hash = lface_hash (base_face->lface);
 +  i = hash % FACE_CACHE_BUCKETS_SIZE;
 +
 +  for (face = cache->buckets[i]; face; face = face->next)
 +    {
 +      if (face->ascii_face == face)
 +      continue;
 +      if (face->ascii_face == base_face
 +        && face->font_info == (struct font_info *) font)
 +      return face->id;
 +    }
 +
 +  /* If not found, realize a new face.  */
 +  face = realize_non_ascii_face (f, -1, base_face);
 +  face->font = font->font.font;
 +  face->font_info = (struct font_info *) font;
 +  face->font_info_id = 0;
 +  face->font_name = font->font.full_name;
 +  return face->id;
 +}
 +#endif        /* USE_FONT_BACKEND */
 +
 +#endif        /* HAVE_WINDOW_SYSTEM */
  
  /* Return the face id of the realized face for named face SYMBOL on
 -   frame F suitable for displaying character C.  Value is -1 if the
 -   face couldn't be determined, which might happen if the default face
 -   isn't realized and cannot be realized.  */
 +   frame F suitable for displaying ASCII characters.  Value is -1 if
 +   the face couldn't be determined, which might happen if the default
 +   face isn't realized and cannot be realized.  */
  
  int
 -lookup_named_face (f, symbol, c, signal_p)
 +lookup_named_face (f, symbol, signal_p)
       struct frame *f;
       Lisp_Object symbol;
 -     int c;
       int signal_p;
  {
    Lisp_Object attrs[LFACE_VECTOR_SIZE];
    bcopy (default_face->lface, attrs, sizeof attrs);
    merge_face_vectors (f, symbol_attrs, attrs, 0);
  
 -  return lookup_face (f, attrs, c, NULL);
 +  return lookup_face (f, attrs);
  }
  
  
@@@ -6152,7 -5744,7 +6152,7 @@@ ascii_face_of_lisp_face (f, lface_id
    if (lface_id >= 0 && lface_id < lface_id_to_name_size)
      {
        Lisp_Object face_name = lface_id_to_name[lface_id];
 -      face_id = lookup_named_face (f, face_name, 0, 1);
 +      face_id = lookup_named_face (f, face_name, 1);
      }
    else
      face_id = -1;
@@@ -6200,7 -5792,7 +6200,7 @@@ smaller_face (f, face_id, steps
        /* Look up a face for a slightly smaller/larger font.  */
        pt += delta;
        attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
 -      new_face_id = lookup_face (f, attrs, 0, NULL);
 +      new_face_id = lookup_face (f, attrs);
        new_face = FACE_FROM_ID (f, new_face_id);
  
        /* If height changes, count that as one step.  */
@@@ -6243,7 -5835,7 +6243,7 @@@ face_with_height (f, face_id, height
    face = FACE_FROM_ID (f, face_id);
    bcopy (face->lface, attrs, sizeof attrs);
    attrs[LFACE_HEIGHT_INDEX] = make_number (height);
 -  face_id = lookup_face (f, attrs, 0, NULL);
 +  face_id = lookup_face (f, attrs);
  #endif /* HAVE_WINDOW_SYSTEM */
  
    return face_id;
  
  
  /* Return the face id of the realized face for named face SYMBOL on
 -   frame F suitable for displaying character C, and use attributes of
 -   the face FACE_ID for attributes that aren't completely specified by
 -   SYMBOL.  This is like lookup_named_face, except that the default
 -   attributes come from FACE_ID, not from the default face.  FACE_ID
 -   is assumed to be already realized.  */
 +   frame F suitable for displaying ASCII characters, and use
 +   attributes of the face FACE_ID for attributes that aren't
 +   completely specified by SYMBOL.  This is like lookup_named_face,
 +   except that the default attributes come from FACE_ID, not from the
 +   default face.  FACE_ID is assumed to be already realized.  */
  
  int
 -lookup_derived_face (f, symbol, c, face_id, signal_p)
 +lookup_derived_face (f, symbol, face_id, signal_p)
       struct frame *f;
       Lisp_Object symbol;
 -     int c;
       int face_id;
       int signal_p;
  {
    get_lface_attributes (f, symbol, symbol_attrs, signal_p);
    bcopy (default_face->lface, attrs, sizeof attrs);
    merge_face_vectors (f, symbol_attrs, attrs, 0);
 -  return lookup_face (f, attrs, c, default_face);
 +  return lookup_face (f, attrs);
  }
  
  DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
@@@ -6361,7 -5954,6 +6361,7 @@@ x_supports_face_attributes_p (f, attrs
        || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
        || !UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX]))
      {
 +      int face_id;
        struct face *face;
        Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
  
  
        merge_face_vectors (f, attrs, merged_attrs, 0);
  
 -      face = FACE_FROM_ID (f, lookup_face (f, merged_attrs, 0, 0));
 +      face_id = lookup_face (f, merged_attrs);
 +      face = FACE_FROM_ID (f, face_id);
  
        if (! face)
        error ("Cannot make face");
@@@ -6652,7 -6243,7 +6652,7 @@@ face for italic.  */
                            Font selection
   ***********************************************************************/
  
 -DEFUN ("internal-set-font-selection-order",
 + DEFUN ("internal-set-font-selection-order",
         Finternal_set_font_selection_order,
         Sinternal_set_font_selection_order, 1, 1, 0,
         doc: /* Set font selection order for face font selection to ORDER.
@@@ -6708,10 -6299,6 +6708,10 @@@ Value is ORDER.  */
        free_all_realized_faces (Qnil);
      }
  
 +#ifdef USE_FONT_BACKEND
 +  font_update_sort_order (font_sort_order);
 +#endif        /* USE_FONT_BACKEND */
 +
    return Qnil;
  }
  
@@@ -6902,12 -6489,6 +6902,12 @@@ build_scalable_font_name (f, font, spec
    double resy = FRAME_X_DISPLAY_INFO (f)->resy;
    double pt;
  
 +  if (font->numeric[XLFD_PIXEL_SIZE] != 0
 +      || font->numeric[XLFD_POINT_SIZE] != 0)
 +    /* This is a scalable font but is requested for a specific size.
 +       We should not change that size.  */
 +    return build_font_name (font);
 +
    /* If scalable font is for a specific resolution, compute
       the point size we must specify from the resolution of
       the display and the specified resolution of the font.  */
@@@ -7180,62 -6761,78 +7180,62 @@@ try_alternative_families (f, family, re
  
  /* Get a list of matching fonts on frame F.
  
 -   FAMILY, if a string, specifies a font family derived from the fontset.
 -   It is only used if the face does not specify any family in ATTRS or
 -   if we cannot find any font of the face's family.
 +   PATTERN, if a string, specifies a font name pattern to match while
 +   ignoring FAMILY and REGISTRY.
  
 -   REGISTRY, if a string, specifies a font registry and encoding to
 -   match.  A value of nil means include fonts of any registry and
 -   encoding.
 +   FAMILY, if a list, specifies a list of font families to try.
  
 -   If PREFER_FACE_FAMILY is nonzero, perfer face's family to FAMILY.
 -   Otherwise, prefer FAMILY.
 +   REGISTRY, if a list, specifies a list of font registries and
 +   encodinging to try.
  
     Return in *FONTS a pointer to a vector of font_name structures for
     the fonts matched.  Value is the number of fonts found.  */
  
  static int
 -try_font_list (f, attrs, family, registry, fonts, prefer_face_family)
 +try_font_list (f, pattern, family, registry, fonts)
       struct frame *f;
 -     Lisp_Object *attrs;
 -     Lisp_Object family, registry;
 +     Lisp_Object pattern, family, registry;
       struct font_name **fonts;
 -     int prefer_face_family;
  {
    int nfonts = 0;
 -  Lisp_Object face_family = attrs[LFACE_FAMILY_INDEX];
 -  Lisp_Object try_family;
 -
 -  try_family = (prefer_face_family || NILP (family)) ? face_family : family;
 -
 -  if (STRINGP (try_family))
 -    nfonts = try_alternative_families (f, try_family, registry, fonts);
  
 -#ifdef MAC_OS
 -  if (nfonts == 0 && STRINGP (try_family) && STRINGP (registry))
 -    {
 -      if (xstricmp (SDATA (registry), "mac-roman") == 0)
 -      /* When realizing the default face and a font spec does not
 -         matched exactly, Emacs looks for ones with the same registry
 -         as the default font.  On the Mac, this is mac-roman, which
 -         does not work if the family is -etl-fixed, e.g.  The
 -         following widens the choices and fixes that problem.  */
 -      nfonts = try_alternative_families (f, try_family, Qnil, fonts);
 -      else if (SBYTES (try_family) > 0
 -             && SREF (try_family, SBYTES (try_family) - 1) != '*')
 -      /* Some Central European/Cyrillic font family names have the
 -         Roman counterpart name as their prefix.  */
 -      nfonts = try_alternative_families (f, concat2 (try_family,
 -                                                     build_string ("*")),
 -                                         registry, fonts);
 +  if (STRINGP (pattern))
 +    {
 +      nfonts = font_list (f, pattern, Qnil, Qnil, fonts);
 +      if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt))
 +      {
 +        int count = SPECPDL_INDEX ();
 +        specbind (Qscalable_fonts_allowed, Qt);
 +        nfonts = font_list (f, pattern, Qnil, Qnil, fonts);
 +        unbind_to (count, Qnil);
 +      }
      }
 -#endif
 +  else
 +    {
 +      Lisp_Object tail;
  
 -  if (EQ (try_family, family))
 -    family = face_family;
 +      if (NILP (family))
 +      nfonts = font_list (f, Qnil, Qnil, registry, fonts);
 +      else
 +      for (tail = family; ! nfonts && CONSP (tail); tail = XCDR (tail))
 +        nfonts = try_alternative_families (f, XCAR (tail), registry, fonts);
  
 -  if (nfonts == 0 && STRINGP (family))
 -    nfonts = try_alternative_families (f, family, registry, fonts);
 +      /* Try font family of the default face or "fixed".  */
 +      if (nfonts == 0 && !NILP (family))
 +      {
 +        struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
 +        if (default_face)
 +          family = default_face->lface[LFACE_FAMILY_INDEX];
 +        else
 +          family = build_string ("fixed");
 +        nfonts = try_alternative_families (f, family, registry, fonts);
 +      }
  
 -  /* Try font family of the default face or "fixed".  */
 -  if (nfonts == 0)
 -    {
 -      struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
 -      if (default_face)
 -      family = default_face->lface[LFACE_FAMILY_INDEX];
 -      else
 -      family = build_string ("fixed");
 -      nfonts = font_list (f, Qnil, family, registry, fonts);
 +      /* Try any family with the given registry.  */
 +      if (nfonts == 0 && !NILP (family))
 +      nfonts = try_alternative_families (f, Qnil, registry, fonts);
      }
  
 -  /* Try any family with the given registry.  */
 -  if (nfonts == 0)
 -    nfonts = try_alternative_families (f, Qnil, registry, fonts);
 -
    return nfonts;
  }
  
@@@ -7250,108 -6847,63 +7250,108 @@@ face_fontset (attrs
  {
    Lisp_Object name;
  
 -  name = attrs[LFACE_FONT_INDEX];
 +  name = attrs[LFACE_FONTSET_INDEX];
    if (!STRINGP (name))
      return -1;
    return fs_query_fontset (name, 0);
  }
  
  
 -/* Choose a name of font to use on frame F to display character C with
 +/* Choose a name of font to use on frame F to display characters with
     Lisp face attributes specified by ATTRS.  The font name is
 -   determined by the font-related attributes in ATTRS and the name
 -   pattern for C in FONTSET.  Value is the font name which is
 -   allocated from the heap and must be freed by the caller, or NULL if
 -   we can get no information about the font name of C.  It is assured
 -   that we always get some information for a single byte
 -   character.
 +   determined by the font-related attributes in ATTRS and FONT-SPEC
 +   (if specified).
  
 -   If NEEDS_OVERSTRIKE is non-zero, a boolean is returned in it to
 -   indicate whether the resulting font should be drawn using overstrike
 -   to simulate bold-face.  */
 +   When we are choosing a font for ASCII characters, FONT-SPEC is
 +   always nil.  Otherwise FONT-SPEC is a list
 +      [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
 +   or a string specifying a font name pattern.
  
 -static char *
 -choose_face_font (f, attrs, fontset, c, needs_overstrike)
 +   If NEEDS_OVERSTRIKE is not NULL, a boolean is returned in it to
 +   indicate whether the resulting font should be drawn using
 +   overstrike to simulate bold-face.
 +
 +   Value is the font name which is allocated from the heap and must be
 +   freed by the caller.  */
 +
 +char *
 +choose_face_font (f, attrs, font_spec, needs_overstrike)
       struct frame *f;
       Lisp_Object *attrs;
 -     int fontset, c;
 +     Lisp_Object font_spec;
       int *needs_overstrike;
  {
 -  Lisp_Object pattern;
 +  Lisp_Object pattern, family, adstyle, registry;
    char *font_name = NULL;
    struct font_name *fonts;
 -  int nfonts, width_ratio;
 +  int nfonts;
  
    if (needs_overstrike)
      *needs_overstrike = 0;
  
 -  /* Get (foundry and) family name and registry (and encoding) name of
 -     a font for C.  */
 -  pattern = fontset_font_pattern (f, fontset, c);
 -  if (NILP (pattern))
 +  /* If we are choosing an ASCII font and a font name is explicitly
 +     specified in ATTRS, return it.  */
 +  if (NILP (font_spec) && STRINGP (attrs[LFACE_FONT_INDEX]))
 +    return xstrdup (SDATA (attrs[LFACE_FONT_INDEX]));
 +
 +  if (NILP (attrs[LFACE_FAMILY_INDEX]))
 +    family = Qnil;
 +  else
 +    family = Fcons (attrs[LFACE_FAMILY_INDEX], Qnil);
 +
 +  /* Decide FAMILY, ADSTYLE, and REGISTRY from FONT_SPEC.  But,
 +     ADSTYLE is not used in the font selector for the moment.  */
 +  if (VECTORP (font_spec))
      {
 -      xassert (!SINGLE_BYTE_CHAR_P (c));
 -      return NULL;
 +      pattern = Qnil;
 +      if (STRINGP (AREF (font_spec, FONT_SPEC_FAMILY_INDEX)))
 +      family = Fcons (AREF (font_spec, FONT_SPEC_FAMILY_INDEX), family);
 +      adstyle = AREF (font_spec, FONT_SPEC_ADSTYLE_INDEX);
 +      registry = Fcons (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX), Qnil);
 +    }
 +  else if (STRINGP (font_spec))
 +    {
 +      pattern = font_spec;
 +      family = Qnil;
 +      adstyle = Qnil;
 +      registry = Qnil;
 +    }
 +  else
 +    {
 +      /* We are choosing an ASCII font.  By default, use the registry
 +       name "iso8859-1".  But, if the registry name of the ASCII
 +       font specified in the fontset of ATTRS is not "iso8859-1"
 +       (e.g "iso10646-1"), use also that name with higher
 +       priority.  */
 +      int fontset = face_fontset (attrs);
 +      Lisp_Object ascii;
 +      int len;
 +      struct font_name font;
 +
 +      pattern = Qnil;
 +      adstyle = Qnil;
 +      registry = Fcons (build_string ("iso8859-1"), Qnil);
 +
 +      ascii = fontset_ascii (fontset);
 +      len = SBYTES (ascii);
 +      if (len < 9
 +        || strcmp (SDATA (ascii) + len - 9, "iso8859-1"))
 +      {
 +        font.name = LSTRDUPA (ascii);
 +        /* Check if the name is in XLFD.  */
 +        if (split_font_name (f, &font, 0))
 +          {
 +            font.fields[XLFD_ENCODING][-1] = '-';
 +            registry = Fcons (build_string (font.fields[XLFD_REGISTRY]),
 +                              registry);
 +          }
 +      }
      }
 -
 -  /* If what we got is a name pattern, return it.  */
 -  if (STRINGP (pattern))
 -    return xstrdup (SDATA (pattern));
  
    /* Get a list of fonts matching that pattern and choose the
       best match for the specified face attributes from it.  */
 -  nfonts = try_font_list (f, attrs, XCAR (pattern), XCDR (pattern), &fonts,
 -                        (SINGLE_BYTE_CHAR_P (c)
 -                         || CHAR_CHARSET (c) == charset_latin_iso8859_1));
 -  width_ratio = (SINGLE_BYTE_CHAR_P (c)
 -               ? 1
 -               : CHARSET_WIDTH (CHAR_CHARSET (c)));
 -  font_name = best_matching_font (f, attrs, fonts, nfonts, width_ratio,
 +  nfonts = try_font_list (f, pattern, family, registry, &fonts);
 +  font_name = best_matching_font (f, attrs, fonts, nfonts, NILP (font_spec),
                                  needs_overstrike);
    return font_name;
  }
@@@ -7439,27 -6991,12 +7439,27 @@@ realize_default_face (f
  #ifdef HAVE_WINDOW_SYSTEM
    if (FRAME_WINDOW_P (f))
      {
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend)
 +      {
 +        frame_font = font_find_object (FRAME_FONT_OBJECT (f));
 +        xassert (FONT_OBJECT_P (frame_font));
 +        set_lface_from_font_and_fontset (f, lface, frame_font,
 +                                         FRAME_FONTSET (f),
 +                                         f->default_face_done_p);
 +      }
 +      else
 +      {
 +#endif        /* USE_FONT_BACKEND */
        /* Set frame_font to the value of the `font' frame parameter.  */
        frame_font = Fassq (Qfont, f->param_alist);
        xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
        frame_font = XCDR (frame_font);
        set_lface_from_font_name (f, lface, frame_font,
                                  f->default_face_done_p, 1);
 +#ifdef USE_FONT_BACKEND
 +      }
 +#endif        /* USE_FONT_BACKEND */
        f->default_face_done_p = 1;
      }
  #endif /* HAVE_WINDOW_SYSTEM */
    xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
    check_lface (lface);
    bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
 -  face = realize_face (c, attrs, 0, NULL, DEFAULT_FACE_ID);
 +  face = realize_face (c, attrs, DEFAULT_FACE_ID);
  
  #ifdef HAVE_WINDOW_SYSTEM
  #ifdef HAVE_X_WINDOWS
@@@ -7586,19 -7123,23 +7586,19 @@@ realize_named_face (f, symbol, id
    merge_face_vectors (f, symbol_attrs, attrs, 0);
  
    /* Realize the face.  */
 -  new_face = realize_face (c, attrs, 0, NULL, id);
 +  new_face = realize_face (c, attrs, id);
  }
  
  
  /* Realize the fully-specified face with attributes ATTRS in face
 -   cache CACHE for character C.  If C is a multibyte character,
 -   BASE_FACE is a face that has the same attributes.  Otherwise,
 -   BASE_FACE is ignored.  If FORMER_FACE_ID is non-negative, it is an
 -   ID of face to remove before caching the new face.  Value is a
 -   pointer to the newly created realized face.  */
 +   cache CACHE for ASCII characters.  If FORMER_FACE_ID is
 +   non-negative, it is an ID of face to remove before caching the new
 +   face.  Value is a pointer to the newly created realized face.  */
  
  static struct face *
 -realize_face (cache, attrs, c, base_face, former_face_id)
 +realize_face (cache, attrs, former_face_id)
       struct face_cache *cache;
       Lisp_Object *attrs;
 -     int c;
 -     struct face *base_face;
       int former_face_id;
  {
    struct face *face;
      }
  
    if (FRAME_WINDOW_P (cache->f))
 -    face = realize_x_face (cache, attrs, c, base_face);
 +    face = realize_x_face (cache, attrs);
    else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
 -    face = realize_tty_face (cache, attrs, c);
 +    face = realize_tty_face (cache, attrs);
    else
      abort ();
  
    /* Insert the new face.  */
    cache_face (cache, face, lface_hash (attrs));
 +  return face;
 +}
 +
 +
  #ifdef HAVE_WINDOW_SYSTEM
 -  if (FRAME_WINDOW_P (cache->f) && face->font == NULL)
 -    load_face_font (cache->f, face, c);
 -#endif  /* HAVE_WINDOW_SYSTEM */
 +/* Realize the fully-specified face that has the same attributes as
 +   BASE_FACE except for the font on frame F.  If FONT_ID is not
 +   negative, it is an ID number of an already opened font that should
 +   be used by the face.  If FONT_ID is negative, the face has no font,
 +   i.e., characters are displayed by empty boxes.  */
 +
 +static struct face *
 +realize_non_ascii_face (f, font_id, base_face)
 +     struct frame *f;
 +     int font_id;
 +     struct face *base_face;
 +{
 +  struct face_cache *cache = FRAME_FACE_CACHE (f);
 +  struct face *face;
 +  struct font_info *font_info;
 +
 +  face = (struct face *) xmalloc (sizeof *face);
 +  *face = *base_face;
 +  face->gc = 0;
 +#ifdef USE_FONT_BACKEND
 +  face->extra = NULL;
 +#endif
 +
 +  /* Don't try to free the colors copied bitwise from BASE_FACE.  */
 +  face->colors_copied_bitwise_p = 1;
 +
 +  face->font_info_id = font_id;
 +  if (font_id >= 0)
 +    {
 +      font_info = FONT_INFO_FROM_ID (f, font_id);
 +      face->font = font_info->font;
 +      face->font_name = font_info->full_name;
 +    }
 +  else
 +    {
 +      face->font = NULL;
 +      face->font_name = NULL;
 +    }
 +
 +  face->gc = 0;
 +
 +  cache_face (cache, face, face->hash);
 +
    return face;
  }
 +#endif        /* HAVE_WINDOW_SYSTEM */
  
  
  /* Realize the fully-specified face with attributes ATTRS in face
 -   cache CACHE for character C.  Do it for X frame CACHE->f.  If C is
 -   a multibyte character, BASE_FACE is a face that has the same
 -   attributes.  Otherwise, BASE_FACE is ignored.  If the new face
 -   doesn't share font with the default face, a fontname is allocated
 -   from the heap and set in `font_name' of the new face, but it is not
 -   yet loaded here.  Value is a pointer to the newly created realized
 -   face.  */
 +   cache CACHE for ASCII characters.  Do it for X frame CACHE->f.  If
 +   the new face doesn't share font with the default face, a fontname
 +   is allocated from the heap and set in `font_name' of the new face,
 +   but it is not yet loaded here.  Value is a pointer to the newly
 +   created realized face.  */
  
  static struct face *
 -realize_x_face (cache, attrs, c, base_face)
 +realize_x_face (cache, attrs)
       struct face_cache *cache;
       Lisp_Object *attrs;
 -     int c;
 -     struct face *base_face;
  {
    struct face *face = NULL;
  #ifdef HAVE_WINDOW_SYSTEM
    Lisp_Object stipple, overline, strike_through, box;
  
    xassert (FRAME_WINDOW_P (cache->f));
 -  xassert (SINGLE_BYTE_CHAR_P (c)
 -         || base_face);
  
    /* Allocate a new realized face.  */
    face = make_realized_face (attrs);
 +  face->ascii_face = face;
  
    f = cache->f;
  
 -  /* If C is a multibyte character, we share all face attirbutes with
 -     BASE_FACE including the realized fontset.  But, we must load a
 -     different font.  */
 -  if (!SINGLE_BYTE_CHAR_P (c))
 -    {
 -      bcopy (base_face, face, sizeof *face);
 -      face->gc = 0;
 -
 -      /* Don't try to free the colors copied bitwise from BASE_FACE.  */
 -      face->colors_copied_bitwise_p = 1;
 -
 -      /* to force realize_face to load font */
 -      face->font = NULL;
 -      return face;
 -    }
 -
 -  /* Now we are realizing a face for ASCII (and unibyte) characters.  */
 -
    /* Determine the font to use.  Most of the time, the font will be
       the same as the font of the default face, so try that first.  */
    default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
    if (default_face
 -      && FACE_SUITABLE_FOR_CHAR_P (default_face, c)
        && lface_same_font_attributes_p (default_face->lface, attrs))
      {
        face->font = default_face->font;
 -      face->fontset = default_face->fontset;
        face->font_info_id = default_face->font_info_id;
 +#ifdef USE_FONT_BACKEND
 +      face->font_info = default_face->font_info;
 +#endif        /* USE_FONT_BACKEND */
        face->font_name = default_face->font_name;
 -      face->ascii_face = face;
 -
 -      /* But, as we can't share the fontset, make a new realized
 -       fontset that has the same base fontset as of the default
 -       face.  */
        face->fontset
 -      = make_fontset_for_ascii_face (f, default_face->fontset);
 +      = make_fontset_for_ascii_face (f, default_face->fontset, face);
      }
    else
      {
         are constructed from ATTRS.  */
        int fontset = face_fontset (attrs);
  
 -      if ((fontset == -1) && default_face)
 +      /* If we are realizing the default face, ATTRS should specify a
 +       fontset.  In other words, if FONTSET is -1, we are not
 +       realizing the default face, thus the default face should have
 +       already been realized.  */
 +      if (fontset == -1)
        fontset = default_face->fontset;
 -      face->fontset = make_fontset_for_ascii_face (f, fontset);
 -      face->font = NULL;      /* to force realize_face to load font */
 +      if (fontset == -1)
 +      abort ();
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend)
 +      font_load_for_face (f, face);
 +      else
 +#endif        /* USE_FONT_BACKEND */
 +      load_face_font (f, face);
 +      if (face->font)
 +      face->fontset = make_fontset_for_ascii_face (f, fontset, face);
 +      else
 +      face->fontset = -1;
      }
  
    /* Load colors, and set remaining attributes.  */
    stipple = attrs[LFACE_STIPPLE_INDEX];
    if (!NILP (stipple))
      face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
 -
 -  xassert (FACE_SUITABLE_FOR_CHAR_P (face, c));
  #endif /* HAVE_WINDOW_SYSTEM */
 +
    return face;
  }
  
@@@ -7969,13 -7479,14 +7969,13 @@@ map_tty_color (f, face, idx, defaulted
  
  
  /* Realize the fully-specified face with attributes ATTRS in face
 -   cache CACHE for character C.  Do it for TTY frame CACHE->f.  Value is a
 -   pointer to the newly created realized face.  */
 +   cache CACHE for ASCII characters.  Do it for TTY frame CACHE->f.
 +   Value is a pointer to the newly created realized face.  */
  
  static struct face *
 -realize_tty_face (cache, attrs, c)
 +realize_tty_face (cache, attrs)
       struct face_cache *cache;
       Lisp_Object *attrs;
 -     int c;
  {
    struct face *face;
    int weight, slant;
@@@ -8068,7 -7579,7 +8068,7 @@@ compute_char_face (f, ch, prop
    if (NILP (prop))
      {
        struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
 -      face_id = FACE_FOR_CHAR (f, face, ch);
 +      face_id = FACE_FOR_CHAR (f, face, ch, -1, Qnil);
      }
    else
      {
        struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
        bcopy (default_face->lface, attrs, sizeof attrs);
        merge_face_ref (f, prop, attrs, 1, 0);
 -      face_id = lookup_face (f, attrs, ch, NULL);
 +      face_id = lookup_face (f, attrs);
      }
  
    return face_id;
@@@ -8193,7 -7704,7 +8193,7 @@@ face_at_buffer_position (w, pos, region
  
    /* Look up a realized face with the given face attributes,
       or realize a new one for ASCII characters.  */
 -  return lookup_face (f, attrs, 0, NULL);
 +  return lookup_face (f, attrs);
  }
  
  
@@@ -8289,7 -7800,7 +8289,7 @@@ face_at_string_position (w, string, pos
  
    /* Look up a realized face with the given face attributes,
       or realize a new one for ASCII characters.  */
 -  return lookup_face (f, attrs, 0, NULL);
 +  return lookup_face (f, attrs);
  }
  
  
@@@ -8326,7 -7837,7 +8326,7 @@@ merge_faces (f, face_name, face_id, bas
        if (face_id < 0 || face_id >= lface_id_to_name_size)
        return base_face_id;
        face_name = lface_id_to_name[face_id];
 -      face_id = lookup_derived_face (f, face_name, 0, base_face_id, 1);
 +      face_id = lookup_derived_face (f, face_name, base_face_id, 1);
        if (face_id >= 0)
        return face_id;
        return base_face_id;
  
    /* Look up a realized face with the given face attributes,
       or realize a new one for ASCII characters.  */
 -  return lookup_face (f, attrs, 0, NULL);
 +  return lookup_face (f, attrs);
  }
  
  \f
@@@ -8391,6 -7902,7 +8391,6 @@@ dump_realized_face (face
           face->underline_p,
           SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
    fprintf (stderr, "hash: %d\n", face->hash);
 -  fprintf (stderr, "charset: %d\n", face->charset);
  }
  
  
@@@ -8483,8 -7995,6 +8483,8 @@@ syms_of_xfaces (
    staticpro (&QCwidth);
    QCfont = intern (":font");
    staticpro (&QCfont);
 +  QCfontset = intern (":fontset");
 +  staticpro (&QCfontset);
    QCbold = intern (":bold");
    staticpro (&QCbold);
    QCitalic = intern (":italic");
diff --combined src/xfns.c
index 2b9e656b9f1f77746dbd27bb1761f2c4fb10225c,47e78222cbf2e1c383e431efefb51329cafc1c9e..74f20357657d9327477a41e7598516ba8cb68fcc
@@@ -1,6 -1,6 +1,6 @@@
  /* Functions for the X window system.
     Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-                  2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -41,7 -41,6 +41,7 @@@ Boston, MA 02110-1301, USA.  *
  #include "keyboard.h"
  #include "blockinput.h"
  #include <epaths.h>
 +#include "character.h"
  #include "charset.h"
  #include "coding.h"
  #include "fontset.h"
  #include "termhooks.h"
  #include "atimer.h"
  
 +#ifdef USE_FONT_BACKEND
 +#include "font.h"
 +#endif        /* USE_FONT_BACKEND */
 +
  #ifdef HAVE_X_WINDOWS
  
  #include <ctype.h>
@@@ -545,8 -540,6 +545,8 @@@ x_top_window_to_frame (dpyinfo, wdesc
  
  \f
  
 +static void x_default_font_parameter P_ ((struct frame *, Lisp_Object));
 +
  static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
  static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
  
@@@ -1546,30 -1539,51 +1546,30 @@@ x_encode_text (string, coding_system, s
       int selectionp;
       int *freep;
  {
 -  unsigned char *str = SDATA (string);
 -  int chars = SCHARS (string);
 -  int bytes = SBYTES (string);
 -  int charset_info;
 -  int bufsize;
 -  unsigned char *buf;
 +  int result = string_xstring_p (string);
    struct coding_system coding;
 -  extern Lisp_Object Qcompound_text_with_extensions;
  
 -  charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
 -  if (charset_info == 0)
 +  if (result == 0)
      {
        /* No multibyte character in OBJ.  We need not encode it.  */
 -      *text_bytes = bytes;
 +      *text_bytes = SBYTES (string);
        *stringp = 1;
        *freep = 0;
 -      return str;
 +      return SDATA (string);
      }
  
    setup_coding_system (coding_system, &coding);
 -  if (selectionp
 -      && SYMBOLP (coding.pre_write_conversion)
 -      && !NILP (Ffboundp (coding.pre_write_conversion)))
 -    {
 -      string = run_pre_post_conversion_on_str (string, &coding, 1);
 -      str = SDATA (string);
 -      chars = SCHARS (string);
 -      bytes = SBYTES (string);
 -    }
 -  coding.src_multibyte = 1;
 -  coding.dst_multibyte = 0;
 -  coding.mode |= CODING_MODE_LAST_BLOCK;
 -  if (coding.type == coding_type_iso2022)
 -    coding.flags |= CODING_FLAG_ISO_SAFE;
 +  coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
    /* We suppress producing escape sequences for composition.  */
 -  coding.composing = COMPOSITION_DISABLED;
 -  bufsize = encoding_buffer_size (&coding, bytes);
 -  buf = (unsigned char *) xmalloc (bufsize);
 -  encode_coding (&coding, str, buf, bytes, bufsize);
 +  coding.common_flags &= ~CODING_ANNOTATION_MASK;
 +  coding.dst_bytes = SCHARS (string) * 2;
 +  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
 +  encode_coding_object (&coding, string, 0, 0,
 +                      SCHARS (string), SBYTES (string), Qnil);
    *text_bytes = coding.produced;
 -  *stringp = (charset_info == 1
 -            || (!EQ (coding_system, Qcompound_text)
 -                && !EQ (coding_system, Qcompound_text_with_extensions)));
 +  *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
    *freep = 1;
 -  return buf;
 +  return coding.destination;
  }
  
  \f
@@@ -1938,7 -1952,6 +1938,7 @@@ hack_wm_protocols (f, widget
  #ifdef HAVE_X_I18N
  
  static XFontSet xic_create_xfontset P_ ((struct frame *, char *));
 +static XFontSet xic_create_xfontset2 P_ ((struct frame *));
  static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
  
  
@@@ -2090,29 -2103,6 +2090,29 @@@ xic_create_fontsetname (base_fontname, 
    return fontsetname;
  }
  
 +#ifdef DEBUG_XIC_FONTSET
 +static void
 +print_fontset_result (xfs, name, missing_list, missing_count)
 +     XFontSet xfs;
 +     char *name;
 +     char **missing_list;
 +     int missing_count;
 +{
 +  if (xfs)
 +    fprintf (stderr, "XIC Fontset created: %s\n", name);
 +  else
 +    {
 +      fprintf (stderr, "XIC Fontset failed: %s\n", name);
 +      while (missing_count-- > 0)
 +      {
 +        fprintf (stderr, "  missing: %s\n", *missing_list);
 +        missing_list++;
 +      }
 +    }
 +
 +}
 +#endif
 +
  static XFontSet
  xic_create_xfontset (f, base_fontname)
       struct frame *f;
        xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
                            fontsetname, &missing_list,
                            &missing_count, &def_string);
 +#ifdef DEBUG_XIC_FONTSET
 +      print_fontset_result (xfs, fontsetname, missing_list, missing_count);
 +#endif
        if (missing_list)
        XFreeStringList (missing_list);
        if (! xfs)
              xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
                                    p0, &missing_list,
                                    &missing_count, &def_string);
 +#ifdef DEBUG_XIC_FONTSET
 +            print_fontset_result (xfs, p0, missing_list, missing_count);
 +#endif
              if (missing_list)
                XFreeStringList (missing_list);
              if (xfs)
            }
        }
        xfree (fontsetname);
 +      if (! xfs && base_fontname != xic_defaut_fontset)
 +      {
 +        /* Try the default fontset name at a last resort.  */
 +        fontsetname = xic_create_fontsetname (xic_defaut_fontset, False);
 +        xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
 +                              fontsetname, &missing_list,
 +                              &missing_count, &def_string);
 +#ifdef DEBUG_XIC_FONTSET
 +        print_fontset_result (xfs, fontsetname, missing_list, missing_count);
 +#endif
 +        if (missing_list)
 +          XFreeStringList (missing_list);
 +        xfree (fontsetname);
 +      }
      }
  
    if (FRAME_XIC_BASE_FONTNAME (f))
    return xfs;
  }
  
 +#ifdef USE_FONT_BACKEND
 +
 +static XFontSet
 +xic_create_xfontset2 (f)
 +     struct frame *f;
 +{
 +  XFontSet xfs = NULL;
 +  struct font *font = FRAME_FONT_OBJECT (f);
 +  int pixel_size = font->pixel_size;
 +  Lisp_Object rest, frame;
 +
 +  /* See if there is another frame already using same fontset.  */
 +  FOR_EACH_FRAME (rest, frame)
 +    {
 +      struct frame *cf = XFRAME (frame);
 +
 +      if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
 +          && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
 +        && FRAME_FONT_OBJECT (f)
 +        && FRAME_FONT_OBJECT (f)->pixel_size == pixel_size)
 +        {
 +          xfs = FRAME_XIC_FONTSET (cf);
 +          break;
 +        }
 +    }
 +
 +  if (! xfs)
 +    {
 +      char buf[256];
 +      char **missing_list;
 +      int missing_count;
 +      char *def_string;
 +      char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
 +
 +      sprintf (buf, xlfd_format, pixel_size);
 +      missing_list = NULL;
 +      xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
 +                          &missing_list, &missing_count, &def_string);
 +#ifdef DEBUG_XIC_FONTSET
 +      print_fontset_result (xfs, buf, missing_list, missing_count);
 +#endif
 +      if (missing_list)
 +      XFreeStringList (missing_list);
 +      if (! xfs)
 +      {
 +        /* List of pixel sizes most likely available.  Find one that
 +           is closest to pixel_size.  */
 +        int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
 +        int *smaller, *larger;
 +
 +        for (smaller = sizes; smaller[1]; smaller++)
 +          if (smaller[1] >= pixel_size)
 +            break;
 +        larger = smaller + 1;
 +        if (*larger == pixel_size)
 +          larger++;
 +        while (*smaller || *larger)
 +          {
 +            int this_size;
 +
 +            if (! *larger)
 +              this_size = *smaller--;
 +            else if (! *smaller)
 +              this_size = *larger++;
 +            else if (pixel_size - *smaller < *larger - pixel_size)
 +              this_size = *smaller--;
 +            else
 +              this_size = *larger++;
 +            sprintf (buf, xlfd_format, this_size);
 +            missing_list = NULL;
 +            xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
 +                                  &missing_list, &missing_count, &def_string);
 +#ifdef DEBUG_XIC_FONTSET
 +            print_fontset_result (xfs, buf, missing_list, missing_count);
 +#endif
 +            if (missing_list)
 +              XFreeStringList (missing_list);
 +            if (xfs)
 +              break;
 +          }
 +      }
 +      if (! xfs)
 +      {
 +        char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
 +
 +        missing_list = NULL;
 +        xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
 +                              &missing_list, &missing_count, &def_string);
 +#ifdef DEBUG_XIC_FONTSET
 +        print_fontset_result (xfs, last_resort, missing_list, missing_count);
 +#endif
 +        if (missing_list)
 +          XFreeStringList (missing_list);
 +      }
 +
 +    }
 +
 +  return xfs;
 +}
 +#endif        /* USE_FONT_BACKEND */
 +
  /* Free the X fontset of frame F if it is the last frame using it.  */
  
  void
@@@ -2378,11 -2247,6 +2378,11 @@@ create_frame_xic (f
      return;
  
    /* Create X fontset. */
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    xfs = xic_create_xfontset2 (f);
 +  else
 +#endif
    xfs = xic_create_xfontset
      (f, (FRAME_FONTSET (f) < 0) ? NULL
          : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f))));
@@@ -2541,11 -2405,6 +2541,11 @@@ xic_set_xfontset (f, base_fontname
  
    xic_free_xfontset (f);
  
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    xfs = xic_create_xfontset2 (f);
 +  else
 +#endif
    xfs = xic_create_xfontset (f, base_fontname);
  
    attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
@@@ -3165,44 -3024,6 +3165,44 @@@ unwind_create_frame (frame
    return Qnil;
  }
  
 +#ifdef USE_FONT_BACKEND
 +static void
 +x_default_font_parameter (f, parms)
 +     struct frame *f;
 +     Lisp_Object parms;
 +{
 +  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
 +  Lisp_Object font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font",
 +                              RES_TYPE_STRING);
 +
 +  if (! STRINGP (font))
 +    {
 +      char *names[]
 +      = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
 +          "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
 +          "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
 +          /* This was formerly the first thing tried, but it finds
 +             too many fonts and takes too long.  */
 +          "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
 +          /* If those didn't work, look for something which will
 +             at least work.  */
 +          "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
 +          "fixed",
 +          NULL };
 +      int i;
 +
 +      for (i = 0; names[i]; i++)
 +      {
 +        font = font_open_by_name (f, names[i]);
 +        if (! NILP (font))
 +          break;
 +      }
 +      if (NILP (font))
 +      error ("No suitable font was found");
 +    }
 +  x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
 +}
 +#endif        /* USE_FONT_BACKEND */
  
  DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
         1, 1, 0,
@@@ -3380,75 -3201,43 +3380,75 @@@ This function is an internal primitive-
        specbind (Qx_resource_name, name);
      }
  
 +  f->resx = dpyinfo->resx;
 +  f->resy = dpyinfo->resy;
 +
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      /* Perhaps, we must allow frame parameter, say `font-backend',
 +       to specify which font backends to use.  */
 +#ifdef HAVE_FREETYPE
 +#ifdef HAVE_XFT
 +      register_font_driver (&xftfont_driver, f);
 +#else /* not HAVE_XFT */
 +      register_font_driver (&ftxfont_driver, f);
 +#endif        /* not HAVE_XFT */
 +#endif        /* HAVE_FREETYPE */
 +      register_font_driver (&xfont_driver, f);
 +
 +      x_default_parameter (f, parms, Qfont_backend, Qnil,
 +                         "fontBackend", "FontBackend", RES_TYPE_STRING);
 +    }
 +#endif        /* USE_FONT_BACKEND */
 +
    /* Extract the window parameters from the supplied values
       that are needed to determine window geometry.  */
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    x_default_font_parameter (f, parms);
 +else
 +#endif        /* USE_FONT_BACKEND */
    {
      Lisp_Object font;
  
      font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
  
 -    BLOCK_INPUT;
 -    /* First, try whatever font the caller has specified.  */
 -    if (STRINGP (font))
 -      {
 -      tem = Fquery_fontset (font, Qnil);
 -      if (STRINGP (tem))
 -        font = x_new_fontset (f, SDATA (tem));
 -      else
 -        font = x_new_font (f, SDATA (font));
 -      }
 -
 -    /* Try out a font which we hope has bold and italic variations.  */
 -    if (!STRINGP (font))
 -      font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
 +    /* If the caller has specified no font, try out fonts which we
 +       hope have bold and italic variations.  */
      if (!STRINGP (font))
 -      font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
 -    if (! STRINGP (font))
 -      font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
 -    if (! STRINGP (font))
 -      /* This was formerly the first thing tried, but it finds too many fonts
 -       and takes too long.  */
 -      font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
 -    /* If those didn't work, look for something which will at least work.  */
 -    if (! STRINGP (font))
 -      font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
 -    UNBLOCK_INPUT;
 -    if (! STRINGP (font))
 -      font = build_string ("fixed");
 +      {
 +      char *names[]
 +        = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
 +            "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
 +            "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
 +            /* This was formerly the first thing tried, but it finds
 +               too many fonts and takes too long.  */
 +            "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
 +            /* If those didn't work, look for something which will
 +               at least work.  */
 +            "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
 +            NULL };
 +      int i;
 +
 +      BLOCK_INPUT;
 +      for (i = 0; names[i]; i++)
 +        {
 +          Lisp_Object list;
  
 -    x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
 +          list = x_list_fonts (f, build_string (names[i]), 0, 1);
 +          if (CONSP (list))
 +            {
 +              font = XCAR (list);
 +              break;
 +            }
 +        }
 +      UNBLOCK_INPUT;
 +      if (! STRINGP (font))
 +        font = build_string ("fixed");
 +      }
 +    x_default_parameter (f, parms, Qfont, font,
 +                       "font", "Font", RES_TYPE_STRING);
    }
  
  #ifdef USE_LUCID
@@@ -4992,35 -4781,8 +4992,35 @@@ x_create_tip_frame (dpyinfo, parms, tex
        specbind (Qx_resource_name, name);
      }
  
 +  f->resx = dpyinfo->resx;
 +  f->resy = dpyinfo->resy;
 +
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      /* Perhaps, we must allow frame parameter, say `font-backend',
 +       to specify which font backends to use.  */
 +#ifdef HAVE_FREETYPE
 +#ifdef HAVE_XFT
 +      register_font_driver (&xftfont_driver, f);
 +#else /* not HAVE_XFT */
 +      register_font_driver (&ftxfont_driver, f);
 +#endif        /* not HAVE_XFT */
 +#endif        /* HAVE_FREETYPE */
 +      register_font_driver (&xfont_driver, f);
 +
 +      x_default_parameter (f, parms, Qfont_backend, Qnil,
 +                         "fontBackend", "FontBackend", RES_TYPE_STRING);
 +    }
 +#endif        /* USE_FONT_BACKEND */
 +
    /* Extract the window parameters from the supplied values that are
       needed to determine window geometry.  */
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    x_default_font_parameter (f, parms);
 +else
 +#endif        /* USE_FONT_BACKEND */
    {
      Lisp_Object font;
  
        {
        tem = Fquery_fontset (font, Qnil);
        if (STRINGP (tem))
 -        font = x_new_fontset (f, SDATA (tem));
 +        font = x_new_fontset (f, tem);
        else
          font = x_new_font (f, SDATA (font));
        }
      if (! STRINGP (font))
        font = build_string ("fixed");
  
 -    x_default_parameter (f, parms, Qfont, font,
 -                       "font", "Font", RES_TYPE_STRING);
 +    x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
    }
  
    x_default_parameter (f, parms, Qborder_width, make_number (2),
@@@ -5974,9 -5737,6 +5974,9 @@@ frame_parm_handler x_frame_parm_handler
    x_set_fringe_width,
    x_set_wait_for_wm,
    x_set_fullscreen,
 +#ifdef USE_FONT_BACKEND
 +  x_set_font_backend
 +#endif        /* USE_FONT_BACKEND */
  };
  
  void
@@@ -6187,7 -5947,6 +6187,7 @@@ the tool bar buttons.  */)
    find_ccl_program_func = x_find_ccl_program;
    query_font_func = x_query_font;
    set_frame_fontset_func = x_set_font;
 +  get_font_repertory_func = x_get_font_repertory;
    check_window_system_func = check_x;
  
    hourglass_atimer = NULL;
diff --combined src/xmenu.c
index 5066c9076e3f8da566430ab38daed10d25d63ef4,b9aabd94ae1b758421f6b1e52ae322dad3d675f3..e2a67510de2dd270e8e7d2b71d8abd802052d83a
@@@ -1,6 -1,6 +1,6 @@@
  /* X Communication module for terminals which understand the X protocol.
     Copyright (C) 1986, 1988, 1993, 1994, 1996, 1999, 2000, 2001, 2002, 2003,
-                  2004, 2005, 2006 Free Software Foundation, Inc.
+                  2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -1621,7 -1621,7 +1621,7 @@@ menu_highlight_callback (widget, id, ca
  static void
  find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
       FRAME_PTR f;
 -     int menu_bar_items_used;
 +     EMACS_INT menu_bar_items_used;
       Lisp_Object vector;
       void *client_data;
  {
diff --combined src/xrdb.c
index 6885123c19426762c5d0df24b353d2fdc4ceae34,4c9f3c60b3585380d9fe4c8779b563fec4369dcf..3a85c14e8ffc4522c6bfa2e59671e3f93ef5ab20
@@@ -1,6 -1,6 +1,6 @@@
  /* Deal with the X Resource Manager.
     Copyright (C) 1990, 1993, 1994, 2000, 2001, 2002, 2003, 2004,
-                  2005, 2006 Free Software Foundation, Inc.
+                  2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -610,29 -610,6 +610,29 @@@ x_load_resources (display, xrm_string, 
  
  #endif /* not USE_MOTIF */
  
 +#ifdef HAVE_X_I18N
 +  {
 +#ifdef USE_MOTIF
 +    Bool motif = True;
 +#else  /* not USE_MOTIF */
 +    Bool motif = False;
 +#endif  /* not USE_MOTIF */
 +    /* Setup the default fontSet resource.  */
 +    extern char *xic_create_fontsetname P_ ((char *base_fontname, Bool motif));
 +    char *fontsetname = xic_create_fontsetname (helv, motif);
 +    int len = strlen (fontsetname);
 +    char *buf = line;
 +
 +    /* fontsetname may be very long.  */
 +    if (len + 16 > 256)
 +      buf = alloca (len + 16);
 +    sprintf (buf, "Emacs*fontSet: %s", fontsetname);
 +    XrmPutLineResource (&rdb, buf);
 +    if (fontsetname != helv)
 +      xfree (fontsetname);
 +  }
 +#endif        /* HAVE_X_I18N */
 +
    user_database = get_user_db (display);
  
    /* Figure out what the "customization string" is, so we can use it
diff --combined src/xterm.c
index 977325f0b7559cdccc230a3291c525a76d2d8f11,e3fb3ae1c141caae0abe2d6d51e0d8d788d8f145..efbc3c7b7ea7eb4161d51e803ed4cb052eb2fb15
@@@ -1,6 -1,6 +1,6 @@@
  /* X Communication module for terminals which understand the X protocol.
     Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-                  2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -68,7 -68,6 +68,7 @@@ Boston, MA 02110-1301, USA.  *
  /* #include <sys/param.h>  */
  
  #include "charset.h"
 +#include "character.h"
  #include "coding.h"
  #include "ccl.h"
  #include "frame.h"
  #include "gtkutil.h"
  #endif
  
 +#ifdef USE_FONT_BACKEND
 +#include "font.h"
 +#endif        /* USE_FONT_BACKEND */
 +
  #ifdef USE_LUCID
  extern int xlwmenu_window_p P_ ((Widget w, Window window));
  extern void xlwmenu_redisplay P_ ((Widget));
@@@ -282,6 -277,10 +282,10 @@@ static Lisp_Object last_mouse_scroll_ba
  
  static Time last_mouse_movement_time;
  
+ /* Time for last user interaction as returned in X events.  */
+ static Time last_user_time;
  /* Incremented by XTread_socket whenever it really tries to read
     events.  */
  
@@@ -813,8 -812,7 +817,8 @@@ XTreset_terminal_modes (
  
  /* Function prototypes of this page.  */
  
 -static int x_encode_char P_ ((int, XChar2b *, struct font_info *, int *));
 +static int x_encode_char P_ ((int, XChar2b *, struct font_info *,
 +                            struct charset *, int *));
  
  
  /* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
@@@ -893,13 -891,13 +897,13 @@@ x_per_char_metric (font, char2b, font_t
     the two-byte form of C.  Encoding is returned in *CHAR2B.  */
  
  static int
 -x_encode_char (c, char2b, font_info, two_byte_p)
 +x_encode_char (c, char2b, font_info, charset, two_byte_p)
       int c;
       XChar2b *char2b;
       struct font_info *font_info;
 +     struct charset *charset;
       int *two_byte_p;
  {
 -  int charset = CHAR_CHARSET (c);
    XFontStruct *font = font_info->font;
  
    /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
        check_ccl_update (ccl);
        if (CHARSET_DIMENSION (charset) == 1)
        {
 -        ccl->reg[0] = charset;
 +        ccl->reg[0] = CHARSET_ID (charset);
          ccl->reg[1] = char2b->byte2;
          ccl->reg[2] = -1;
        }
        else
        {
 -        ccl->reg[0] = charset;
 +        ccl->reg[0] = CHARSET_ID (charset);
          ccl->reg[1] = char2b->byte1;
          ccl->reg[2] = char2b->byte2;
        }
  
 -      ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
 +      ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
  
        /* We assume that MSBs are appropriately set/reset by CCL
         program.  */
        if (font->max_byte1 == 0)       /* 1-byte font */
 -      char2b->byte1 = 0, char2b->byte2 = ccl->reg[1];
 +      STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
        else
 -      char2b->byte1 = ccl->reg[1], char2b->byte2 = ccl->reg[2];
 +      STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
      }
 -  else if (font_info->encoding[charset])
 +  else if (font_info->encoding_type)
      {
        /* Fixed encoding scheme.  See fontset.h for the meaning of the
         encoding numbers.  */
 -      int enc = font_info->encoding[charset];
 +      unsigned char enc = font_info->encoding_type;
  
        if ((enc == 1 || enc == 2)
          && CHARSET_DIMENSION (charset) == 2)
@@@ -1065,20 -1063,15 +1069,20 @@@ x_set_mouse_face_gc (s
      face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
  
    if (s->first_glyph->type == CHAR_GLYPH)
 -    face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
 +    face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
    else
 -    face_id = FACE_FOR_CHAR (s->f, face, 0);
 +    face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
    s->face = FACE_FROM_ID (s->f, face_id);
    PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
  
    /* If font in this face is same as S->font, use it.  */
    if (s->font == s->face->font)
      s->gc = s->face->gc;
 +#ifdef USE_FONT_BACKEND
 +  else if (enable_font_backend)
 +    /* No need of setting a font for s->gc.  */
 +    s->gc = s->face->gc;
 +#endif        /* USE_FONT_BACKEND */
    else
      {
        /* Otherwise construct scratch_cursor_gc with values from FACE
@@@ -1176,50 -1169,12 +1180,50 @@@ x_set_glyph_string_clipping (s
    XRectangle r;
    get_glyph_string_clip_rect (s, &r);
    XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted);
 +#ifdef USE_FONT_BACKEND
 +  s->clip_x = r.x, s->clip_y = r.y;
 +  s->clip_width = r.width, s->clip_height = r.height;
 +#endif        /* USE_FONT_BACKEND */
 +}
 +
 +
 +/* Set SRC's clipping for output of glyph string DST.  This is called
 +   when we are drawing DST's left_overhang or right_overhang only in
 +   the area of SRC.  */
 +
 +static void
 +x_set_glyph_string_clipping_exactly (src, dst)
 +     struct glyph_string *src, *dst;
 +{
 +  XRectangle r;
 +
 +#ifdef USE_FONT_BACKEND
 +  if (enable_font_backend)
 +    {
 +      r.x = dst->clip_x = src->x;
 +      r.width = dst->clip_width = src->width;
 +      r.y = dst->clip_y = src->y;
 +      r.height = dst->clip_height = src->height;
 +    }
 +  else
 +    {
 +#endif        /* USE_FONT_BACKEND */
 +  struct glyph_string *clip_head = src->clip_head;
 +  struct glyph_string *clip_tail = src->clip_tail;
 +
 +  /* This foces clipping just this glyph string.  */
 +  src->clip_head = src->clip_tail = src;
 +  get_glyph_string_clip_rect (src, &r);
 +  src->clip_head = clip_head, src->clip_tail = clip_tail;
 +#ifdef USE_FONT_BACKEND
 +    }
 +#endif        /* USE_FONT_BACKEND */
 +  XSetClipRectangles (dst->display, dst->gc, 0, 0, &r, 1, Unsorted);
  }
  
  
  /* RIF:
 -   Compute left and right overhang of glyph string S.  If S is a glyph
 -   string for a composition, assume overhangs don't exist.  */
 +   Compute left and right overhang of glyph string S.  */
  
  static void
  x_compute_glyph_string_overhangs (s)
      {
        XCharStruct cs;
        int direction, font_ascent, font_descent;
 +
 +#ifdef USE_FONT_BACKEND
 +      if (enable_font_backend)
 +      {
 +        unsigned *code = alloca (sizeof (unsigned) * s->nchars);
 +        struct font *font = (struct font *) s->font_info;
 +        struct font_metrics metrics;
 +        int i;
 +
 +        for (i = 0; i < s->nchars; i++)
 +          code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
 +        font->driver->text_extents (font, code, s->nchars, &metrics);
 +        cs.rbearing = metrics.rbearing;
 +        cs.lbearing = metrics.lbearing;
 +        cs.width = metrics.width;
 +      }
 +      else
 +#endif        /* USE_FONT_BACKEND */
        XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
                      &font_ascent, &font_descent, &cs);
        s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
        s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
      }
 +  else if (s->cmp)
 +    {
 +      s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
 +      s->left_overhang = - s->cmp->lbearing;
 +    }
  }
  
  
@@@ -1347,30 -1279,6 +1351,30 @@@ x_draw_glyph_string_foreground (s
          x += g->pixel_width;
        }
      }
 +#ifdef USE_FONT_BACKEND
 +  else if (enable_font_backend)
 +    {
 +      unsigned *code = alloca (sizeof (unsigned) * s->nchars);
 +      int boff = s->font_info->baseline_offset;
 +      struct font *font = (struct font *) s->font_info;
 +      int y;
 +
 +      for (i = 0; i < s->nchars; i++)
 +      code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
 +
 +      if (s->font_info->vertical_centering)
 +      boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
 +
 +      y = s->ybase - boff;
 +      if (s->for_overlaps
 +        || (s->background_filled_p && s->hl != DRAW_CURSOR))
 +      font->driver->draw (s, 0, s->nchars, x, y, 0);
 +      else
 +      font->driver->draw (s, 0, s->nchars, x, y, 1);
 +      if (s->face->overstrike)
 +      font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
 +    }
 +#endif        /* USE_FONT_BACKEND */
    else
      {
        char *char1b = (char *) s->char2b;
@@@ -1434,7 -1342,7 +1438,7 @@@ x_draw_composite_glyph_string_foregroun
  
    /* If first glyph of S has a left box line, start drawing the text
       of S to the right of that box line.  */
 -  if (s->face->box != FACE_NO_BOX
 +  if (s->face && s->face->box != FACE_NO_BOX
        && s->first_glyph->left_box_line_p)
      x = s->x + abs (s->face->box_line_width);
    else
        XDrawRectangle (s->display, s->window, s->gc, x, s->y,
                        s->width - 1, s->height - 1);
      }
 +#ifdef USE_FONT_BACKEND
 +  else if (enable_font_backend)
 +    {
 +      struct font *font = (struct font *) s->font_info;
 +      int y = s->ybase;
 +      int width = 0;
 +
 +      if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
 +      {
 +        Lisp_Object gstring = AREF (XHASH_TABLE (composition_hash_table)
 +                                    ->key_and_value,
 +                                    s->cmp->hash_index * 2);
 +        int from;
 +
 +        for (i = from = 0; i < s->nchars; i++)
 +          {
 +            Lisp_Object g = LGSTRING_GLYPH (gstring, i);
 +            Lisp_Object adjustment = LGLYPH_ADJUSTMENT (g);
 +            int xoff, yoff, wadjust;
 +
 +            if (! VECTORP (adjustment))
 +              {
 +                width += XINT (LGLYPH_WIDTH (g));
 +                continue;
 +              }
 +            if (from < i)
 +              {
 +                font->driver->draw (s, from, i, x, y, 0);
 +                x += width;
 +              }
 +            xoff = XINT (AREF (adjustment, 0));
 +            yoff = XINT (AREF (adjustment, 1));
 +            wadjust = XINT (AREF (adjustment, 2));
 +
 +            font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
 +            x += XINT (LGLYPH_WIDTH (g)) + wadjust;
 +            from = i + 1;
 +            width = 0;
 +          }
 +        if (from < i)
 +          font->driver->draw (s, from, i, x, y, 0);
 +      }
 +      else
 +      {
 +        for (i = 0; i < s->nchars; i++, ++s->gidx)
 +          if (COMPOSITION_GLYPH (s->cmp, s->gidx) != '\t')
 +            {
 +              int xx = x + s->cmp->offsets[s->gidx * 2];
 +              int yy = y - s->cmp->offsets[s->gidx * 2 + 1];
 +
 +              font->driver->draw (s, s->gidx, s->gidx + 1, xx, yy, 0);
 +              if (s->face->overstrike)
 +                font->driver->draw (s, s->gidx, s->gidx + 1, xx + 1, yy, 0);
 +            }
 +      }
 +    }
 +#endif        /* USE_FONT_BACKEND */
    else
      {
        for (i = 0; i < s->nchars; i++, ++s->gidx)
 -      {
 -        XDrawString16 (s->display, s->window, s->gc,
 -                       x + s->cmp->offsets[s->gidx * 2],
 -                       s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
 -                       s->char2b + i, 1);
 -        if (s->face->overstrike)
 +      if (s->face)
 +        {
            XDrawString16 (s->display, s->window, s->gc,
 -                         x + s->cmp->offsets[s->gidx * 2] + 1,
 +                         x + s->cmp->offsets[s->gidx * 2],
                           s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
 -                         s->char2b + i, 1);
 -      }
 +                         s->char2b + s->gidx, 1);
 +          if (s->face->overstrike)
 +            XDrawString16 (s->display, s->window, s->gc,
 +                           x + s->cmp->offsets[s->gidx * 2] + 1,
 +                           s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
 +                           s->char2b + s->gidx, 1);
 +        }
      }
  }
  
@@@ -2770,25 -2620,15 +2774,25 @@@ x_draw_glyph_string (s
  {
    int relief_drawn_p = 0;
  
 -  /* If S draws into the background of its successor, draw the
 -     background of the successor first so that S can draw into it.
 +  /* If S draws into the background of its successors, draw the
 +     background of the successors first so that S can draw into it.
       This makes S->next use XDrawString instead of XDrawImageString.  */
    if (s->next && s->right_overhang && !s->for_overlaps)
      {
 -      xassert (s->next->img == NULL);
 -      x_set_glyph_string_gc (s->next);
 -      x_set_glyph_string_clipping (s->next);
 -      x_draw_glyph_string_background (s->next, 1);
 +      int width;
 +      struct glyph_string *next;
 +
 +      for (width = 0, next = s->next; next;
 +         width += next->width, next = next->next)
 +      if (next->first_glyph->type != IMAGE_GLYPH)
 +        {
 +          x_set_glyph_string_gc (next);
 +          x_set_glyph_string_clipping (next);
 +          x_draw_glyph_string_background (next, 1);
 +#ifdef USE_FONT_BACKEND
 +          next->clip_width = 0;
 +#endif        /* USE_FONT_BACKEND */
 +        }
      }
  
    /* Set up S->gc, set clipping and draw S.  */
        x_set_glyph_string_clipping (s);
        relief_drawn_p = 1;
      }
 +  else if ((s->prev && s->prev->hl != s->hl && s->left_overhang)
 +         || (s->next && s->next->hl != s->hl && s->right_overhang))
 +    /* We must clip just this glyph.  left_overhang part has already
 +       drawn when s->prev was drawn, and right_overhang part will be
 +       drawn later when s->next is drawn. */
 +    x_set_glyph_string_clipping_exactly (s, s);
    else
      x_set_glyph_string_clipping (s);
  
          int y;
  
          /* Get the underline thickness.  Default is 1 pixel.  */
 +#ifdef USE_FONT_BACKEND
 +        if (enable_font_backend)
 +          /* In the future, we must use information of font.  */
 +          h = 1;
 +        else
 +#endif        /* USE_FONT_BACKEND */
          if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
            h = 1;
  
 -        y = s->y + s->height - h;
 -        if (!x_underline_at_descent_line)
 -            {
 -            /* Get the underline position.  This is the recommended
 -                 vertical offset in pixels from the baseline to the top of
 -                 the underline.  This is a signed value according to the
 -                 specs, and its default is
 -
 -               ROUND ((maximum descent) / 2), with
 -               ROUND(x) = floor (x + 0.5)  */
 -
 -              if (x_use_underline_position_properties
 -                  && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
 -                y = s->ybase + (long) tem;
 -              else if (s->face->font)
 -                y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
 -            }
 +#ifdef USE_FONT_BACKEND
 +        if (enable_font_backend)
 +          {
 +            if (s->face->font)
 +              /* In the future, we must use information of font.  */
 +              y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
 +            else
 +              y = s->y + s->height - h;
 +          }
 +        else
 +#endif
 +          {
 +            y = s->y + s->height - h;
 +            if (!x_underline_at_descent_line)
 +              {
 +                /* Get the underline position.  This is the recommended
 +                   vertical offset in pixels from the baseline to the top of
 +                   the underline.  This is a signed value according to the
 +                   specs, and its default is
 +
 +                   ROUND ((maximum descent) / 2), with
 +                   ROUND(x) = floor (x + 0.5)  */
 +
 +                if (x_use_underline_position_properties
 +                    && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
 +                  y = s->ybase + (long) tem;
 +                else if (s->face->font)
 +                  y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
 +              }
 +          }
  
          if (s->face->underline_defaulted_p)
            XFillRectangle (s->display, s->window, s->gc,
        /* Draw relief if not yet drawn.  */
        if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
        x_draw_glyph_string_box (s);
 +
 +      if (s->prev)
 +      {
 +        struct glyph_string *prev;
 +
 +        for (prev = s->prev; prev; prev = prev->prev)
 +          if (prev->hl != s->hl
 +              && prev->x + prev->width + prev->right_overhang > s->x)
 +            {
 +              /* As prev was drawn while clipped to its own area, we
 +                 must draw the right_overhang part using s->hl now.  */
 +              enum draw_glyphs_face save = prev->hl;
 +
 +              prev->hl = s->hl;
 +              x_set_glyph_string_gc (prev);
 +              x_set_glyph_string_clipping_exactly (s, prev);
 +              if (prev->first_glyph->type == CHAR_GLYPH)
 +                x_draw_glyph_string_foreground (prev);
 +              else
 +                x_draw_composite_glyph_string_foreground (prev);
 +              XSetClipMask (prev->display, prev->gc, None);
 +              prev->hl = save;
 +#ifdef USE_FONT_BACKEND
 +              prev->clip_width = 0;
 +#endif        /* USE_FONT_BACKEND */
 +            }
 +      }
 +
 +      if (s->next)
 +      {
 +        struct glyph_string *next;
 +
 +        for (next = s->next; next; next = next->next)
 +          if (next->hl != s->hl
 +              && next->x - next->left_overhang < s->x + s->width)
 +            {
 +              /* As next will be drawn while clipped to its own area,
 +                 we must draw the left_overhang part using s->hl now.  */
 +              enum draw_glyphs_face save = next->hl;
 +
 +              next->hl = s->hl;
 +              x_set_glyph_string_gc (next);
 +              x_set_glyph_string_clipping_exactly (s, next);
 +              if (next->first_glyph->type == CHAR_GLYPH)
 +                x_draw_glyph_string_foreground (next);
 +              else
 +                x_draw_composite_glyph_string_foreground (next);
 +              XSetClipMask (next->display, next->gc, None);
 +              next->hl = save;
 +#ifdef USE_FONT_BACKEND
 +              next->clip_width = 0;
 +#endif        /* USE_FONT_BACKEND */
 +            }
 +      }
      }
  
    /* Reset clipping.  */
    XSetClipMask (s->display, s->gc, None);
 +#ifdef USE_FONT_BACKEND
 +  s->clip_width = 0;
 +#endif        /* USE_FONT_BACKEND */
  }
  
  /* Shift display to make room for inserted glyphs.   */
@@@ -6115,6 -5873,7 +6119,7 @@@ handle_one_xevent (dpyinfo, eventp, fin
        break;
  
      case SelectionNotify:
+       last_user_time = event.xselection.time;
  #ifdef USE_X_TOOLKIT
        if (! x_window_to_frame (dpyinfo, event.xselection.requestor))
          goto OTHER;
        break;
  
      case SelectionClear:      /* Someone has grabbed ownership.  */
+       last_user_time = event.xselectionclear.time;
  #ifdef USE_X_TOOLKIT
        if (! x_window_to_frame (dpyinfo, event.xselectionclear.window))
          goto OTHER;
        break;
  
      case SelectionRequest:    /* Someone wants our selection.  */
+       last_user_time = event.xselectionrequest.time;
  #ifdef USE_X_TOOLKIT
        if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
          goto OTHER;
        break;
  
      case PropertyNotify:
+       last_user_time = event.xproperty.time;
  #if 0 /* This is plain wrong.  In the case that we are waiting for a
         PropertyNotify used as an ACK in incremental selection
         transfer, the property will be on the receiver's window.  */
  
            /* Perhaps reparented due to a WM restart.  Reset this.  */
            FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
+           FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0;
          }
        goto OTHER;
  
  
      case KeyPress:
  
+       last_user_time = event.xkey.time;
        ignore_next_mouse_click_timeout = 0;
  
  #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
              goto done_keysym;
            }
  
 -        /* Keysyms directly mapped to supported Unicode characters.  */
 -        if ((keysym >= 0x01000000 && keysym <= 0x010033ff)
 -            || (keysym >= 0x0100e000 && keysym <= 0x0100ffff))
 +        /* Keysyms directly mapped to Unicode characters.  */
 +        if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
            {
 -            int code = keysym & 0xFFFF, charset_id, c1, c2;
 -
 -            if (code < 0x80)
 -              {
 -                inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 -                inev.ie.code = code;
 -              }
 -            else if (code < 0x100)
 -              {
 -                if (code < 0xA0)
 -                  charset_id = CHARSET_8_BIT_CONTROL;
 -                else
 -                  charset_id = charset_latin_iso8859_1;
 -                inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 -                inev.ie.code = MAKE_CHAR (charset_id, code, 0);
 -              }
 +            if (keysym < 0x01000080)
 +              inev.ie.kind = ASCII_KEYSTROKE_EVENT;
              else
 -              {
 -                if (code < 0x2500)
 -                  charset_id = charset_mule_unicode_0100_24ff,
 -                    code -= 0x100;
 -                else if (code < 0xE000)
 -                  charset_id = charset_mule_unicode_2500_33ff,
 -                    code -= 0x2500;
 -                else
 -                  charset_id = charset_mule_unicode_e000_ffff,
 -                    code -= 0xE000;
 -                c1 = (code / 96) + 32, c2 = (code % 96) + 32;
 -                inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 -                inev.ie.code = MAKE_CHAR (charset_id, c1, c2);
 -              }
 +              inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 +            inev.ie.code = keysym & 0xFFFFFF;
              goto done_keysym;
            }
  
            register int c;
            int nchars, len;
  
 -          /* The input should be decoded with `coding_system'
 -             which depends on which X*LookupString function
 -             we used just above and the locale.  */
 -          setup_coding_system (coding_system, &coding);
 -          coding.src_multibyte = 0;
 -          coding.dst_multibyte = 1;
 -          /* The input is converted to events, thus we can't
 -             handle composition.  Anyway, there's no XIM that
 -             gives us composition information.  */
 -          coding.composing = COMPOSITION_DISABLED;
 -
 -          for (i = 0; i < nbytes; i++)
 +          for (i = 0, nchars = 0; i < nbytes; i++)
              {
 +              if (ASCII_BYTE_P (copy_bufptr[i]))
 +                nchars++;
                STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
              }
  
 -          {
 -            /* Decode the input data.  */
 -            int require;
 -            unsigned char *p;
 -
 -            require = decoding_buffer_size (&coding, nbytes);
 -            p = (unsigned char *) alloca (require);
 -            coding.mode |= CODING_MODE_LAST_BLOCK;
 -            /* We explicitly disable composition handling because
 -               key data should not contain any composition sequence.  */
 -            coding.composing = COMPOSITION_DISABLED;
 -            decode_coding (&coding, copy_bufptr, p, nbytes, require);
 -            nbytes = coding.produced;
 -            nchars = coding.produced_char;
 -            copy_bufptr = p;
 -          }
 +          if (nchars < nbytes)
 +            {
 +              /* Decode the input data.  */
 +              int require;
 +              unsigned char *p;
 +
 +              /* The input should be decoded with `coding_system'
 +                 which depends on which X*LookupString function
 +                 we used just above and the locale.  */
 +              setup_coding_system (coding_system, &coding);
 +              coding.src_multibyte = 0;
 +              coding.dst_multibyte = 1;
 +              /* The input is converted to events, thus we can't
 +                 handle composition.  Anyway, there's no XIM that
 +                 gives us composition information.  */
 +              coding.common_flags &= ~CODING_ANNOTATION_MASK;
 +
 +              require = MAX_MULTIBYTE_LENGTH * nbytes;
 +              coding.destination = alloca (require);
 +              coding.dst_bytes = require;
 +              coding.mode |= CODING_MODE_LAST_BLOCK;
 +              decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil);
 +              nbytes = coding.produced;
 +              nchars = coding.produced_char;
 +              copy_bufptr = coding.destination;
 +            }
  
            /* Convert the input data to a sequence of
               character events.  */
  #endif
  
      case KeyRelease:
+       last_user_time = event.xkey.time;
  #ifdef HAVE_X_I18N
        /* Don't dispatch this event since XtDispatchEvent calls
           XFilterEvent, and two calls in a row may freeze the
  #endif
  
      case EnterNotify:
+       last_user_time = event.xcrossing.time;
        x_detect_focus_change (dpyinfo, &event, &inev.ie);
  
        f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
        goto OTHER;
  
      case LeaveNotify:
+       last_user_time = event.xcrossing.time;
        x_detect_focus_change (dpyinfo, &event, &inev.ie);
  
        f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
  
      case MotionNotify:
        {
+         last_user_time = event.xmotion.time;
          previous_help_echo_string = help_echo_string;
          help_echo_string = Qnil;
  
  
          bzero (&compose_status, sizeof (compose_status));
        last_mouse_glyph_frame = 0;
+         last_user_time = event.xbutton.time;
  
          if (dpyinfo->grabbed
              && last_mouse_frame
@@@ -8091,16 -7886,11 +8106,16 @@@ x_new_font (f, fontname
       register char *fontname;
  {
    struct font_info *fontp
 -    = FS_LOAD_FONT (f, 0, fontname, -1);
 +    = FS_LOAD_FONT (f, fontname);
  
    if (!fontp)
      return Qnil;
  
 +  if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
 +    /* This font is already set in frame F.  There's nothing more to
 +       do.  */
 +    return build_string (fontp->full_name);
 +
    FRAME_FONT (f) = (XFontStruct *) (fontp->font);
    FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
    FRAME_FONTSET (f) = -1;
    return build_string (fontp->full_name);
  }
  
 -/* Give frame F the fontset named FONTSETNAME as its default font, and
 -   return the full name of that fontset.  FONTSETNAME may be a wildcard
 -   pattern; in that case, we choose some fontset that fits the pattern.
 -   The return value shows which fontset we chose.  */
 +/* Give frame F the fontset named FONTSETNAME as its default fontset,
 +   and return the full name of that fontset.  FONTSETNAME may be a
 +   wildcard pattern; in that case, we choose some fontset that fits
 +   the pattern.  FONTSETNAME may be a font name for ASCII characters;
 +   in that case, we create a fontset from that font name.
 +
 +   The return value shows which fontset we chose.
 +   If FONTSETNAME specifies the default fontset, return Qt.
 +   If an ASCII font in the specified fontset can't be loaded, return
 +   Qnil.  */
  
  Lisp_Object
  x_new_fontset (f, fontsetname)
       struct frame *f;
 -     char *fontsetname;
 +     Lisp_Object fontsetname;
  {
 -  int fontset = fs_query_fontset (build_string (fontsetname), 0);
 +  int fontset = fs_query_fontset (fontsetname, 0);
    Lisp_Object result;
  
 -  if (fontset < 0)
 -    return Qnil;
 -
 -  if (FRAME_FONTSET (f) == fontset)
 +  if (fontset > 0 && f->output_data.x->fontset == fontset)
      /* This fontset is already set in frame F.  There's nothing more
         to do.  */
      return fontset_name (fontset);
 +  else if (fontset == 0)
 +    /* The default fontset can't be the default font.   */
 +    return Qt;
  
 -  result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 +  if (fontset > 0)
 +    result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
 +  else
 +    result = x_new_font (f, SDATA (fontsetname));
  
    if (!STRINGP (result))
      /* Can't load ASCII font.  */
      return Qnil;
  
 +  if (fontset < 0)
 +    fontset = new_fontset_from_font_name (result);
 +
    /* Since x_new_font doesn't update any fontset information, do it now.  */
    FRAME_FONTSET (f) = fontset;
  
      xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
  #endif
  
 -  return build_string (fontsetname);
 +  return fontset_name (fontset);
  }
  
 +#ifdef USE_FONT_BACKEND
 +Lisp_Object
 +x_new_fontset2 (f, fontset, font_object)
 +     struct frame *f;
 +     int fontset;
 +     Lisp_Object font_object;
 +{
 +  struct font *font = XSAVE_VALUE (font_object)->pointer;
 +
 +  if (FRAME_FONT_OBJECT (f) == font)
 +    /* This font is already set in frame F.  There's nothing more to
 +       do.  */
 +    return fontset_name (fontset);
 +
 +  BLOCK_INPUT;
 +
 +  FRAME_FONT_OBJECT (f) = font;
 +  FRAME_FONT (f) = font->font.font;
 +  FRAME_BASELINE_OFFSET (f) = font->font.baseline_offset;
 +  FRAME_FONTSET (f) = fontset;
 +
 +  FRAME_COLUMN_WIDTH (f) = font->font.average_width;
 +  FRAME_SPACE_WIDTH (f) = font->font.space_width;
 +  FRAME_LINE_HEIGHT (f) = font->font.height;
 +
 +  compute_fringe_widths (f, 1);
 +
 +  /* Compute the scroll bar width in character columns.  */
 +  if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
 +    {
 +      int wid = FRAME_COLUMN_WIDTH (f);
 +      FRAME_CONFIG_SCROLL_BAR_COLS (f)
 +      = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
 +    }
 +  else
 +    {
 +      int wid = FRAME_COLUMN_WIDTH (f);
 +      FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
 +    }
 +
 +  /* Now make the frame display the given font.  */
 +  if (FRAME_X_WINDOW (f) != 0)
 +    {
 +      /* Don't change the size of a tip frame; there's no point in
 +       doing it because it's done in Fx_show_tip, and it leads to
 +       problems because the tip frame has no widget.  */
 +      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
 +      x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
 +    }
 +
 +#ifdef HAVE_X_I18N
 +  if (FRAME_XIC (f)
 +      && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
 +    xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
 +#endif
 +
 +  UNBLOCK_INPUT;
 +
 +  return fontset_name (fontset);
 +}
 +#endif        /* USE_FONT_BACKEND */
 +
  \f
  /***********************************************************************
                           X Input Methods
@@@ -8595,40 -8311,111 +8610,111 @@@ x_set_offset (f, xoff, yoff, change_gra
    UNBLOCK_INPUT;
  }
  
- /* Do fullscreen as specified in extended window manager hints */
+ /* Return non-zero if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED
+    on the root window for frame F contains ATOMNAME.
+    This is how a WM check shall be done according to the Window Manager
+    Specification/Extended Window Manager Hints at
+    http://freedesktop.org/wiki/Standards_2fwm_2dspec.  */
  static int
do_ewmh_fullscreen (f)
wm_supports (f, atomname)
       struct frame *f;
+      const char *atomname;
  {
-   int have_net_atom = FRAME_X_DISPLAY_INFO (f)->have_net_atoms;
+   Atom actual_type;
+   unsigned long actual_size, bytes_remaining;
+   int i, rc, actual_format;
+   Atom prop_atom;
+   Window wmcheck_window;
+   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+   Window target_window = dpyinfo->root_window;
+   long max_len = 65536;
+   Display *dpy = FRAME_X_DISPLAY (f);
+   unsigned char *tmp_data = NULL;
+   Atom target_type = XA_WINDOW;
+   Atom want_atom;
  
-   if (!have_net_atom)
+   BLOCK_INPUT;
+   prop_atom = XInternAtom (dpy, "_NET_SUPPORTING_WM_CHECK", False);
+   x_catch_errors (dpy);
+   rc = XGetWindowProperty (dpy, target_window,
+                            prop_atom, 0, max_len, False, target_type,
+                            &actual_type, &actual_format, &actual_size,
+                            &bytes_remaining, &tmp_data);
+   
+   if (rc != Success || actual_type != XA_WINDOW || x_had_errors_p (dpy))
+     {
+       if (tmp_data) XFree (tmp_data);
+       x_uncatch_errors ();
+       UNBLOCK_INPUT;
+       return 0;
+     }
+   wmcheck_window = *(Window *) tmp_data;
+   XFree (tmp_data);
+   /* Check if window exists. */
+   XSelectInput (dpy, wmcheck_window, StructureNotifyMask);
+   x_sync (f);
+   if (x_had_errors_p (dpy))
+     {
+       x_uncatch_errors ();
+       UNBLOCK_INPUT;
+       return 0;
+     }
+   if (dpyinfo->net_supported_window != wmcheck_window)
      {
-       int num;
-       Atom *atoms = XListProperties (FRAME_X_DISPLAY (f),
-                                      FRAME_X_DISPLAY_INFO (f)->root_window,
-                                      &num);
-       if (atoms && num > 0)
+       /* Window changed, reload atoms */
+       if (dpyinfo->net_supported_atoms != NULL)
+         XFree (dpyinfo->net_supported_atoms);
+       dpyinfo->net_supported_atoms = NULL;
+       dpyinfo->nr_net_supported_atoms = 0;
+       dpyinfo->net_supported_window = 0;
+       target_type = XA_ATOM;
+       prop_atom = XInternAtom (dpy, "_NET_SUPPORTED", False);
+       tmp_data = NULL;
+       rc = XGetWindowProperty (dpy, target_window,
+                                prop_atom, 0, max_len, False, target_type,
+                                &actual_type, &actual_format, &actual_size,
+                                &bytes_remaining, &tmp_data);
+       if (rc != Success || actual_type != XA_ATOM || x_had_errors_p (dpy))
          {
-           char **names = (char **) xmalloc (num * sizeof(*names));
-           if (XGetAtomNames (FRAME_X_DISPLAY (f), atoms, num, names))
-             {
-               int i;
-               for (i = 0; i < num; ++i)
-                 {
-                   if (!have_net_atom)
-                     have_net_atom = strncmp (names[i], "_NET_", 5) == 0;
-                   XFree (names[i]);
-                 }
-             }
-           xfree (names);
+           if (tmp_data) XFree (tmp_data);
+           x_uncatch_errors ();
+           UNBLOCK_INPUT;
+           return 0;
          }
-       if (atoms)
-         XFree (atoms);
  
-       FRAME_X_DISPLAY_INFO (f)->have_net_atoms = have_net_atom;
+       dpyinfo->net_supported_atoms = (Atom *)tmp_data;
+       dpyinfo->nr_net_supported_atoms = actual_size;
+       dpyinfo->net_supported_window = wmcheck_window;
      }
  
+   rc = 0;
+   want_atom = XInternAtom (dpy, atomname, False);
+   for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i) 
+     rc = dpyinfo->net_supported_atoms[i] == want_atom;
+   x_uncatch_errors ();
+   UNBLOCK_INPUT;
+   return rc;
+ }
+ /* Do fullscreen as specified in extended window manager hints */
+ static int
+ do_ewmh_fullscreen (f)
+      struct frame *f;
+ {
+   int have_net_atom = wm_supports (f, "_NET_WM_STATE");
    if (have_net_atom)
      {
        Lisp_Object frame;
            break;
          }
  
+       if (!wm_supports (f, what)) return 0;
        Fx_send_client_event (frame, make_number (0), frame,
                              make_unibyte_string (atom, strlen (atom)),
                              make_number (32),
@@@ -9055,23 -8845,27 +9144,27 @@@ XTframe_raise_lower (f, raise_flag
        /* The following code is needed for `raise-frame' to work on
         some versions of metacity; see Window Manager
         Specification/Extended Window Manager Hints at
-        http://freedesktop.org/wiki/Standards_2fwm_2dspec
+        http://freedesktop.org/wiki/Standards_2fwm_2dspec  */
  
-        However, on other versions (metacity 2.17.2-1.fc7), it
+ #if 0
+       /* However, on other versions (metacity 2.17.2-1.fc7), it
         reportedly causes hangs when resizing frames.  */
  
-       /* Lisp_Object frame;
-          const char *atom = "_NET_ACTIVE_WINDOW"; */
-       x_raise_frame (f);
-       /* XSETFRAME (frame, f);
-          Fx_send_client_event (frame, make_number (0), frame,
-                             make_unibyte_string (atom, strlen (atom)),
-                             make_number (32),
-                             Fcons (make_number (1),
-                                    Fcons (make_number (time (NULL) * 1000),
-                                  Qnil))); */
+       const char *atom = "_NET_ACTIVE_WINDOW";
+       if (f->async_visible && wm_supports (f, atom))
+         {
+           Lisp_Object frame;
+           XSETFRAME (frame, f);
+           Fx_send_client_event (frame, make_number (0), frame,
+                                 make_unibyte_string (atom, strlen (atom)),
+                                 make_number (32),
+                                 Fcons (make_number (1),
+                                        Fcons (make_number (last_user_time),
+                                               Qnil)));
+         }
+       else
+ #endif
+         x_raise_frame (f);
      }
    else
      x_lower_frame (f);
@@@ -9469,15 -9263,6 +9562,15 @@@ x_free_frame_resources (f
       commands to the X server.  */
    if (dpyinfo->display)
      {
 +#ifdef USE_FONT_BACKEND
 +      /* We must free faces before destroying windows because some
 +       font-driver (e.g. xft) access a window while finishing a
 +       face.  */
 +      if (enable_font_backend
 +        && FRAME_FACE_CACHE (f))
 +      free_frame_faces (f);
 +#endif        /* USE_FONT_BACKEND */
 +
        if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
  
@@@ -9872,7 -9657,7 +9965,7 @@@ x_get_font_info (f, font_idx
     If SIZE is > 0, it is the size (maximum bounds width) of fonts
     to be listed.
  
 -   SIZE < 0 means include scalable fonts.
 +   SIZE < 0 means include auto scaled fonts.
  
     Frame F null means we have not yet created any frame on X, and
     consult the first display in x_display_list.  MAXNAMES sets a limit
@@@ -10345,7 -10130,6 +10438,7 @@@ x_load_font (f, fontname, size
      bzero (fontp, sizeof (*fontp));
      fontp->font = font;
      fontp->font_idx = i;
 +    fontp->charset = -1;      /* fs_load_font sets it.  */
      fontp->name = (char *) xmalloc (strlen (fontname) + 1);
      bcopy (fontname, fontp->name, strlen (fontname) + 1);
  
         the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
         (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
         2:0xA020..0xFF7F).  For the moment, we don't know which charset
 -       uses this font.  So, we set information in fontp->encoding[1]
 +       uses this font.  So, we set information in fontp->encoding_type
         which is never used by any charset.  If mapping can't be
         decided, set FONT_ENCODING_NOT_DECIDED.  */
 -    fontp->encoding[1]
 +    fontp->encoding_type
        = (font->max_byte1 == 0
         /* 1-byte font */
         ? (font->min_char_or_byte2 < 0x80
@@@ -10560,160 -10344,6 +10653,160 @@@ x_find_ccl_program (fontp
  }
  
  
 +/* Return a char-table whose elements are t if the font FONT_INFO
 +   contains a glyph for the corresponding character, and nil if
 +   not.  */
 +
 +Lisp_Object
 +x_get_font_repertory (f, font_info)
 +     FRAME_PTR f;
 +     struct font_info *font_info;
 +{
 +  XFontStruct *font = (XFontStruct *) font_info->font;
 +  Lisp_Object table;
 +  int min_byte1, max_byte1, min_byte2, max_byte2;
 +  int c;
 +  struct charset *charset = CHARSET_FROM_ID (font_info->charset);
 +  int offset = CHARSET_OFFSET (charset);
 +
 +  table = Fmake_char_table (Qnil, Qnil);
 +
 +  min_byte1 = font->min_byte1;
 +  max_byte1 = font->max_byte1;
 +  min_byte2 = font->min_char_or_byte2;
 +  max_byte2 = font->max_char_or_byte2;
 +  if (min_byte1 == 0 && max_byte1 == 0)
 +    {
 +      if (! font->per_char || font->all_chars_exist == True)
 +      {
 +        if (offset >= 0)
 +          char_table_set_range (table, offset + min_byte2,
 +                                offset + max_byte2, Qt);
 +        else
 +          for (; min_byte2 <= max_byte2; min_byte2++)
 +            {
 +              c = DECODE_CHAR (charset, min_byte2);
 +              CHAR_TABLE_SET (table, c, Qt);
 +            }
 +      }
 +      else
 +      {
 +        XCharStruct *pcm = font->per_char;
 +        int from = -1;
 +        int i;
 +
 +        for (i = min_byte2; i <= max_byte2; i++, pcm++)
 +          {
 +            if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
 +              {
 +                if (from >= 0)
 +                  {
 +                    if (offset >= 0)
 +                      char_table_set_range (table, offset + from,
 +                                            offset + i - 1, Qt);
 +                    else
 +                      for (; from < i; from++)
 +                        {
 +                          c = DECODE_CHAR (charset, from);
 +                          CHAR_TABLE_SET (table, c, Qt);
 +                        }
 +                    from = -1;
 +                  }
 +              }
 +            else if (from < 0)
 +              from = i;
 +          }
 +        if (from >= 0)
 +          {
 +            if (offset >= 0)
 +              char_table_set_range (table, offset + from, offset + i - 1,
 +                                    Qt);
 +            else
 +              for (; from < i; from++)
 +                {
 +                  c = DECODE_CHAR (charset, from);
 +                  CHAR_TABLE_SET (table, c, Qt);
 +                }
 +          }
 +      }
 +    }
 +  else
 +    {
 +      if (! font->per_char || font->all_chars_exist == True)
 +      {
 +        int i, j;
 +
 +        if (offset >= 0)
 +          for (i = min_byte1; i <= max_byte1; i++)
 +            char_table_set_range
 +              (table, offset + ((i << 8) | min_byte2),
 +               offset + ((i << 8) | max_byte2), Qt);
 +        else
 +          for (i = min_byte1; i <= max_byte1; i++)        
 +            for (j = min_byte2; j <= max_byte2; j++)
 +              {
 +                unsigned code = (i << 8) | j;
 +                c = DECODE_CHAR (charset, code);
 +                CHAR_TABLE_SET (table, c, Qt);
 +              }
 +      }
 +      else
 +      {
 +        XCharStruct *pcm = font->per_char;
 +        int i;
 +
 +        for (i = min_byte1; i <= max_byte1; i++)
 +          {
 +            int from = -1;
 +            int j;
 +
 +            for (j = min_byte2; j <= max_byte2; j++, pcm++)
 +              {
 +                if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
 +                  {
 +                    if (from >= 0)
 +                      {
 +                        if (offset >= 0)
 +                          char_table_set_range
 +                            (table, offset + ((i << 8) | from),
 +                             offset + ((i << 8) | (j - 1)), Qt);
 +                        else
 +                          {
 +                            for (; from < j; from++)
 +                              {
 +                                unsigned code = (i << 8) | from;
 +                                c = ENCODE_CHAR (charset, code);
 +                                CHAR_TABLE_SET (table, c, Qt);
 +                              }
 +                          }
 +                        from = -1;
 +                      }
 +                  }
 +                else if (from < 0)
 +                  from = j;
 +              }
 +            if (from >= 0)
 +              {
 +                if (offset >= 0)
 +                  char_table_set_range
 +                    (table, offset + ((i << 8) | from),
 +                     offset + ((i << 8) | (j - 1)), Qt);
 +                else
 +                  {
 +                    for (; from < j; from++)
 +                      {
 +                        unsigned code = (i << 8) | from;
 +                        c = DECODE_CHAR (charset, code);
 +                        CHAR_TABLE_SET (table, c, Qt);
 +                      }
 +                  }
 +              }
 +          }
 +      }
 +    }
 +
 +  return table;
 +}
  \f
  /***********************************************************************
                            Initialization
@@@ -11210,6 -10840,10 +11303,10 @@@ x_term_init (display_name, xrm_option, 
    dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms)
                                    * dpyinfo->x_dnd_atoms_size);
  
+   dpyinfo->net_supported_atoms = NULL;
+   dpyinfo->nr_net_supported_atoms = 0;
+   dpyinfo->net_supported_window = 0;
    connection = ConnectionNumber (dpyinfo->display);
    dpyinfo->connection = connection;
  
@@@ -11598,6 -11232,8 +11695,6 @@@ syms_of_xterm (
    staticpro (&Qvendor_specific_keysyms);
    Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
  
 -  staticpro (&Qutf_8);
 -  Qutf_8 = intern ("utf-8");
    staticpro (&Qlatin_1);
    Qlatin_1 = intern ("latin-1");
  
diff --combined src/xterm.h
index 35ab08162864bccc107bad17e2948b6eada3feba,13b0b4983ada28b7321e01ea41f21677cc4deff5..141f58168e10dbc19044f2e9284b2b97f0578bfe
@@@ -1,6 -1,6 +1,6 @@@
  /* Definitions and headers for communication with X protocol.
     Copyright (C) 1989, 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003,
-                  2004, 2005, 2006 Free Software Foundation, Inc.
+                  2004, 2005, 2006, 2007 Free Software Foundation, Inc.
  
  This file is part of GNU Emacs.
  
@@@ -396,7 -396,10 +396,10 @@@ struct x_display_inf
    size_t x_dnd_atoms_size;
    size_t x_dnd_atoms_length;
  
-   int have_net_atoms;
+   /* Extended window manager hints, Atoms supported by the window manager  */
+   Atom *net_supported_atoms;
+   int nr_net_supported_atoms;
+   Window net_supported_window;
  };
  
  #ifdef HAVE_X_I18N
@@@ -439,9 -442,6 +442,9 @@@ extern struct font_info *x_get_font_inf
  extern struct font_info *x_load_font P_ ((struct frame *, char *, int));
  extern struct font_info *x_query_font P_ ((struct frame *, char *));
  extern void x_find_ccl_program P_ ((struct font_info *));
 +extern Lisp_Object x_get_font_repertory P_ ((struct frame *,
 +                                           struct font_info *));
 +
  \f
  /* Each X frame object points to its own struct x_output object
     in the output_data.x field.  The x_output structure contains
@@@ -523,10 -523,6 +526,10 @@@ struct x_outpu
    /* Default ASCII font of this frame.  */
    XFontStruct *font;
  
 +#ifdef USE_FONT_BACKEND
 +  struct font *fontp;
 +#endif        /* USE_FONT_BACKEND */
 +
    /* The baseline offset of the default ASCII font.  */
    int baseline_offset;
  
@@@ -712,10 -708,6 +715,10 @@@ enu
  #define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.x->toolbar_height)
  #define FRAME_BASELINE_OFFSET(f) ((f)->output_data.x->baseline_offset)
  
 +#ifdef USE_FONT_BACKEND
 +#define FRAME_FONT_OBJECT(f) ((f)->output_data.x->fontp)
 +#endif        /* USE_FONT_BACKEND */
 +
  /* This gives the x_display_info structure for the display F is on.  */
  #define FRAME_X_DISPLAY_INFO(f) ((f)->output_data.x->display_info)