*** empty log message ***
[elisp/tamago.git] / egg-com.el
1 ;;; egg-com.el --- Communication Routines in Egg Input Method Architecture
2
3 ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc
4
5 ;; Author: Hisashi Miyashita <himi@bird.scphys.kyoto-u.ac.jp>
6 ;;         NIIBE Yutaka <gniibe@chroot.org>
7 ;;         KATAYAMA Yoshio <kate@pfu.co.jp>  ; Korean, Chinese support.
8
9 ;; Maintainer: TOMURA Satoru <tomura@etl.go.jp>
10
11 ;; Keywords: mule, multilingual, input method
12
13 ;; This file is part of EGG.
14
15 ;; EGG is free software; you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; any later version.
19
20 ;; EGG is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 ;; GNU General Public License for more details.
24
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
27 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 ;; Boston, MA 02111-1307, USA.
29
30 ;;; Commentary:
31
32 ;;; Code:
33
34
35 (require 'egg-edep)
36
37 (defvar egg-fixed-euc '(fixed-euc-jp))
38 (make-variable-buffer-local 'egg-fixed-euc)
39 (put 'egg-fixed-euc 'permanent-local t)
40
41 (defvar egg-mb-euc 'euc-japan)
42 (make-variable-buffer-local 'egg-mb-euc)
43 (put 'egg-mb-euc 'permanent-local t)
44
45 ;; Japanese
46
47 (eval-and-compile
48 (define-ccl-program ccl-decode-fixed-euc-jp
49   `(2
50     ((r2 = ,(charset-id 'japanese-jisx0208))
51      (r3 = ,(charset-id 'japanese-jisx0212))
52      (r4 = ,(charset-id 'katakana-jisx0201))
53      (read r0)
54      (loop
55       (read r1)
56       (if (r0 < ?\x80)
57           ((r0 = r1)
58            (if (r1 < ?\x80)
59                (write-read-repeat r0))
60            (write r4)
61            (write-read-repeat r0))
62         ((if (r1 > ?\x80)
63              ((write r2 r0)
64               (r0 = r1)
65               (write-read-repeat r0))
66            ((write r3 r0)
67             (r0 = (r1 | ?\x80))
68             (write-read-repeat r0)))))))))
69
70 (define-ccl-program ccl-encode-fixed-euc-jp
71   `(2
72     ((read r0)
73      (loop
74       (if (r0 == ,(charset-id 'latin-jisx0201))                   ; Unify
75           ((read r0)
76            (r0 &= ?\x7f)))
77       (if (r0 < ?\x80)                                            ;G0
78           ((write 0)
79            (write-read-repeat r0)))
80       (r6 = (r0 == ,(charset-id 'japanese-jisx0208)))
81       (r6 |= (r0 == ,(charset-id 'japanese-jisx0208-1978)))
82       (if r6                                                      ;G1
83           ((read r0)
84            (write r0)
85            (read r0)
86            (write-read-repeat r0)))
87       (if (r0 == ,(charset-id 'katakana-jisx0201))                ;G2
88           ((read r0)
89            (write 0)
90            (write-read-repeat r0)))
91       (if (r0 == ,(charset-id 'japanese-jisx0212))                ;G3
92           ((read r0)
93            (write r0)
94            (read r0)
95            (r0 &= ?\x7f)
96            (write-read-repeat r0)))
97       (read r0)
98       (repeat)))))
99 )
100
101 (make-coding-system 'fixed-euc-jp 4 ?W "Coding System for fixed EUC Japanese"
102                     (cons ccl-decode-fixed-euc-jp ccl-encode-fixed-euc-jp))
103
104 ;; Korean
105
106 (eval-and-compile
107 (define-ccl-program ccl-decode-fixed-euc-kr
108   `(2
109     ((r2 = ,(charset-id 'korean-ksc5601))
110      (read r0)
111      (loop
112       (read r1)
113       (if (r0 < ?\x80)
114           (r0 = r1 & ?\x7f)
115         ((write r2 r0)
116          (r0 = r1 | ?\x80)))
117       (write-read-repeat r0)))))
118
119 (define-ccl-program ccl-encode-fixed-euc-kr
120   `(2
121     ((read r0)
122      (loop
123       (if (r0 < ?\x80)
124           ((write 0)
125            (write-read-repeat r0)))
126       (if (r0 == ,(charset-id 'korean-ksc5601))
127           ((read r0)
128            (write r0)
129            (read r0)
130            (write-read-repeat r0)))
131       (read r0)
132       (repeat)))))
133 )
134
135 (make-coding-system 'fixed-euc-kr 4 ?W "Coding System for fixed EUC Korean"
136                     (cons ccl-decode-fixed-euc-kr ccl-encode-fixed-euc-kr))
137
138 ;; Chinese
139
140 (defconst egg-pinyin-shengmu
141   '((""  . 0)  ("B" . 1)  ("C"  . 2)  ("Ch" . 3)  ("D" . 4)
142     ("F" . 5)  ("G" . 6)  ("H"  . 7)  ("J"  . 8)  ("K" . 9)
143     ("L" . 10) ("M" . 11) ("N"  . 12) ("P"  . 13) ("Q" . 14)
144     ("R" . 15) ("S" . 16) ("Sh" . 17) ("T"  . 18) ("W" . 19)
145     ("X" . 20) ("Y" . 21) ("Z"  . 22) ("Zh" . 23)))
146
147 (defconst egg-pinyin-yunmu
148   '(("\e(0@\e(B"      0 0) ("\e(0@\e(B"      0 1) ("\e(0@\e(B"      0 3) ("\e(0@\e(B"      0 5) ("\e(0@\e(B"      0 7)
149     ("a\e(0@\e(B"     1 0) ("\e(0!@\e(B"     1 1) ("\e(0"@\e(B"     1 3) ("\e(0#@\e(B"     1 5) ("\e(0$@\e(B"     1 7)
150     ("ai\e(0@\e(B"    2 0) ("\e(0!\e(Bi\e(0@\e(B"    2 1) ("\e(0"\e(Bi\e(0@\e(B"    2 3) ("\e(0#\e(Bi\e(0@\e(B"    2 5) ("\e(0$\e(Bi\e(0@\e(B"    2 7)
151     ("an\e(0@\e(B"    3 0) ("\e(0!\e(Bn\e(0@\e(B"    3 1) ("\e(0"\e(Bn\e(0@\e(B"    3 3) ("\e(0#\e(Bn\e(0@\e(B"    3 5) ("\e(0$\e(Bn\e(0@\e(B"    3 7)
152     ("ang\e(0@\e(B"   4 0) ("\e(0!\e(Bng\e(0@\e(B"   4 1) ("\e(0"\e(Bng\e(0@\e(B"   4 3) ("\e(0#\e(Bng\e(0@\e(B"   4 5) ("\e(0$\e(Bng\e(0@\e(B"   4 7)
153     ("ao\e(0@\e(B"    5 0) ("\e(0!\e(Bo\e(0@\e(B"    5 1) ("\e(0"\e(Bo\e(0@\e(B"    5 3) ("\e(0#\e(Bo\e(0@\e(B"    5 5) ("\e(0$\e(Bo\e(0@\e(B"    5 7)
154     ("e\e(0@\e(B"     6 0) ("\e(0%@\e(B"     6 1) ("\e(0&@\e(B"     6 3) ("\e(0'@\e(B"     6 5) ("\e(0(@\e(B"     6 7)
155     ("ei\e(0@\e(B"    7 0) ("\e(0%\e(Bi\e(0@\e(B"    7 1) ("\e(0&\e(Bi\e(0@\e(B"    7 3) ("\e(0'\e(Bi\e(0@\e(B"    7 5) ("\e(0(\e(Bi\e(0@\e(B"    7 7)
156     ("en\e(0@\e(B"    8 0) ("\e(0%\e(Bn\e(0@\e(B"    8 1) ("\e(0&\e(Bn\e(0@\e(B"    8 3) ("\e(0'\e(Bn\e(0@\e(B"    8 5) ("\e(0(\e(Bn\e(0@\e(B"    8 7)
157     ("eng\e(0@\e(B"   9 0) ("\e(0%\e(Bng\e(0@\e(B"   9 1) ("\e(0&\e(Bng\e(0@\e(B"   9 3) ("\e(0'\e(Bng\e(0@\e(B"   9 5) ("\e(0(\e(Bng\e(0@\e(B"   9 7)
158     ("er\e(0@\e(B"   10 0) ("\e(0%\e(Br\e(0@\e(B"   10 1) ("\e(0&\e(Br\e(0@\e(B"   10 3) ("\e(0'\e(Br\e(0@\e(B"   10 5) ("\e(0(\e(Br\e(0@\e(B"   10 7)
159     ("i\e(0@\e(B"    11 0) ("\e(0)@\e(B"    11 1) ("\e(0*@\e(B"    11 3) ("\e(0+@\e(B"    11 5) ("\e(0,@\e(B"    11 7)
160     ("ia\e(0@\e(B"   12 0) ("i\e(0!@\e(B"   12 1) ("i\e(0"@\e(B"   12 3) ("i\e(0#@\e(B"   12 5) ("i\e(0$@\e(B"   12 7)
161     ("ian\e(0@\e(B"  13 0) ("i\e(0!\e(Bn\e(0@\e(B"  13 1) ("i\e(0"\e(Bn\e(0@\e(B"  13 3) ("i\e(0#\e(Bn\e(0@\e(B"  13 5) ("i\e(0$\e(Bn\e(0@\e(B"  13 7)
162     ("iang\e(0@\e(B" 14 0) ("i\e(0!\e(Bng\e(0@\e(B" 14 1) ("i\e(0"\e(Bng\e(0@\e(B" 14 3) ("i\e(0#\e(Bng\e(0@\e(B" 14 5) ("i\e(0$\e(Bng\e(0@\e(B" 14 7)
163     ("iao\e(0@\e(B"  15 0) ("i\e(0!\e(Bo\e(0@\e(B"  15 1) ("i\e(0"\e(Bo\e(0@\e(B"  15 3) ("i\e(0#\e(Bo\e(0@\e(B"  15 5) ("i\e(0$\e(Bo\e(0@\e(B"  15 7)
164     ("ie\e(0@\e(B"   16 0) ("i\e(0%@\e(B"   16 1) ("i\e(0&@\e(B"   16 3) ("i\e(0'@\e(B"   16 5) ("i\e(0(@\e(B"   16 7)
165     ("in\e(0@\e(B"   17 0) ("\e(0)\e(Bn\e(0@\e(B"   17 1) ("\e(0*\e(Bn\e(0@\e(B"   17 3) ("\e(0+\e(Bn\e(0@\e(B"   17 5) ("\e(0,\e(Bn\e(0@\e(B"   17 7)
166     ("ing\e(0@\e(B"  18 0) ("\e(0)\e(Bng\e(0@\e(B"  18 1) ("\e(0*\e(Bng\e(0@\e(B"  18 3) ("\e(0+\e(Bng\e(0@\e(B"  18 5) ("\e(0,\e(Bng\e(0@\e(B"  18 7)
167     ("iong\e(0@\e(B" 19 0) ("i\e(0-\e(Bng\e(0@\e(B" 19 1) ("i\e(0.\e(Bng\e(0@\e(B" 19 3) ("i\e(0/\e(Bng\e(0@\e(B" 19 5) ("i\e(00\e(Bng\e(0@\e(B" 19 7)
168     ("iu\e(0@\e(B"   20 0) ("i\e(01@\e(B"   20 1) ("i\e(02@\e(B"   20 3) ("i\e(03@\e(B"   20 5) ("i\e(04@\e(B"   20 7)
169     ("m\e(0@\e(B"    21 0) ("m\e(0@\e(B"    21 1) ("m\e(0@\e(B"    21 3) ("m\e(0@\e(B"    21 5) ("m\e(0@\e(B"    21 7)
170     ("n\e(0@\e(B"    22 0) ("n\e(0@\e(B"    22 1) ("\e(0=@\e(B"    22 3) ("\e(0>@\e(B"    22 5) ("\e(0?@\e(B"    22 7)
171     ("ng\e(0@\e(B"   23 0) ("ng\e(0@\e(B"   23 1) ("ng\e(0@\e(B"   23 3) ("ng\e(0@\e(B"   23 5) ("ng\e(0@\e(B"   23 7)
172     ("o\e(0@\e(B"    24 0) ("\e(0-@\e(B"    24 1) ("\e(0.@\e(B"    24 3) ("\e(0/@\e(B"    24 5) ("\e(00@\e(B"    24 7)
173     ("ong\e(0@\e(B"  25 0) ("\e(0-\e(Bng\e(0@\e(B"  25 1) ("\e(0.\e(Bng\e(0@\e(B"  25 3) ("\e(0/\e(Bng\e(0@\e(B"  25 5) ("\e(00\e(Bng\e(0@\e(B"  25 7)
174     ("ou\e(0@\e(B"   26 0) ("\e(0-\e(Bu\e(0@\e(B"   26 1) ("\e(0.\e(Bu\e(0@\e(B"   26 3) ("\e(0/\e(Bu\e(0@\e(B"   26 5) ("\e(00\e(Bu\e(0@\e(B"   26 7)
175     ("u\e(0@\e(B"    27 0) ("\e(01@\e(B"    27 1) ("\e(02@\e(B"    27 3) ("\e(03@\e(B"    27 5) ("\e(04@\e(B"    27 7)
176     ("ua\e(0@\e(B"   28 0) ("u\e(0!@\e(B"   28 1) ("u\e(0"@\e(B"   28 3) ("u\e(0#@\e(B"   28 5) ("u\e(0$@\e(B"   28 7)
177     ("uai\e(0@\e(B"  29 0) ("u\e(0!\e(Bi\e(0@\e(B"  29 1) ("u\e(0"\e(Bi\e(0@\e(B"  29 3) ("u\e(0#\e(Bi\e(0@\e(B"  29 5) ("u\e(0$\e(Bi\e(0@\e(B"  29 7)
178     ("uan\e(0@\e(B"  30 0) ("u\e(0!\e(Bn\e(0@\e(B"  30 1) ("u\e(0"\e(Bn\e(0@\e(B"  30 3) ("u\e(0#\e(Bn\e(0@\e(B"  30 5) ("u\e(0$\e(Bn\e(0@\e(B"  30 7)
179     ("uang\e(0@\e(B" 31 0) ("u\e(0!\e(Bng\e(0@\e(B" 31 1) ("u\e(0"\e(Bng\e(0@\e(B" 31 3) ("u\e(0#\e(Bng\e(0@\e(B" 31 5) ("u\e(0$\e(Bng\e(0@\e(B" 31 7)
180     ("ue\e(0@\e(B"   32 0) ("u\e(0%@\e(B"   32 1) ("u\e(0&@\e(B"   32 3) ("u\e(0'@\e(B"   32 5) ("u\e(0(@\e(B"   32 7)
181     ("ui\e(0@\e(B"   33 0) ("u\e(0)@\e(B"   33 1) ("u\e(0*@\e(B"   33 3) ("u\e(0+@\e(B"   33 5) ("u\e(0,@\e(B"   33 7)
182     ("un\e(0@\e(B"   34 0) ("\e(01\e(Bn\e(0@\e(B"   34 1) ("\e(02\e(Bn\e(0@\e(B"   34 3) ("\e(03\e(Bn\e(0@\e(B"   34 5) ("\e(04\e(Bn\e(0@\e(B"   34 7)
183     ("uo\e(0@\e(B"   35 0) ("u\e(0-@\e(B"   35 1) ("u\e(0.@\e(B"   35 3) ("u\e(0/@\e(B"   35 5) ("u\e(00@\e(B"   35 7)
184     ("\e(09@\e(B"    36 0) ("\e(05@\e(B"    36 1) ("\e(06@\e(B"    36 3) ("\e(07@\e(B"    36 5) ("\e(08@\e(B"    36 7)
185     ("\e(09\e(Be\e(0@\e(B"   37 0) ("\e(09%@\e(B"   37 1) ("\e(09&@\e(B"   37 3) ("\e(09'@\e(B"   37 5) ("\e(09(@\e(B"   37 7)
186     ("0\e(0@\e(B"    38 0) ("1\e(0@\e(B"    38 1) ("2\e(0@\e(B"    38 3) ("3\e(0@\e(B"    38 5) ("4\e(0@\e(B"    38 7)))
187
188 (defconst egg-pinyin-table
189   [
190    0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
191    0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1
192    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
193    0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
194    0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 0 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
195    0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
196    0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
197    0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
198    0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
199    0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
200    0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1
201    0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 1 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
202    0 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 0 1 1 1 1
203    0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
204    0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
205    0 0 0 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 0 0 1
206    0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
207    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 0 1
208    0 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
209    0 1 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1
210    0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
211    0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 1 0 0 0 1
212    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
213    0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
214    ])
215
216 (defconst egg-zhuyin-shengmu
217   '((""  .  0) ("\e(0E\e(B" .  1) ("\e(0X\e(B" .  2) ("\e(0T\e(B" .  3) ("\e(0I\e(B" .  4)
218     ("\e(0H\e(B" .  5) ("\e(0M\e(B" .  6) ("\e(0O\e(B" .  7) ("\e(0P\e(B" .  8) ("\e(0N\e(B" .  9)
219     ("\e(0L\e(B" . 10) ("\e(0G\e(B" . 11) ("\e(0K\e(B" . 12) ("\e(0F\e(B" . 13) ("\e(0Q\e(B" . 14)
220     ("\e(0V\e(B" . 15) ("\e(0Y\e(B" . 16) ("\e(0U\e(B" . 17) ("\e(0J\e(B" . 18) ("\e(0h\e(B" . 19)
221     ("\e(0R\e(B" . 20) ("\e(0g\e(B" . 21) ("\e(0W\e(B" . 22) ("\e(0S\e(B" . 23)))
222
223 (defconst egg-zhuyin-yunmu
224   '(("\e(0@\e(B"    0 0) ("\e(0A\e(B"    0 1) ("\e(0B\e(B"    0 3) ("\e(0C\e(B"    0 5) ("\e(0D\e(B"    0 7) ; i
225     ("\e(0Z@\e(B"   1 0) ("\e(0ZA\e(B"   1 1) ("\e(0ZB\e(B"   1 3) ("\e(0ZC\e(B"   1 5) ("\e(0ZD\e(B"   1 7) ; a
226     ("\e(0^@\e(B"   2 0) ("\e(0^A\e(B"   2 1) ("\e(0^B\e(B"   2 3) ("\e(0^C\e(B"   2 5) ("\e(0^D\e(B"   2 7) ; ai
227     ("\e(0b@\e(B"   3 0) ("\e(0bA\e(B"   3 1) ("\e(0bB\e(B"   3 3) ("\e(0bC\e(B"   3 5) ("\e(0bD\e(B"   3 7) ; an
228     ("\e(0d@\e(B"   4 0) ("\e(0dA\e(B"   4 1) ("\e(0dB\e(B"   4 3) ("\e(0dC\e(B"   4 5) ("\e(0dD\e(B"   4 7) ; ang
229     ("\e(0`@\e(B"   5 0) ("\e(0`A\e(B"   5 1) ("\e(0`B\e(B"   5 3) ("\e(0`C\e(B"   5 5) ("\e(0`D\e(B"   5 7) ; ao
230     ("\e(0\@\e(B"   6 0) ("\e(0\A\e(B"   6 1) ("\e(0\B\e(B"   6 3) ("\e(0\C\e(B"   6 5) ("\e(0\D\e(B"   6 7) ; e
231     ("\e(0_@\e(B"   7 0) ("\e(0_A\e(B"   7 1) ("\e(0_B\e(B"   7 3) ("\e(0_C\e(B"   7 5) ("\e(0_D\e(B"   7 7) ; ei
232     ("\e(0c@\e(B"   8 0) ("\e(0cA\e(B"   8 1) ("\e(0cB\e(B"   8 3) ("\e(0cC\e(B"   8 5) ("\e(0cD\e(B"   8 7) ; en
233     ("\e(0e@\e(B"   9 0) ("\e(0eA\e(B"   9 1) ("\e(0eB\e(B"   9 3) ("\e(0eC\e(B"   9 5) ("\e(0eD\e(B"   9 7) ; eng
234     ("\e(0f@\e(B"  10 0) ("\e(0fA\e(B"  10 1) ("\e(0fB\e(B"  10 3) ("\e(0fC\e(B"  10 5) ("\e(0fD\e(B"  10 7) ; er
235     ("\e(0g@\e(B"  11 0) ("\e(0gA\e(B"  11 1) ("\e(0gB\e(B"  11 3) ("\e(0gC\e(B"  11 5) ("\e(0gD\e(B"  11 7) ; i
236     ("\e(0gZ@\e(B" 12 0) ("\e(0gZA\e(B" 12 1) ("\e(0gZB\e(B" 12 3) ("\e(0gZC\e(B" 12 5) ("\e(0gZD\e(B" 12 7) ; ia
237     ("\e(0gb@\e(B" 13 0) ("\e(0gbA\e(B" 13 1) ("\e(0gbB\e(B" 13 3) ("\e(0gbC\e(B" 13 5) ("\e(0gbD\e(B" 13 7) ; ian
238     ("\e(0gd@\e(B" 14 0) ("\e(0gdA\e(B" 14 1) ("\e(0gdB\e(B" 14 3) ("\e(0gdC\e(B" 14 5) ("\e(0gdD\e(B" 14 7) ; iang
239     ("\e(0g`@\e(B" 15 0) ("\e(0g`A\e(B" 15 1) ("\e(0g`B\e(B" 15 3) ("\e(0g`C\e(B" 15 5) ("\e(0g`D\e(B" 15 7) ; iao
240     ("\e(0g]@\e(B" 16 0) ("\e(0g]A\e(B" 16 1) ("\e(0g]B\e(B" 16 3) ("\e(0g]C\e(B" 16 5) ("\e(0g]D\e(B" 16 7) ; ie
241     ("\e(0gc@\e(B" 17 0) ("\e(0gcA\e(B" 17 1) ("\e(0gcB\e(B" 17 3) ("\e(0gcC\e(B" 17 5) ("\e(0gcD\e(B" 17 7) ; in
242     ("\e(0ge@\e(B" 18 0) ("\e(0geA\e(B" 18 1) ("\e(0geB\e(B" 18 3) ("\e(0geC\e(B" 18 5) ("\e(0geD\e(B" 18 7) ; ing
243     ("\e(0ie@\e(B" 19 0) ("\e(0ieA\e(B" 19 1) ("\e(0ieB\e(B" 19 3) ("\e(0ieC\e(B" 19 5) ("\e(0ieD\e(B" 19 7) ; iong
244     ("\e(0ga@\e(B" 20 0) ("\e(0gaA\e(B" 20 1) ("\e(0gaB\e(B" 20 3) ("\e(0gaC\e(B" 20 5) ("\e(0gaD\e(B" 20 7) ; iu
245     ("\e(0G@\e(B"  21 0) ("\e(0GA\e(B"  21 1) ("\e(0GB\e(B"  21 3) ("\e(0GC\e(B"  21 5) ("\e(0GD\e(B"  21 7) ; m
246     ("\e(0K@\e(B"  22 0) ("\e(0KA\e(B"  22 1) ("\e(0KB\e(B"  22 3) ("\e(0KC\e(B"  22 5) ("\e(0KD\e(B"  22 7) ; n
247     ("@\e(0@\e(B"  23 0) ("@\e(0A\e(B"  23 1) ("@\e(0B\e(B"  23 3) ("@\e(0C\e(B"  23 5) ("@\e(0D\e(B"  23 7) ; ng
248     ("\e(0[@\e(B"  24 0) ("\e(0[A\e(B"  24 1) ("\e(0[B\e(B"  24 3) ("\e(0[C\e(B"  24 5) ("\e(0[D\e(B"  24 7) ; o
249     ("\e(0he@\e(B" 25 0) ("\e(0heA\e(B" 25 1) ("\e(0heB\e(B" 25 3) ("\e(0heC\e(B" 25 5) ("\e(0heD\e(B" 25 7) ; ong
250     ("\e(0a@\e(B"  26 0) ("\e(0aA\e(B"  26 1) ("\e(0aB\e(B"  26 3) ("\e(0aC\e(B"  26 5) ("\e(0aD\e(B"  26 7) ; ou
251     ("\e(0h@\e(B"  27 0) ("\e(0hA\e(B"  27 1) ("\e(0hB\e(B"  27 3) ("\e(0hC\e(B"  27 5) ("\e(0hD\e(B"  27 7) ; u
252     ("\e(0hZ@\e(B" 28 0) ("\e(0hZA\e(B" 28 1) ("\e(0hZB\e(B" 28 3) ("\e(0hZC\e(B" 28 5) ("\e(0hZD\e(B" 28 7) ; ua
253     ("\e(0h^@\e(B" 29 0) ("\e(0h^A\e(B" 29 1) ("\e(0h^B\e(B" 29 3) ("\e(0h^C\e(B" 29 5) ("\e(0h^D\e(B" 29 7) ; uai
254     ("\e(0hb@\e(B" 30 0) ("\e(0hbA\e(B" 30 1) ("\e(0hbB\e(B" 30 3) ("\e(0hbC\e(B" 30 5) ("\e(0hbD\e(B" 30 7) ; uan
255     ("\e(0hd@\e(B" 31 0) ("\e(0hdA\e(B" 31 1) ("\e(0hdB\e(B" 31 3) ("\e(0hdC\e(B" 31 5) ("\e(0hdD\e(B" 31 7) ; uang
256     ("\e(0i]@\e(B" 37 0) ("\e(0i]A\e(B" 37 1) ("\e(0i]B\e(B" 37 3) ("\e(0i]C\e(B" 37 5) ("\e(0i]D\e(B" 37 7) ; ue
257     ("\e(0h_@\e(B" 33 0) ("\e(0h_A\e(B" 33 1) ("\e(0h_B\e(B" 33 3) ("\e(0h_C\e(B" 33 5) ("\e(0h_D\e(B" 33 7) ; ui
258     ("\e(0hc@\e(B" 34 0) ("\e(0hcA\e(B" 34 1) ("\e(0hcB\e(B" 34 3) ("\e(0hcC\e(B" 34 5) ("\e(0hcD\e(B" 34 7) ; un
259     ("\e(0h[@\e(B" 35 0) ("\e(0h[A\e(B" 35 1) ("\e(0h[B\e(B" 35 3) ("\e(0h[C\e(B" 35 5) ("\e(0h[D\e(B" 35 7) ; uo
260     ("\e(0i@\e(B"  36 0) ("\e(0iA\e(B"  36 1) ("\e(0iB\e(B"  36 3) ("\e(0iC\e(B"  36 5) ("\e(0iD\e(B"  36 7) ; \e(09\e(B
261     ("\e(0i]@\e(B" 37 0) ("\e(0i]A\e(B" 37 1) ("\e(0i]B\e(B" 37 3) ("\e(0i]C\e(B" 37 5) ("\e(0i]D\e(B" 37 7) ; \e(09\e(Be
262     ("0\e(0@\e(B"  38 0) ("1\e(0A\e(B"  38 1) ("2\e(0B\e(B"  38 3) ("3\e(0C\e(B"  38 5) ("4\e(0D\e(B"  38 7) ; undefined
263     ("\e(0ib@\e(B" 39 0) ("\e(0ibA\e(B" 39 1) ("\e(0ibB\e(B" 39 3) ("\e(0ibC\e(B" 39 5) ("\e(0ibD\e(B" 39 7) ; \e(09\e(Ban
264     ("\e(0ic@\e(B" 40 0) ("\e(0icA\e(B" 40 1) ("\e(0icB\e(B" 40 3) ("\e(0icC\e(B" 40 5) ("\e(0icD\e(B" 40 7) ; \e(09\e(Bn
265     ))
266
267 (defconst egg-zhuyin-table
268   [
269    ;; empty ShengMu
270    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
271    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x9586 ?\x0000 ?\x9592 ?\x9599
272    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x0000
273    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x959b ?\x95a0 ?\x0000 ?\x959e
274    ?\x95a2
275    ;; ShengMu B
276    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
277    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
278    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000
279    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
280    ?\x0000
281    ;; ShengMu C
282    ?\x828b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
283    ?\x0000 ?\x0280 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
284    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
285    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
286    ?\x0000
287    ;; ShengMu Ch
288    ?\x838b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
289    ?\x0000 ?\x0380 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
290    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
291    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
292    ?\x0000
293    ;; ShengMu D
294    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
295    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000
296    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
297    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
298    ?\x0000
299    ;; ShengMu F
300    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
301    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
302    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
303    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
304    ?\x0000
305    ;; ShengMu G
306    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
307    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
308    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
309    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
310    ?\x0000
311    ;; ShengMu H
312    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
313    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
314    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
315    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
316    ?\x0000
317    ;; ShengMu J
318    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
319    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
320    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x08a4 ?\x0000 ?\x0000
321    ?\x08a7 ?\x0000 ?\x08a5 ?\x0000 ?\x08a8 ?\x0000 ?\x889b ?\x88a0 ?\x8000 ?\x889e
322    ?\x88a2
323    ;; ShengMu K
324    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
325    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
326    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
327    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
328    ?\x0000
329    ;; ShengMu L
330    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000
331    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
332    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
333    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
334    ?\x0000
335    ;; ShengMu M
336    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
337    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
338    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
339    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
340    ?\x0000
341    ;; ShengMu N
342    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
343    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
344    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
345    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
346    ?\x0000
347    ;; ShengMu P
348    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
349    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
350    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
351    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
352    ?\x0000 
353    ;; ShengMu Q
354    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
355    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
356    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0ea4 ?\x0000 ?\x0000
357    ?\x0ea7 ?\x0000 ?\x0ea5 ?\x0000 ?\x0ea8 ?\x0000 ?\x8e9b ?\x8ea0 ?\x8000 ?\x8e9e
358    ?\x8ea2
359    ;; ShengMu R
360    ?\x8f8b ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
361    ?\x0000 ?\x0f80 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
362    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
363    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
364    ?\x0000
365    ;; ShengMu S
366    ?\x908b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
367    ?\x0000 ?\x1080 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
368    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
369    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
370    ?\x0000
371    ;; ShengMu Sh
372    ?\x918b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
373    ?\x0000 ?\x1180 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
374    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
375    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
376    ?\x0000
377    ;; ShengMu T
378    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000
379    ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000
380    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
381    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
382    ?\x0000
383    ;; ShengMu W
384    ?\x939b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
385    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
386    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x1380 ?\x0000 ?\x0000
387    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
388    ?\x0000
389    ;; ShengMu X
390    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
391    ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
392    ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x14a4 ?\x0000 ?\x0000
393    ?\x14a7 ?\x0000 ?\x14a5 ?\x0000 ?\x14a8 ?\x0000 ?\x949b ?\x94a0 ?\x8000 ?\x949e
394    ?\x94a2
395    ;; ShengMu Y 
396    ?\x958b ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0090 ?\x0000 ?\x9591 ?\x9592
397    ?\x0000 ?\x1580 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x1588 ?\x1589 ?\x0000
398    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0093 ?\x8000 ?\x00a4 ?\x0000 ?\x0000
399    ?\x00a7 ?\x0000 ?\x00a5 ?\x0000 ?\x00a8 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
400    ?\x0000
401    ;; ShengMu Z
402    ?\x968b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
403    ?\x0000 ?\x1680 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
404    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
405    ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
406    ?\x0000
407    ;; ShengMu Zh 
408    ?\x978b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
409    ?\x0000 ?\x1780 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
410    ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
411    ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
412    ?\x0000
413    ])
414
415 (defconst egg-chinese-syllable-max-len
416   (max (length "Zhu\e(0!\e(Bng\e(0@\e(B") (length "\e(0ShdA\e(B")))
417
418 (defun egg-chinese-syllable (str pos)
419   (setq str (substring str pos (min (length str)
420                                     (+ pos egg-chinese-syllable-max-len))))
421   (or (car (egg-pinyin-syllable str))
422       (car (egg-zhuyin-syllable str))))
423
424 (defsubst egg-make-fixed-euc-china-code (s y)
425   (cons
426    (+ (* 2 (nth 1 y)) (logand (nth 2 y) 1) 32)
427    (+ (* 4 (if (= s 0) 20 s)) (lsh (nth 2 y) -1) 156)))
428
429 (defun egg-pinyin-syllable (str)
430   (if (eq (string-match "^[A-Za-z\e(0!\e(B-\e(0?\e(B]+\e(0@\e(B" str) 0)
431       (let (s y end)
432         (setq end (match-end 0))
433         (cond
434          ((setq s (cdr (assoc (substring str 0 2) egg-pinyin-shengmu)))
435           (setq y (substring str 2 end)))
436          ((setq s (cdr (assoc (substring str 0 1) egg-pinyin-shengmu)))
437           (setq y (substring str 1 end)))
438          (t
439           (setq s 0 y (substring str 0 end))))
440         (if (and (setq y (assoc y egg-pinyin-yunmu))
441                  (= (aref egg-pinyin-table (+ (* 39 s) (nth 1 y))) 1))
442             (cons end (egg-make-fixed-euc-china-code s y))))))
443
444 (defun egg-zhuyin-syllable (str)
445   (if (eq (string-match "^[\e(0E\e(B-\e(0i\e(B@0-4]+[\e(0@ABCD\e(B]" str) 0)
446       (let (end s y c z (zhuyin-len (length "\e(0E\e(B")))
447         (setq end (match-end 0)
448               c (substring str 0 zhuyin-len)
449               s (cdr (assoc c egg-zhuyin-shengmu))
450               y (assoc (substring str zhuyin-len end) egg-zhuyin-yunmu))
451         (if (or (null (and s y))
452                 (and (or (eq s 11) (eq s 12)) (eq (nth 1 y) 0))) ; [\e(0GK\e(B][\e(0@ABCD\e(B]
453             (setq s 0
454                   y (assoc (substring str 0 end) egg-zhuyin-yunmu)))
455         (if (and y
456                  (setq z (aref egg-zhuyin-table (+ (* 41 s) (nth 1 y))))
457                  (/= (logand z ?\x8000) 0))
458             (if (/= (logand z ?\x80) 0)
459                 (cons end (egg-make-fixed-euc-china-code
460                            (logand (lsh z -8) ?\x7f)
461                            (list nil (logand z ?\x7f) (nth 2 y))))
462               (cons end (egg-make-fixed-euc-china-code s y)))))))
463
464 (defun encode-fixed-euc-china-region (beg end type)
465   "Encode the text in the region to EUC-CN/TW."
466   (let (s syl c cset)
467     (save-excursion
468       (save-restriction
469         (narrow-to-region beg end)
470         (goto-char (point-min))
471         (while (< (point) (point-max))
472           (setq s (buffer-substring
473                    (point)
474                    (min (point-max) (+ (point) egg-chinese-syllable-max-len))))
475           (cond
476            ((setq syl (egg-pinyin-syllable s))
477             (delete-region (point) (+ (point) (car syl)))
478             (insert (car (cdr syl)) (cdr (cdr syl))))
479            ((setq syl (egg-zhuyin-syllable s))
480             (delete-region (point) (+ (point) (car syl)))
481             (insert (car (cdr syl)) (cdr (cdr syl))))
482            (t
483             (setq c (split-char (following-char))
484                   cset (car c))
485             (cond
486              ((or (and (eq cset 'chinese-gb2312) (eq type 'cn))
487                   (and (eq cset 'chinese-cns11643-1) (eq type 'tw)))
488               (delete-char 1)
489               (insert (+ (nth 1 c) 128) (+ (nth 2 c) 128)))
490              ((and (eq cset 'chinese-cns11643-2) (eq type 'tw))
491               (delete-char 1)
492               (insert (+ (nth 1 c) 128) (nth 2 c)))
493              ((eq cset 'chinese-sisheng)
494               (delete-char 1)
495               (insert 0 (+ (nth 1 c) 128)))
496              ((eq cset 'ascii)
497               (delete-char 1)
498               (insert 0 (nth 1 c)))
499              (t
500               (delete-char 1))))))
501         (- (point-max) (point-min))))))
502
503 (defun pre-write-encode-fixed-euc-china (from to type)
504   (let ((buf (current-buffer))
505         (work (get-buffer-create " *pre-write-encoding-work*")))
506     (set-buffer work)
507     (erase-buffer)
508     (if (null (stringp from))
509         (save-excursion
510           (set-buffer buf)
511           (setq from (buffer-substring from to))))
512     (insert (string-as-multibyte from))
513     (encode-fixed-euc-china-region 1 (point-max) type)
514     nil))
515
516 (defun pre-write-encode-euc-cn (from to)
517   (pre-write-encode-fixed-euc-china from to 'cn))
518
519 (defun pre-write-encode-euc-tw (from to)
520   (pre-write-encode-fixed-euc-china from to 'tw))
521
522 (defun decode-fixed-euc-china-region (beg end type zhuyin)
523   "Decode EUC-CN/TW encoded text in the region.
524 Return the length of resulting text."
525   (let ((str (string-as-unibyte (buffer-substring beg end)))
526         (i 0)
527         (char (make-string 3 0))
528         l c0 c1 s y ss)
529     (delete-region beg end)
530     (setq l (1- (length str)))
531     (while (< i l)
532       (setq c0 (aref str i)
533             c1 (aref str (1+ i))
534             i  (+ i 2))
535       (cond
536        ((eq c0 0)
537         (if (<= c1 ?\xa0)
538             (insert c1)
539           (aset char 0 leading-code-private-11)
540           (aset char 1 (charset-id 'chinese-sisheng))
541           (aset char 2 c1)
542           (insert (string-as-multibyte char))))
543        ((>= c0 ?\x80)
544         (cond
545          ((eq type 'cn)
546           (aset char 0 (charset-id 'chinese-gb2312))
547           (aset char 1 c0)
548           (aset char 2 (logior c1 ?\x80)))
549          ((>= c1 ?\x80)
550           (aset char 0 (charset-id 'chinese-cns11643-1))
551           (aset char 1 c0)
552           (aset char 2 c1))
553          (t
554           (aset char 0 (charset-id 'chinese-cns11643-2))
555           (aset char 1 c0)
556           (aset char 2 (+ c1 ?\x80))))
557         (insert (string-as-multibyte char)))
558        (t
559         (setq c1 (logand c1 ?\x7f))
560         (setq s (- (lsh c1 -2) 7);;(+ (lsh (- c1 32) -2) 1)
561               y (- (lsh c0 -1) 16);;(lsh (- c0 32) -1)
562               ss (+ (logand c0 1) (logand c1 3)))
563         (if (and (eq s 20)
564                  (eq (aref egg-pinyin-table (+ (* 39 20) y)) 0))
565             (setq s 0))
566         (if (null zhuyin)
567             (setq s (car (nth s egg-pinyin-shengmu))
568                   y (car (nth (+ (* 5 y) ss) egg-pinyin-yunmu)))
569           (setq c0 (aref egg-zhuyin-table (+ (* 41 s) y)))
570           (if (eq (logand c0 ?\x8080) ?\x80)
571               (setq s (lsh c0 -8)
572                     y (logand c0 ?\x7f)))
573           (setq s (car (nth s egg-zhuyin-shengmu))
574                 y (car (nth (+ (* 5 y) ss) egg-zhuyin-yunmu))))
575         (if enable-multibyte-characters
576             (insert s y)
577           (insert (string-as-unibyte s) (string-as-unibyte y))))))
578     (- (point) beg)))
579
580 (defun post-read-decode-fixed-euc-china (len type zhuyin)
581   (let ((pos (point))
582         (buffer-modified-p (buffer-modified-p)))
583     (prog1
584         (decode-fixed-euc-china-region pos (+ pos len) type zhuyin)
585       (set-buffer-modified-p buffer-modified-p))))
586
587 (defun post-read-decode-euc-py-cn (len)
588   (post-read-decode-fixed-euc-china len 'cn nil))
589
590 (defun post-read-decode-euc-zy-cn (len)
591   (post-read-decode-fixed-euc-china len 'cn t))
592
593 (defun post-read-decode-euc-py-tw (len)
594   (post-read-decode-fixed-euc-china len 'tw nil))
595
596 (defun post-read-decode-euc-zy-tw (len)
597   (post-read-decode-fixed-euc-china len 'tw t))
598
599 (make-coding-system 'fixed-euc-py-cn 0 ?W
600                     "Coding System for fixed EUC Chinese-gb2312")
601 (coding-system-put 'fixed-euc-py-cn
602                    'pre-write-conversion 'pre-write-encode-euc-cn)
603 (coding-system-put 'fixed-euc-py-cn
604                    'post-read-conversion 'post-read-decode-euc-py-cn)
605
606 (make-coding-system 'fixed-euc-zy-cn 0 ?W
607                     "Coding System for fixed EUC Chinese-gb2312")
608 (coding-system-put 'fixed-euc-zy-cn
609                    'pre-write-conversion 'pre-write-encode-euc-cn)
610 (coding-system-put 'fixed-euc-zy-cn
611                    'post-read-conversion 'post-read-decode-euc-zy-cn)
612
613 (make-coding-system 'fixed-euc-py-tw 0 ?W
614                     "Coding System for fixed EUC Chinese-cns11643")
615 (coding-system-put 'fixed-euc-py-tw
616                    'pre-write-conversion 'pre-write-encode-euc-tw)
617 (coding-system-put 'fixed-euc-py-tw
618                    'post-read-conversion 'post-read-decode-euc-py-tw)
619
620 (make-coding-system 'fixed-euc-zy-tw 0 ?W
621                     "Coding System for fixed EUC Chinese-cns11643")
622 (coding-system-put 'fixed-euc-zy-tw
623                    'pre-write-conversion 'pre-write-encode-euc-tw)
624 (coding-system-put 'fixed-euc-zy-tw
625                    'post-read-conversion 'post-read-decode-euc-zy-tw)
626
627 ;; Binary data
628
629 (eval-and-compile
630 (define-ccl-program ccl-decode-egg-binary
631   `(1
632     ((read r0)
633      (loop
634       (if (r0 == ?\xff)
635           (read r1))                    ; toss out
636       (write-read-repeat r0)))))
637
638 (define-ccl-program ccl-encode-egg-binary
639   `(2
640     ((read r0)
641      (loop
642       (if (r0 == ?\xff)
643           ((write r0)
644            (r0 = 0)))
645       (write-read-repeat r0))))))
646
647 (make-coding-system 'egg-binary 4 ?W "Coding System for binary data"
648                     (cons ccl-decode-egg-binary ccl-encode-egg-binary))
649
650 \f
651 (defun comm-format-u32c (uint32c)
652   (insert-char (logand (lsh (car uint32c) -8) 255) 1)
653   (insert-char (logand (car uint32c) 255) 1)
654   (insert-char (logand (lsh (nth 1 uint32c) -8) 255) 1)
655   (insert-char (logand (nth 1 uint32c) 255) 1))
656
657 (defun comm-format-u32 (uint32)
658   (insert-char (logand (lsh uint32 -24) 255) 1)
659   (insert-char (logand (lsh uint32 -16) 255) 1)
660   (insert-char (logand (lsh uint32 -8) 255) 1)
661   (insert-char (logand uint32 255) 1))
662
663 (defun comm-format-i32 (int32)
664   (insert-char (logand (ash int32 -24) 255) 1)
665   (insert-char (logand (ash int32 -16) 255) 1)
666   (insert-char (logand (ash int32 -8) 255) 1)
667   (insert-char (logand int32 255) 1))
668
669 (defun comm-format-u16 (uint16)
670   (insert-char (logand (lsh uint16 -8) 255) 1)
671   (insert-char (logand uint16 255) 1))
672
673 (defun comm-format-u8 (uint8)
674   (insert-char (logand uint8 255) 1))
675
676 (defun comm-format-truncate-after-null (s)
677   (if (string-match "\0" s)
678       (substring s 0 (match-beginning 0))
679     s))
680
681 (defun comm-format-u16-string (s)
682   (insert (encode-coding-string (comm-format-truncate-after-null s)
683                                 egg-fixed-euc))
684   (insert-char 0 2))
685
686 (defun comm-format-mb-string (s)
687   (insert (encode-coding-string  (comm-format-truncate-after-null s)
688                                  egg-mb-euc))
689   (insert-char 0 1))
690
691 (defun comm-format-u8-string (s)
692   (insert (comm-format-truncate-after-null s))
693   (insert-char 0 1))
694
695 (defun comm-format-binary-data (s)
696   (insert (encode-coding-string s 'egg-binary))
697   (insert-char ?\377 2))
698
699 (defun comm-format-fixlen-string (s len)
700   (setq s (comm-format-truncate-after-null s))
701   (insert (if (< (length s) len) s (substring s 0 (1- len))))
702   (insert-char 0 (max (- len (length s)) 1)))
703
704 (defun comm-format-vector (s len)
705   (setq s (concat s))
706   (insert (if (<= (length s) len) s (substring s 0 len)))
707   (insert-char 0 (- len (length s))))
708
709 (defmacro comm-format (format &rest args)
710   "Format a string out of a control-list and arguments into the buffer.
711 The formated datas are network byte oder (i.e. big endian)..
712 U: 32-bit integer.  The argument is 2 element 16-bit unsigned integer list.
713 u: 32-bit integer.  The argument is treat as unsigned integer.
714    (Note:  Elisp's integer may be less than 32 bits)
715 i: 32-bit integer.
716    (Note:  Elisp's integer may be greater than 32 bits)
717 w: 16-bit integer.
718 b: 8-bit integer.
719 S: 16-bit wide-character EUC string (0x0000 terminated).
720 E: Multibyte EUC string (0x00 terminated).
721 s: 8-bit string (0x00 terminated).
722 B: Binary data (0xff terminated).
723 v: 8-bit vector (no terminator).  This takes 2 args (data length).
724 V: Fixed length string (0x00 terminated).  This takes 2 args (data length)."
725   (let ((p args)
726         (form format)
727         (result (list 'progn))
728         f arg)
729     (while (and form p)
730       (setq f (car form)
731             arg (car p))
732       (nconc result
733              (list
734               (cond ((eq f 'U) (list 'comm-format-u32c arg))
735                     ((eq f 'u) (list 'comm-format-u32 arg))
736                     ((eq f 'i) (list 'comm-format-i32 arg))
737                     ((eq f 'w) (list 'comm-format-u16 arg))
738                     ((eq f 'b) (list 'comm-format-u8 arg))
739                     ((eq f 'S) (list 'comm-format-u16-string arg))
740                     ((eq f 'E) (list 'comm-format-mb-string arg))
741                     ((eq f 's) (list 'comm-format-u8-string arg))
742                     ((eq f 'B) (list 'comm-format-binary-data arg))
743                     ((eq f 'V) (setq p (cdr p))
744                                (list 'comm-format-fixlen-string arg (car p)))
745                     ((eq f 'v) (setq p (cdr p))
746                                (list 'comm-format-vector arg (car p))))))
747       (setq form (cdr form)
748             p (cdr p)))
749     (if (or form p)
750         (error "comm-format %s: arguments mismatch" format))
751     result))
752 \f
753 (defvar comm-accept-timeout nil)
754
755 ;; Assume PROC is bound to the process of current buffer
756 ;; Do not move the point, leave it where it was.
757 (defmacro comm-accept-process-output ()
758   `(let ((p (point)))
759      (if (null (accept-process-output proc comm-accept-timeout))
760          (egg-error "backend timeout"))
761      (goto-char p)))
762
763 (defmacro comm-require-process-output (n)
764   `(if (< (point-max) (+ (point) ,n))
765        (comm-wait-for-space proc ,n)))
766
767 (defun comm-wait-for-space (proc n)
768   (let ((p (point))
769         (r (+ (point) n)))
770     (while (< (point-max) r)
771       (if (null (accept-process-output proc comm-accept-timeout))
772           (egg-error "backend timeout"))
773       (goto-char p))))
774
775 (defmacro comm-following+forward-char ()
776   `(prog1
777        (following-char)
778      (forward-char 1)))
779
780 (defun comm-unpack-u32c ()
781   (progn
782     (comm-require-process-output 4)
783     (list (+ (lsh (comm-following+forward-char) 8)
784              (comm-following+forward-char))
785           (+ (lsh (comm-following+forward-char) 8)
786              (comm-following+forward-char)))))
787
788 (defun comm-unpack-i32 ()
789   (progn
790     (comm-require-process-output 4)
791     (+ (lsh (- (logxor (comm-following+forward-char) 128) 128) 24)
792        (lsh (comm-following+forward-char) 16)
793        (lsh (comm-following+forward-char) 8)
794        (comm-following+forward-char))))
795
796 (defun comm-unpack-u32 ()
797   (progn
798     (comm-require-process-output 4)
799     (+ (lsh (comm-following+forward-char) 24)
800        (lsh (comm-following+forward-char) 16)
801        (lsh (comm-following+forward-char) 8)
802        (comm-following+forward-char))))
803
804 (defun comm-unpack-u16 ()
805   (progn
806     (comm-require-process-output 2)
807     (+ (lsh (comm-following+forward-char) 8)
808        (comm-following+forward-char))))
809
810 (defun comm-unpack-u8 ()
811   (progn
812     (comm-require-process-output 1)
813     (comm-following+forward-char)))
814
815 (defun comm-unpack-u16-string ()
816   (let ((start (point)))
817     (while (not (search-forward "\0\0" nil t))
818       (comm-accept-process-output))
819     (decode-coding-string (buffer-substring start (- (point) 2))
820                           egg-fixed-euc)))
821
822 (defun comm-unpack-mb-string ()
823   (let ((start (point)))
824     (while (not (search-forward "\0" nil t))
825       (comm-accept-process-output))
826     (decode-coding-string (buffer-substring start (1- (point)))
827                           egg-mb-euc)))
828
829 (defun comm-unpack-u8-string ()
830   (let ((start (point)))
831     (while (not (search-forward "\0" nil 1))
832       (comm-accept-process-output))
833     (buffer-substring start (1- (point)))))
834
835 (defun comm-unpack-binary-data ()
836   (let ((start (point)))
837     (while (not (search-forward "\377\377" nil 1))
838       (comm-accept-process-output))
839     (string-as-unibyte
840      (decode-coding-string (buffer-substring start (- (point) 2))
841                            'egg-binary))))
842
843 (defun comm-unpack-fixlen-string (len)
844   (let (s)
845     (comm-require-process-output len)
846     (goto-char (+ (point) len))
847     (setq s (buffer-substring (- (point) len) (point)))
848     (if (string-match "\0" s)
849         (setq s (substring s 0 (match-beginning 0))))
850     s))
851
852 (defun comm-unpack-vector (len)
853   (progn
854     (comm-require-process-output len)
855     (goto-char (+ (point) len))
856     (buffer-substring (- (point) len) (point))))
857
858 (defmacro comm-unpack (format &rest args)
859   "Unpack a string out of a control-string and set arguments.
860 See `comm-format' for FORMAT."
861   (let ((p args)
862         (form format)
863         (result (list 'progn))
864         arg f)
865     (while (and form p)
866       (setq f (car form)
867             arg (car p))
868       (nconc result
869              (list
870               (cond ((eq f 'U) `(setq ,arg (comm-unpack-u32c)))
871                     ((eq f 'u) `(setq ,arg (comm-unpack-u32)))
872                     ((eq f 'i) `(setq ,arg (comm-unpack-i32)))
873                     ((eq f 'w) `(setq ,arg (comm-unpack-u16)))
874                     ((eq f 'b) `(setq ,arg (comm-unpack-u8)))
875                     ((eq f 'S) `(setq ,arg (comm-unpack-u16-string)))
876                     ((eq f 'E) `(setq ,arg (comm-unpack-mb-string)))
877                     ((eq f 's) `(setq ,arg (comm-unpack-u8-string)))
878                     ((eq f 'B) `(setq ,arg (comm-unpack-binary-data)))
879                     ((eq f 'V) (setq p (cdr p))
880                                `(setq ,arg (comm-unpack-fixlen-string ,(car p))))
881                     ((eq f 'v) (setq p (cdr p))
882                                `(setq ,arg (comm-unpack-vector ,(car p)))))))
883       (setq form (cdr form)
884             p (cdr p)))
885     (if (or form p)
886         (error "comm-unpack %s: arguments mismatch" format))
887     result))
888 \f
889 (defmacro comm-call-with-proc (proc vlist send-expr &rest receive-exprs)
890   (let ((euc-select
891          (and (eq (car-safe (car vlist)) 'zhuyin)
892               '((egg-fixed-euc (nth (if zhuyin 1 0) egg-fixed-euc))))))
893   `(let* ((proc ,proc)
894           (buffer (process-buffer proc))
895           ,@vlist)
896      (if (and (eq (process-status proc) 'open)
897               (buffer-live-p buffer))
898          (save-excursion
899            (set-buffer buffer)
900            (let ,euc-select
901              (erase-buffer)
902              ,send-expr
903              (goto-char (point-max))
904              (process-send-region proc (point-min) (point-max))
905              ,@receive-exprs))
906        (egg-error "process %s was killed" proc)))))
907
908 (defmacro comm-call-with-proc-1 (proc vlist send-expr &rest receive-exprs)
909   `(let ,vlist
910      (erase-buffer)
911      ,send-expr
912      (goto-char (point-max))
913      (process-send-region proc (point-min) (point-max))
914      ,@receive-exprs))
915
916 (provide 'egg-com)
917 ;;; egg-com.el ends here.