3 # rbchise compatible ruby library by eto 2003-0317
4 # Copyright (C) 2002-2003 Kouichirou Eto
6 # This is free software with ABSOLUTELY NO WARRANTY.
8 # You can redistribute it and/or modify it under the terms of
9 # the GNU General Public License version 2.
16 class DBS #======================================================================複数のDBを集めたclass、未完成
19 class ADB < BDB::Hash #======================================================================一つのDB
25 self.close #これがないと、うまくデータベースがセーブされないのです。
29 def self.open_create(filename)
30 ADB.open(filename, nil, BDB::CREATE | BDB::EXCL) #上書きはしない
34 if key.char_length == 1
35 return '?'+key #Stringだったら引く前に?を足す
38 #key = key.to_s if key.is_a?(Numeric) #NumberだったらStringにする。
39 #ここで && key ! =~ /^\?/ をいれると、?自身を検索できなくなってしまう。
44 return v.to_i if v =~ /^\d+$/ #数字だったらここで変換しておく
45 return v.sub(/^\?/, '') if v =~ /^\?/ #冒頭の?は取り除く
46 return $1 if v =~ /^"(.+)"$/ #最初と最後に"がついていたら、取り除く
47 #p ['get', v, t, key, db]
48 #return parse_sexp(v) if v =~ /^\(.+\)$/ #最初と最後が()の時は、S式にparseする
51 def myget(key) #keyキーを引いて返す
53 v = get(key) #存在しなかったらnilを返すことになる
56 def myput(key, v) #keyにvをいれる
63 class DB #======================================================= データベース群のabstract class
64 def self.unix_to_win(unix) #Windowsファイル名制限のため、変換する
65 win = unix.gsub(/</, '(')
71 def self.win_to_unix(win)
72 unix = win.gsub(%r|\)|, '>')
73 unix.gsub!(%r|\(|, '<')
74 unix.gsub!(%r|!|, '?')
75 unix.gsub!(%r|\+|, '*')
79 return @pre + DB.unix_to_win(t) + @post if windows?
80 return @pre + t + @post
82 def get_dirname(t) File.dirname(get_filename(t)) end
86 keys.each {|key| open_db(key) }
91 next if ! File.file?(f)
98 t.sub!(%r|^#{@pre}|, '')
99 t.sub!(%r|#{@post}$|, '') if @post != ""
106 return nil if db.nil?
111 return nil if get(t) #すでにopenしていたら再openはしない。
113 bdb = ADB.open(get_filename(t), nil, 0)
114 @dbs[t] = bdb if bdb != nil
116 p ["open error", get_filename(t)]; return nil
120 def make_db(t, h=nil) #tという名前でhという中身のデータベースを作る
121 return nil if get(t) #すでにある場合はreturn
122 Dir.mkdir(get_dirname(t)) unless FileTest.exist?(get_dirname(t))
125 db = ADB.open_create(get_filename(t)) #上書きはしない
128 k = '?'+k if k.is_a?(String)
134 p ["make error", get_filename(t)]; return nil
138 def make_db_no_question_mark(t, h=nil) #tという名前でhという中身のデータベースを作る
139 return nil if get(t) #すでにある場合はreturn
140 Dir.mkdir(get_dirname(t)) unless FileTest.exist?(get_dirname(t))
143 db = ADB.open_create(get_filename(t)) #上書きはしない
146 # k = '?'+k if k.is_a?(String)
152 p ["make error", get_filename(t)]; return nil
156 def remove_db(t) #tという名前のデータベースを消去する
163 File.unlink(get_filename(t)) if FileTest.file?(get_filename(t))
165 p ["unlink error", get_filename(t)]; return nil
168 Dir.rmdir(dn) if FileTest.directory?(dn) && Dir.entries(dn).length <= 2 #空directoryだったら消す
172 return s.to_i if s =~ /^\d+$/
178 file = get_filename(t)
179 open("#{file}.txt", "w"){|out|
180 # out.binmode.sync = true
182 ar.map! {|k, v| [to_num(k), to_num(v)] }
184 out.printf("%s\t%s\n", k, v)
189 def each_db() @dbs.to_a.sort.each {|t, db| yield(t, db) } end
190 def dump_all() each_db {|t, db| dump_db(t) } end
191 def close_all() each_db {|t, db| db.close } end
192 def keys() @dbs.keys end
194 return unless block_given?
200 k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
201 vv = get(t, k) #p ['each', t, k, v, vv]
206 return unless block_given?
210 ar.map! {|k, v| [to_num(k), to_num(v)] }
212 k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
213 vv = get(t, k) #p ['each', t, k, v, vv]
217 #----------------------------------------------------------------------
218 def get(t, key=nil) #tというデータベースのkeyキーを引いて返す
220 return db if key.nil?
224 def put(t, key, v) #tというデータベースのkeyにvをいれる
231 db.myput(key, v) #putする
235 class CharDB < DB #------------------------------------ MCS-UTF8をキーとした属性へのデータベース
239 @glob, @pre, @post = "#{DB_DIR}/system-char-id/*", "#{DB_DIR}/system-char-id/", ""
242 def get_all(u8) #全データベースのu8キーを引いてHashにまとめて返す
246 atrs[t] = v if v != nil
252 class CodesysDB < DB #----------------------------------------------------------------------
256 @glob, @pre, @post = "#{DB_DIR}/*/system-char-id", "#{DB_DIR}/", "/system-char-id"
259 #def keys() @dbs.keys.sort end #どんなCodesysの情報を持っているかの一覧
260 def keys() @dbs.keys end #どんなCodesysの情報を持っているかの一覧
264 return Codesys.new(t)
268 class Codesys < DB #======================================================================
272 @dbs = CodesysDB.instance
274 def keys() #どんなコードポイントの情報を持っているかの一覧
275 ks = @dbs.get(@name).keys
276 # if @name =~ /jisx0208/ #特別処理
277 # n = @dbs.get('=jis-x0208').keys
278 # # p ['keys', @name, ks, n]
281 ks.map! {|k| to_num(k) }
285 v = @dbs.get(@name, key)
287 # if @name =~ /jisx0208/ #jisx0208が含まれている場合だけ特別処理する
288 # return @dbs.get('=jis-x0208', key)
293 return unless block_given?
299 k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
300 vv = @dbs.get(@name, k) #p ['each', t, k, v, vv]
305 return unless block_given?
309 ar.map! {|k, v| [to_num(k), to_num(v)] }
311 k.sub!(/^\?/, '') if k =~ /^\?/ #冒頭の?は取り除く
312 vv = @dbs.get(@name, k) #p ['each', t, k, v, vv]
318 class JISX0208 #======================================================================
320 db = CodesysDB.instance
321 @common = db.get_codesys('=jis-x0208')
322 @newest = db.get_codesys('japanese-jisx0208-1990')
325 char = @common.get(code)
326 return char unless char.nil?
327 char = @newest.get(code)
328 return char unless char.nil?
333 class DBS_Management #======================================================================ファイル管理
334 OBSOLETE_ATTRIBUTES = "
366 ancient-char-of-shinjigen-1
367 original-ideograph-of
368 original-char-of-shinjigen-1
369 simplified-ideograph-of
371 vulgar-char-of-shinjigen-1
374 variant-of-shinjigen-1
379 @odir = DB_DIR+"/system-char-id/obsolete" #直打ちしている。
381 def move_obsolete_files # 廃止予定のbdbファイルをobsoleteディレクトリーにつっこむ
384 Dir.mkdir(@odir) unless FileTest.directory? @odir
385 OBSOLETE_ATTRIBUTES.each {|attr|
387 filename = db.get_filename(attr)
388 move_to_obsolete(filename)
389 move_to_obsolete(filename+".txt")
392 def move_to_obsolete(file)
393 cmd = "mv \"#{file}\" #{@odir}"
401 #----------------------------------------------------------------------終了