+++ /dev/null
-#!/usr/bin/env ruby
-#
-# rbchise compatible ruby library by eto 2003-0317
-# Copyright (C) 2002-2003 Kouichirou Eto
-# All rights reserved.
-# This is free software with ABSOLUTELY NO WARRANTY.
-#
-# You can redistribute it and/or modify it under the terms of
-# the GNU General Public License version 2.
-#
-
-require 'db'
-
-module CHISE
-
- class DBS #======================================================================複数のDBを集めたclass、未完成
- end
-
- class ADB < BDB::Hash #======================================================================一つのDB
- def initialize(*args)
- super
- @modified = false
- at_exit {
- if @modified
- self.close #これがないと、うまくデータベースがセーブされないのです。
- end
- }
- end
- def self.open_create(filename)
- ADB.open(filename, nil, BDB::CREATE | BDB::EXCL) #上書きはしない
- end
- def mykey(key)
- if key.is_a?(String)
- if key.char_length == 1
- return '?'+key #Stringだったら引く前に?を足す
- end
- end
- #key = key.to_s if key.is_a?(Numeric) #NumberだったらStringにする。
- #ここで && key ! =~ /^\?/ をいれると、?自身を検索できなくなってしまう。
- return key
- end
- def myvalue(v)
- return v if v == nil
- return v.to_i if v =~ /^\d+$/ #数字だったらここで変換しておく
- return v.sub(/^\?/, '') if v =~ /^\?/ #冒頭の?は取り除く
- return $1 if v =~ /^"(.+)"$/ #最初と最後に"がついていたら、取り除く
- #p ['get', v, t, key, db]
- #return parse_sexp(v) if v =~ /^\(.+\)$/ #最初と最後が()の時は、S式にparseする
- return v #それ以外って何?
- end
- def myget(key) #keyキーを引いて返す
- key = mykey(key)
- v = get(key) #存在しなかったらnilを返すことになる
- return myvalue(v)
- end
- def myput(key, v) #keyにvをいれる
- key = mykey(key)
- put(key, v) #putする
- @modified = true
- end
- end
-
- class DB #======================================================= データベース群のabstract class
- def self.unix_to_win(unix) #Windowsファイル名制限のため、変換する
- win = unix.gsub(/</, '(')
- win.gsub!(/>/, ')')
- win.gsub!(/\*/, '+')
- win.gsub!(/\?/, '!')
- return win
- end
- def self.win_to_unix(win)
- unix = win.gsub(%r|\)|, '>')
- unix.gsub!(%r|\(|, '<')
- unix.gsub!(%r|!|, '?')
- unix.gsub!(%r|\+|, '*')
- return unix
- end
- def get_filename(t)
- return @pre + DB.unix_to_win(t) + @post if windows?
- return @pre + t + @post
- end
- def get_dirname(t) File.dirname(get_filename(t)) end
- def open_dbs()
- @dbs = Hash.new
- keys = find_keys()
- keys.each {|key| open_db(key) }
- end
- def find_keys()
- files = []
- Dir.glob(@glob){|f|
- next if ! File.file?(f)
- next if f =~ /.txt$/
- files << f
- }
- keys = []
- files.each {|f|
- t = DB.win_to_unix(f)
- t.sub!(%r|^#{@pre}|, '')
- t.sub!(%r|#{@post}$|, '') if @post != ""
- keys << t
- }
- return keys
- end
- def close_db(t)
- db = get(t)
- return nil if db.nil?
- db.close
- @dbs.delete(t)
- end
- def open_db(t)
- return nil if get(t) #すでにopenしていたら再openはしない。
- begin
- bdb = ADB.open(get_filename(t), nil, 0)
- @dbs[t] = bdb if bdb != nil
- rescue
- p ["open error", get_filename(t)]; return nil
- end
- return true
- end
- def make_db(t, h=nil) #tという名前でhという中身のデータベースを作る
- return nil if get(t) #すでにある場合はreturn
- Dir.mkdir(get_dirname(t)) unless FileTest.exist?(get_dirname(t))
- db = nil
- begin
- db = ADB.open_create(get_filename(t)) #上書きはしない
- if h != nil
- h.each {|k, v|
- k = '?'+k if k.is_a?(String)
- db[k] = v
- }
- end
- db.close
- rescue
- p ["make error", get_filename(t)]; return nil
- end
- return true
- end
- def make_db_no_question_mark(t, h=nil) #tという名前でhという中身のデータベースを作る
- return nil if get(t) #すでにある場合はreturn
- Dir.mkdir(get_dirname(t)) unless FileTest.exist?(get_dirname(t))
- db = nil
- begin
- db = ADB.open_create(get_filename(t)) #上書きはしない
- if h != nil
- h.each {|k, v|
- # k = '?'+k if k.is_a?(String)
- db[k] = v
- }
- end
- db.close
- rescue
- p ["make error", get_filename(t)]; return nil
- end
- return true
- end
- def remove_db(t) #tという名前のデータベースを消去する
- db = get(t)
- if db
- db.close
- @dbs.delete(t)
- end
- begin
- File.unlink(get_filename(t)) if FileTest.file?(get_filename(t))
- rescue
- p ["unlink error", get_filename(t)]; return nil
- end
- dn = get_dirname(t)
- Dir.rmdir(dn) if FileTest.directory?(dn) && Dir.entries(dn).length <= 2 #空directoryだったら消す
- return true
- end
- def to_num(s)
- return s.to_i if s =~ /^\d+$/
- return s
- end
- def dump_db(t)
- db = get(t)
- return nil unless db
- file = get_filename(t)
- open("#{file}.txt", "w"){|out|
- # out.binmode.sync = true
- ar = db.to_a
- ar.map! {|k, v| [to_num(k), to_num(v)] }
- ar.sort.each {|k, v|
- out.printf("%s\t%s\n", k, v)
- }
- }
- return true
- end
- def each_db() @dbs.to_a.sort.each {|t, db| yield(t, db) } end
- def dump_all() each_db {|t, db| dump_db(t) } end
- def close_all() each_db {|t, db| db.close } end
- def keys() @dbs.keys end
- def each(t)
- return unless block_given?
- db = @dbs[t]
- return nil unless db
- db.each {|k, v|
- k = to_num(k)
- v = to_num(v)
- k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
- vv = get(t, k) #p ['each', t, k, v, vv]
- yield(k, vv)
- }
- end
- def each_sort(t)
- return unless block_given?
- db = @dbs[t]
- return nil unless db
- ar = db.to_a
- ar.map! {|k, v| [to_num(k), to_num(v)] }
- ar.sort.each {|k, v|
- k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
- vv = get(t, k) #p ['each', t, k, v, vv]
- yield(k, vv)
- }
- end
- #----------------------------------------------------------------------
- def get(t, key=nil) #tというデータベースのkeyキーを引いて返す
- db = @dbs[t]
- return db if key.nil?
- return nil unless db
- return db.myget(key)
- end
- def put(t, key, v) #tというデータベースのkeyにvをいれる
- db = @dbs[t]
- if db == nil
- db = make_db(t)
- db = open_db(t)
- db = @dbs[t]
- end
- db.myput(key, v) #putする
- end
- end
-
- class CharDB < DB #------------------------------------ MCS-UTF8をキーとした属性へのデータベース
- include Singleton
- def initialize()
- super
- @glob, @pre, @post = "#{DB_DIR}/system-char-id/*", "#{DB_DIR}/system-char-id/", ""
- open_dbs()
- end
- def get_all(u8) #全データベースのu8キーを引いてHashにまとめて返す
- atrs = Hash.new
- @dbs.each {|t, db|
- v = get(t, u8)
- atrs[t] = v if v != nil
- }
- return atrs
- end
- end
-
- class CodesysDB < DB #----------------------------------------------------------------------
- include Singleton
- def initialize()
- super
- @glob, @pre, @post = "#{DB_DIR}/*/system-char-id", "#{DB_DIR}/", "/system-char-id"
- open_dbs()
- end
- #def keys() @dbs.keys.sort end #どんなCodesysの情報を持っているかの一覧
- def keys() @dbs.keys end #どんなCodesysの情報を持っているかの一覧
- def get_codesys(t)
- db = get(t)
- return nil unless db
- return Codesys.new(t)
- end
- end
-
- class Codesys < DB #======================================================================
- def initialize(name)
- # super
- @name = name
- @dbs = CodesysDB.instance
- end
- def keys() #どんなコードポイントの情報を持っているかの一覧
- ks = @dbs.get(@name).keys
-# if @name =~ /jisx0208/ #特別処理
-# n = @dbs.get('=jis-x0208').keys
-# # p ['keys', @name, ks, n]
-# ks += n
-# end
- ks.map! {|k| to_num(k) }
- ks
- end
- def get(key)
- v = @dbs.get(@name, key)
- return v if v
-# if @name =~ /jisx0208/ #jisx0208が含まれている場合だけ特別処理する
-# return @dbs.get('=jis-x0208', key)
-# end
- return nil
- end
- def each()
- return unless block_given?
- db = @dbs.get(@name)
- return nil unless db
- db.each {|k, v|
- k = to_num(k)
- v = to_num(v)
- k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
- vv = @dbs.get(@name, k) #p ['each', t, k, v, vv]
- yield(k, vv)
- }
- end
- def each_sort()
- return unless block_given?
- db = @dbs.get(@name)
- return nil unless db
- ar = db.to_a
- ar.map! {|k, v| [to_num(k), to_num(v)] }
- ar.sort.each {|k, v|
- k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
- vv = @dbs.get(@name, k) #p ['each', t, k, v, vv]
- yield(k, vv)
- }
- end
- end
-
- class JISX0208 #======================================================================
- def initialize
- db = CodesysDB.instance
- @common = db.get_codesys('=jis-x0208')
- @newest = db.get_codesys('japanese-jisx0208-1990')
- end
- def get_char(code)
- char = @common.get(code)
- return char unless char.nil?
- char = @newest.get(code)
- return char unless char.nil?
- return nil
- end
- end
-
- class DBS_Management #======================================================================ファイル管理
- OBSOLETE_ATTRIBUTES = "
-cns-radical
-cns-radical?
-kangxi-radical
-daikanwa-radical
-unicode-radical
-
-cns-strokes
-kangxi-strokes
-daikanwa-strokes
-shinjigen-1-radical
-gb-original-radical
-japanese-strokes
-jis-strokes-a
-jis-strokes-b
-jisx0208-strokes
-jis-x0213-strokes
-jisx0213-strokes
-unicode-strokes
-
-totalstrokes
-cns-total-strokes
-jis-total-strokes-b
-
-non-morohashi
-
-=>ucs*
-#=>mojikyo
-#=mojikyo
-->identical
-
-ancient-ideograph-of
-ancient-char-of-shinjigen-1
-original-ideograph-of
-original-char-of-shinjigen-1
-simplified-ideograph-of
-vulgar-ideograph-of
-vulgar-char-of-shinjigen-1
-ideograph=
-ideographic-variants
-variant-of-shinjigen-1
-
-iso-10646-comment
-".split
- def initialize
- @odir = DB_DIR+"/system-char-id/obsolete" #直打ちしている。
- end
- def move_obsolete_files # 廃止予定のbdbファイルをobsoleteディレクトリーにつっこむ
- db = CharDB.instance
- db.close_all
- Dir.mkdir(@odir) unless FileTest.directory? @odir
- OBSOLETE_ATTRIBUTES.each {|attr|
- next if attr =~ /^#/
- filename = db.get_filename(attr)
- move_to_obsolete(filename)
- move_to_obsolete(filename+".txt")
- }
- end
- def move_to_obsolete(file)
- cmd = "mv \"#{file}\" #{@odir}"
- # p cmd
- system cmd
- end
- end
-
-end
-
-#----------------------------------------------------------------------終了