(shuowen-radicals): Add ?木, ?東, ?林, ?才, ?叒, ?之, ?帀, ?出, ?𣎵,
[chise/xemacs-chise.git.1] / lisp / utf-2000 / char-db-util.el
1 ;;; char-db-util.el --- Character Database utility -*- coding: utf-8-er; -*-
2
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 ;;   2007 MORIOKA Tomohiko.
5
6 ;; Author: MORIOKA Tomohiko <tomo@kanji.zinbun.kyoto-u.ac.jp>
7 ;; Keywords: CHISE, Character Database, ISO/IEC 10646, UCS, Unicode, MULE.
8
9 ;; This file is part of XEmacs CHISE.
10
11 ;; XEmacs CHISE is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation; either version 2, or (at
14 ;; your option) any later version.
15
16 ;; XEmacs CHISE is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 ;; General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with XEmacs CHISE; see the file COPYING.  If not, write to
23 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;;; Code:
27
28 (require 'alist)
29
30 (defconst unidata-normative-category-alist
31   '(("Lu" letter        uppercase)
32     ("Ll" letter        lowercase)
33     ("Lt" letter        titlecase)
34     ("Mn" mark          non-spacing)
35     ("Mc" mark          spacing-combining)
36     ("Me" mark          enclosing)
37     ("Nd" number        decimal-digit)
38     ("Nl" number        letter)
39     ("No" number        other)
40     ("Zs" separator     space)
41     ("Zl" separator     line)
42     ("Zp" separator     paragraph)
43     ("Cc" other         control)
44     ("Cf" other         format)
45     ("Cs" other         surrogate)
46     ("Co" other         private-use)
47     ("Cn" other         not-assigned)))
48
49 (defconst unidata-informative-category-alist
50   '(("Lm" letter        modifier)
51     ("Lo" letter        other)
52     ("Pc" punctuation   connector)
53     ("Pd" punctuation   dash)
54     ("Ps" punctuation   open)
55     ("Pe" punctuation   close)
56     ("Pi" punctuation   initial-quote)
57     ("Pf" punctuation   final-quote)
58     ("Po" punctuation   other)
59     ("Sm" symbol        math)
60     ("Sc" symbol        currency)
61     ("Sk" symbol        modifier)
62     ("So" symbol        other)
63     ))
64
65 (defconst ideographic-radicals
66   (let ((v (make-vector 215 nil))
67         (i 1))
68     (while (< i 215)
69       (aset v i (decode-char '=ucs (+ #x2EFF i)))
70       (setq i (1+ i)))
71     v))
72
73 (defun ideographic-radical (number)
74   (aref ideographic-radicals number))
75
76 (defconst shuowen-radicals
77   [?一 ?上 ?示 ?三 ?王 ?玉 ?玨 ?气 ?士 ?丨 ; 010
78    ?屮 ?艸 ?蓐 ?茻 ?小 ?八 ?釆 ?半 ?牛 ?犛 ; 020
79    ?告 ?口 ?凵 ?吅 ?哭 ?走 ?止 ?癶 ?步 ?此 ; 030
80    ?正 ?是 ?辵 ?彳 ?廴 ?㢟 ?行 ?齒 ?牙 ?足 ; 040
81    ?疋 ?品 ?龠 ?冊 ?㗊 ?舌 ?干 ?谷 ?只 ?㕯 ; 050
82    ?句 ?丩 ?古 ?十 ?卅 ?言 ?誩 ?音 ?䇂 ?丵 ; 060
83    ?菐 ?𠬞 ?廾 ?共 ?異 ?舁 ?𦥑 ?䢅 ?爨 ?革 ; 070
84    ?鬲 ?䰜 ?爪 ?𠃨 ?鬥 ?又 ?𠂇 ?㕜 ?支 ?𦘒 ; 080
85    ?聿 ?畫 ?隶 ?臤 ?臣 ?殳 ?殺 ?𠘧 ?寸 ?皮 ; 090
86    ?㼱 ?攴 ?敎 ?卜 ?用 ?爻 ?㸚 ?𥄎 ?目 ?䀠 ; 100
87    ?眉 ?盾 ?自 ?白 ?鼻 ?皕 ?習 ?羽 ?隹 ?奞 ; 110
88    ?萑 ?𦫳 ?苜 ?羊 ?羴 ?瞿 ?雔 ?雥 ?鳥 ?烏 ; 120
89    ?𠦒 ?冓 ?幺 ?𢆶 ?叀 ?玄 ?予 ?放 ?𠬪 ?𣦼 ; 130
90    ?歺 ?死 ?冎 ?骨 ?肉 ?筋 ?刀 ?刃 ?㓞 ?丰 ; 140
91    ?耒 ?𧢲 ?竹 ?箕 ?丌 ?左 ?工 ?㠭 ?巫 ?甘 ; 150
92    ?曰 ?乃 ?丂 ?可 ?兮 ?号 ?亏 ?旨 ?喜 ?壴 ; 160
93    ?鼓 ?豈 ?豆 ?豊 ?豐 ?䖒 ?虍 ?虎 ?虤 ?皿 ; 170
94    ?𠙴 ?去 ?血 ?丶 ?丹 ?青 ?井 ?皀 ?鬯 ?食 ; 180
95    ?亼 ?會 ?倉 ?入 ?缶 ?矢 ?高 ?冂 ?𩫏 ?京 ; 190
96    ?亯 ?𣆪 ?畗 ?㐭 ?嗇 ?來 ?麥 ?夊 ?舛 ?䑞 ; 200
97    ?韋 ?弟 ?夂 ?久 ?桀 ?木 ?東 ?林 ?才 ?叒 ; 210
98    ?之 ?帀 ?出 ?𣎵 ?生 ?乇 ?𠂹 ?𠌶 ?華 ?𥝌 ; 220
99    ?稽 ?巢 ?桼 ?束 ?㯻 ?囗 ?員 ?貝 ?邑 ?𨛜 ; 230
100    ])
101
102 (defun shuowen-radical (number)
103   (aref shuowen-radicals (1- number)))
104
105 (defvar char-db-file-coding-system 'utf-8-mcs-er)
106
107 (defvar char-db-feature-domains
108   '(ucs ucs/compat daikanwa cns gt jis jis/alt jis/a jis/b
109         jis-x0212 jis-x0213 cdp shinjigen misc unknown))
110
111 (defvar char-db-ignored-attributes '(ideographic-products))
112
113 (defun char-attribute-name< (ka kb)
114   (cond
115    ((eq '->denotational kb)
116     t)
117    ((eq '->subsumptive kb)
118     (not (eq '->denotational ka)))
119    ((eq '->denotational ka)
120     nil)
121    ((eq '->subsumptive ka)
122     nil)
123    ((and (symbolp ka)
124          (string-match "^->" (symbol-name ka)))
125     (cond ((and (symbolp kb)
126                 (string-match "^->" (symbol-name kb)))
127            (string< (symbol-name ka)
128                     (symbol-name kb))
129            ))
130     )
131    ((and (symbolp kb)
132          (string-match "^->" (symbol-name kb)))
133     t)
134    ((and (symbolp ka)
135          (string-match "^<-" (symbol-name ka)))
136     (cond ((symbolp kb)
137            (cond ((string-match "^<-" (symbol-name kb))
138                   (string< (symbol-name ka)
139                            (symbol-name kb))
140                   )
141                  ;; ((string-match "^->" (symbol-name kb))
142                  ;;  t)
143                  )))
144     )
145    ((and (symbolp kb)
146          (string-match "^<-" (symbol-name kb)))
147     t
148     ;; (not (string-match "^->" (symbol-name ka)))
149     )
150    ((find-charset ka)
151     (if (find-charset kb)
152         (if (<= (charset-id ka) 1)
153             (if (<= (charset-id kb) 1)
154                 (cond
155                  ((= (charset-dimension ka)
156                      (charset-dimension kb))
157                   (> (charset-id ka)(charset-id kb)))
158                  (t
159                   (> (charset-dimension ka)
160                      (charset-dimension kb))
161                   ))
162               t)
163           (if (<= (charset-id kb) 1)
164               nil
165             (< (charset-id ka)(charset-id kb))))
166       nil))
167    ((find-charset kb)
168     t)
169    ((symbolp ka)
170     (cond ((symbolp kb)
171            (string< (symbol-name ka)
172                     (symbol-name kb)))
173           (t)))
174    ((symbolp kb)
175     nil)))
176
177 (defvar char-db-coded-charset-priority-list
178   '(ascii
179     control-1
180     latin-iso8859-1
181     latin-iso8859-2
182     latin-iso8859-3
183     latin-iso8859-4
184     latin-iso8859-9
185     latin-jisx0201
186     cyrillic-iso8859-5
187     greek-iso8859-7
188     thai-tis620
189     =jis-x0208
190     =jis-x0208@1978
191     =jis-x0208@1983
192     japanese-jisx0212
193     chinese-gb2312
194     =jis-x0208@1990
195     chinese-cns11643-1
196     chinese-cns11643-2
197     chinese-cns11643-3
198     chinese-cns11643-4
199     chinese-cns11643-5
200     chinese-cns11643-6
201     chinese-cns11643-7
202     =jis-x0213-1-2000
203     =jis-x0213-2-2000
204     korean-ksc5601
205     chinese-isoir165
206     katakana-jisx0201
207     hebrew-iso8859-8
208     chinese-gb12345
209     latin-viscii
210     ethiopic-ucs
211     =big5-cdp
212     =gt
213     ideograph-daikanwa-2
214     ideograph-daikanwa
215     =cbeta
216     ideograph-hanziku-1
217     ideograph-hanziku-2
218     ideograph-hanziku-3
219     ideograph-hanziku-4
220     ideograph-hanziku-5
221     ideograph-hanziku-6
222     ideograph-hanziku-7
223     ideograph-hanziku-8
224     ideograph-hanziku-9
225     ideograph-hanziku-10
226     ideograph-hanziku-11
227     ideograph-hanziku-12
228     =gt-k
229     =ucs@iso
230     =ucs@unicode
231     =big5
232     =big5-eten
233     =jis-x0208@1997
234     =zinbun-oracle
235     =ruimoku-v6
236     =jef-china3))
237
238 (defun char-db-make-char-spec (char)
239   (let (ret char-spec)
240     (cond ((characterp char)
241            (cond ((and (setq ret (encode-char char '=ucs 'defined-only))
242                        (not (and (<= #xE000 ret)(<= ret #xF8FF))))
243                   (setq char-spec (list (cons '=ucs ret)))
244                   (cond ((setq ret (get-char-attribute char 'name))
245                          (setq char-spec (cons (cons 'name ret) char-spec))
246                          )
247                         ((setq ret (get-char-attribute char 'name*))
248                          (setq char-spec (cons (cons 'name* ret) char-spec))
249                          ))
250                   )
251                  ((setq ret
252                         (catch 'tag
253                           (let ((rest char-db-coded-charset-priority-list)
254                                 ccs)
255                             (while rest
256                               (setq ccs (charset-name
257                                          (find-charset (car rest))))
258                               (if (setq ret
259                                         (encode-char char ccs
260                                                      'defined-only))
261                                   (throw 'tag (cons ccs ret)))
262                               (setq rest (cdr rest))))))
263                   (setq char-spec (list ret))
264                   (dolist (ccs (delq (car ret) (charset-list)))
265                     (if (and (or (charset-iso-final-char ccs)
266                                  (memq ccs
267                                        '(=daikanwa
268                                          =daikanwa@rev2
269                                          ;; =gt-k
270                                          =jis-x0208@1997
271                                          )))
272                              (setq ccs (charset-name ccs))
273                              (null (assq ccs char-spec))
274                              (setq ret (encode-char char ccs 'defined-only)))
275                         (setq char-spec (cons (cons ccs ret) char-spec))))
276                   (if (null char-spec)
277                       (setq char-spec (split-char char)))
278                   (cond ((setq ret (get-char-attribute char 'name))
279                          (setq char-spec (cons (cons 'name ret) char-spec))
280                          )
281                         ((setq ret (get-char-attribute char 'name*))
282                          (setq char-spec (cons (cons 'name* ret) char-spec))
283                          ))
284                   ))
285            char-spec)
286           ((consp char)
287            char))))
288     
289 (defun char-db-insert-char-spec (char &optional readable column
290                                       required-features)
291   (unless column
292     (setq column (current-column)))
293   (let (char-spec temp-char)
294     (setq char-spec (char-db-make-char-spec char))
295     (unless (or (characterp char) ; char
296                 (condition-case nil
297                     (setq char (find-char char-spec))
298                   (error nil)))
299       ;; define temporary character
300       ;;   Current implementation is dirty.
301       (setq temp-char (define-char (cons '(ideograph-daikanwa . 0)
302                                          char-spec)))
303       (remove-char-attribute temp-char 'ideograph-daikanwa)
304       (setq char temp-char))
305     (insert-char-attributes char
306                             readable
307                             (union (mapcar #'car char-spec)
308                                    required-features))
309     (when temp-char
310       ;; undefine temporary character
311       ;;   Current implementation is dirty.
312       (setq char-spec (char-attribute-alist temp-char))
313       (while char-spec
314         (remove-char-attribute temp-char (car (car char-spec)))
315         (setq char-spec (cdr char-spec))))))
316
317 (defun char-db-insert-alist (alist &optional readable column)
318   (unless column
319     (setq column (current-column)))
320   (let ((line-breaking
321          (concat "\n" (make-string (1+ column) ?\ )))
322         name value
323         ret al ; cal
324         key
325         lbs cell rest separator)
326     (insert "(")
327     (while alist
328       (setq name (car (car alist))
329             value (cdr (car alist)))
330       (cond ((eq name 'char)
331              (insert "(char . ")
332              (if (setq ret (condition-case nil
333                                (find-char value)
334                              (error nil)))
335                  (progn
336                    (setq al nil
337                          ;; cal nil
338                          )
339                    (while value
340                      (setq key (car (car value)))
341                      ;; (if (find-charset key)
342                      ;;     (setq cal (cons key cal))
343                      (setq al (cons key al))
344                      ;; )
345                      (setq value (cdr value)))
346                    (insert-char-attributes ret
347                                            readable
348                                            (or al 'none) ; cal
349                                            ))
350                (insert (prin1-to-string value)))
351              (insert ")")
352              (insert line-breaking))
353             ((consp value)
354              (insert (format "(%-18s " name))
355              (setq lbs (concat "\n" (make-string (current-column) ?\ )))
356              (while (consp value)
357                (setq cell (car value))
358                (if (and (consp cell)
359                         (consp (car cell))
360                         (setq ret (condition-case nil
361                                       (find-char cell)
362                                     (error nil)))
363                         )
364                    (progn
365                      (setq rest cell
366                            al nil
367                            ;; cal nil
368                            )
369                      (while rest
370                        (setq key (car (car rest)))
371                        ;; (if (find-charset key)
372                        ;;     (setq cal (cons key cal))
373                        (setq al (cons key al))
374                        ;; )
375                        (setq rest (cdr rest)))
376                      (if separator
377                          (insert lbs))
378                      (insert-char-attributes ret
379                                              readable
380                                              al ; cal
381                                              )
382                      (setq separator lbs))
383                  (if separator
384                      (insert separator))
385                  (insert (prin1-to-string cell))
386                  (setq separator " "))
387                (setq value (cdr value)))
388              (insert ")")
389              (insert line-breaking))
390             (t
391              (insert (format "(%-18s . %S)%s"
392                              name value
393                              line-breaking))))
394       (setq alist (cdr alist))))
395   (insert ")"))
396
397 (defun char-db-insert-char-reference (plist &optional readable column)
398   (unless column
399     (setq column (current-column)))
400   (let ((line-breaking
401          (concat "\n" (make-string (1+ column) ?\ )))
402         (separator "")
403         name value)
404     (insert "(")
405     (while plist
406       (setq name (pop plist))
407       (setq value (pop plist))
408       (cond ((eq name :char)
409              (insert separator)
410              (insert ":char\t")
411              (cond ((numberp value)
412                     (setq value (decode-char '=ucs value)))
413                    ;; ((consp value)
414                    ;;  (setq value (or (find-char value)
415                    ;;                  value)))
416                    )
417              (char-db-insert-char-spec value readable)
418              (insert line-breaking)
419              (setq separator ""))
420             ((eq name :radical)
421              (insert (format "%s%s\t%d ; %c%s"
422                              separator
423                              name value
424                              (ideographic-radical value)
425                              line-breaking))
426              (setq separator ""))
427             (t
428              (insert (format "%s%s\t%S" separator name value))
429              (setq separator line-breaking)))
430       ))
431   (insert ")"))
432
433 (defun char-db-decode-isolated-char (ccs code-point)
434   (let (ret)
435     (setq ret
436           (cond ((eq ccs 'arabic-iso8859-6)
437                  (decode-char ccs code-point))
438                 ((and (memq ccs '(=gt-pj-1
439                                   =gt-pj-2
440                                   =gt-pj-3
441                                   =gt-pj-4
442                                   =gt-pj-5
443                                   =gt-pj-6
444                                   =gt-pj-7
445                                   =gt-pj-8
446                                   =gt-pj-9
447                                   =gt-pj-10
448                                   =gt-pj-11))
449                       (setq ret (decode-char ccs code-point))
450                       (setq ret (encode-char ret '=gt 'defined-only)))
451                  (decode-builtin-char '=gt ret))
452                 (t
453                  (decode-builtin-char ccs code-point))))
454     (cond ((and (<= 0 (char-int ret))
455                 (<= (char-int ret) #x1F))
456            (decode-char '=ucs (+ #x2400 (char-int ret))))
457           ((= (char-int ret) #x7F)
458            ?\u2421)
459           (t ret))))
460
461 (defvar char-db-convert-obsolete-format t)
462
463 (defun char-db-insert-ccs-feature (name value line-breaking)
464   (insert
465    (format
466     (cond ((or (memq name '(=daikanwa
467                             =daikanwa@rev1 =daikanwa@rev2
468                             =gt =gt-k =cbeta =zinbun-oracle))
469                (string-match "^=adobe-" (symbol-name name)))
470            "(%-18s . %05d)\t; %c")
471           ((eq name 'mojikyo)
472            "(%-18s . %06d)\t; %c")
473           ((>= (charset-dimension name) 2)
474            "(%-18s . #x%04X)\t; %c")
475           (t
476            "(%-18s . #x%02X)\t; %c"))
477     name
478     (if (= (charset-iso-graphic-plane name) 1)
479         (logior value
480                 (cond ((= (charset-dimension name) 1)
481                        #x80)
482                       ((= (charset-dimension name) 2)
483                        #x8080)
484                       ((= (charset-dimension name) 3)
485                        #x808080)
486                       (t 0)))
487       value)
488     (char-db-decode-isolated-char name value)))
489   (if (and (= (charset-chars name) 94)
490            (= (charset-dimension name) 2))
491       (insert (format " [%02d-%02d]"
492                       (- (lsh value -8) 32)
493                       (- (logand value 255) 32))))
494   (insert line-breaking))
495
496 (defun char-db-insert-relation-feature (char name value line-breaking
497                                              ccss readable)
498   (insert (format "(%-18s%s " name line-breaking))
499   (let ((lbs (concat "\n" (make-string (current-column) ?\ )))
500         separator cell sources required-features
501         ret)
502     (while (consp value)
503       (setq cell (car value))
504       (if (integerp cell)
505           (setq cell (decode-char '=ucs cell)))
506       (cond
507        ((eq name '->subsumptive)
508         (when (or (not (some (lambda (atr)
509                                (get-char-attribute cell atr))
510                              char-db-ignored-attributes))
511                   (some (lambda (ccs)
512                           (encode-char cell ccs 'defined-only))
513                         ccss))
514           (if separator
515               (insert lbs))
516           (let ((char-db-ignored-attributes
517                  (cons '<-subsumptive
518                        char-db-ignored-attributes)))
519             (insert-char-attributes cell readable))
520           (setq separator lbs))
521         )
522        ((characterp cell)
523         (setq sources
524               (get-char-attribute
525                char (intern (format "%s*sources" name))))
526         (setq required-features nil)
527         (dolist (source sources)
528           (cond
529            ((memq source '(JP JP/Jouyou shinjigen-1))
530             (setq required-features
531                   (union required-features
532                          '(=jis-x0208
533                            =jis-x0208@1990
534                            =jis-x0213-1-2000
535                            =jis-x0213-2-2000
536                            =jis-x0212
537                            =jis-x0208@1983
538                            =jis-x0208@1978))))
539            ((eq source 'CN)
540             (setq required-features
541                   (union required-features
542                          '(=gb2312
543                            =gb12345
544                            =iso-ir165)))))
545           (cond
546            ((find-charset (setq ret (intern (format "=%s" source))))
547             (setq required-features
548                   (cons ret required-features)))
549            (t (setq required-features
550                     (cons source required-features)))))
551         (cond ((string-match "@JP" (symbol-name name))
552                (setq required-features
553                      (union required-features
554                             '(=jis-x0208
555                               =jis-x0208@1990
556                               =jis-x0213-1-2000
557                               =jis-x0213-2-2000
558                               =jis-x0212
559                               =jis-x0208@1983
560                               =jis-x0208@1978))))
561               ((string-match "@CN" (symbol-name name))
562                (setq required-features
563                      (union required-features
564                             '(=gb2312
565                               =gb12345
566                               =iso-ir165)))))
567         (if separator
568             (insert lbs))
569         (if readable
570             (insert (format "%S" cell))
571           (char-db-insert-char-spec cell readable
572                                     nil
573                                     required-features))
574         (setq separator lbs))
575        ((consp cell)
576         (if separator
577             (insert lbs))
578         (if (consp (car cell))
579             (char-db-insert-char-spec cell readable)
580           (char-db-insert-char-reference cell readable))
581         (setq separator lbs))
582        (t
583         (if separator
584             (insert separator))
585         (insert (prin1-to-string cell))
586         (setq separator " ")))
587       (setq value (cdr value)))
588     (insert ")")
589     (insert line-breaking)))
590
591 (defun insert-char-attributes (char &optional readable attributes column)
592   (unless column
593     (setq column (current-column)))
594   (let (name value ; has-long-ccs-name
595         rest
596         radical strokes
597         (line-breaking
598          (concat "\n" (make-string (1+ column) ?\ )))
599         lbs cell separator ret
600         key al cal
601         dest-ccss ; sources required-features
602         ccss)
603     (let (atr-d)
604       (setq attributes
605             (sort (if attributes
606                       (if (consp attributes)
607                           (progn
608                             (dolist (name attributes)
609                               (unless (memq name char-db-ignored-attributes)
610                                 (if (find-charset name)
611                                     (push name ccss))
612                                 (push name atr-d)))
613                             atr-d))
614                     (dolist (name (char-attribute-list))
615                       (unless (memq name char-db-ignored-attributes)
616                         (if (find-charset name)
617                             (push name ccss))
618                         (push name atr-d)))
619                     atr-d)
620                   #'char-attribute-name<)))
621     (insert "(")
622     (when (memq '<-subsumptive attributes)
623       (when readable
624         (when (setq value (get-char-attribute char '<-subsumptive))
625           (char-db-insert-relation-feature char '<-subsumptive value
626                                            line-breaking
627                                            ccss readable)))
628       (setq attributes (delq '<-subsumptive attributes)))
629     (when (and (memq '<-denotational attributes)
630                (setq value (get-char-attribute char '<-denotational)))
631       (char-db-insert-relation-feature char '<-denotational value
632                                        line-breaking
633                                        ccss readable)
634       (setq attributes (delq '<-denotational attributes)))
635     (when (and (memq 'name attributes)
636                (setq value (get-char-attribute char 'name)))
637       (insert (format
638                (if (> (+ (current-column) (length value)) 48)
639                    "(name . %S)%s"
640                  "(name               . %S)%s")
641                value line-breaking))
642       (setq attributes (delq 'name attributes))
643       )
644     (when (and (memq 'name* attributes)
645                (setq value (get-char-attribute char 'name*)))
646       (insert (format
647                (if (> (+ (current-column) (length value)) 48)
648                    "(name* . %S)%s"
649                  "(name*              . %S)%s")
650                value line-breaking))
651       (setq attributes (delq 'name* attributes))
652       )
653     (when (and (memq 'script attributes)
654                (setq value (get-char-attribute char 'script)))
655       (insert (format "(script\t\t%s)%s"
656                       (mapconcat (function prin1-to-string)
657                                  value " ")
658                       line-breaking))
659       (setq attributes (delq 'script attributes))
660       )
661     (dolist (name '(=>ucs =>ucs*))
662       (when (and (memq name attributes)
663                  (setq value (get-char-attribute char name)))
664         (insert (format "(%-18s . #x%04X)\t; %c%s"
665                         name value (decode-char '=ucs value)
666                         line-breaking))
667         (setq attributes (delq name attributes))))
668     (dolist (name '(=>ucs@gb =>ucs@cns =>ucs@jis =>ucs@ks =>ucs@big5))
669       (when (and (memq name attributes)
670                  (setq value (get-char-attribute char name)))
671         (insert (format "(%-18s . #x%04X)\t; %c%s"
672                         name value
673                         (decode-char (intern
674                                       (concat "="
675                                               (substring
676                                                (symbol-name name) 2)))
677                                      value)
678                         line-breaking))
679         (setq attributes (delq name attributes))
680         ))
681     (dolist (name '(=>daikanwa))
682       (when (and (memq name attributes)
683                  (setq value (get-char-attribute char name)))
684         (insert
685          (if (integerp value)
686              (format "(%-18s . %05d)\t; %c%s"
687                      name value (decode-char '=daikanwa value)
688                      line-breaking)
689            (format "(%-18s %s)\t; %c%s"
690                    name
691                    (mapconcat (function prin1-to-string)
692                               value " ")
693                    (char-representative-of-daikanwa char)
694                    line-breaking)))
695         (setq attributes (delq name attributes))))
696     (when (and (memq 'general-category attributes)
697                (setq value (get-char-attribute char 'general-category)))
698       (insert (format
699                "(general-category\t%s) ; %s%s"
700                (mapconcat (lambda (cell)
701                             (format "%S" cell))
702                           value " ")
703                (cond ((rassoc value unidata-normative-category-alist)
704                       "Normative Category")
705                      ((rassoc value unidata-informative-category-alist)
706                       "Informative Category")
707                      (t
708                       "Unknown Category"))
709                line-breaking))
710       (setq attributes (delq 'general-category attributes))
711       )
712     (when (and (memq 'bidi-category attributes)
713                (setq value (get-char-attribute char 'bidi-category)))
714       (insert (format "(bidi-category\t. %S)%s"
715                       value
716                       line-breaking))
717       (setq attributes (delq 'bidi-category attributes))
718       )
719     (unless (or (not (memq 'mirrored attributes))
720                 (eq (setq value (get-char-attribute char 'mirrored 'empty))
721                     'empty))
722       (insert (format "(mirrored\t\t. %S)%s"
723                       value
724                       line-breaking))
725       (setq attributes (delq 'mirrored attributes))
726       )
727     (cond
728      ((and (memq 'decimal-digit-value attributes)
729            (setq value (get-char-attribute char 'decimal-digit-value)))
730       (insert (format "(decimal-digit-value . %S)%s"
731                       value
732                       line-breaking))
733       (setq attributes (delq 'decimal-digit-value attributes))
734       (when (and (memq 'digit-value attributes)
735                  (setq value (get-char-attribute char 'digit-value)))
736         (insert (format "(digit-value\t . %S)%s"
737                         value
738                         line-breaking))
739         (setq attributes (delq 'digit-value attributes))
740         )
741       (when (and (memq 'numeric-value attributes)
742                  (setq value (get-char-attribute char 'numeric-value)))
743         (insert (format "(numeric-value\t . %S)%s"
744                         value
745                         line-breaking))
746         (setq attributes (delq 'numeric-value attributes))
747         )
748       )
749      (t
750       (when (and (memq 'digit-value attributes)
751                  (setq value (get-char-attribute char 'digit-value)))
752         (insert (format "(digit-value\t. %S)%s"
753                         value
754                         line-breaking))
755         (setq attributes (delq 'digit-value attributes))
756         )
757       (when (and (memq 'numeric-value attributes)
758                  (setq value (get-char-attribute char 'numeric-value)))
759         (insert (format "(numeric-value\t. %S)%s"
760                         value
761                         line-breaking))
762         (setq attributes (delq 'numeric-value attributes))
763         )))
764     (when (and (memq 'iso-10646-comment attributes)
765                (setq value (get-char-attribute char 'iso-10646-comment)))
766       (insert (format "(iso-10646-comment\t. %S)%s"
767                       value
768                       line-breaking))
769       (setq attributes (delq 'iso-10646-comment attributes))
770       )
771     (when (and (memq 'morohashi-daikanwa attributes)
772                (setq value (get-char-attribute char 'morohashi-daikanwa)))
773       (insert (format "(morohashi-daikanwa\t%s)%s"
774                       (mapconcat (function prin1-to-string) value " ")
775                       line-breaking))
776       (setq attributes (delq 'morohashi-daikanwa attributes))
777       )
778     (setq radical nil
779           strokes nil)
780     (when (and (memq 'ideographic-radical attributes)
781                (setq value (get-char-attribute char 'ideographic-radical)))
782       (setq radical value)
783       (insert (format "(ideographic-radical . %S)\t; %c%s"
784                       radical
785                       (ideographic-radical radical)
786                       line-breaking))
787       (setq attributes (delq 'ideographic-radical attributes))
788       )
789     (when (and (memq 'shuowen-radical attributes)
790                (setq value (get-char-attribute char 'shuowen-radical)))
791       (insert (format "(shuowen-radical\t. %S)\t; %c%s"
792                       value
793                       (shuowen-radical value)
794                       line-breaking))
795       (setq attributes (delq 'shuowen-radical attributes))
796       )
797     (let (key)
798       (dolist (domain
799                (append
800                 char-db-feature-domains
801                 (let (dest domain)
802                   (dolist (feature (char-attribute-list))
803                     (setq feature (symbol-name feature))
804                     (when (string-match
805                            "\\(radical\\|strokes\\)@\\([^@*]+\\)\\(\\*\\|$\\)"
806                            feature)
807                       (setq domain (intern (match-string 2 feature)))
808                      (unless (memq domain dest)
809                        (setq dest (cons domain dest)))))
810                   (sort dest #'string<))))
811         (setq key (intern (format "%s@%s" 'ideographic-radical domain)))
812         (when (and (memq key attributes)
813                    (setq value (get-char-attribute char key)))
814           (setq radical value)
815           (insert (format "(%s . %S)\t; %c%s"
816                           key
817                           radical
818                           (ideographic-radical radical)
819                           line-breaking))
820           (setq attributes (delq key attributes))
821           )
822         (setq key (intern (format "%s@%s" 'ideographic-strokes domain)))
823         (when (and (memq key attributes)
824                    (setq value (get-char-attribute char key)))
825           (setq strokes value)
826           (insert (format "(%s . %S)%s"
827                           key
828                           strokes
829                           line-breaking))
830           (setq attributes (delq key attributes))
831           )
832         (setq key (intern (format "%s@%s" 'total-strokes domain)))
833         (when (and (memq key attributes)
834                    (setq value (get-char-attribute char key)))
835           (insert (format "(%s       . %S)%s"
836                           key
837                           value
838                           line-breaking))
839           (setq attributes (delq key attributes))
840           )
841         (dolist (feature '(ideographic-radical
842                            ideographic-strokes
843                            total-strokes))
844           (setq key (intern (format "%s@%s*sources" feature domain)))
845           (when (and (memq key attributes)
846                      (setq value (get-char-attribute char key)))
847             (insert (format "(%s%s" key line-breaking))
848             (dolist (cell value)
849               (insert (format " %s" cell)))
850             (insert ")")
851             (insert line-breaking)
852             (setq attributes (delq key attributes))
853             ))
854         ))
855     (when (and (memq 'ideographic-strokes attributes)
856                (setq value (get-char-attribute char 'ideographic-strokes)))
857       (setq strokes value)
858       (insert (format "(ideographic-strokes . %S)%s"
859                       strokes
860                       line-breaking))
861       (setq attributes (delq 'ideographic-strokes attributes))
862       )
863     (when (and (memq 'kangxi-radical attributes)
864                (setq value (get-char-attribute char 'kangxi-radical)))
865       (unless (eq value radical)
866         (insert (format "(kangxi-radical\t . %S)\t; %c%s"
867                         value
868                         (ideographic-radical value)
869                         line-breaking))
870         (or radical
871             (setq radical value)))
872       (setq attributes (delq 'kangxi-radical attributes))
873       )
874     (when (and (memq 'kangxi-strokes attributes)
875                (setq value (get-char-attribute char 'kangxi-strokes)))
876       (unless (eq value strokes)
877         (insert (format "(kangxi-strokes\t . %S)%s"
878                         value
879                         line-breaking))
880         (or strokes
881             (setq strokes value)))
882       (setq attributes (delq 'kangxi-strokes attributes))
883       )
884     (when (and (memq 'japanese-radical attributes)
885                (setq value (get-char-attribute char 'japanese-radical)))
886       (unless (eq value radical)
887         (insert (format "(japanese-radical\t . %S)\t; %c%s"
888                         value
889                         (ideographic-radical value)
890                         line-breaking))
891         (or radical
892             (setq radical value)))
893       (setq attributes (delq 'japanese-radical attributes))
894       )
895     (when (and (memq 'japanese-strokes attributes)
896                (setq value (get-char-attribute char 'japanese-strokes)))
897       (unless (eq value strokes)
898         (insert (format "(japanese-strokes\t . %S)%s"
899                         value
900                         line-breaking))
901         (or strokes
902             (setq strokes value)))
903       (setq attributes (delq 'japanese-strokes attributes))
904       )
905     (when (and (memq 'cns-radical attributes)
906                (setq value (get-char-attribute char 'cns-radical)))
907       (insert (format "(cns-radical\t . %S)\t; %c%s"
908                       value
909                       (ideographic-radical value)
910                       line-breaking))
911       (setq attributes (delq 'cns-radical attributes))
912       )
913     (when (and (memq 'cns-strokes attributes)
914                (setq value (get-char-attribute char 'cns-strokes)))
915       (unless (eq value strokes)
916         (insert (format "(cns-strokes\t . %S)%s"
917                         value
918                         line-breaking))
919         (or strokes
920             (setq strokes value)))
921       (setq attributes (delq 'cns-strokes attributes))
922       )
923     (when (and (memq 'shinjigen-1-radical attributes)
924                (setq value (get-char-attribute char 'shinjigen-1-radical)))
925       (unless (eq value radical)
926         (insert (format "(shinjigen-1-radical . %S)\t; %c%s"
927                         value
928                         (ideographic-radical value)
929                         line-breaking))
930         (or radical
931             (setq radical value)))
932       (setq attributes (delq 'shinjigen-1-radical attributes))
933       )
934     (when (and (memq 'ideographic- attributes)
935                (setq value (get-char-attribute char 'ideographic-)))
936       (insert "(ideographic-       ")
937       (setq lbs (concat "\n" (make-string (current-column) ?\ ))
938             separator nil)
939       (while (consp value)
940         (setq cell (car value))
941         (if (integerp cell)
942             (setq cell (decode-char '=ucs cell)))
943         (cond ((characterp cell)
944                (if separator
945                    (insert lbs))
946                (if readable
947                    (insert (format "%S" cell))
948                  (char-db-insert-char-spec cell readable))
949                (setq separator lbs))
950               ((consp cell)
951                (if separator
952                    (insert lbs))
953                (if (consp (car cell))
954                    (char-db-insert-char-spec cell readable)
955                  (char-db-insert-char-reference cell readable))
956                (setq separator lbs))
957               (t
958                (if separator
959                    (insert separator))
960                (insert (prin1-to-string cell))
961                (setq separator " ")))
962         (setq value (cdr value)))
963       (insert ")")
964       (insert line-breaking)
965       (setq attributes (delq 'ideographic- attributes)))
966     (when (and (memq 'total-strokes attributes)
967                (setq value (get-char-attribute char 'total-strokes)))
968       (insert (format "(total-strokes       . %S)%s"
969                       value
970                       line-breaking))
971       (setq attributes (delq 'total-strokes attributes))
972       )
973     (when (and (memq '->ideograph attributes)
974                (setq value (get-char-attribute char '->ideograph)))
975       (insert (format "(->ideograph\t%s)%s"
976                       (mapconcat (lambda (code)
977                                    (cond ((symbolp code)
978                                           (symbol-name code))
979                                          ((integerp code)
980                                           (format "#x%04X" code))
981                                          (t
982                                           (format "%s %S"
983                                                   line-breaking code))))
984                                  value " ")
985                       line-breaking))
986       (setq attributes (delq '->ideograph attributes))
987       )
988     ;; (when (and (memq '->decomposition attributes)
989     ;;            (setq value (get-char-attribute char '->decomposition)))
990     ;;   (insert (format "(->decomposition\t%s)%s"
991     ;;                   (mapconcat (lambda (code)
992     ;;                                (cond ((symbolp code)
993     ;;                                       (symbol-name code))
994     ;;                                      ((characterp code)
995     ;;                                       (if readable
996     ;;                                           (format "%S" code)
997     ;;                                         (format "#x%04X"
998     ;;                                                 (char-int code))
999     ;;                                         ))
1000     ;;                                      ((integerp code)
1001     ;;                                       (format "#x%04X" code))
1002     ;;                                      (t
1003     ;;                                       (format "%s%S" line-breaking code))))
1004     ;;                              value " ")
1005     ;;                   line-breaking))
1006     ;;   (setq attributes (delq '->decomposition attributes))
1007     ;;   )
1008     (if (equal (get-char-attribute char '->titlecase)
1009                (get-char-attribute char '->uppercase))
1010         (setq attributes (delq '->titlecase attributes)))
1011     (when (and (memq '->mojikyo attributes)
1012                (setq value (get-char-attribute char '->mojikyo)))
1013       (insert (format "(->mojikyo\t\t. %06d)\t; %c%s"
1014                       value (decode-char 'mojikyo value)
1015                       line-breaking))
1016       (setq attributes (delq '->mojikyo attributes))
1017       )
1018     (when (and (memq 'hanyu-dazidian-vol attributes)
1019                (setq value (get-char-attribute char 'hanyu-dazidian-vol)))
1020       (insert (format "(hanyu-dazidian-vol  . %d)%s"
1021                       value line-breaking))
1022       (setq attributes (delq 'hanyu-dazidian-vol attributes))
1023       )
1024     (when (and (memq 'hanyu-dazidian-page attributes)
1025                (setq value (get-char-attribute char 'hanyu-dazidian-page)))
1026       (insert (format "(hanyu-dazidian-page . %d)%s"
1027                       value line-breaking))
1028       (setq attributes (delq 'hanyu-dazidian-page attributes))
1029       )
1030     (when (and (memq 'hanyu-dazidian-char attributes)
1031                (setq value (get-char-attribute char 'hanyu-dazidian-char)))
1032       (insert (format "(hanyu-dazidian-char . %d)%s"
1033                       value line-breaking))
1034       (setq attributes (delq 'hanyu-dazidian-char attributes))
1035       )
1036     (unless readable
1037       (dolist (ignored '(composition
1038                          ->denotational <-subsumptive ->ucs-unified
1039                          ->ideographic-component-forms))
1040         (setq attributes (delq ignored attributes))))
1041     (while attributes
1042       (setq name (car attributes))
1043       (if (setq value (get-char-attribute char name))
1044           (cond ((setq ret (find-charset name))
1045                  (setq name (charset-name ret))
1046                  (if (and (not (memq name dest-ccss))
1047                           (prog1
1048                               (setq value (get-char-attribute char name))
1049                             (setq dest-ccss (cons name dest-ccss))))
1050                      (char-db-insert-ccs-feature name value line-breaking))
1051                  )
1052                 ((string-match "^=>ucs@" (symbol-name name))
1053                  (insert (format "(%-18s . #x%04X)\t; %c%s"
1054                                  name value (decode-char '=ucs value)
1055                                  line-breaking))
1056                  )
1057                 ((eq name 'jisx0208-1978/4X)
1058                  (insert (format "(%-18s . #x%04X)%s"
1059                                  name value
1060                                  line-breaking))
1061                  )
1062                 ((and
1063                   (not readable)
1064                   (not (eq name '->subsumptive))
1065                   (not (eq name '->uppercase))
1066                   (not (eq name '->lowercase))
1067                   (not (eq name '->titlecase))
1068                   (not (eq name '->canonical))
1069                   (not (eq name '->Bopomofo))
1070                   (not (eq name '->mistakable))
1071                   (not (eq name '->ideographic-variants))
1072                   (null (get-char-attribute
1073                          char (intern (format "%s*sources" name))))
1074                   (not (string-match "\\*sources$" (symbol-name name)))
1075                   (null (get-char-attribute
1076                          char (intern (format "%s*note" name))))
1077                   (not (string-match "\\*note$" (symbol-name name)))
1078                   (or (eq name '<-identical)
1079                       (eq name '<-uppercase)
1080                       (eq name '<-lowercase)
1081                       (eq name '<-titlecase)
1082                       (eq name '<-canonical)
1083                       (eq name '<-ideographic-variants)
1084                       ;; (eq name '<-synonyms)
1085                       (string-match "^<-synonyms" (symbol-name name))
1086                       (eq name '<-mistakable)
1087                       (when (string-match "^->" (symbol-name name))
1088                         (cond
1089                          ((string-match "^->fullwidth" (symbol-name name))
1090                           (not (and (consp value)
1091                                     (characterp (car value))
1092                                     (encode-char
1093                                      (car value) '=ucs 'defined-only)))
1094                           )
1095                          (t)))
1096                       ))
1097                  )
1098                 ((or (eq name 'ideographic-structure)
1099                      (eq name 'ideographic-combination)
1100                      (eq name 'ideographic-)
1101                      (eq name '=decomposition)
1102                      (string-match "^=>decomposition" (symbol-name name))
1103                      (string-match "^\\(->\\|<-\\)[^*]*$" (symbol-name name))
1104                      (string-match "^\\(->\\|<-\\)[^*]*\\*sources$"
1105                                    (symbol-name name))
1106                      )
1107                  (char-db-insert-relation-feature char name value
1108                                                   line-breaking
1109                                                   ccss readable))
1110                 ((memq name '(ideograph=
1111                               original-ideograph-of
1112                               ancient-ideograph-of
1113                               vulgar-ideograph-of
1114                               wrong-ideograph-of
1115                               ;; simplified-ideograph-of
1116                               ideographic-variants
1117                               ;; ideographic-different-form-of
1118                               ))
1119                  (insert (format "(%-18s%s " name line-breaking))
1120                  (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1121                        separator nil)
1122                  (while (consp value)
1123                    (setq cell (car value))
1124                    (if (and (consp cell)
1125                             (consp (car cell)))
1126                        (progn
1127                          (if separator
1128                              (insert lbs))
1129                          (char-db-insert-alist cell readable)
1130                          (setq separator lbs))
1131                      (if separator
1132                          (insert separator))
1133                      (insert (prin1-to-string cell))
1134                      (setq separator " "))
1135                    (setq value (cdr value)))
1136                  (insert ")")
1137                  (insert line-breaking))
1138                 ((consp value)
1139                  (insert (format "(%-18s " name))
1140                  (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1141                        separator nil)
1142                  (while (consp value)
1143                    (setq cell (car value))
1144                    (if (and (consp cell)
1145                             (consp (car cell))
1146                             (setq ret (condition-case nil
1147                                           (find-char cell)
1148                                         (error nil))))
1149                        (progn
1150                          (setq rest cell
1151                                al nil
1152                                cal nil)
1153                          (while rest
1154                            (setq key (car (car rest)))
1155                            (if (find-charset key)
1156                                (setq cal (cons key cal))
1157                              (setq al (cons key al)))
1158                            (setq rest (cdr rest)))
1159                          (if separator
1160                              (insert lbs))
1161                          (insert-char-attributes ret
1162                                                  readable
1163                                                  al cal)
1164                          (setq separator lbs))
1165                      (setq ret (prin1-to-string cell))
1166                      (if separator
1167                          (if (< (+ (current-column)
1168                                    (length ret)
1169                                    (length separator))
1170                                 76)
1171                              (insert separator)
1172                            (insert lbs)))
1173                      (insert ret)
1174                      (setq separator " "))
1175                    (setq value (cdr value)))
1176                  (insert ")")
1177                  (insert line-breaking))
1178                 (t
1179                  (insert (format "(%-18s" name))
1180                  (setq ret (prin1-to-string value))
1181                  (unless (< (+ (current-column)
1182                                (length ret)
1183                                3)
1184                             76)
1185                    (insert line-breaking))
1186                  (insert " . " ret ")" line-breaking)
1187                  ;; (insert (format "(%-18s . %S)%s"
1188                  ;;                 name value
1189                  ;;                 line-breaking))
1190                  )
1191                 ))
1192       (setq attributes (cdr attributes)))
1193     (insert ")")))
1194
1195 (defun insert-char-data (char &optional readable
1196                               attributes)
1197   (save-restriction
1198     (narrow-to-region (point)(point))
1199     (insert "(define-char
1200   '")
1201     (insert-char-attributes char readable attributes)
1202     (insert ")\n")
1203     (goto-char (point-min))
1204     (while (re-search-forward "[ \t]+$" nil t)
1205       (replace-match ""))
1206     ;; from tabify.
1207     (goto-char (point-min))
1208     (while (re-search-forward "[ \t][ \t][ \t]*" nil t)
1209       (let ((column (current-column))
1210             (indent-tabs-mode t))
1211         (delete-region (match-beginning 0) (point))
1212         (indent-to column)))
1213     (goto-char (point-max))
1214     ;; (tabify (point-min)(point-max))
1215     ))
1216
1217 (defun insert-char-data-with-variant (char &optional printable
1218                                            no-ucs-unified
1219                                            script excluded-script)
1220   (insert-char-data char printable)
1221   (let ((variants (char-variants char))
1222         rest
1223         variant vs ret)
1224     (setq variants (sort variants #'<))
1225     (setq rest variants)
1226     (setq variants (cons char variants))
1227     (while rest
1228       (setq variant (car rest))
1229       (unless (get-char-attribute variant '<-subsumptive)
1230         (if (and (or (null script)
1231                      (null (setq vs (get-char-attribute variant 'script)))
1232                      (memq script vs))
1233                  (or (null excluded-script)
1234                      (null (setq vs (get-char-attribute variant 'script)))
1235                      (not (memq excluded-script vs))))
1236             (unless (and no-ucs-unified (get-char-attribute variant '=ucs))
1237               (insert-char-data variant printable)
1238               (if (setq ret (char-variants variant))
1239                   (while ret
1240                     (or (memq (car ret) variants)
1241                         ;; (get-char-attribute (car ret) '<-subsumptive)
1242                         (setq rest (nconc rest (list (car ret)))))
1243                     (setq ret (cdr ret)))))))
1244       (setq rest (cdr rest)))))
1245
1246 (defun insert-char-range-data (min max &optional script excluded-script)
1247   (let ((code min)
1248         char)
1249     (while (<= code max)
1250       (setq char (decode-char '=ucs code))
1251       (if (encode-char char '=ucs 'defined-only)
1252           (insert-char-data-with-variant char nil 'no-ucs-unified
1253                                          script excluded-script))
1254       (setq code (1+ code)))))
1255
1256 (defun write-char-range-data-to-file (min max file
1257                                           &optional script excluded-script)
1258   (let ((coding-system-for-write char-db-file-coding-system))
1259     (with-temp-buffer
1260       (insert (format ";; -*- coding: %s -*-\n"
1261                       char-db-file-coding-system))
1262       (insert-char-range-data min max script excluded-script)
1263       (write-region (point-min)(point-max) file))))
1264
1265 (defvar what-character-original-window-configuration)
1266
1267 ;;;###autoload
1268 (defun what-char-definition (char)
1269   (interactive (list (char-after)))
1270   (let ((buf (get-buffer-create "*Character Description*"))
1271         (the-buf (current-buffer))
1272         (win-conf (current-window-configuration)))
1273     (pop-to-buffer buf)
1274     (make-local-variable 'what-character-original-window-configuration)
1275     (setq what-character-original-window-configuration win-conf)
1276     (setq buffer-read-only nil)
1277     (erase-buffer)
1278     (condition-case err
1279         (progn
1280           (insert-char-data-with-variant char 'printable)
1281           (unless (char-attribute-alist char)
1282             (insert (format ";; = %c\n"
1283                             (let* ((rest (split-char char))
1284                                    (ccs (pop rest))
1285                                    (code (pop rest)))
1286                               (while rest
1287                                 (setq code (logior (lsh code 8)
1288                                                    (pop rest))))
1289                               (decode-char ccs code)))))
1290           ;; (char-db-update-comment)
1291           (set-buffer-modified-p nil)
1292           (view-mode the-buf (lambda (buf)
1293                                (set-window-configuration
1294                                 what-character-original-window-configuration)
1295                                ))
1296           (goto-char (point-min)))
1297       (error (progn
1298                (set-window-configuration
1299                 what-character-original-window-configuration)
1300                (signal (car err) (cdr err)))))))
1301
1302 (provide 'char-db-util)
1303
1304 ;;; char-db-util.el ends here