summaryrefslogtreecommitdiff
path: root/tool
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-06 18:17:01 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-06 18:17:01 +0000
commit8354d2f700b0f432c6868a0b8e5eb4d1f823d79a (patch)
tree0fc162441b2bf21b22bc5bcf5eef3b861d2eac26 /tool
parente02ad7327ec249e52425bbb7828f9b28c3dbc356 (diff)
* enc/unicode/name2ctype.h, tool/transcode-tblgen.rb: revert
unlogged changes which committed by accident probably. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35247 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'tool')
-rwxr-xr-xtool/transcode-tblgen.rb488
1 files changed, 26 insertions, 462 deletions
diff --git a/tool/transcode-tblgen.rb b/tool/transcode-tblgen.rb
index ac91200be6..b25901d375 100755
--- a/tool/transcode-tblgen.rb
+++ b/tool/transcode-tblgen.rb
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
require 'optparse'
require 'erb'
require 'fileutils'
@@ -554,48 +553,37 @@ class ActionMap
min = max = 0
end
- # 一つの文字コード変換を Tables クラスとしてデータで格納
- GENERATED_CODE << Tables.new(name, min, max, offsets, infos)
-
-=begin
- # 文字列化をしない
- offsets_key = [min, max, offsets[min..max]]
- if n = OffsetsMemo[offsets_key]
- offsets_name = n
- else
- offsets_name = "#{name}_offsets"
- OffsetsMemo[offsets_key] = offsets_name
-
- size = bytes_code.length
- bytes_code.insert_at_last(2+max-min+1,
- "\#define #{offsets_name} #{size}\n" +
- format_offsets(min,max,offsets) + "\n")
- end
-
- if n = InfosMemo[infos]
- infos_name = n
- else
- infos_name = "#{name}_infos"
- InfosMemo[infos] = infos_name
-
-
- size = words_code.length
- words_code.insert_at_last(infos.length,
- "\#define #{infos_name} WORDINDEX2INFO(#{size})\n" +
- format_infos(infos) + "\n")
+ offsets_key = [min, max, offsets[min..max]]
+ if n = OffsetsMemo[offsets_key]
+ offsets_name = n
+ else
+ offsets_name = "#{name}_offsets"
+ OffsetsMemo[offsets_key] = offsets_name
+ size = bytes_code.length
+ bytes_code.insert_at_last(2+max-min+1,
+ "\#define #{offsets_name} #{size}\n" +
+ format_offsets(min,max,offsets) + "\n")
+ end
- infos_state = 0
- end
+ if n = InfosMemo[infos]
+ infos_name = n
+ else
+ infos_name = "#{name}_infos"
+ InfosMemo[infos] = infos_name
size = words_code.length
- words_code.insert_at_last(NUM_ELEM_BYTELOOKUP,
- "\#define #{name} WORDINDEX2INFO(#{size})\n" +
- <<"End" + "\n")
+ words_code.insert_at_last(infos.length,
+ "\#define #{infos_name} WORDINDEX2INFO(#{size})\n" +
+ format_infos(infos) + "\n")
+ end
+
+ size = words_code.length
+ words_code.insert_at_last(NUM_ELEM_BYTELOOKUP,
+ "\#define #{name} WORDINDEX2INFO(#{size})\n" +
+ <<"End" + "\n")
#{offsets_name},
#{infos_name},
End
-=end
-
end
PreMemo = {}
@@ -876,428 +864,7 @@ def transcode_generate_node(am, name_hint=nil)
''
end
-# 一つの offsets テーブルを表すクラス
-class Offsets
- attr_accessor :content, :min, :max
- attr_reader :name
- def initialize(name, min, max, content)
- @name = name
- @content = content
- @min = min
- @max = max
- end
-
- # 以下、既存のものをコピー・修正
- def format_offsets
- offsets = @content[@min..@max]
- code = "%d, %d,\n" % [min, max]
- 0.step(offsets.length-1,16) {|i|
- code << " "
- code << offsets[i,8].map {|off| "%3d," % off.to_s }.join('')
- if i+8 < offsets.length
- code << " "
- code << offsets[i+8,8].map {|off| "%3d," % off.to_s }.join('')
- end
- code << "\n"
- }
- code
- end
-end
-
-# 一つの infos テーブルを表すクラス
-class Infos
- attr_accessor :content
- attr_reader :name
- def initialize(name, content)
- @name = name
- @content = content
- end
-
- # 以下、既存のものをコピー・修正
- UsedName = {}
-
- StrMemo = {}
-
- def str_name(bytes)
- size = TRANSCODE_GENERATED_BYTES_CODE.length
- rawbytes = [bytes].pack("H*")
-
- n = nil
- if !n && !(suf = rawbytes.gsub(/[^A-Za-z0-9_]/, '')).empty? && !UsedName[nn = "str1_" + suf] then n = nn end
- if !n && !UsedName[nn = "str1_" + bytes] then n = nn end
- n ||= "str1s_#{size}"
-
- StrMemo[bytes] = n
- UsedName[n] = true
- n
- end
-
- def gen_str(bytes)
- if n = StrMemo[bytes]
- n
- else
- len = bytes.length/2
- size = TRANSCODE_GENERATED_BYTES_CODE.length
- n = str_name(bytes)
- TRANSCODE_GENERATED_BYTES_CODE.insert_at_last(1 + len,
- "\#define #{n} makeSTR1(#{size})\n" +
- " makeSTR1LEN(#{len})," + bytes.gsub(/../, ' 0x\&,') + "\n\n")
- n
- end
- end
-
- def generate_info(info)
- case info
- when :info_a
- "INFO_A"
- when :info_b
- "INFO_B"
- when :info_c
- "INFO_C"
- when :info_d
- "INFO_D"
- when :info_e
- "INFO_E"
- when :nomap, :nomap0
- # :nomap0 is low priority. it never collides.
- "NOMAP"
- when :undef
- "UNDEF"
- when :invalid
- "INVALID"
- when :func_ii
- "FUNii"
- when :func_si
- "FUNsi"
- when :func_io
- "FUNio"
- when :func_so
- "FUNso"
- when /\A(#{HEX2})\z/o
- "o1(0x#$1)"
- when /\A(#{HEX2})(#{HEX2})\z/o
- "o2(0x#$1,0x#$2)"
- when /\A(#{HEX2})(#{HEX2})(#{HEX2})\z/o
- "o3(0x#$1,0x#$2,0x#$3)"
- when /funsio\((\d+)\)/
- "funsio(#{$1})"
- when /\A(#{HEX2})(3[0-9])(#{HEX2})(3[0-9])\z/o
- "g4(0x#$1,0x#$2,0x#$3,0x#$4)"
- when /\A(f[0-7])(#{HEX2})(#{HEX2})(#{HEX2})\z/o
- "o4(0x#$1,0x#$2,0x#$3,0x#$4)"
- when /\A(#{HEX2}){4,259}\z/o
- gen_str(info.upcase)
- when /\A\/\*BYTE_LOOKUP\*\// # pointer to BYTE_LOOKUP structure
- $'.to_s
- else
- raise "unexpected action: #{info.inspect}"
- end
- end
-
- def format_infos
- infos = @content.map {|info| generate_info(info) }
- maxlen = infos.map {|info| info.length }.max
- columns = maxlen <= 16 ? 4 : 2
- code = ""
- 0.step(infos.length-1, columns) {|i|
- code << " "
- is = infos[i,columns]
- is.each {|info|
- code << sprintf(" %#{maxlen}s,", info)
- }
- code << "\n"
- }
- code
- end
-end
-
-# 一つの文字コード変換を表すクラス
-class Tables
- attr_accessor :offsets, :infos, :have_tbls
- attr_reader :offsets_org, :infos_org, :name
- def initialize(name, min, max, offsets, infos)
- @name = name
- @offsets = Offsets.new(name + "_offsets", min, max, offsets)
- # 元の offsets テーブル(変更されない)
- @offsets_org = Offsets.new(name + "_offsets", min, max, offsets)
- @infos = Infos.new(name + "_infos", infos)
- # 元の infos テーブル(変更されない)
- @infos_org = Infos.new(name + "_infos", infos)
- @have_tbls = 1 # 自分を含めて共用してるテーブルの数
- end
-end
-
-# 完全に offsets が一致する場合に共有
-def share_no_change
- GENERATED_CODE.each_with_index do |tables, i|
- # 対象の offsets がすでに共用されているかどうかチェック
- # 共用済みだった場合は次へ
- next if tables.offsets.class == Tables
- j = i + 1
- while j < GENERATED_CODE.length
- # offsets の content, min, max 全てが一致すれば共用
- # 既存の変換と整合性を保つ
- if tables.offsets.class == Offsets && GENERATED_CODE[j].offsets.class == Offsets
- if tables.offsets_org.content == GENERATED_CODE[j].offsets_org.content &&
- tables.offsets_org.min == GENERATED_CODE[j].offsets_org.min &&
- tables.offsets_org.max == GENERATED_CODE[j].offsets_org.max
- # 共用する Tables クラスを 共用される Tables クラスの offsets に代入
- # 共用の関係を保存しておく
- GENERATED_CODE[j].offsets = tables
- # 削減メモリ計算のための処理
- tables.have_tbls += GENERATED_CODE[j].have_tbls
- end
- end
- j += 1
- end
- end
-end
-
-# 片方を共用することができるパターン
-# 共用する方は infos テーブルの変更が必要(generate_string メソッドで行っている)
-def share_infos_change
- cutback = [0] # 削減したメモリ量を保存(一つのファイルの削減)
- GENERATED_CODE.each do |trg| # trg = target
- STDERR.print "." # 処理の経過を見る
-
- # target が共有済みで無ければ
- if trg.offsets.class == Offsets
- GENERATED_CODE.each do |comp|
- # 同じ文字コード変換の場合はスキップ
- next if trg.name == comp.name
-
- # 比較する方が共用済みで無ければ
- if comp.offsets.class == Offsets
- if comp_offsets(trg, comp, cutback)
- # trg の offsets テーブルのサイズが comp のものより狭い場合
- # comp のサイズに合わせる必要がある
- trg.offsets.max = comp.offsets.max if comp.offsets.max > trg.offsets.max
- trg.offsets.min = comp.offsets.min if comp.offsets.min < trg.offsets.min
- # comp の offsets を Tables クラス trg に変更
- comp.offsets = trg
- # 共用されたテーブルの数を増やす
- trg.have_tbls += comp.have_tbls
- end
- end
- end
- end
- end
- STDERR.puts # STDERR.print "." を見やすくする
- # puts cutback[0] # 削減メモリを出力
-end
-
-# 二つの文字コード変換の offsets テーブルが片方に共用可能かどうか判断する
-def comp_offsets(trg, comp, cutback)
- # target の offset の種類が comp の offsets の種類より小さいと共用できない
- return FALSE if trg.offsets.content.max <= comp.offsets.content.max
- return FALSE if calc_cut(trg, comp) <= 0 # 削減量による共用の条件を指定
- set_offset = {} # それぞれの offsets テーブルにある同位置の offset をセットとする
-
- # 同位置にある offset のペアの種類を調べ、出現回数をカウント
- trg.offsets.content.each_with_index do |o_trg, i|
- o_comp = comp.offsets.content[i]
- key = [o_trg, o_comp]
- if set_offset[key]
- set_offset[key] += 1
- else
- set_offset[key] = 1
- end
- end
-
- # offset ペアの数が target の offset の種類以下(等しい)でなければそのまま共用できない
- return FALSE if set_offset.length > trg.offsets.content.max + 1
-
- # 以下、共用可能
- # どれくらい削減できるか計算して、条件によって実行するかどうか決める
- cutback[0] += calc_cut(trg, comp) # デバック用として削減できたメモリの量を再計算
- return TRUE
-end
-
-def calc_cut(trg, comp) # 今のところは offsets のみを代えた場合の計算
- # offset 共用により削減できる量
- cut_offsets = comp.offsets.max - comp.offsets.min + 1
- # infos 増加より増加する量
- # (共用 offsets の種類 - 削減 offsets の種類) * 4 byte * (削減するテーブルが共用してる数)
- add_infos = ((trg.offsets.content.max + 1) - (comp.offsets.content.max + 1)) * 4 * comp.have_tbls
-
- return cut_offsets - add_infos
-end
-
-# 共用されていた場合に最終的に利用する offsets テーブルを探索する
-def search_real_offsets(target)
- if target.offsets.class == Tables
- return search_real_offsets(target.offsets)
- else
- return target.offsets
- end
-end
-
-# 共用されていた場合に最終的に利用する infos テーブルを探索する
-def search_real_infos(target)
- if target.infos.class == Tables
- return search_real_infos(target.infos)
- else
- return target.infos
- end
-end
-
-# データとして格納していた文字コード変換を文字列化
-# 文字列化の部分は既存の処理を一部修正し、利用している
-def generate_string
- GENERATED_CODE.each do |tables|
- name = tables.name # 文字コード変換自体の名前
-
- # 共用済みとそうでない場合で処理を分ける
- if tables.offsets.class == Offsets # 共用なし
- # 既存の処理と変わらない
- offsets_name = tables.offsets.name
- size = TRANSCODE_GENERATED_BYTES_CODE.length
- TRANSCODE_GENERATED_BYTES_CODE.insert_at_last(2+tables.offsets.max-tables.offsets.min+1,
- "\#define #{offsets_name} #{size}\n" +
- tables.offsets.format_offsets + "\n")
- else # 共用あり
- # 実際に利用している offsets テーブルを探索
- offsets_real = search_real_offsets(tables.offsets)
- offsets_name = offsets_real.name
-
- # 実際に利用している infos テーブルを探索
- infos_real = search_real_infos(tables)
- if tables.infos.class == Infos
- # offsets 共用済みかつ infos の共用なしの場合
- # offsets の変更による infos の変更を調整
- tables.infos.content = adjust_infos(tables, offsets_real)
- end
- end
-
- # 変更後の offsets から infos を計算し、変更前と同じかどうか確かめるテスト
- # test_tables(tables, offsets_real)
-
- key = tables.infos.content # 完全に一致するものを共用するためのもの
- # infos の共用は既存の処理と同じ
- if i_name = WORD_CODE[key]
- infos_name = i_name
- else
- WORD_CODE[key] = infos_name = tables.infos.name
- size = TRANSCODE_GENERATED_WORDS_CODE.length
- TRANSCODE_GENERATED_WORDS_CODE.insert_at_last(tables.infos.content.length,
- "\#define #{infos_name} WORDINDEX2INFO(#{size})\n" +
- tables.infos.format_infos + "\n")
- end
-
- size = TRANSCODE_GENERATED_WORDS_CODE.length
- TRANSCODE_GENERATED_WORDS_CODE.insert_at_last(NUM_ELEM_BYTELOOKUP,
- "\#define #{name} WORDINDEX2INFO(#{size})\n" +
- <<"End" + "\n")
- #{offsets_name},
- #{infos_name},
-End
- end
-end
-
-# 新旧の 2 段階テーブルの整合性を確かめるテスト
-def test_tables(tables, new_offsets)
- old_o = tables.offsets_org.content.dup # 元の offsets テーブル
- old_i = tables.infos_org.content.dup # 元の infos テーブル
- new_i = tables.infos.content.dup # 新しい infos テーブル
- # 新しい offsets(共用なしなら、自分自身を新しい offsets テーブルとする)
- new_o = tables.offsets.class == Offsets ?
- tables.offsets.content.dup : new_offsets.content.dup
-
- # offsets から求めた infos が新旧で正しいか正しくないかを格納
- t_or_f = {"true"=>0, "false"=>0}
-
- # offsets から求めた infos が新旧で正しいか正しくないかを一つずつ検証
- i = 0
- while (i < 256)
- index_old = old_o[i]
- info_old = old_i[index_old]
- index_new = new_o[i]
- info_new = new_i[index_new]
-
- info_old == info_new ? t_or_f["true"] += 1 : t_or_f["false"] += 1
-
- i += 1
- end
-
- puts t_or_f
- # output_tables は文字コート変換を形式的に出力するメソッド
- output_tables(tables) if t_or_f["false"] > 0
-end
-
-# 変更後の offsets に対応した infos を作成するメソッド
-def adjust_infos(tables, offsets_real)
- o_new = offsets_real.content
- o_old = tables.offsets_org.content
- i_old = tables.infos_org.content
-
- # 新しい offsets の最大値が新しい infos の数となる
- num_info = o_new.max
- i_new = []
- # あらかじめ必要となる infos の配列を初期化
- # offsets の数値が順番通りに並んでいないことを考慮
- i_new.fill("", 0..num_info)
- set_offset = {}
-
- # 旧 offset と 新 offset のペアを作る
- o_old.each_with_index do |o1, i|
- o2 = o_new[i]
- key = [o1, o2]
- if !set_offset[key]
- set_offset[key] = 1
- end
- end
-
- # 新 offset の値の場所に、旧 offset が示す info を挿入
- set_offset.each_key do |key|
- num_old, num_new = key
- i_new[num_new] = i_old[num_old]
- end
-
- return i_new
-end
-
-# 文字コート変換を形式的に出力するメソッド
-def output_tables(tables)
- puts "##TRANSCODE_NAME##"
- puts tables.name
-
- puts "##OFFSETS_INFO##"
- real_offsets = search_real_offsets(tables)
-
- if tables.offsets.class == Offsets
- puts tables.offsets.name
- else
- print tables.name + " > "
- puts output_real_offsets(tables.offsets)
- end
-
- puts
- puts "It has #{tables.have_tbls} offsets tables."
- puts "changed #{real_offsets.content.max + 1} <> original #{tables.offsets_org.content.max + 1}"
-
- puts "##INFOS_INFO##"
- real_infos = search_real_infos(tables)
- p tables.infos_org.content
- p real_infos.content
-
- puts
- puts
-end
-
-# 実際の offsets テーブルまでのつながりを出力
-def output_real_offsets(tables)
- if tables.offsets.class == Tables
- return tables.name + " > " + output_real_offsets(tables.offsets)
- else
- return tables.name
- end
-end
-
def transcode_generated_code
- share_no_change # 完全に一致する offsets を共用
- share_infos_change # 片方を利用できる offsets を共用 (infos に変更が必要)
- generate_string # 最終的な文字列化と infos テーブルが完全に一致する場合の共用を行う
-
TRANSCODE_GENERATED_BYTES_CODE.to_s +
TRANSCODE_GENERATED_WORDS_CODE.to_s +
"\#define TRANSCODE_TABLE_INFO " +
@@ -1421,9 +988,6 @@ if __FILE__ == $0
TRANSCODE_GENERATED_BYTES_CODE = ArrayCode.new("unsigned char", "#{OUTPUT_PREFIX}byte_array")
TRANSCODE_GENERATED_WORDS_CODE = ArrayCode.new("unsigned int", "#{OUTPUT_PREFIX}word_array")
- GENERATED_CODE = [] # 文字コード変換の Tables クラスを格納する変数
- WORD_CODE = {} # infos テーブルの完全一致を判断するために格納するハッシュ
-
arg = ARGV.shift
$srcdir = File.dirname(arg)
$:.unshift $srcdir unless $:.include? $srcdir
@@ -1495,6 +1059,6 @@ if __FILE__ == $0
elapsed = Time.now - start_time
STDERR.puts "done. (#{'%.2f' % tms.utime}user #{'%.2f' % tms.stime}system #{'%.2f' % elapsed}elapsed)" if VERBOSE_MODE
else
- #print result
+ print result
end
end