]>
Commit | Line | Data |
---|---|---|
d879a707 BP |
1 | #! @PYTHON@ |
2 | ||
3 | import getopt | |
00732bf5 | 4 | import os |
d879a707 | 5 | import re |
d879a707 BP |
6 | import sys |
7 | ||
8 | sys.path.insert(0, "@abs_top_srcdir@/ovsdb") | |
9 | import simplejson as json | |
10 | ||
89365653 | 11 | from OVSDB import * |
d879a707 | 12 | |
89365653 | 13 | argv0 = sys.argv[0] |
45a7de56 | 14 | |
bfc96d9b BP |
15 | class Datum: |
16 | def __init__(self, type, values): | |
17 | self.type = type | |
18 | self.values = values | |
19 | ||
20 | @staticmethod | |
21 | def fromJson(type_, json): | |
22 | if not type_.value: | |
23 | if len(json) == 2 and json[0] == "set": | |
24 | values = [] | |
25 | for atomJson in json[1]: | |
26 | values += [Atom.fromJson(type_.key, atomJson)] | |
27 | else: | |
28 | values = [Atom.fromJson(type_.key, json)] | |
29 | else: | |
30 | if len(json) != 2 or json[0] != "map": | |
31 | raise Error("%s is not valid JSON for a map" % json) | |
32 | values = [] | |
33 | for pairJson in json[1]: | |
34 | values += [(Atom.fromJson(type_.key, pairJson[0]), | |
35 | Atom.fromJson(type_.value, pairJson[1]))] | |
36 | return Datum(type_, values) | |
37 | ||
38 | def cInitDatum(self, var): | |
39 | if len(self.values) == 0: | |
40 | return ["ovsdb_datum_init_empty(%s);" % var] | |
41 | ||
42 | s = ["%s->n = %d;" % (var, len(self.values))] | |
43 | s += ["%s->keys = xmalloc(%d * sizeof *%s->keys);" | |
44 | % (var, len(self.values), var)] | |
45 | ||
46 | for i in range(len(self.values)): | |
47 | key = self.values[i] | |
48 | if self.type.value: | |
49 | key = key[0] | |
50 | s += key.cInitAtom("%s->keys[%d]" % (var, i)) | |
51 | ||
52 | if self.type.value: | |
53 | s += ["%s->values = xmalloc(%d * sizeof *%s->values);" | |
54 | % (var, len(self.values), var)] | |
55 | for i in range(len(self.values)): | |
56 | value = self.values[i][1] | |
57 | s += key.cInitAtom("%s->values[%d]" % (var, i)) | |
58 | else: | |
59 | s += ["%s->values = NULL;" % var] | |
60 | ||
61 | if len(self.values) > 1: | |
62 | s += ["ovsdb_datum_sort_assert(%s, OVSDB_TYPE_%s);" | |
63 | % (var, self.type.key.upper())] | |
64 | ||
65 | return s | |
66 | ||
d879a707 | 67 | def parseSchema(filename): |
89365653 | 68 | return IdlSchema.fromJson(json.load(open(filename, "r"))) |
00732bf5 BP |
69 | |
70 | def annotateSchema(schemaFile, annotationFile): | |
71 | schemaJson = json.load(open(schemaFile, "r")) | |
72 | execfile(annotationFile, globals(), {"s": schemaJson}) | |
73 | json.dump(schemaJson, sys.stdout) | |
d879a707 | 74 | |
02630ff2 BP |
75 | def constify(cType, const): |
76 | if (const | |
77 | and cType.endswith('*') and not cType.endswith('**') | |
78 | and (cType.startswith('struct uuid') or cType.startswith('char'))): | |
79 | return 'const %s' % cType | |
80 | else: | |
81 | return cType | |
82 | ||
83 | def cMembers(prefix, columnName, column, const): | |
475281c0 BP |
84 | type = column.type |
85 | if type.min == 1 and type.max == 1: | |
86 | singleton = True | |
87 | pointer = '' | |
88 | else: | |
89 | singleton = False | |
bd76d25d | 90 | if type.isOptionalPointer(): |
475281c0 BP |
91 | pointer = '' |
92 | else: | |
93 | pointer = '*' | |
94 | ||
95 | if type.value: | |
96 | key = {'name': "key_%s" % columnName, | |
bd76d25d | 97 | 'type': constify(type.key.toCType(prefix) + pointer, const), |
475281c0 BP |
98 | 'comment': ''} |
99 | value = {'name': "value_%s" % columnName, | |
bd76d25d | 100 | 'type': constify(type.value.toCType(prefix) + pointer, const), |
475281c0 BP |
101 | 'comment': ''} |
102 | members = [key, value] | |
103 | else: | |
104 | m = {'name': columnName, | |
bd76d25d BP |
105 | 'type': constify(type.key.toCType(prefix) + pointer, const), |
106 | 'comment': type.cDeclComment()} | |
475281c0 BP |
107 | members = [m] |
108 | ||
bd76d25d | 109 | if not singleton and not type.isOptionalPointer(): |
475281c0 BP |
110 | members.append({'name': 'n_%s' % columnName, |
111 | 'type': 'size_t ', | |
112 | 'comment': ''}) | |
113 | return members | |
114 | ||
00732bf5 BP |
115 | def printCIDLHeader(schemaFile): |
116 | schema = parseSchema(schemaFile) | |
c3bb4bd7 | 117 | prefix = schema.idlPrefix |
d879a707 BP |
118 | print '''\ |
119 | /* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */ | |
120 | ||
121 | #ifndef %(prefix)sIDL_HEADER | |
122 | #define %(prefix)sIDL_HEADER 1 | |
123 | ||
124 | #include <stdbool.h> | |
125 | #include <stddef.h> | |
126 | #include <stdint.h> | |
c3bb4bd7 | 127 | #include "ovsdb-idl-provider.h" |
d879a707 | 128 | #include "uuid.h"''' % {'prefix': prefix.upper()} |
979821c0 | 129 | |
bd76d25d | 130 | for tableName, table in sorted(schema.tables.iteritems()): |
c3bb4bd7 | 131 | structName = "%s%s" % (prefix, tableName.lower()) |
979821c0 BP |
132 | |
133 | print "\f" | |
134 | print "/* %s table. */" % tableName | |
c3bb4bd7 BP |
135 | print "struct %s {" % structName |
136 | print "\tstruct ovsdb_idl_row header_;" | |
bd76d25d | 137 | for columnName, column in sorted(table.columns.iteritems()): |
d879a707 | 138 | print "\n\t/* %s column. */" % columnName |
02630ff2 | 139 | for member in cMembers(prefix, columnName, column, False): |
475281c0 | 140 | print "\t%(type)s%(name)s;%(comment)s" % member |
979821c0 | 141 | print "};" |
c3bb4bd7 | 142 | |
979821c0 BP |
143 | # Column indexes. |
144 | printEnum(["%s_COL_%s" % (structName.upper(), columnName.upper()) | |
bd76d25d | 145 | for columnName in sorted(table.columns)] |
979821c0 BP |
146 | + ["%s_N_COLUMNS" % structName.upper()]) |
147 | ||
148 | ||
149 | for columnName in table.columns: | |
150 | print "#define %(s)s_col_%(c)s (%(s)s_columns[%(S)s_COL_%(C)s])" % { | |
151 | 's': structName, | |
152 | 'S': structName.upper(), | |
153 | 'c': columnName, | |
154 | 'C': columnName.upper()} | |
155 | ||
156 | print "\nextern struct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (structName, structName.upper()) | |
157 | ||
158 | print ''' | |
c3bb4bd7 BP |
159 | const struct %(s)s *%(s)s_first(const struct ovsdb_idl *); |
160 | const struct %(s)s *%(s)s_next(const struct %(s)s *); | |
58bc1a52 BP |
161 | #define %(S)s_FOR_EACH(ROW, IDL) \\ |
162 | for ((ROW) = %(s)s_first(IDL); \\ | |
163 | (ROW); \\ | |
164 | (ROW) = %(s)s_next(ROW)) | |
165 | #define %(S)s_FOR_EACH_SAFE(ROW, NEXT, IDL) \\ | |
166 | for ((ROW) = %(s)s_first(IDL); \\ | |
167 | (ROW) ? ((NEXT) = %(s)s_next(ROW), 1) : 0; \\ | |
168 | (ROW) = (NEXT)) | |
475281c0 BP |
169 | |
170 | void %(s)s_delete(const struct %(s)s *); | |
171 | struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *); | |
172 | ''' % {'s': structName, 'S': structName.upper()} | |
173 | ||
bd76d25d | 174 | for columnName, column in sorted(table.columns.iteritems()): |
475281c0 BP |
175 | print 'void %(s)s_verify_%(c)s(const struct %(s)s *);' % {'s': structName, 'c': columnName} |
176 | ||
177 | ||
bd76d25d | 178 | for columnName, column in sorted(table.columns.iteritems()): |
475281c0 BP |
179 | |
180 | print 'void %(s)s_set_%(c)s(const struct %(s)s *,' % {'s': structName, 'c': columnName}, | |
181 | args = ['%(type)s%(name)s' % member for member | |
02630ff2 | 182 | in cMembers(prefix, columnName, column, True)] |
475281c0 BP |
183 | print '%s);' % ', '.join(args) |
184 | ||
979821c0 | 185 | # Table indexes. |
bd76d25d | 186 | printEnum(["%sTABLE_%s" % (prefix.upper(), tableName.upper()) for tableName in sorted(schema.tables)] + ["%sN_TABLES" % prefix.upper()]) |
979821c0 BP |
187 | |
188 | for tableName in schema.tables: | |
189 | print "#define %(p)stable_%(t)s (%(p)stable_classes[%(P)sTABLE_%(T)s])" % { | |
190 | 'p': prefix, | |
191 | 'P': prefix.upper(), | |
192 | 't': tableName.lower(), | |
193 | 'T': tableName.upper()} | |
194 | print "\nextern struct ovsdb_idl_table_class %stable_classes[%sN_TABLES];" % (prefix, prefix.upper()) | |
195 | ||
c3bb4bd7 | 196 | print "\nextern struct ovsdb_idl_class %sidl_class;" % prefix |
bd76d25d | 197 | print "\nvoid %sinit(void);" % prefix |
c3bb4bd7 BP |
198 | print "\n#endif /* %(prefix)sIDL_HEADER */" % {'prefix': prefix.upper()} |
199 | ||
200 | def printEnum(members): | |
201 | if len(members) == 0: | |
202 | return | |
203 | ||
204 | print "\nenum {"; | |
205 | for member in members[:-1]: | |
206 | print " %s," % member | |
207 | print " %s" % members[-1] | |
208 | print "};" | |
209 | ||
00732bf5 BP |
210 | def printCIDLSource(schemaFile): |
211 | schema = parseSchema(schemaFile) | |
c3bb4bd7 BP |
212 | prefix = schema.idlPrefix |
213 | print '''\ | |
214 | /* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */ | |
215 | ||
216 | #include <config.h> | |
217 | #include %s | |
bd76d25d | 218 | #include <assert.h> |
c3bb4bd7 | 219 | #include <limits.h> |
bd76d25d BP |
220 | #include "ovsdb-data.h" |
221 | #include "ovsdb-error.h" | |
222 | ||
223 | static bool inited; | |
89521e3f | 224 | ''' % schema.idlHeader |
c3bb4bd7 | 225 | |
66095e15 | 226 | # Cast functions. |
bd76d25d | 227 | for tableName, table in sorted(schema.tables.iteritems()): |
66095e15 BP |
228 | structName = "%s%s" % (prefix, tableName.lower()) |
229 | print ''' | |
230 | static struct %(s)s * | |
979821c0 | 231 | %(s)s_cast(const struct ovsdb_idl_row *row) |
66095e15 BP |
232 | { |
233 | return row ? CONTAINER_OF(row, struct %(s)s, header_) : NULL; | |
234 | }\ | |
235 | ''' % {'s': structName} | |
236 | ||
237 | ||
bd76d25d | 238 | for tableName, table in sorted(schema.tables.iteritems()): |
c3bb4bd7 BP |
239 | structName = "%s%s" % (prefix, tableName.lower()) |
240 | print "\f" | |
2e57b537 | 241 | print "/* %s table. */" % (tableName) |
c3bb4bd7 | 242 | |
979821c0 | 243 | # Parse functions. |
bd76d25d | 244 | for columnName, column in sorted(table.columns.iteritems()): |
979821c0 | 245 | print ''' |
c3bb4bd7 | 246 | static void |
979821c0 | 247 | %(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum) |
c3bb4bd7 | 248 | { |
979821c0 BP |
249 | struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName, |
250 | 'c': columnName} | |
c3bb4bd7 | 251 | |
c3bb4bd7 | 252 | type = column.type |
c3bb4bd7 BP |
253 | if type.value: |
254 | keyVar = "row->key_%s" % columnName | |
255 | valueVar = "row->value_%s" % columnName | |
256 | else: | |
257 | keyVar = "row->%s" % columnName | |
258 | valueVar = None | |
259 | ||
bd76d25d | 260 | if (type.min == 1 and type.max == 1) or type.isOptionalPointer(): |
979821c0 | 261 | |
bd76d25d | 262 | print " assert(inited);" |
c3bb4bd7 | 263 | print " if (datum->n >= 1) {" |
bd76d25d BP |
264 | if not type.key.refTable: |
265 | print " %s = datum->keys[0].%s;" % (keyVar, type.key.type) | |
c3bb4bd7 | 266 | else: |
bd76d25d | 267 | print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[0].uuid));" % (keyVar, prefix, type.key.refTable.lower(), prefix, prefix.upper(), type.key.refTable.upper()) |
c3bb4bd7 BP |
268 | |
269 | if valueVar: | |
bd76d25d BP |
270 | if type.value.refTable: |
271 | print " %s = datum->values[0].%s;" % (valueVar, type.value.type) | |
c3bb4bd7 | 272 | else: |
bd76d25d | 273 | print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[0].uuid));" % (valueVar, prefix, type.value.refTable.lower(), prefix, prefix.upper(), type.value.refTable.upper()) |
979821c0 | 274 | print " } else {" |
bd76d25d | 275 | print " %s" % type.key.initCDefault(keyVar, type.min == 0) |
979821c0 | 276 | if valueVar: |
bd76d25d | 277 | print " %s" % type.value.initCDefault(valueVar, type.min == 0) |
c3bb4bd7 BP |
278 | print " }" |
279 | else: | |
280 | if type.max != 'unlimited': | |
979821c0 BP |
281 | print " size_t n = MIN(%d, datum->n);" % type.max |
282 | nMax = "n" | |
c3bb4bd7 BP |
283 | else: |
284 | nMax = "datum->n" | |
979821c0 BP |
285 | print " size_t i;" |
286 | ||
bd76d25d | 287 | print " assert(inited);" |
979821c0 BP |
288 | print " %s = NULL;" % keyVar |
289 | if valueVar: | |
290 | print " %s = NULL;" % valueVar | |
291 | print " row->n_%s = 0;" % columnName | |
c3bb4bd7 BP |
292 | print " for (i = 0; i < %s; i++) {" % nMax |
293 | refs = [] | |
bd76d25d BP |
294 | if type.key.refTable: |
295 | print " struct %s%s *keyRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[i].uuid));" % (prefix, type.key.refTable.lower(), prefix, type.key.refTable.lower(), prefix, prefix.upper(), type.key.refTable.upper()) | |
c3bb4bd7 BP |
296 | keySrc = "keyRow" |
297 | refs.append('keyRow') | |
298 | else: | |
bd76d25d BP |
299 | keySrc = "datum->keys[i].%s" % type.key.type |
300 | if type.value and type.value.refTable: | |
301 | print " struct %s%s *valueRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[i].uuid));" % (prefix, type.value.refTable.lower(), prefix, type.value.refTable.lower(), prefix, prefix.upper(), type.value.refTable.upper()) | |
c3bb4bd7 BP |
302 | valueSrc = "valueRow" |
303 | refs.append('valueRow') | |
304 | elif valueVar: | |
bd76d25d | 305 | valueSrc = "datum->values[i].%s" % type.value.type |
c3bb4bd7 BP |
306 | if refs: |
307 | print " if (%s) {" % ' && '.join(refs) | |
308 | indent = " " | |
309 | else: | |
310 | indent = " " | |
311 | print "%sif (!row->n_%s) {" % (indent, columnName) | |
312 | print "%s %s = xmalloc(%s * sizeof *%s);" % (indent, keyVar, nMax, keyVar) | |
313 | if valueVar: | |
d78ac388 | 314 | print "%s %s = xmalloc(%s * sizeof *%s);" % (indent, valueVar, nMax, valueVar) |
c3bb4bd7 BP |
315 | print "%s}" % indent |
316 | print "%s%s[row->n_%s] = %s;" % (indent, keyVar, columnName, keySrc) | |
317 | if valueVar: | |
66095e15 | 318 | print "%s%s[row->n_%s] = %s;" % (indent, valueVar, columnName, valueSrc) |
c3bb4bd7 BP |
319 | print "%srow->n_%s++;" % (indent, columnName) |
320 | if refs: | |
321 | print " }" | |
322 | print " }" | |
979821c0 | 323 | print "}" |
c3bb4bd7 | 324 | |
979821c0 | 325 | # Unparse functions. |
bd76d25d | 326 | for columnName, column in sorted(table.columns.iteritems()): |
c3bb4bd7 | 327 | type = column.type |
bd76d25d | 328 | if (type.min != 1 or type.max != 1) and not type.isOptionalPointer(): |
979821c0 | 329 | print ''' |
c3bb4bd7 | 330 | static void |
979821c0 | 331 | %(s)s_unparse_%(c)s(struct ovsdb_idl_row *row_) |
c3bb4bd7 | 332 | { |
979821c0 | 333 | struct %(s)s *row = %(s)s_cast(row_); |
bd76d25d BP |
334 | |
335 | assert(inited);''' % {'s': structName, 'c': columnName} | |
c3bb4bd7 BP |
336 | if type.value: |
337 | keyVar = "row->key_%s" % columnName | |
338 | valueVar = "row->value_%s" % columnName | |
339 | else: | |
340 | keyVar = "row->%s" % columnName | |
341 | valueVar = None | |
342 | print " free(%s);" % keyVar | |
343 | if valueVar: | |
344 | print " free(%s);" % valueVar | |
979821c0 BP |
345 | print '}' |
346 | else: | |
347 | print ''' | |
c3bb4bd7 | 348 | static void |
c69ee87c | 349 | %(s)s_unparse_%(c)s(struct ovsdb_idl_row *row OVS_UNUSED) |
979821c0 BP |
350 | { |
351 | /* Nothing to do. */ | |
352 | }''' % {'s': structName, 'c': columnName} | |
353 | ||
c3bb4bd7 BP |
354 | # First, next functions. |
355 | print ''' | |
66095e15 BP |
356 | const struct %(s)s * |
357 | %(s)s_first(const struct ovsdb_idl *idl) | |
c3bb4bd7 | 358 | { |
66095e15 | 359 | return %(s)s_cast(ovsdb_idl_first_row(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s])); |
c3bb4bd7 BP |
360 | } |
361 | ||
66095e15 BP |
362 | const struct %(s)s * |
363 | %(s)s_next(const struct %(s)s *row) | |
c3bb4bd7 | 364 | { |
66095e15 | 365 | return %(s)s_cast(ovsdb_idl_next_row(&row->header_)); |
475281c0 BP |
366 | }''' % {'s': structName, |
367 | 'p': prefix, | |
368 | 'P': prefix.upper(), | |
369 | 'T': tableName.upper()} | |
370 | ||
371 | print ''' | |
372 | void | |
9e336f49 | 373 | %(s)s_delete(const struct %(s)s *row) |
475281c0 | 374 | { |
475281c0 BP |
375 | ovsdb_idl_txn_delete(&row->header_); |
376 | } | |
377 | ||
378 | struct %(s)s * | |
379 | %(s)s_insert(struct ovsdb_idl_txn *txn) | |
380 | { | |
ce5a3e38 | 381 | return %(s)s_cast(ovsdb_idl_txn_insert(txn, &%(p)stable_classes[%(P)sTABLE_%(T)s], NULL)); |
475281c0 BP |
382 | } |
383 | ''' % {'s': structName, | |
384 | 'p': prefix, | |
385 | 'P': prefix.upper(), | |
386 | 'T': tableName.upper()} | |
387 | ||
388 | # Verify functions. | |
bd76d25d | 389 | for columnName, column in sorted(table.columns.iteritems()): |
475281c0 BP |
390 | print ''' |
391 | void | |
392 | %(s)s_verify_%(c)s(const struct %(s)s *row) | |
393 | { | |
bd76d25d | 394 | assert(inited); |
475281c0 BP |
395 | ovsdb_idl_txn_verify(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s]); |
396 | }''' % {'s': structName, | |
397 | 'S': structName.upper(), | |
398 | 'c': columnName, | |
399 | 'C': columnName.upper()} | |
400 | ||
401 | # Set functions. | |
bd76d25d | 402 | for columnName, column in sorted(table.columns.iteritems()): |
475281c0 BP |
403 | type = column.type |
404 | print '\nvoid' | |
02630ff2 | 405 | members = cMembers(prefix, columnName, column, True) |
475281c0 BP |
406 | keyVar = members[0]['name'] |
407 | nVar = None | |
408 | valueVar = None | |
409 | if type.value: | |
410 | valueVar = members[1]['name'] | |
411 | if len(members) > 2: | |
412 | nVar = members[2]['name'] | |
413 | else: | |
414 | if len(members) > 1: | |
415 | nVar = members[1]['name'] | |
979821c0 | 416 | print '%(s)s_set_%(c)s(const struct %(s)s *row, %(args)s)' % \ |
475281c0 BP |
417 | {'s': structName, 'c': columnName, |
418 | 'args': ', '.join(['%(type)s%(name)s' % m for m in members])} | |
419 | print "{" | |
475281c0 BP |
420 | print " struct ovsdb_datum datum;" |
421 | if type.min == 1 and type.max == 1: | |
422 | ||
bd76d25d | 423 | print " assert(inited);" |
475281c0 BP |
424 | print " datum.n = 1;" |
425 | print " datum.keys = xmalloc(sizeof *datum.keys);" | |
bd76d25d | 426 | print " " + type.key.copyCValue("datum.keys[0].%s" % type.key.type, keyVar) |
475281c0 BP |
427 | if type.value: |
428 | print " datum.values = xmalloc(sizeof *datum.values);" | |
bd76d25d | 429 | print " "+ type.value.copyCValue("datum.values[0].%s" % type.value.type, valueVar) |
475281c0 BP |
430 | else: |
431 | print " datum.values = NULL;" | |
bd76d25d | 432 | elif type.isOptionalPointer(): |
475281c0 | 433 | |
bd76d25d | 434 | print " assert(inited);" |
475281c0 BP |
435 | print " if (%s) {" % keyVar |
436 | print " datum.n = 1;" | |
437 | print " datum.keys = xmalloc(sizeof *datum.keys);" | |
bd76d25d | 438 | print " " + type.key.copyCValue("datum.keys[0].%s" % type.key.type, keyVar) |
475281c0 BP |
439 | print " } else {" |
440 | print " datum.n = 0;" | |
441 | print " datum.keys = NULL;" | |
442 | print " }" | |
443 | print " datum.values = NULL;" | |
444 | else: | |
445 | print " size_t i;" | |
446 | ||
bd76d25d | 447 | print " assert(inited);" |
475281c0 BP |
448 | print " datum.n = %s;" % nVar |
449 | print " datum.keys = xmalloc(%s * sizeof *datum.keys);" % nVar | |
450 | if type.value: | |
451 | print " datum.values = xmalloc(%s * sizeof *datum.values);" % nVar | |
452 | else: | |
453 | print " datum.values = NULL;" | |
454 | print " for (i = 0; i < %s; i++) {" % nVar | |
bd76d25d | 455 | print " " + type.key.copyCValue("datum.keys[i].%s" % type.key.type, "%s[i]" % keyVar) |
475281c0 | 456 | if type.value: |
bd76d25d | 457 | print " " + type.value.copyCValue("datum.values[i].%s" % type.value.type, "%s[i]" % valueVar) |
475281c0 BP |
458 | print " }" |
459 | print " ovsdb_idl_txn_write(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s], &datum);" \ | |
460 | % {'s': structName, | |
461 | 'S': structName.upper(), | |
462 | 'C': columnName.upper()} | |
463 | print "}" | |
c3bb4bd7 BP |
464 | |
465 | # Table columns. | |
bd76d25d | 466 | print "\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % ( |
c3bb4bd7 | 467 | structName, structName.upper()) |
bd76d25d BP |
468 | print """ |
469 | static void\n%s_columns_init(void) | |
470 | { | |
471 | struct ovsdb_idl_column *c;\ | |
472 | """ % structName | |
473 | for columnName, column in sorted(table.columns.iteritems()): | |
474 | cs = "%s_col_%s" % (structName, columnName) | |
475 | d = {'cs': cs, 'c': columnName, 's': structName} | |
476 | ||
477 | print " /* Initialize %(cs)s. */" % d | |
478 | print " c = &%(cs)s;" % d | |
479 | print " c->name = \"%(c)s\";" % d | |
480 | print column.type.cInitType(" ", "c->type") | |
481 | print " c->parse = %(s)s_parse_%(c)s;" % d | |
482 | print " c->unparse = %(s)s_unparse_%(c)s;" % d | |
483 | print "}" | |
c3bb4bd7 BP |
484 | |
485 | # Table classes. | |
486 | print "\f" | |
979821c0 | 487 | print "struct ovsdb_idl_table_class %stable_classes[%sN_TABLES] = {" % (prefix, prefix.upper()) |
bd76d25d | 488 | for tableName, table in sorted(schema.tables.iteritems()): |
c3bb4bd7 BP |
489 | structName = "%s%s" % (prefix, tableName.lower()) |
490 | print " {\"%s\"," % tableName | |
491 | print " %s_columns, ARRAY_SIZE(%s_columns)," % ( | |
492 | structName, structName) | |
979821c0 | 493 | print " sizeof(struct %s)}," % structName |
c3bb4bd7 BP |
494 | print "};" |
495 | ||
496 | # IDL class. | |
497 | print "\nstruct ovsdb_idl_class %sidl_class = {" % prefix | |
9cb53f26 BP |
498 | print " \"%s\", %stable_classes, ARRAY_SIZE(%stable_classes)" % ( |
499 | schema.name, prefix, prefix) | |
c3bb4bd7 | 500 | print "};" |
d879a707 | 501 | |
bd76d25d BP |
502 | # global init function |
503 | print """ | |
504 | void | |
505 | %sinit(void) | |
506 | { | |
507 | if (inited) { | |
508 | return; | |
509 | } | |
510 | inited = true; | |
511 | """ % prefix | |
512 | for tableName, table in sorted(schema.tables.iteritems()): | |
513 | structName = "%s%s" % (prefix, tableName.lower()) | |
514 | print " %s_columns_init();" % structName | |
515 | print "}" | |
516 | ||
d879a707 BP |
517 | def ovsdb_escape(string): |
518 | def escape(match): | |
519 | c = match.group(0) | |
520 | if c == '\0': | |
521 | raise Error("strings may not contain null bytes") | |
522 | elif c == '\\': | |
523 | return '\\\\' | |
524 | elif c == '\n': | |
525 | return '\\n' | |
526 | elif c == '\r': | |
527 | return '\\r' | |
528 | elif c == '\t': | |
529 | return '\\t' | |
530 | elif c == '\b': | |
531 | return '\\b' | |
532 | elif c == '\a': | |
533 | return '\\a' | |
534 | else: | |
535 | return '\\x%02x' % ord(c) | |
536 | return re.sub(r'["\\\000-\037]', escape, string) | |
537 | ||
45a7de56 | 538 | |
45a7de56 | 539 | |
d879a707 BP |
540 | def usage(): |
541 | print """\ | |
542 | %(argv0)s: ovsdb schema compiler | |
00732bf5 | 543 | usage: %(argv0)s [OPTIONS] COMMAND ARG... |
d879a707 | 544 | |
00732bf5 BP |
545 | The following commands are supported: |
546 | annotate SCHEMA ANNOTATIONS print SCHEMA combined with ANNOTATIONS | |
547 | c-idl-header IDL print C header file for IDL | |
548 | c-idl-source IDL print C source file for IDL implementation | |
89365653 | 549 | nroff IDL print schema documentation in nroff format |
d879a707 BP |
550 | |
551 | The following options are also available: | |
552 | -h, --help display this help message | |
553 | -V, --version display version information\ | |
554 | """ % {'argv0': argv0} | |
555 | sys.exit(0) | |
556 | ||
557 | if __name__ == "__main__": | |
558 | try: | |
559 | try: | |
00732bf5 BP |
560 | options, args = getopt.gnu_getopt(sys.argv[1:], 'C:hV', |
561 | ['directory', | |
562 | 'help', | |
d879a707 BP |
563 | 'version']) |
564 | except getopt.GetoptError, geo: | |
565 | sys.stderr.write("%s: %s\n" % (argv0, geo.msg)) | |
566 | sys.exit(1) | |
567 | ||
00732bf5 BP |
568 | for key, value in options: |
569 | if key in ['-h', '--help']: | |
570 | usage() | |
571 | elif key in ['-V', '--version']: | |
572 | print "ovsdb-idlc (Open vSwitch) @VERSION@" | |
573 | elif key in ['-C', '--directory']: | |
574 | os.chdir(value) | |
575 | else: | |
576 | sys.exit(0) | |
577 | ||
d879a707 | 578 | optKeys = [key for key, value in options] |
00732bf5 BP |
579 | |
580 | if not args: | |
581 | sys.stderr.write("%s: missing command argument " | |
582 | "(use --help for help)\n" % argv0) | |
d879a707 BP |
583 | sys.exit(1) |
584 | ||
00732bf5 BP |
585 | commands = {"annotate": (annotateSchema, 2), |
586 | "c-idl-header": (printCIDLHeader, 1), | |
89365653 | 587 | "c-idl-source": (printCIDLSource, 1)} |
00732bf5 BP |
588 | |
589 | if not args[0] in commands: | |
590 | sys.stderr.write("%s: unknown command \"%s\" " | |
591 | "(use --help for help)\n" % (argv0, args[0])) | |
d879a707 | 592 | sys.exit(1) |
00732bf5 BP |
593 | |
594 | func, n_args = commands[args[0]] | |
595 | if len(args) - 1 != n_args: | |
596 | sys.stderr.write("%s: \"%s\" requires %d arguments but %d " | |
597 | "provided\n" | |
598 | % (argv0, args[0], n_args, len(args) - 1)) | |
599 | sys.exit(1) | |
600 | ||
601 | func(*args[1:]) | |
d879a707 BP |
602 | except Error, e: |
603 | sys.stderr.write("%s: %s\n" % (argv0, e.msg)) | |
604 | sys.exit(1) | |
605 | ||
606 | # Local variables: | |
607 | # mode: python | |
608 | # End: |