]> git.proxmox.com Git - mirror_ovs.git/blame - ovsdb/ovsdb-idlc.in
ovsdb: Introduce experimental support for clustered databases.
[mirror_ovs.git] / ovsdb / ovsdb-idlc.in
CommitLineData
d879a707
BP
1#! @PYTHON@
2
d34a1cc0 3from __future__ import print_function
d879a707 4import getopt
00732bf5 5import os
d879a707 6import re
d879a707
BP
7import sys
8
99155935
BP
9import ovs.json
10import ovs.db.error
11import ovs.db.schema
0a8606ee 12from ovs.db.types import StringType, IntegerType, RealType
d879a707 13
89365653 14argv0 = sys.argv[0]
45a7de56 15
d879a707 16def parseSchema(filename):
99155935 17 return ovs.db.schema.IdlSchema.from_json(ovs.json.from_file(filename))
00732bf5
BP
18
19def annotateSchema(schemaFile, annotationFile):
99155935 20 schemaJson = ovs.json.from_file(schemaFile)
a4d10a7c 21 exec(compile(open(annotationFile, "rb").read(), annotationFile, 'exec'), globals(), {"s": schemaJson})
99155935 22 ovs.json.to_stream(schemaJson, sys.stdout)
292aefc4 23 sys.stdout.write('\n')
d879a707 24
02630ff2 25def constify(cType, const):
47058293
RB
26 if (const
27 and cType.endswith('*') and
28 (cType == 'char **' or not cType.endswith('**'))):
02630ff2
BP
29 return 'const %s' % cType
30 else:
31 return cType
32
4bb7f568 33def cMembers(prefix, tableName, columnName, column, const, refTable=True):
7cc398cb 34 comment = ""
475281c0 35 type = column.type
a699f614
EJ
36
37 if type.is_smap():
7cc398cb
JP
38 comment = """
39/* Sets the "%(c)s" column's value from the "%(t)s" table in 'row'
40 * to '%(c)s'.
41 *
42 * The caller retains ownership of '%(c)s' and everything in it. */""" \
43 % {'c': columnName,
44 't': tableName}
45 return (comment, [{'name': columnName,
46 'type': 'struct smap ',
47 'comment': ''}])
48
49 comment = """\n/* Sets the "%s" column from the "%s" table in """\
50 """'row' to\n""" % (columnName, tableName)
a699f614 51
99155935 52 if type.n_min == 1 and type.n_max == 1:
475281c0
BP
53 singleton = True
54 pointer = ''
55 else:
56 singleton = False
99155935 57 if type.is_optional_pointer():
475281c0
BP
58 pointer = ''
59 else:
60 pointer = '*'
61
7cc398cb 62
475281c0 63 if type.value:
7cc398cb
JP
64 keyName = "key_%s" % columnName
65 valueName = "value_%s" % columnName
66
67 key = {'name': keyName,
4bb7f568 68 'type': constify(type.key.toCType(prefix, refTable) + pointer, const),
475281c0 69 'comment': ''}
7cc398cb 70 value = {'name': valueName,
4bb7f568 71 'type': constify(type.value.toCType(prefix, refTable) + pointer, const),
475281c0 72 'comment': ''}
7cc398cb
JP
73
74 if singleton:
75 comment += " * the map with key '%s' and value '%s'\n *" \
76 % (keyName, valueName)
77 else:
78 comment += " * the map with keys '%s' and values '%s'\n *" \
79 % (keyName, valueName)
475281c0
BP
80 members = [key, value]
81 else:
82 m = {'name': columnName,
4bb7f568 83 'type': constify(type.key.toCType(prefix, refTable) + pointer, const),
bd76d25d 84 'comment': type.cDeclComment()}
7cc398cb
JP
85
86 if singleton:
87 comment += " * '%s'" % columnName
88 else:
89 comment += " * the '%s' set" % columnName
475281c0
BP
90 members = [m]
91
99155935 92 if not singleton and not type.is_optional_pointer():
7cc398cb
JP
93 sizeName = "n_%s" % columnName
94
95 comment += " with '%s' entries" % sizeName
96 members.append({'name': sizeName,
475281c0
BP
97 'type': 'size_t ',
98 'comment': ''})
7cc398cb
JP
99
100 comment += ".\n"
101
102 if type.is_optional() and not type.is_optional_pointer():
103 comment += """ *
104 * '%s' may be 0 or 1; if it is 0, then '%s'
105 * may be NULL.\n""" \
106 % ("n_%s" % columnName, columnName)
107
108 if type.is_optional_pointer():
109 comment += """ *
110 * If "%s" is null, the column will be the empty set,
111 * otherwise it will contain the specified value.\n""" % columnName
112
113 if type.constraintsToEnglish():
114 comment += """ *
115 * Argument constraints: %s\n""" \
116 % type.constraintsToEnglish(lambda s : '"%s"' % s)
117
118 comment += " *\n * The caller retains ownership of the arguments. */"
119
120 return (comment, members)
475281c0 121
01928c96
BP
122# This is equivalent to sorted(table.columns.items()), except that the
123# sorting includes a topological component: if column B has a
124# dependency on column A, then A will be sorted before B.
e0b1744f 125def sorted_columns(table):
01928c96
BP
126 input = []
127 for name, column in table.columns.items():
128 dependencies = column.extensions.get('dependencies', [])
129 for d in dependencies:
130 if d not in table.columns:
131 sys.stderr.write("Table %s column %s depends on column %s "
132 "but there is no such column\n"
133 % (table.name, name, d))
134 sys.exit(1)
135 input += [(name, column, set(dependencies))]
136
137 output = []
138 satisfied_dependencies = set()
139 while input:
140 done = []
141 next = []
142 for name, column, dependencies in input:
143 if dependencies <= satisfied_dependencies:
144 done += [(name, column)]
145 else:
146 next += [(name, column, dependencies)]
147
148 if not done:
149 sys.stderr.write("Table %s columns have circular dependencies\n"
150 % table.name)
151 sys.exit(1)
152
153 for name, column in done:
154 satisfied_dependencies.add(name)
155 output += sorted(done)
156 input = next
157 return output
e0b1744f 158
adb4185d
YHW
159# If a column name in the schema is a C or C++ keyword, append an underscore
160# to the column name.
161def replace_cplusplus_keyword(schema):
162 keywords = {'alignas', 'alignof', 'and', 'and_eq', 'asm', 'auto', 'bitand',
163 'bitor', 'bool', 'break', 'case', 'catch', 'char', 'char16_t',
164 'char32_t', 'class', 'compl', 'concept', 'const', 'const_cast',
165 'constexpr', 'continue', 'decltype', 'default', 'delete', 'do',
166 'double', 'dynamic_cast', 'else', 'enum', 'explicit', 'export',
167 'extern', 'false', 'float', 'for', 'friend', 'goto', 'if',
168 'inline', 'int', 'long', 'mutable', 'namespace', 'new',
169 'noexcept', 'not', 'not_eq', 'nullptr', 'operator', 'or',
170 'or_eq', 'private', 'protected', 'public', 'register',
171 'reinterpret_cast', 'requires', 'restrict', 'return', 'short',
172 'signed', 'sizeof', 'static', 'static_assert', 'static_cast',
173 'struct', 'switch', 'template', 'this', 'thread_local',
174 'throw', 'true', 'try', 'typedef', 'typeid', 'typename',
175 'union', 'unsigned', 'using', 'virtual', 'void', 'volatile',
176 'wchar_t', 'while', 'xor', 'xor_eq'}
177
178 for tableName, table in schema.tables.items():
179 for columnName in table.columns:
180 if columnName in keywords:
181 table.columns[columnName + '_'] = table.columns.pop(columnName)
182
00732bf5
BP
183def printCIDLHeader(schemaFile):
184 schema = parseSchema(schemaFile)
adb4185d 185 replace_cplusplus_keyword(schema)
c3bb4bd7 186 prefix = schema.idlPrefix
d34a1cc0 187 print('''\
d879a707
BP
188/* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
189
190#ifndef %(prefix)sIDL_HEADER
191#define %(prefix)sIDL_HEADER 1
192
193#include <stdbool.h>
194#include <stddef.h>
195#include <stdint.h>
a6ec9089 196#include "ovsdb-data.h"
c3bb4bd7 197#include "ovsdb-idl-provider.h"
a699f614 198#include "smap.h"
9131abe2
YHW
199#include "uuid.h"
200
201#ifdef __cplusplus
202extern "C" {
203#endif
0ea866bb
BP
204%(hDecls)s''' % {'prefix': prefix.upper(),
205 'hDecls': schema.hDecls})
979821c0 206
4ab66562 207 for tableName, table in sorted(schema.tables.items()):
c3bb4bd7 208 structName = "%s%s" % (prefix, tableName.lower())
979821c0 209
d34a1cc0
JW
210 print("\f")
211 print("/* %s table. */" % tableName)
212 print("struct %s {" % structName)
213 print("\tstruct ovsdb_idl_row header_;")
e0b1744f 214 for columnName, column in sorted_columns(table):
d34a1cc0 215 print("\n\t/* %s column. */" % columnName)
01928c96
BP
216 if column.extensions.get("members"):
217 print("\t%s" % column.extensions["members"])
218 continue
7cc398cb
JP
219 comment, members = cMembers(prefix, tableName,
220 columnName, column, False)
221 for member in members:
d34a1cc0
JW
222 print("\t%(type)s%(name)s;%(comment)s" % member)
223 print("};")
c3bb4bd7 224
979821c0 225 # Column indexes.
32d37ce8 226 printEnum("%s_column_id" % structName.lower(), ["%s_COL_%s" % (structName.upper(), columnName.upper())
e0b1744f 227 for columnName, column in sorted_columns(table)]
979821c0
BP
228 + ["%s_N_COLUMNS" % structName.upper()])
229
d34a1cc0 230 print("")
979821c0 231 for columnName in table.columns:
d34a1cc0 232 print("#define %(s)s_col_%(c)s (%(s)s_columns[%(S)s_COL_%(C)s])" % {
979821c0
BP
233 's': structName,
234 'S': structName.upper(),
235 'c': columnName,
d34a1cc0 236 'C': columnName.upper()})
979821c0 237
d34a1cc0 238 print("\nextern struct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (structName, structName.upper()))
979821c0 239
d34a1cc0 240 print('''
8c6cf7b8 241const struct %(s)s *%(s)s_get_for_uuid(const struct ovsdb_idl *, const struct uuid *);
c3bb4bd7
BP
242const struct %(s)s *%(s)s_first(const struct ovsdb_idl *);
243const struct %(s)s *%(s)s_next(const struct %(s)s *);
58bc1a52
BP
244#define %(S)s_FOR_EACH(ROW, IDL) \\
245 for ((ROW) = %(s)s_first(IDL); \\
246 (ROW); \\
247 (ROW) = %(s)s_next(ROW))
248#define %(S)s_FOR_EACH_SAFE(ROW, NEXT, IDL) \\
249 for ((ROW) = %(s)s_first(IDL); \\
250 (ROW) ? ((NEXT) = %(s)s_next(ROW), 1) : 0; \\
251 (ROW) = (NEXT))
475281c0 252
932104f4
SA
253unsigned int %(s)s_get_seqno(const struct ovsdb_idl *);
254unsigned int %(s)s_row_get_seqno(const struct %(s)s *row, enum ovsdb_idl_change change);
255const struct %(s)s *%(s)s_track_get_first(const struct ovsdb_idl *);
256const struct %(s)s *%(s)s_track_get_next(const struct %(s)s *);
257#define %(S)s_FOR_EACH_TRACKED(ROW, IDL) \\
258 for ((ROW) = %(s)s_track_get_first(IDL); \\
259 (ROW); \\
260 (ROW) = %(s)s_track_get_next(ROW))
261
9a33cd70
BP
262/* Returns true if 'row' was inserted since the last change tracking reset. */
263static inline bool %(s)s_is_new(const struct %(s)s *row)
264{
265 return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_MODIFY) == 0;
266}
267
268/* Returns true if 'row' was deleted since the last change tracking reset. */
269static inline bool %(s)s_is_deleted(const struct %(s)s *row)
270{
271 return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_DELETE) > 0;
272}
273
0a8606ee
LR
274void %(s)s_index_destroy_row(const struct %(s)s *);
275int %(s)s_index_compare(struct ovsdb_idl_index_cursor *, const struct %(s)s *, const struct %(s)s *);
276const struct %(s)s *%(s)s_index_first(struct ovsdb_idl_index_cursor *);
277const struct %(s)s *%(s)s_index_next(struct ovsdb_idl_index_cursor *);
278const struct %(s)s *%(s)s_index_find(struct ovsdb_idl_index_cursor *, const struct %(s)s *);
279const struct %(s)s *%(s)s_index_forward_to(struct ovsdb_idl_index_cursor *, const struct %(s)s *);
280const struct %(s)s *%(s)s_index_get_data(const struct ovsdb_idl_index_cursor *);
281#define %(S)s_FOR_EACH_RANGE(ROW, CURSOR, FROM, TO) \\
282 for ((ROW) = %(s)s_index_forward_to(CURSOR, FROM); \\
283 ((ROW) && %(s)s_index_compare(CURSOR, ROW, TO) <= 0); \\
284 (ROW) = %(s)s_index_next(CURSOR))
285#define %(S)s_FOR_EACH_EQUAL(ROW, CURSOR, KEY) \\
286 for ((ROW) = %(s)s_index_find(CURSOR, KEY); \\
287 ((ROW) && %(s)s_index_compare(CURSOR, ROW, KEY) == 0); \\
288 (ROW) = %(s)s_index_next(CURSOR))
289#define %(S)s_FOR_EACH_BYINDEX(ROW, CURSOR) \\
290 for ((ROW) = %(s)s_index_first(CURSOR); \\
291 (ROW); \\
292 (ROW) = %(s)s_index_next(CURSOR))
293
a699f614 294void %(s)s_init(struct %(s)s *);
475281c0
BP
295void %(s)s_delete(const struct %(s)s *);
296struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *);
32d37ce8 297bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id);
d34a1cc0 298''' % {'s': structName, 'S': structName.upper()})
475281c0 299
e0b1744f 300 for columnName, column in sorted_columns(table):
01928c96
BP
301 if column.extensions.get('synthetic'):
302 continue
d34a1cc0 303 print('void %(s)s_verify_%(c)s(const struct %(s)s *);' % {'s': structName, 'c': columnName})
475281c0 304
d34a1cc0 305 print("")
e0b1744f 306 for columnName, column in sorted_columns(table):
01928c96
BP
307 if column.extensions.get('synthetic'):
308 continue
a6ec9089
BP
309 if column.type.value:
310 valueParam = ', enum ovsdb_atomic_type value_type'
311 else:
312 valueParam = ''
d34a1cc0
JW
313 print('const struct ovsdb_datum *%(s)s_get_%(c)s(const struct %(s)s *, enum ovsdb_atomic_type key_type%(v)s);' % {
314 's': structName, 'c': columnName, 'v': valueParam})
a6ec9089 315
d34a1cc0 316 print("")
e0b1744f 317 for columnName, column in sorted_columns(table):
01928c96
BP
318 if column.extensions.get('synthetic'):
319 continue
d34a1cc0 320 print('void %(s)s_set_%(c)s(const struct %(s)s *,' % {'s': structName, 'c': columnName}, end=' ')
a699f614
EJ
321 if column.type.is_smap():
322 args = ['const struct smap *']
323 else:
7cc398cb
JP
324 comment, members = cMembers(prefix, tableName, columnName,
325 column, True)
326 args = ['%(type)s%(name)s' % member for member in members]
d34a1cc0 327 print('%s);' % ', '.join(args))
475281c0 328
d34a1cc0 329 print("")
e0b1744f 330 for columnName, column in sorted_columns(table):
01928c96
BP
331 if column.extensions.get('synthetic'):
332 continue
16ebb90e 333 if column.type.is_map():
d34a1cc0
JW
334 print('void %(s)s_update_%(c)s_setkey(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
335 print('%(coltype)s, %(valtype)s);' % {'coltype':column.type.key.to_const_c_type(prefix), 'valtype':column.type.value.to_const_c_type(prefix)})
336 print('void %(s)s_update_%(c)s_delkey(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
337 print('%(coltype)s);' % {'coltype':column.type.key.to_const_c_type(prefix)})
f1ab6e06 338 if column.type.is_set():
d34a1cc0
JW
339 print('void %(s)s_update_%(c)s_addvalue(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
340 print('%(valtype)s);' % {'valtype':column.type.key.to_const_c_type(prefix)})
341 print('void %(s)s_update_%(c)s_delvalue(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
342 print('%(valtype)s);' % {'valtype':column.type.key.to_const_c_type(prefix)})
16ebb90e 343
d34a1cc0 344 print('void %(s)s_add_clause_%(c)s(struct ovsdb_idl_condition *, enum ovsdb_function function,' % {'s': structName, 'c': columnName}, end=' ')
16ebb90e
LS
345 if column.type.is_smap():
346 args = ['const struct smap *']
347 else:
348 comment, members = cMembers(prefix, tableName, columnName,
4bb7f568 349 column, True, refTable=False)
16ebb90e 350 args = ['%(type)s%(name)s' % member for member in members]
d34a1cc0 351 print('%s);' % ', '.join(args))
16ebb90e 352
d34a1cc0 353 print('void %(s)s_set_condition(struct ovsdb_idl *, struct ovsdb_idl_condition *);' % {'s': structName})
16ebb90e 354
d34a1cc0 355 print("")
f67f1354 356
979821c0 357 # Table indexes.
0a8606ee
LR
358 print("struct %(s)s * %(s)s_index_init_row(struct ovsdb_idl *, const struct ovsdb_idl_table_class *);" % {'s': structName})
359 print
81068700 360 for columnName, column in sorted(table.columns.items()):
0a8606ee
LR
361 print('void %(s)s_index_set_%(c)s(const struct %(s)s *,' % {'s': structName, 'c': columnName})
362 if column.type.is_smap():
363 args = ['const struct smap *']
364 else:
365 comment, members = cMembers(prefix, tableName, columnName,
366 column, True)
367 args = ['%(type)s%(name)s' % member for member in members]
368 print('%s);' % ', '.join(args))
369
370 print
32d37ce8 371 printEnum("%stable_id" % prefix.lower(), ["%sTABLE_%s" % (prefix.upper(), tableName.upper()) for tableName in sorted(schema.tables)] + ["%sN_TABLES" % prefix.upper()])
d34a1cc0 372 print("")
979821c0 373 for tableName in schema.tables:
d34a1cc0 374 print("#define %(p)stable_%(t)s (%(p)stable_classes[%(P)sTABLE_%(T)s])" % {
979821c0
BP
375 'p': prefix,
376 'P': prefix.upper(),
377 't': tableName.lower(),
d34a1cc0
JW
378 'T': tableName.upper()})
379 print("\nextern struct ovsdb_idl_table_class %stable_classes[%sN_TABLES];" % (prefix, prefix.upper()))
979821c0 380
d34a1cc0 381 print("\nextern struct ovsdb_idl_class %sidl_class;" % prefix)
87412f02 382
d34a1cc0 383 print("\nconst char * %sget_db_version(void);" % prefix)
9131abe2
YHW
384 print('''
385#ifdef __cplusplus
386}
387#endif''')
d34a1cc0 388 print("\n#endif /* %(prefix)sIDL_HEADER */" % {'prefix': prefix.upper()})
c3bb4bd7 389
32d37ce8 390def printEnum(type, members):
c3bb4bd7
BP
391 if len(members) == 0:
392 return
393
d34a1cc0 394 print("\nenum %s {" % type)
c3bb4bd7 395 for member in members[:-1]:
d34a1cc0
JW
396 print(" %s," % member)
397 print(" %s" % members[-1])
398 print("};")
c3bb4bd7 399
00732bf5
BP
400def printCIDLSource(schemaFile):
401 schema = parseSchema(schemaFile)
adb4185d 402 replace_cplusplus_keyword(schema)
c3bb4bd7 403 prefix = schema.idlPrefix
d34a1cc0 404 print('''\
c3bb4bd7
BP
405/* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
406
407#include <config.h>
0ea866bb 408#include %(header)s
c3bb4bd7 409#include <limits.h>
558103f0 410#include "ovs-thread.h"
bd76d25d
BP
411#include "ovsdb-data.h"
412#include "ovsdb-error.h"
cb22974d 413#include "util.h"
bd76d25d 414
0ea866bb
BP
415%(cDecls)s
416
417''' % {'header': schema.idlHeader,
418 'cDecls': schema.cDecls})
c3bb4bd7 419
66095e15 420 # Cast functions.
4ab66562 421 for tableName, table in sorted(schema.tables.items()):
66095e15 422 structName = "%s%s" % (prefix, tableName.lower())
d34a1cc0 423 print('''
66095e15 424static struct %(s)s *
979821c0 425%(s)s_cast(const struct ovsdb_idl_row *row)
66095e15
BP
426{
427 return row ? CONTAINER_OF(row, struct %(s)s, header_) : NULL;
428}\
d34a1cc0 429''' % {'s': structName})
66095e15
BP
430
431
4ab66562 432 for tableName, table in sorted(schema.tables.items()):
c3bb4bd7 433 structName = "%s%s" % (prefix, tableName.lower())
d34a1cc0
JW
434 print("\f")
435 print("/* %s table. */" % (tableName))
c3bb4bd7 436
979821c0 437 # Parse functions.
e0b1744f 438 for columnName, column in sorted_columns(table):
01928c96
BP
439 if 'parse' in column.extensions:
440 print('''
441static void
442%(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum OVS_UNUSED)
443{
444 struct %(s)s *row = %(s)s_cast(row_);\
445''' % {'s': structName, 'c': columnName})
446 print(column.extensions["parse"])
447 print("}")
448 continue
449 if column.extensions.get('synthetic'):
450 # Synthetic columns aren't parsed from a datum.
451 unused = " OVS_UNUSED"
452 else:
453 unused = ""
d34a1cc0 454 print('''
c3bb4bd7 455static void
979821c0 456%(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum)
c3bb4bd7 457{
979821c0 458 struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName,
d34a1cc0 459 'c': columnName})
c3bb4bd7 460 type = column.type
01928c96
BP
461 if 'parse' in column.extensions:
462 print(column.extensions["parse"])
463 print("}")
464 continue
c3bb4bd7
BP
465 if type.value:
466 keyVar = "row->key_%s" % columnName
467 valueVar = "row->value_%s" % columnName
468 else:
469 keyVar = "row->%s" % columnName
470 valueVar = None
471
a699f614 472 if type.is_smap():
d34a1cc0
JW
473 print(" smap_init(&row->%s);" % columnName)
474 print(" for (size_t i = 0; i < datum->n; i++) {")
475 print(" smap_add(&row->%s," % columnName)
476 print(" datum->keys[i].string,")
477 print(" datum->values[i].string);")
478 print(" }")
a699f614 479 elif (type.n_min == 1 and type.n_max == 1) or type.is_optional_pointer():
d34a1cc0
JW
480 print("")
481 print(" if (datum->n >= 1) {")
99155935 482 if not type.key.ref_table:
d34a1cc0 483 print(" %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_string()))
c3bb4bd7 484 else:
d34a1cc0 485 print(" %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->keys[0].uuid));" % (keyVar, prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower()))
c3bb4bd7
BP
486
487 if valueVar:
ae661470 488 if not type.value.ref_table:
d34a1cc0 489 print(" %s = datum->values[0].%s;" % (valueVar, type.value.type.to_string()))
c3bb4bd7 490 else:
d34a1cc0
JW
491 print(" %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->values[0].uuid));" % (valueVar, prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower()))
492 print(" } else {")
493 print(" %s" % type.key.initCDefault(keyVar, type.n_min == 0))
979821c0 494 if valueVar:
d34a1cc0
JW
495 print(" %s" % type.value.initCDefault(valueVar, type.n_min == 0))
496 print(" }")
c3bb4bd7 497 else:
fa145f1a 498 if type.n_max != sys.maxsize:
d34a1cc0 499 print(" size_t n = MIN(%d, datum->n);" % type.n_max)
979821c0 500 nMax = "n"
c3bb4bd7
BP
501 else:
502 nMax = "datum->n"
d34a1cc0 503 print(" %s = NULL;" % keyVar)
979821c0 504 if valueVar:
d34a1cc0
JW
505 print(" %s = NULL;" % valueVar)
506 print(" row->n_%s = 0;" % columnName)
507 print(" for (size_t i = 0; i < %s; i++) {" % nMax)
99155935 508 if type.key.ref_table:
d34a1cc0 509 print("""\
9478f52f 510 struct %s%s *keyRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->keys[i].uuid));
cff5afcf
BP
511 if (!keyRow) {
512 continue;
513 }\
d34a1cc0 514""" % (prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower()))
c3bb4bd7 515 keySrc = "keyRow"
c3bb4bd7 516 else:
99155935
BP
517 keySrc = "datum->keys[i].%s" % type.key.type.to_string()
518 if type.value and type.value.ref_table:
d34a1cc0 519 print("""\
9478f52f 520 struct %s%s *valueRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->values[i].uuid));
cff5afcf
BP
521 if (!valueRow) {
522 continue;
523 }\
d34a1cc0 524""" % (prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower()))
c3bb4bd7 525 valueSrc = "valueRow"
c3bb4bd7 526 elif valueVar:
99155935 527 valueSrc = "datum->values[i].%s" % type.value.type.to_string()
d34a1cc0 528 print(" if (!row->n_%s) {" % (columnName))
1bf2c909 529
d34a1cc0
JW
530 print(" %s = xmalloc(%s * sizeof *%s);" % (
531 keyVar, nMax, keyVar))
c3bb4bd7 532 if valueVar:
d34a1cc0
JW
533 print(" %s = xmalloc(%s * sizeof *%s);" % (
534 valueVar, nMax, valueVar))
535 print(" }")
536 print(" %s[row->n_%s] = %s;" % (keyVar, columnName, keySrc))
c3bb4bd7 537 if valueVar:
d34a1cc0
JW
538 print(" %s[row->n_%s] = %s;" % (valueVar, columnName, valueSrc))
539 print(" row->n_%s++;" % columnName)
540 print(" }")
541 print("}")
c3bb4bd7 542
979821c0 543 # Unparse functions.
e0b1744f 544 for columnName, column in sorted_columns(table):
c3bb4bd7 545 type = column.type
01928c96 546 if (type.is_smap() or (type.n_min != 1 or type.n_max != 1) and not type.is_optional_pointer()) or 'unparse' in column.extensions:
d34a1cc0 547 print('''
c3bb4bd7 548static void
979821c0 549%(s)s_unparse_%(c)s(struct ovsdb_idl_row *row_)
c3bb4bd7 550{
74e98efd 551 struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName,
d34a1cc0 552 'c': columnName})
01928c96
BP
553 if 'unparse' in column.extensions:
554 print(column.extensions["unparse"])
555 elif type.is_smap():
d34a1cc0 556 print(" smap_destroy(&row->%s);" % columnName)
c3bb4bd7 557 else:
a699f614
EJ
558 if type.value:
559 keyVar = "row->key_%s" % columnName
560 valueVar = "row->value_%s" % columnName
561 else:
562 keyVar = "row->%s" % columnName
563 valueVar = None
d34a1cc0 564 print(" free(%s);" % keyVar)
a699f614 565 if valueVar:
d34a1cc0
JW
566 print(" free(%s);" % valueVar)
567 print('}')
979821c0 568 else:
d34a1cc0 569 print('''
c3bb4bd7 570static void
c69ee87c 571%(s)s_unparse_%(c)s(struct ovsdb_idl_row *row OVS_UNUSED)
979821c0
BP
572{
573 /* Nothing to do. */
d34a1cc0 574}''' % {'s': structName, 'c': columnName})
c5c7c7c5 575
a699f614 576 # Generic Row Initialization function.
d34a1cc0 577 print("""
a699f614
EJ
578static void
579%(s)s_init__(struct ovsdb_idl_row *row)
580{
581 %(s)s_init(%(s)s_cast(row));
d34a1cc0 582}""" % {'s': structName})
a699f614
EJ
583
584 # Row Initialization function.
d34a1cc0 585 print("""
d797877d 586/* Clears the contents of 'row' in table "%(t)s". */
a699f614
EJ
587void
588%(s)s_init(struct %(s)s *row)
589{
d34a1cc0 590 memset(row, 0, sizeof *row); """ % {'s': structName, 't': tableName})
e0b1744f 591 for columnName, column in sorted_columns(table):
a699f614 592 if column.type.is_smap():
d34a1cc0 593 print(" smap_init(&row->%s);" % columnName)
5a98d741
BP
594 elif (column.type.n_min == 1 and
595 column.type.n_max == 1 and
596 column.type.key.type == ovs.db.types.StringType and
597 not column.type.value):
d34a1cc0
JW
598 print(" row->%s = \"\";" % columnName)
599 print("}")
a699f614 600
c3bb4bd7 601 # First, next functions.
d34a1cc0 602 print('''
d797877d
JP
603/* Searches table "%(t)s" in 'idl' for a row with UUID 'uuid'. Returns
604 * a pointer to the row if there is one, otherwise a null pointer. */
8c6cf7b8
BP
605const struct %(s)s *
606%(s)s_get_for_uuid(const struct ovsdb_idl *idl, const struct uuid *uuid)
607{
9478f52f 608 return %(s)s_cast(ovsdb_idl_get_row_for_uuid(idl, &%(p)stable_%(tl)s, uuid));
8c6cf7b8
BP
609}
610
d797877d
JP
611/* Returns a row in table "%(t)s" in 'idl', or a null pointer if that
612 * table is empty.
613 *
614 * Database tables are internally maintained as hash tables, so adding or
615 * removing rows while traversing the same table can cause some rows to be
616 * visited twice or not at apply. */
66095e15
BP
617const struct %(s)s *
618%(s)s_first(const struct ovsdb_idl *idl)
c3bb4bd7 619{
9478f52f 620 return %(s)s_cast(ovsdb_idl_first_row(idl, &%(p)stable_%(tl)s));
c3bb4bd7
BP
621}
622
d797877d
JP
623/* Returns a row following 'row' within its table, or a null pointer if 'row'
624 * is the last row in its table. */
66095e15
BP
625const struct %(s)s *
626%(s)s_next(const struct %(s)s *row)
c3bb4bd7 627{
66095e15 628 return %(s)s_cast(ovsdb_idl_next_row(&row->header_));
932104f4
SA
629}
630
631unsigned int %(s)s_get_seqno(const struct ovsdb_idl *idl)
632{
9478f52f 633 return ovsdb_idl_table_get_seqno(idl, &%(p)stable_%(tl)s);
932104f4
SA
634}
635
636unsigned int %(s)s_row_get_seqno(const struct %(s)s *row, enum ovsdb_idl_change change)
637{
638 return ovsdb_idl_row_get_seqno(&row->header_, change);
639}
640
641const struct %(s)s *
642%(s)s_track_get_first(const struct ovsdb_idl *idl)
643{
9478f52f 644 return %(s)s_cast(ovsdb_idl_track_get_first(idl, &%(p)stable_%(tl)s));
932104f4
SA
645}
646
647const struct %(s)s
648*%(s)s_track_get_next(const struct %(s)s *row)
649{
650 return %(s)s_cast(ovsdb_idl_track_get_next(&row->header_));
475281c0
BP
651}''' % {'s': structName,
652 'p': prefix,
653 'P': prefix.upper(),
d797877d 654 't': tableName,
9478f52f 655 'tl': tableName.lower(),
d34a1cc0 656 'T': tableName.upper()})
475281c0 657
d34a1cc0 658 print('''
932104f4 659
d797877d
JP
660/* Deletes 'row' from table "%(t)s". 'row' may be freed, so it must not be
661 * accessed afterward.
662 *
663 * The caller must have started a transaction with ovsdb_idl_txn_create(). */
475281c0 664void
9e336f49 665%(s)s_delete(const struct %(s)s *row)
475281c0 666{
475281c0
BP
667 ovsdb_idl_txn_delete(&row->header_);
668}
669
d797877d
JP
670/* Inserts and returns a new row in the table "%(t)s" in the database
671 * with open transaction 'txn'.
672 *
673 * The new row is assigned a randomly generated provisional UUID.
674 * ovsdb-server will assign a different UUID when 'txn' is committed,
675 * but the IDL will replace any uses of the provisional UUID in the
676 * data to be to be committed by the UUID assigned by ovsdb-server. */
475281c0
BP
677struct %(s)s *
678%(s)s_insert(struct ovsdb_idl_txn *txn)
679{
9478f52f 680 return %(s)s_cast(ovsdb_idl_txn_insert(txn, &%(p)stable_%(tl)s, NULL));
32d37ce8
SA
681}
682
683bool
684%(s)s_is_updated(const struct %(s)s *row, enum %(s)s_column_id column)
685{
686 return ovsdb_idl_track_is_updated(&row->header_, &%(s)s_columns[column]);
d797877d
JP
687}''' % {'s': structName,
688 'p': prefix,
689 'P': prefix.upper(),
690 't': tableName,
9478f52f 691 'tl': tableName.lower(),
d34a1cc0 692 'T': tableName.upper()})
475281c0
BP
693
694 # Verify functions.
e0b1744f 695 for columnName, column in sorted_columns(table):
01928c96
BP
696 if column.extensions.get('synthetic'):
697 continue
d34a1cc0 698 print('''
d797877d
JP
699/* Causes the original contents of column "%(c)s" in 'row' to be
700 * verified as a prerequisite to completing the transaction. That is, if
701 * "%(c)s" in 'row' changed (or if 'row' was deleted) between the
702 * time that the IDL originally read its contents and the time that the
b17c8228 703 * transaction aborts and ovsdb_idl_txn_commit() returns TXN_TRY_AGAIN.
d797877d
JP
704 *
705 * The intention is that, to ensure that no transaction commits based on dirty
706 * reads, an application should call this function any time "%(c)s" is
707 * read as part of a read-modify-write operation.
708 *
709 * In some cases this function reduces to a no-op, because the current value
710 * of "%(c)s" is already known:
711 *
712 * - If 'row' is a row created by the current transaction (returned by
713 * %(s)s_insert()).
714 *
715 * - If "%(c)s" has already been modified (with
716 * %(s)s_set_%(c)s()) within the current transaction.
717 *
718 * Because of the latter property, always call this function *before*
719 * %(s)s_set_%(c)s() for a given read-modify-write.
720 *
721 * The caller must have started a transaction with ovsdb_idl_txn_create(). */
475281c0
BP
722void
723%(s)s_verify_%(c)s(const struct %(s)s *row)
724{
1f2d2557 725 ovsdb_idl_txn_verify(&row->header_, &%(s)s_col_%(c)s);
475281c0
BP
726}''' % {'s': structName,
727 'S': structName.upper(),
728 'c': columnName,
d34a1cc0 729 'C': columnName.upper()})
475281c0 730
a6ec9089 731 # Get functions.
e0b1744f 732 for columnName, column in sorted_columns(table):
01928c96
BP
733 if column.extensions.get('synthetic'):
734 continue
a6ec9089
BP
735 if column.type.value:
736 valueParam = ',\n\tenum ovsdb_atomic_type value_type OVS_UNUSED'
cb22974d 737 valueType = '\n ovs_assert(value_type == %s);' % column.type.value.toAtomicType()
a6ec9089
BP
738 valueComment = "\n * 'value_type' must be %s." % column.type.value.toAtomicType()
739 else:
740 valueParam = ''
741 valueType = ''
742 valueComment = ''
d34a1cc0 743 print("""
d797877d
JP
744/* Returns the "%(c)s" column's value from the "%(t)s" table in 'row'
745 * as a struct ovsdb_datum. This is useful occasionally: for example,
746 * ovsdb_datum_find_key() is an easier and more efficient way to search
747 * for a given key than implementing the same operation on the "cooked"
748 * form in 'row'.
a6ec9089
BP
749 *
750 * 'key_type' must be %(kt)s.%(vc)s
751 * (This helps to avoid silent bugs if someone changes %(c)s's
752 * type without updating the caller.)
753 *
754 * The caller must not modify or free the returned value.
755 *
756 * Various kinds of changes can invalidate the returned value: modifying
757 * 'column' within 'row', deleting 'row', or completing an ongoing transaction.
758 * If the returned value is needed for a long time, it is best to make a copy
d797877d
JP
759 * of it with ovsdb_datum_clone().
760 *
761 * This function is rarely useful, since it is easier to access the value
762 * directly through the "%(c)s" member in %(s)s. */
a6ec9089
BP
763const struct ovsdb_datum *
764%(s)s_get_%(c)s(const struct %(s)s *row,
765\tenum ovsdb_atomic_type key_type OVS_UNUSED%(v)s)
766{
cb22974d 767 ovs_assert(key_type == %(kt)s);%(vt)s
a6ec9089 768 return ovsdb_idl_read(&row->header_, &%(s)s_col_%(c)s);
d797877d 769}""" % {'t': tableName, 's': structName, 'c': columnName,
a6ec9089 770 'kt': column.type.key.toAtomicType(),
d34a1cc0 771 'v': valueParam, 'vt': valueType, 'vc': valueComment})
a6ec9089 772
475281c0 773 # Set functions.
e0b1744f 774 for columnName, column in sorted_columns(table):
01928c96
BP
775 if column.extensions.get('synthetic'):
776 continue
475281c0 777 type = column.type
a699f614 778
7cc398cb
JP
779 comment, members = cMembers(prefix, tableName, columnName,
780 column, True)
781
a699f614 782 if type.is_smap():
d34a1cc0
JW
783 print(comment)
784 print("""void
4946b41d 785%(s)s_set_%(c)s(const struct %(s)s *row, const struct smap *%(c)s)
a699f614
EJ
786{
787 struct ovsdb_datum datum;
788
4946b41d 789 if (%(c)s) {
9b03e59d 790 ovsdb_datum_from_smap(&datum, %(c)s);
a699f614
EJ
791 } else {
792 ovsdb_datum_init_empty(&datum);
793 }
794 ovsdb_idl_txn_write(&row->header_,
1f2d2557 795 &%(s)s_col_%(c)s,
a699f614
EJ
796 &datum);
797}
7cc398cb
JP
798""" % {'t': tableName,
799 's': structName,
a699f614
EJ
800 'S': structName.upper(),
801 'c': columnName,
d34a1cc0 802 'C': columnName.upper()})
a699f614
EJ
803 continue
804
475281c0
BP
805 keyVar = members[0]['name']
806 nVar = None
807 valueVar = None
808 if type.value:
809 valueVar = members[1]['name']
810 if len(members) > 2:
811 nVar = members[2]['name']
812 else:
813 if len(members) > 1:
814 nVar = members[1]['name']
7cc398cb 815
d34a1cc0
JW
816 print(comment)
817 print("""\
cad9a996
BP
818void
819%(s)s_set_%(c)s(const struct %(s)s *row, %(args)s)
820{
cad9a996 821 struct ovsdb_datum datum;""" % {'s': structName,
74e98efd
BP
822 'c': columnName,
823 'args': ', '.join(['%(type)s%(name)s'
d34a1cc0 824 % m for m in members])})
99155935 825 if type.n_min == 1 and type.n_max == 1:
d34a1cc0 826 print(" union ovsdb_atom key;")
fe19569a 827 if type.value:
d34a1cc0
JW
828 print(" union ovsdb_atom value;")
829 print("")
830 print(" datum.n = 1;")
831 print(" datum.keys = &key;")
832 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar))
475281c0 833 if type.value:
d34a1cc0
JW
834 print(" datum.values = &value;")
835 print(" "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar))
475281c0 836 else:
d34a1cc0 837 print(" datum.values = NULL;")
fe19569a 838 txn_write_func = "ovsdb_idl_txn_write_clone"
99155935 839 elif type.is_optional_pointer():
d34a1cc0
JW
840 print(" union ovsdb_atom key;")
841 print("")
842 print(" if (%s) {" % keyVar)
843 print(" datum.n = 1;")
844 print(" datum.keys = &key;")
845 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar))
846 print(" } else {")
847 print(" datum.n = 0;")
848 print(" datum.keys = NULL;")
849 print(" }")
850 print(" datum.values = NULL;")
fe19569a
BP
851 txn_write_func = "ovsdb_idl_txn_write_clone"
852 elif type.n_max == 1:
d34a1cc0
JW
853 print(" union ovsdb_atom key;")
854 print("")
855 print(" if (%s) {" % nVar)
856 print(" datum.n = 1;")
857 print(" datum.keys = &key;")
858 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar))
859 print(" } else {")
860 print(" datum.n = 0;")
861 print(" datum.keys = NULL;")
862 print(" }")
863 print(" datum.values = NULL;")
fe19569a 864 txn_write_func = "ovsdb_idl_txn_write_clone"
475281c0 865 else:
d34a1cc0
JW
866 print("")
867 print(" datum.n = %s;" % nVar)
868 print(" datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar))
475281c0 869 if type.value:
d34a1cc0 870 print(" datum.values = xmalloc(%s * sizeof *datum.values);" % nVar)
475281c0 871 else:
d34a1cc0
JW
872 print(" datum.values = NULL;")
873 print(" for (size_t i = 0; i < %s; i++) {" % nVar)
874 print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar))
475281c0 875 if type.value:
d34a1cc0
JW
876 print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar))
877 print(" }")
a1ec42a3
BP
878 if type.value:
879 valueType = type.value.toAtomicType()
880 else:
881 valueType = "OVSDB_TYPE_VOID"
fe19569a 882 txn_write_func = "ovsdb_idl_txn_write"
d34a1cc0 883 print(" %(f)s(&row->header_, &%(s)s_col_%(c)s, &datum);" \
fe19569a
BP
884 % {'f': txn_write_func,
885 's': structName,
475281c0 886 'S': structName.upper(),
d34a1cc0
JW
887 'c': columnName})
888 print("}")
010fe7ae 889 # Update/Delete of partial map column functions
e0b1744f 890 for columnName, column in sorted_columns(table):
01928c96
BP
891 if column.extensions.get('synthetic'):
892 continue
010fe7ae
EA
893 type = column.type
894 if type.is_map():
d34a1cc0 895 print('''
010fe7ae
EA
896/* Sets an element of the "%(c)s" map column from the "%(t)s" table in 'row'
897 * to 'new_value' given the key value 'new_key'.
898 *
899 */
900void
901%(s)s_update_%(c)s_setkey(const struct %(s)s *row, %(coltype)snew_key, %(valtype)snew_value)
902{
903 struct ovsdb_datum *datum;
904
010fe7ae
EA
905 datum = xmalloc(sizeof *datum);
906 datum->n = 1;
907 datum->keys = xmalloc(datum->n * sizeof *datum->keys);
908 datum->values = xmalloc(datum->n * sizeof *datum->values);
05ba459f
BP
909''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
910 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
d34a1cc0 911 'C': columnName.upper(), 't': tableName})
010fe7ae 912
d34a1cc0
JW
913 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "new_key"))
914 print(" "+ type.value.copyCValue("datum->values[0].%s" % type.value.type.to_string(), "new_value"))
915 print('''
010fe7ae 916 ovsdb_idl_txn_write_partial_map(&row->header_,
1f2d2557 917 &%(s)s_col_%(c)s,
010fe7ae 918 datum);
1f2d2557 919}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0
JW
920 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper()})
921 print('''
010fe7ae
EA
922/* Deletes an element of the "%(c)s" map column from the "%(t)s" table in 'row'
923 * given the key value 'delete_key'.
924 *
925 */
926void
927%(s)s_update_%(c)s_delkey(const struct %(s)s *row, %(coltype)sdelete_key)
928{
929 struct ovsdb_datum *datum;
930
010fe7ae
EA
931 datum = xmalloc(sizeof *datum);
932 datum->n = 1;
933 datum->keys = xmalloc(datum->n * sizeof *datum->keys);
934 datum->values = NULL;
05ba459f
BP
935''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
936 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
d34a1cc0 937 'C': columnName.upper(), 't': tableName})
010fe7ae 938
d34a1cc0
JW
939 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "delete_key"))
940 print('''
010fe7ae 941 ovsdb_idl_txn_delete_partial_map(&row->header_,
1f2d2557 942 &%(s)s_col_%(c)s,
010fe7ae 943 datum);
1f2d2557 944}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0 945 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper()})
010fe7ae 946 # End Update/Delete of partial maps
f1ab6e06
RM
947 # Update/Delete of partial set column functions
948 if type.is_set():
d34a1cc0 949 print('''
f1ab6e06
RM
950/* Adds the value 'new_value' to the "%(c)s" set column from the "%(t)s" table
951 * in 'row'.
952 *
953 */
954void
955%(s)s_update_%(c)s_addvalue(const struct %(s)s *row, %(valtype)snew_value)
956{
957 struct ovsdb_datum *datum;
958
f1ab6e06
RM
959 datum = xmalloc(sizeof *datum);
960 datum->n = 1;
961 datum->keys = xmalloc(datum->n * sizeof *datum->values);
962 datum->values = NULL;
963''' % {'s': structName, 'c': columnName,
d34a1cc0 964 'valtype':column.type.key.to_const_c_type(prefix), 't': tableName})
f1ab6e06 965
d34a1cc0
JW
966 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "new_value"))
967 print('''
f1ab6e06 968 ovsdb_idl_txn_write_partial_set(&row->header_,
1f2d2557 969 &%(s)s_col_%(c)s,
f1ab6e06 970 datum);
1f2d2557 971}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0
JW
972 'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper()})
973 print('''
f1ab6e06
RM
974/* Deletes the value 'delete_value' from the "%(c)s" set column from the
975 * "%(t)s" table in 'row'.
976 *
977 */
978void
979%(s)s_update_%(c)s_delvalue(const struct %(s)s *row, %(valtype)sdelete_value)
980{
981 struct ovsdb_datum *datum;
982
f1ab6e06
RM
983 datum = xmalloc(sizeof *datum);
984 datum->n = 1;
985 datum->keys = xmalloc(datum->n * sizeof *datum->values);
986 datum->values = NULL;
05ba459f
BP
987''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
988 'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper(),
d34a1cc0 989 'C': columnName.upper(), 't': tableName})
f1ab6e06 990
d34a1cc0
JW
991 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "delete_value"))
992 print('''
f1ab6e06 993 ovsdb_idl_txn_delete_partial_set(&row->header_,
1f2d2557 994 &%(s)s_col_%(c)s,
f1ab6e06 995 datum);
1f2d2557 996}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0 997 'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper()})
f1ab6e06 998 # End Update/Delete of partial set
c3bb4bd7 999
16ebb90e 1000 # Add clause functions.
e0b1744f 1001 for columnName, column in sorted_columns(table):
01928c96
BP
1002 if column.extensions.get('synthetic'):
1003 continue
16ebb90e
LS
1004 type = column.type
1005
1006 comment, members = cMembers(prefix, tableName, columnName,
4bb7f568 1007 column, True, refTable=False)
16ebb90e
LS
1008
1009 if type.is_smap():
d34a1cc0
JW
1010 print(comment)
1011 print("""void
0164e367 1012%(s)s_add_clause_%(c)s(struct ovsdb_idl_condition *cond, enum ovsdb_function function, const struct smap *%(c)s)
16ebb90e
LS
1013{
1014 struct ovsdb_datum datum;
1015
16ebb90e 1016 if (%(c)s) {
9b03e59d 1017 ovsdb_datum_from_smap(&datum, %(c)s);
16ebb90e
LS
1018 } else {
1019 ovsdb_datum_init_empty(&datum);
1020 }
1021
0164e367 1022 ovsdb_idl_condition_add_clause(cond,
16ebb90e 1023 function,
1f2d2557 1024 &%(s)s_col_%(c)s,
16ebb90e 1025 &datum);
a4e68acd
BP
1026
1027 ovsdb_datum_destroy(&datum, &%(s)s_col_%(c)s.type);
16ebb90e
LS
1028}
1029""" % {'t': tableName,
9478f52f 1030 'tl': tableName.lower(),
16ebb90e
LS
1031 'T': tableName.upper(),
1032 'p': prefix,
1033 'P': prefix.upper(),
1034 's': structName,
1035 'S': structName.upper(),
d34a1cc0 1036 'c': columnName})
16ebb90e
LS
1037 continue
1038
1039 keyVar = members[0]['name']
1040 nVar = None
1041 valueVar = None
1042 if type.value:
1043 valueVar = members[1]['name']
1044 if len(members) > 2:
1045 nVar = members[2]['name']
1046 else:
1047 if len(members) > 1:
1048 nVar = members[1]['name']
1049
d34a1cc0
JW
1050 print(comment)
1051 print('void')
1052 print('%(s)s_add_clause_%(c)s(struct ovsdb_idl_condition *cond, enum ovsdb_function function, %(args)s)' % \
16ebb90e 1053 {'s': structName, 'c': columnName,
d34a1cc0
JW
1054 'args': ', '.join(['%(type)s%(name)s' % m for m in members])})
1055 print("{")
1056 print(" struct ovsdb_datum datum;")
a4e68acd 1057 free = []
16ebb90e 1058 if type.n_min == 1 and type.n_max == 1:
d34a1cc0 1059 print(" union ovsdb_atom key;")
16ebb90e 1060 if type.value:
d34a1cc0
JW
1061 print(" union ovsdb_atom value;")
1062 print("")
1063 print(" datum.n = 1;")
1064 print(" datum.keys = &key;")
1065 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar, refTable=False))
16ebb90e 1066 if type.value:
d34a1cc0
JW
1067 print(" datum.values = &value;")
1068 print(" "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar, refTable=False))
16ebb90e 1069 else:
d34a1cc0 1070 print(" datum.values = NULL;")
16ebb90e 1071 elif type.is_optional_pointer():
d34a1cc0
JW
1072 print(" union ovsdb_atom key;")
1073 print("")
1074 print(" if (%s) {" % keyVar)
1075 print(" datum.n = 1;")
1076 print(" datum.keys = &key;")
1077 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar, refTable=False))
1078 print(" } else {")
1079 print(" datum.n = 0;")
1080 print(" datum.keys = NULL;")
1081 print(" }")
1082 print(" datum.values = NULL;")
16ebb90e 1083 elif type.n_max == 1:
d34a1cc0
JW
1084 print(" union ovsdb_atom key;")
1085 print("")
1086 print(" if (%s) {" % nVar)
1087 print(" datum.n = 1;")
1088 print(" datum.keys = &key;")
1089 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar, refTable=False))
1090 print(" } else {")
1091 print(" datum.n = 0;")
1092 print(" datum.keys = NULL;")
1093 print(" }")
1094 print(" datum.values = NULL;")
16ebb90e 1095 else:
d34a1cc0
JW
1096 print(" datum.n = %s;" % nVar)
1097 print(" datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar))
a4e68acd 1098 free += ['datum.keys']
16ebb90e 1099 if type.value:
d34a1cc0 1100 print(" datum.values = xmalloc(%s * sizeof *datum.values);" % nVar)
a4e68acd 1101 free += ['datum.values']
16ebb90e 1102 else:
d34a1cc0
JW
1103 print(" datum.values = NULL;")
1104 print(" for (size_t i = 0; i < %s; i++) {" % nVar)
1105 print(" " + type.key.assign_c_value_casting_away_const("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar, refTable=False))
16ebb90e 1106 if type.value:
d34a1cc0
JW
1107 print(" " + type.value.assign_c_value_casting_away_const("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar, refTable=False))
1108 print(" }")
16ebb90e
LS
1109 if type.value:
1110 valueType = type.value.toAtomicType()
1111 else:
1112 valueType = "OVSDB_TYPE_VOID"
d34a1cc0
JW
1113 print(" ovsdb_datum_sort_unique(&datum, %s, %s);" % (
1114 type.key.toAtomicType(), valueType))
16ebb90e 1115
d34a1cc0 1116 print(""" ovsdb_idl_condition_add_clause(cond,
16ebb90e 1117 function,
1f2d2557 1118 &%(s)s_col_%(c)s,
a4e68acd 1119 &datum);\
9478f52f 1120""" % {'tl': tableName.lower(),
16ebb90e
LS
1121 'T': tableName.upper(),
1122 'p': prefix,
1123 'P': prefix.upper(),
1124 's': structName,
1125 'S': structName.upper(),
d34a1cc0 1126 'c': columnName})
a4e68acd 1127 for var in free:
d34a1cc0
JW
1128 print(" free(%s);" % var)
1129 print("}")
16ebb90e 1130
0a8606ee
LR
1131# Index table related functions
1132 print("""
1133/* Destroy 'row' of kind "%(t)s". The row must have been
1134 * created with ovsdb_idl_index_init_row.
1135 */
1136void
1137%(s)s_index_destroy_row(const struct %(s)s *row)
1138{
1139 ovsdb_idl_index_destroy_row__(&row->header_);
1140}
1141 """ % { 's' : structName, 't': tableName })
1142 print("""
1143/* Creates a new row of kind "%(t)s". */
1144struct %(s)s *
3eb14233 1145%(s)s_index_init_row(struct ovsdb_idl *idl, const struct ovsdb_idl_table_class *class_)
0a8606ee 1146{""" % {'s': structName, 't': tableName})
81068700 1147 #for columnName, column in sorted(table.columns.items()):
0a8606ee
LR
1148 # if column.type.is_smap():
1149 # print " smap_init(&row->%s);" % columnName
3eb14233 1150 print(" return (struct %(s)s *) ovsdb_idl_index_init_row(idl, class_);" % {'s': structName, 't': tableName})
0a8606ee
LR
1151 print("}")
1152
1153 print("""
1154/* This function is used to compare "%(s)s" records on table in iteration loops for compound-index operations.
1155 After been called, cursor point to current position in the index
1156 Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table.
1157 const struct "%(s)s" *const_data1, const struct "%(s)s" *const_data2. Data to be compared.
1158 Return value: 0 if both data values are equal, -1 if first parameter is less than second and 1 otherwise. */""" % {'s' : structName})
1159 print('int')
1160 print("""%(s)s_index_compare(struct ovsdb_idl_index_cursor *cursor, const struct %(s)s *const_data1, const struct %(s)s *const_data2)
1161{
1162 struct %(s)s *data1 = CONST_CAST(struct %(s)s *, const_data1);
1163 struct %(s)s *data2 = CONST_CAST(struct %(s)s *, const_data2);
1164 return ovsdb_idl_index_compare(cursor, &data1->header_, &data2->header_);
1165}""" % { 's' : structName })
1166 print("""
1167/* This function is called to position the cursor at the first row in "%(s)s" table on the associated compound-index.
1168 Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table.
1169 Return value: The first row in the corresponding index. */""" % {'s' : structName })
1170 print("""const struct %(s)s *\n%(s)s_index_first(struct ovsdb_idl_index_cursor *cursor)
1171{
1172 return %(s)s_cast(ovsdb_idl_index_first(cursor));
1173}""" % { 's' : structName })
1174 print("""
1175/* This function is called to position the cursor at the next row in "%(s)s" table on the associated compound-index.
1176 Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table.
1177 Return value: The next row in the corresponding index. */""" % {'s' : structName, 'c' : columnName })
1178 print("""const struct %(s)s *\n%(s)s_index_next(struct ovsdb_idl_index_cursor *cursor)
1179{
1180 return %(s)s_cast(ovsdb_idl_index_next(cursor));
1181}""" % { 's' : structName })
1182 print("""
1183/* This function is used to find the data of the row in "%(s)s" table that meet criteria with the requested data
1184 associated in the compound-index.
1185 Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table.
1186 const struct %(s)s *const_data. Data to be searched.
1187 Return value: The row in the corresponding index if found or NULL otherwise. */""" % {'s' : structName })
1188 print("""const struct %(s)s *\n%(s)s_index_find(struct ovsdb_idl_index_cursor *cursor, const struct %(s)s *const_data)
1189{
1190 struct %(s)s *data = CONST_CAST(struct %(s)s *, const_data);
1191 return %(s)s_cast(ovsdb_idl_index_find(cursor, &data->header_));
1192}""" % { 's' : structName })
1193 print("""
1194/* This function is used to set the cursor pointing to the row in "%(s)s" table that meet criteria of the requested data
1195 associated in the compound-index.
1196 Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table.
1197 const struct %(s)s *const_data. Data to be searched.
1198 Return value: The row in the corresponding index closest to the criteria. */""" % {'s' : structName })
1199 print("""const struct %(s)s *\n%(s)s_index_forward_to(struct ovsdb_idl_index_cursor *cursor, const struct %(s)s *const_data)
1200{
1201 struct %(s)s *data = CONST_CAST(struct %(s)s *, const_data);
1202 return %(s)s_cast(ovsdb_idl_index_forward_to(cursor, &data->header_));
1203}""" % { 's' : structName })
1204 print("""
1205/* This function is used to get the data of the row in the current position pointed by the cursor in
1206 "%(s)s" table.
1207 Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table.
1208 Return value: The row in the corresponding index if found or NULL otherwise. */""" % {'s' : structName, 'c' : columnName })
1209 print("""const struct %(s)s *\n%(s)s_index_get_data(const struct ovsdb_idl_index_cursor *cursor)
1210{
1211 return %(s)s_cast(ovsdb_idl_index_data(CONST_CAST(struct ovsdb_idl_index_cursor *, cursor)));
1212}""" % { 's' : structName })
1213 # Indexes Set functions
81068700 1214 for columnName, column in sorted(table.columns.items()):
0a8606ee
LR
1215 type = column.type
1216
1217 comment, members = cMembers(prefix, tableName, columnName,
1218 column, True)
1219
1220 if type.is_smap():
1221 print(comment)
1222 print("""void
1223%(s)s_index_set_%(c)s(const struct %(s)s *row, const struct smap *%(c)s)
1224{
1225 struct ovsdb_datum *datum = xmalloc(sizeof(struct ovsdb_datum));
1226
1227 if (%(c)s) {
1228 struct smap_node *node;
1229 size_t i;
1230
1231 datum->n = smap_count(%(c)s);
1232 datum->keys = xmalloc(datum->n * sizeof *datum->keys);
1233 datum->values = xmalloc(datum->n * sizeof *datum->values);
1234
1235 i = 0;
1236 SMAP_FOR_EACH (node, %(c)s) {
1237 datum->keys[i].string = node->key;
1238 datum->values[i].string = node->value;
1239 i++;
1240 }
1241 ovsdb_datum_sort_unique(datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
1242 } else {
1243 ovsdb_datum_init_empty(datum);
1244 }
1245 ovsdb_idl_index_write_(CONST_CAST(struct ovsdb_idl_row *, &row->header_),
1246 &%(s)s_columns[%(S)s_COL_%(C)s],
1247 datum,
1248 &%(p)stable_classes[%(P)sTABLE_%(T)s]);
1249}
1250""" % {'t': tableName,
1251 'p': prefix,
1252 'P': prefix.upper(),
1253 's': structName,
1254 'S': structName.upper(),
1255 'c': columnName,
1256 'C': columnName.upper(),
1257 't': tableName,
1258 'T': tableName.upper()})
1259 continue
1260
1261 keyVar = members[0]['name']
1262 nVar = None
1263 valueVar = None
1264 if type.value:
1265 valueVar = members[1]['name']
1266 if len(members) > 2:
1267 nVar = members[2]['name']
1268 else:
1269 if len(members) > 1:
1270 nVar = members[1]['name']
1271
1272 print(comment)
1273 print('void')
1274 print('%(s)s_index_set_%(c)s(const struct %(s)s *row, %(args)s)' % \
1275 {'s': structName, 'c': columnName,
1276 'args': ', '.join(['%(type)s%(name)s' % m for m in members])})
1277 print("{")
1278 print(" struct ovsdb_datum datum;")
1279 if type.n_min == 1 and type.n_max == 1:
1280 print(" union ovsdb_atom *key = xmalloc(sizeof(union ovsdb_atom));")
1281 if type.value:
1282 print(" union ovsdb_atom *value = xmalloc(sizeof(union ovsdb_atom));")
1283 print()
1284 print(" datum.n = 1;")
1285 print(" datum.keys = key;")
1286 print(" " + type.key.assign_c_value_casting_away_const("key->%s" % type.key.type.to_string(), keyVar))
1287 if type.value:
1288 print(" datum.values = value;")
1289 print(" "+ type.value.assign_c_value_casting_away_const("value->%s" % type.value.type.to_string(), valueVar))
1290 else:
1291 print(" datum.values = NULL;")
1292 txn_write_func = "ovsdb_idl_index_write_"
1293 elif type.is_optional_pointer():
1294 print(" union ovsdb_atom *key = xmalloc(sizeof (union ovsdb_atom));")
1295 print()
1296 print(" if (%s) {" % keyVar)
1297 print(" datum.n = 1;")
1298 print(" datum.keys = key;")
1299 print(" " + type.key.assign_c_value_casting_away_const("key->%s" % type.key.type.to_string(), keyVar))
1300 print(" } else {")
1301 print(" datum.n = 0;")
1302 print(" datum.keys = NULL;")
1303 print(" }")
1304 print(" datum.values = NULL;")
1305 txn_write_func = "ovsdb_idl_index_write_"
1306 elif type.n_max == 1:
1307 print(" union ovsdb_atom *key = xmalloc(sizeof(union ovsdb_atom));")
1308 print()
1309 print(" if (%s) {" % nVar)
1310 print(" datum.n = 1;")
1311 print(" datum.keys = key;")
1312 print(" " + type.key.assign_c_value_casting_away_const("key->%s" % type.key.type.to_string(), "*" + keyVar))
1313 print(" } else {")
1314 print(" datum.n = 0;")
1315 print(" datum.keys = NULL;")
1316 print(" }")
1317 print(" datum.values = NULL;")
1318 txn_write_func = "ovsdb_idl_index_write_"
1319 else:
1320 print(" size_t i;")
1321 print()
1322 print(" datum.n = %s;" % nVar)
1323 print(" datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar))
1324 if type.value:
1325 print(" datum.values = xmalloc(%s * sizeof *datum.values);" % nVar)
1326 else:
1327 print(" datum.values = NULL;")
1328 print(" for (i = 0; i < %s; i++) {" % nVar)
1329 print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar))
1330 if type.value:
1331 print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar))
1332 print(" }")
1333 if type.value:
1334 valueType = type.value.toAtomicType()
1335 else:
1336 valueType = "OVSDB_TYPE_VOID"
1337 print(" ovsdb_datum_sort_unique(&datum, %s, %s);" % (
1338 type.key.toAtomicType(), valueType))
1339 txn_write_func = "ovsdb_idl_index_write_"
1340 print(" %(f)s(CONST_CAST(struct ovsdb_idl_row *, &row->header_), &%(s)s_columns[ %(S)s_COL_%(C)s ], &datum, &%(p)stable_classes[%(P)sTABLE_%(T)s]);" \
1341 % {'f': txn_write_func,
1342 's': structName,
1343 'S': structName.upper(),
1344 'C': columnName.upper(),
1345 'p': prefix,
1346 'P': prefix.upper(),
1347 't': tableName,
1348 'T': tableName.upper()})
1349 print("}")
1350# End Index table related functions
1351
1352 # Table columns.
1353 print("\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (
1354 structName, structName.upper()))
d34a1cc0 1355 print("""
1f2d2557 1356void
0164e367 1357%(s)s_set_condition(struct ovsdb_idl *idl, struct ovsdb_idl_condition *condition)
16ebb90e 1358{
0164e367
BP
1359 ovsdb_idl_set_condition(idl, &%(p)stable_%(tl)s, condition);
1360}""" % {'p': prefix,
1361 's': structName,
d34a1cc0 1362 'tl': tableName.lower()})
16ebb90e 1363
c3bb4bd7 1364 # Table columns.
74e98efd
BP
1365 for columnName, column in sorted_columns(table):
1366 prereqs = []
1367 x = column.type.cInitType("%s_col_%s" % (tableName, columnName), prereqs)
1368 if prereqs:
d34a1cc0
JW
1369 print('\n'.join(prereqs))
1370 print("\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS] = {" % (
1371 structName, structName.upper()))
e0b1744f 1372 for columnName, column in sorted_columns(table):
341c4e59
BP
1373 if column.mutable:
1374 mutable = "true"
1375 else:
1376 mutable = "false"
01928c96
BP
1377 if column.extensions.get("synthetic"):
1378 synthetic = "true"
1379 else:
1380 synthetic = "false"
74e98efd
BP
1381 type_init = '\n'.join(" " + x
1382 for x in column.type.cInitType("%s_col_%s" % (tableName, columnName), prereqs))
d34a1cc0 1383 print("""\
74e98efd 1384 [%(P)s%(T)s_COL_%(C)s] = {
adb4185d 1385 .name = "%(column_name_in_schema)s",
74e98efd
BP
1386 .type = {
1387%(type)s
1388 },
c6e5d064 1389 .is_mutable = %(mutable)s,
01928c96 1390 .is_synthetic = %(synthetic)s,
74e98efd
BP
1391 .parse = %(s)s_parse_%(c)s,
1392 .unparse = %(s)s_unparse_%(c)s,
1393 },\n""" % {'P': prefix.upper(),
1394 'T': tableName.upper(),
1395 'c': columnName,
1396 'C': columnName.upper(),
1397 's': structName,
1398 'mutable': mutable,
01928c96 1399 'synthetic': synthetic,
adb4185d
YHW
1400 'type': type_init,
1401 'column_name_in_schema': column.name})
d34a1cc0 1402 print("};")
c3bb4bd7
BP
1403
1404 # Table classes.
d34a1cc0
JW
1405 print("\f")
1406 print("struct ovsdb_idl_table_class %stable_classes[%sN_TABLES] = {" % (prefix, prefix.upper()))
4ab66562 1407 for tableName, table in sorted(schema.tables.items()):
c3bb4bd7 1408 structName = "%s%s" % (prefix, tableName.lower())
c5f341ab
BP
1409 if table.is_root:
1410 is_root = "true"
1411 else:
1412 is_root = "false"
25540a77
BP
1413 if table.max_rows == 1:
1414 is_singleton = "true"
1415 else:
1416 is_singleton = "false"
1417 print(" {\"%s\", %s, %s," % (tableName, is_root, is_singleton))
d34a1cc0 1418 print(" %s_columns, ARRAY_SIZE(%s_columns)," % (
25540a77 1419 structName, structName))
d34a1cc0
JW
1420 print(" sizeof(struct %s), %s_init__}," % (structName, structName))
1421 print("};")
c3bb4bd7
BP
1422
1423 # IDL class.
d34a1cc0
JW
1424 print("\nstruct ovsdb_idl_class %sidl_class = {" % prefix)
1425 print(" \"%s\", %stable_classes, ARRAY_SIZE(%stable_classes)" % (
1426 schema.name, prefix, prefix))
1427 print("};")
d879a707 1428
d34a1cc0 1429 print("""
87412f02
JP
1430/* Return the schema version. The caller must not free the returned value. */
1431const char *
1432%sget_db_version(void)
1433{
1434 return "%s";
1435}
d34a1cc0 1436""" % (prefix, schema.version))
87412f02
JP
1437
1438
8cdf0349 1439
d879a707
BP
1440def ovsdb_escape(string):
1441 def escape(match):
1442 c = match.group(0)
1443 if c == '\0':
99155935 1444 raise ovs.db.error.Error("strings may not contain null bytes")
d879a707
BP
1445 elif c == '\\':
1446 return '\\\\'
1447 elif c == '\n':
1448 return '\\n'
1449 elif c == '\r':
1450 return '\\r'
1451 elif c == '\t':
1452 return '\\t'
1453 elif c == '\b':
1454 return '\\b'
1455 elif c == '\a':
1456 return '\\a'
1457 else:
1458 return '\\x%02x' % ord(c)
1459 return re.sub(r'["\\\000-\037]', escape, string)
1460
d879a707 1461def usage():
d34a1cc0 1462 print("""\
d879a707 1463%(argv0)s: ovsdb schema compiler
00732bf5 1464usage: %(argv0)s [OPTIONS] COMMAND ARG...
d879a707 1465
00732bf5
BP
1466The following commands are supported:
1467 annotate SCHEMA ANNOTATIONS print SCHEMA combined with ANNOTATIONS
1468 c-idl-header IDL print C header file for IDL
1469 c-idl-source IDL print C source file for IDL implementation
d879a707
BP
1470
1471The following options are also available:
1472 -h, --help display this help message
1473 -V, --version display version information\
d34a1cc0 1474""" % {'argv0': argv0})
d879a707
BP
1475 sys.exit(0)
1476
1477if __name__ == "__main__":
1478 try:
1479 try:
00732bf5
BP
1480 options, args = getopt.gnu_getopt(sys.argv[1:], 'C:hV',
1481 ['directory',
1482 'help',
d879a707 1483 'version'])
52e4a477 1484 except getopt.GetoptError as geo:
d879a707
BP
1485 sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
1486 sys.exit(1)
c5c7c7c5 1487
00732bf5
BP
1488 for key, value in options:
1489 if key in ['-h', '--help']:
1490 usage()
1491 elif key in ['-V', '--version']:
d34a1cc0 1492 print("ovsdb-idlc (Open vSwitch) @VERSION@")
00732bf5
BP
1493 elif key in ['-C', '--directory']:
1494 os.chdir(value)
1495 else:
1496 sys.exit(0)
c5c7c7c5 1497
d879a707 1498 optKeys = [key for key, value in options]
00732bf5
BP
1499
1500 if not args:
1501 sys.stderr.write("%s: missing command argument "
1502 "(use --help for help)\n" % argv0)
d879a707
BP
1503 sys.exit(1)
1504
00732bf5
BP
1505 commands = {"annotate": (annotateSchema, 2),
1506 "c-idl-header": (printCIDLHeader, 1),
2c84fdf2 1507 "c-idl-source": (printCIDLSource, 1)}
00732bf5
BP
1508
1509 if not args[0] in commands:
1510 sys.stderr.write("%s: unknown command \"%s\" "
1511 "(use --help for help)\n" % (argv0, args[0]))
d879a707 1512 sys.exit(1)
00732bf5
BP
1513
1514 func, n_args = commands[args[0]]
1515 if len(args) - 1 != n_args:
1516 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
1517 "provided\n"
1518 % (argv0, args[0], n_args, len(args) - 1))
1519 sys.exit(1)
1520
1521 func(*args[1:])
52e4a477 1522 except ovs.db.error.Error as e:
99155935 1523 sys.stderr.write("%s: %s\n" % (argv0, e))
d879a707
BP
1524 sys.exit(1)
1525
1526# Local variables:
1527# mode: python
1528# End: