Add missing U to unicode keysym in symbols/us intl-unicode
[xorg/xkeyboard-config] / tests / ruby / xkbparser.rb
1 #
2 # $Id$
3 #
4 # Commont parsing classes for symbols/inet
5 # The parsing is simplified, based on regex - it is NOT a real parser for very
6 # complex XKB format
7 #
8
9 require "utils.rb"
10
11 class Symbols < Hash
12
13   #
14   # Constructor
15   #
16   def initialize
17     @includedSyms = Array.new
18   end
19
20   # Write-only property, parent list of symbols definitions
21   def symbols_list=(symbolsList)
22     @symbolsList = symbolsList
23   end
24
25   # Whether this set of symbols is hidden or not
26   def hidden?
27     @hidden
28   end
29
30   def hidden=(h)
31     @hidden = h
32   end
33
34   #
35   # Add "dependency" - the symbols referenced using the "include" statement.
36   #
37   def add_included(other)
38     @includedSyms.push(other)
39   end
40
41   alias get_original []
42   alias keys_original keys
43
44   #
45   # Get the symbol, trying first own definitions, then walking through all 
46   # dependenies
47   #
48   def [](symName)
49     own = self.get_original(symName)
50     if own.nil?
51       @includedSyms.find_all do | symsName |
52         syms = @symbolsList[symsName]
53         his = syms[symName]
54         if !his.nil?
55           own = his
56           break
57         end
58       end
59     end
60     own
61   end
62
63   #
64   # All keys - including the ones specified in the included sections
65   #
66   def keys()
67     @includedSyms.inject(keys_original) do | rv, symsName |
68       syms = @symbolsList[symsName]
69       rv | syms.keys
70     end
71   end
72
73   # Size of all keys
74   def length()
75     keys().length()
76   end
77
78   #
79   # Size - takes into account overlapping key definitions
80   #
81   def size()
82     keys.size()
83   end
84
85   #
86   # Create a hash including all elements of this hash which are not in the
87   # other hash, use symbols + and * for marking the elements which existed in
88   # the original hash (+ if not existed)
89   #
90   def -(other)
91     diff = self.class.new
92     self.find_all do | key, value | 
93       existing = other[key]
94       if existing != value
95         diff[key] = [ value, existing.nil? ? '+' : '' ]
96       end 
97     end
98     diff
99   end
100
101
102   def to_s
103     s = "{\n"
104     # First output included syms
105     @includedSyms.find_all do | symsName |
106        s += "  include \"inet(#{symsName})\"\n"
107     end
108     # Then - own definitions
109     self.find_all do | key, value |
110        s += "  key #{key} { [ #{value} ] };\n"
111     end
112     s + "}";
113   end
114
115 end
116
117 class SymbolsList < Hash
118
119   #
120   # Add new xkb_symbols
121   #
122   def add_symbols (symbolsName, hidden)
123     newSyms = Symbols.new
124     newSyms.symbols_list = self
125     newSyms.hidden = hidden
126     self[symbolsName] = newSyms
127   end
128
129   def to_s
130     s = "// Autogenerated\n\n"
131     self.find_all do | symbols, mapping |
132       s += "partial alphanumeric_keys\nxkb_symbols \"#{symbols}\" #{mapping};\n\n" 
133     end
134     s
135   end
136
137   def match_symbols(new_symbols,limit)
138     matching = Hash.new
139     find_all do | symbols, mapping |
140       diff = new_symbols - mapping
141       if diff.size <= limit
142         matching[symbols] = diff
143       end
144     end
145     matching
146   end
147
148   def merge()
149     everything = NonuniqueCountingHash.new
150     find_all do | symsName, syms |
151       syms.find_all do | symName, keycode |
152         everything[symName] = keycode
153       end
154     end
155     everything
156   end
157
158 end
159
160 class Parser
161
162   def parse (fileName)
163     allSyms = SymbolsList.new;
164     currentSyms = nil
165     hidden = false
166     File.open(fileName) do | file |
167       file.each_line do | line |
168         line.scan(/xkb_symbols\s+"(\w+)"/) do | symsName |
169           currentSyms = allSyms.add_symbols(symsName[0], hidden)
170         end
171         line.scan(/^\s*key\s*<(\w+)>\s*\{\s*\[\s*(\w+)/) do | keycode, keysym |
172           currentSyms[keycode] = keysym
173         end
174         line.scan(/^partial\s+(hidden\s+)?alphanumeric_keys/) do | h |
175           hidden = !h[0].nil?
176         end
177         line.scan(/^\s*include\s+"inet\((\w+)\)"/) do | otherPart |
178           currentSyms.add_included(otherPart[0])
179         end
180       end
181     end
182     allSyms
183   end
184
185 end