mirror of
https://github.com/ksherlock/gopher.git
synced 2024-12-28 04:31:44 +00:00
147 lines
2.9 KiB
Ruby
147 lines
2.9 KiB
Ruby
#!/usr/binenv 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 }
|
|
|
|
}
|
|
|