]>
Commit | Line | Data |
---|---|---|
0f923be2 MR |
1 | # |
2 | # QAPI helper library | |
3 | # | |
4 | # Copyright IBM, Corp. 2011 | |
5 | # | |
6 | # Authors: | |
7 | # Anthony Liguori <[email protected]> | |
8 | # | |
9 | # This work is licensed under the terms of the GNU GPLv2. | |
10 | # See the COPYING.LIB file in the top-level directory. | |
11 | ||
12 | from ordereddict import OrderedDict | |
13 | ||
14 | def tokenize(data): | |
15 | while len(data): | |
16 | if data[0] in ['{', '}', ':', ',', '[', ']']: | |
17 | yield data[0] | |
18 | data = data[1:] | |
19 | elif data[0] in ' \n': | |
20 | data = data[1:] | |
21 | elif data[0] == "'": | |
22 | data = data[1:] | |
23 | string = '' | |
24 | while data[0] != "'": | |
25 | string += data[0] | |
26 | data = data[1:] | |
27 | data = data[1:] | |
28 | yield string | |
29 | ||
30 | def parse(tokens): | |
31 | if tokens[0] == '{': | |
32 | ret = OrderedDict() | |
33 | tokens = tokens[1:] | |
34 | while tokens[0] != '}': | |
35 | key = tokens[0] | |
36 | tokens = tokens[1:] | |
37 | ||
38 | tokens = tokens[1:] # : | |
39 | ||
40 | value, tokens = parse(tokens) | |
41 | ||
42 | if tokens[0] == ',': | |
43 | tokens = tokens[1:] | |
44 | ||
45 | ret[key] = value | |
46 | tokens = tokens[1:] | |
47 | return ret, tokens | |
48 | elif tokens[0] == '[': | |
49 | ret = [] | |
50 | tokens = tokens[1:] | |
51 | while tokens[0] != ']': | |
52 | value, tokens = parse(tokens) | |
53 | if tokens[0] == ',': | |
54 | tokens = tokens[1:] | |
55 | ret.append(value) | |
56 | tokens = tokens[1:] | |
57 | return ret, tokens | |
58 | else: | |
59 | return tokens[0], tokens[1:] | |
60 | ||
61 | def evaluate(string): | |
62 | return parse(map(lambda x: x, tokenize(string)))[0] | |
63 | ||
64 | def parse_schema(fp): | |
65 | exprs = [] | |
66 | expr = '' | |
67 | expr_eval = None | |
68 | ||
69 | for line in fp: | |
70 | if line.startswith('#') or line == '\n': | |
71 | continue | |
72 | ||
73 | if line.startswith(' '): | |
74 | expr += line | |
75 | elif expr: | |
76 | expr_eval = evaluate(expr) | |
77 | if expr_eval.has_key('enum'): | |
78 | add_enum(expr_eval['enum']) | |
79 | elif expr_eval.has_key('union'): | |
80 | add_enum('%sKind' % expr_eval['union']) | |
81 | exprs.append(expr_eval) | |
82 | expr = line | |
83 | else: | |
84 | expr += line | |
85 | ||
86 | if expr: | |
87 | expr_eval = evaluate(expr) | |
88 | if expr_eval.has_key('enum'): | |
89 | add_enum(expr_eval['enum']) | |
90 | elif expr_eval.has_key('union'): | |
91 | add_enum('%sKind' % expr_eval['union']) | |
92 | exprs.append(expr_eval) | |
93 | ||
94 | return exprs | |
95 | ||
96 | def parse_args(typeinfo): | |
97 | for member in typeinfo: | |
98 | argname = member | |
99 | argentry = typeinfo[member] | |
100 | optional = False | |
101 | structured = False | |
102 | if member.startswith('*'): | |
103 | argname = member[1:] | |
104 | optional = True | |
105 | if isinstance(argentry, OrderedDict): | |
106 | structured = True | |
107 | yield (argname, argentry, optional, structured) | |
108 | ||
109 | def de_camel_case(name): | |
110 | new_name = '' | |
111 | for ch in name: | |
112 | if ch.isupper() and new_name: | |
113 | new_name += '_' | |
114 | if ch == '-': | |
115 | new_name += '_' | |
116 | else: | |
117 | new_name += ch.lower() | |
118 | return new_name | |
119 | ||
120 | def camel_case(name): | |
121 | new_name = '' | |
122 | first = True | |
123 | for ch in name: | |
124 | if ch in ['_', '-']: | |
125 | first = True | |
126 | elif first: | |
127 | new_name += ch.upper() | |
128 | first = False | |
129 | else: | |
130 | new_name += ch.lower() | |
131 | return new_name | |
132 | ||
133 | def c_var(name): | |
c9da228b FS |
134 | return name.replace('-', '_').lstrip("*") |
135 | ||
136 | def c_fun(name): | |
137 | return c_var(name).replace('.', '_') | |
0f923be2 MR |
138 | |
139 | def c_list_type(name): | |
140 | return '%sList' % name | |
141 | ||
142 | def type_name(name): | |
143 | if type(name) == list: | |
144 | return c_list_type(name[0]) | |
145 | return name | |
146 | ||
147 | enum_types = [] | |
148 | ||
149 | def add_enum(name): | |
150 | global enum_types | |
151 | enum_types.append(name) | |
152 | ||
153 | def is_enum(name): | |
154 | global enum_types | |
155 | return (name in enum_types) | |
156 | ||
157 | def c_type(name): | |
158 | if name == 'str': | |
159 | return 'char *' | |
160 | elif name == 'int': | |
161 | return 'int64_t' | |
c46f18ce LE |
162 | elif (name == 'int8' or name == 'int16' or name == 'int32' or |
163 | name == 'int64' or name == 'uint8' or name == 'uint16' or | |
164 | name == 'uint32' or name == 'uint64'): | |
165 | return name + '_t' | |
092705d4 LE |
166 | elif name == 'size': |
167 | return 'uint64_t' | |
0f923be2 MR |
168 | elif name == 'bool': |
169 | return 'bool' | |
170 | elif name == 'number': | |
171 | return 'double' | |
172 | elif type(name) == list: | |
173 | return '%s *' % c_list_type(name[0]) | |
174 | elif is_enum(name): | |
175 | return name | |
176 | elif name == None or len(name) == 0: | |
177 | return 'void' | |
178 | elif name == name.upper(): | |
179 | return '%sEvent *' % camel_case(name) | |
180 | else: | |
181 | return '%s *' % name | |
182 | ||
183 | def genindent(count): | |
184 | ret = "" | |
185 | for i in range(count): | |
186 | ret += " " | |
187 | return ret | |
188 | ||
189 | indent_level = 0 | |
190 | ||
191 | def push_indent(indent_amount=4): | |
192 | global indent_level | |
193 | indent_level += indent_amount | |
194 | ||
195 | def pop_indent(indent_amount=4): | |
196 | global indent_level | |
197 | indent_level -= indent_amount | |
198 | ||
199 | def cgen(code, **kwds): | |
200 | indent = genindent(indent_level) | |
201 | lines = code.split('\n') | |
202 | lines = map(lambda x: indent + x, lines) | |
203 | return '\n'.join(lines) % kwds + '\n' | |
204 | ||
205 | def mcgen(code, **kwds): | |
206 | return cgen('\n'.join(code.split('\n')[1:-1]), **kwds) | |
207 | ||
208 | def basename(filename): | |
209 | return filename.split("/")[-1] | |
210 | ||
211 | def guardname(filename): | |
d8e1f214 MR |
212 | guard = basename(filename).rsplit(".", 1)[0] |
213 | for substr in [".", " ", "-"]: | |
214 | guard = guard.replace(substr, "_") | |
215 | return guard.upper() + '_H' |