-
Notifications
You must be signed in to change notification settings - Fork 0
/
txtable.rb
146 lines (102 loc) · 2.93 KB
/
txtable.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env ruby -w
def dump_rules(rules)
# create another hash for the hash code.
index = []
rules.each {|key, value|
# 1.8 doesn't have getbyte()
# string[] returns a byte in 1.8, string in 1.9
byte = key.bytes.next()
byte |= 0x20
byte ^= key.length
byte &= 0x0f
index[byte] ||= []
index[byte].push(key)
}
indent6 = " "
index.each_index {|ix|
array = index[ix]
next unless array
printf(" case 0x%02x:\n", ix)
array.each{|key|
offset = 0
printf(" // %s\n", key)
printf(" if (size == %d\n", key.length)
key.scan(/..?/) {|xx|
tmp = xx.unpack("C*")
tmp = tmp.map {|xxx| xxx | 0x20 }
if tmp.length == 2
tmp = (tmp[0]) + (tmp[1] << 8 )
printf(" && (wp[%d] | 0x2020) == 0x%04x // '%s'\n",
offset, tmp, xx
)
offset += 1
else
tmp = tmp[0]
printf(" && (cp[%d] | 0x20) == 0x%02x // '%s'\n",
offset * 2, tmp, xx
)
end
} # scan
puts(" ) {")
rules[key].each {|x|
puts(indent6 + x)
}
puts(" }")
}
printf(" break;\n\n")
}
end
ARGV.each {|filename|
state = 0
substate = 0
header = []
trailer = []
tmp = []
rule = nil
rules = {}
IO.foreach(filename) {|line|
#line.chomp!
line.sub!(/\s*$/, ''); #trim trailing space
#next if line == ''
if line == '%%'
state = state + 1
raise "Too many sections" if state > 3
next
end
case state
when 0
raise "invalid section" unless line == ''
next
when 1
header.push(line)
next
when 2
trailer.push(line)
next
end
# state 3
if !rule
next if line == ''
if line =~ /^'([a-zA-Z0-9.+_\/-]+)'\s*->$/
rule = $1;
raise "duplicate rule: #{rule}" if rules[rule]
next
else
raise "oops #{line}"
end
end
if line == '.'
rules[rule] = tmp
tmp = []
rule = nil
else
tmp.push(line)
end
}
if state != 3 || rule
raise "unexpected EOF"
end
header.each {|x| puts x }
dump_rules(rules)
trailer.each{|x| puts x }
}