]> git.proxmox.com Git - mirror_ovs.git/blame - ovsdb/ovsdb-idlc.in
Python3 compatibility: exception cleanup
[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
d879a707 12
89365653 13argv0 = sys.argv[0]
45a7de56 14
d879a707 15def parseSchema(filename):
99155935 16 return ovs.db.schema.IdlSchema.from_json(ovs.json.from_file(filename))
00732bf5
BP
17
18def annotateSchema(schemaFile, annotationFile):
99155935 19 schemaJson = ovs.json.from_file(schemaFile)
00732bf5 20 execfile(annotationFile, globals(), {"s": schemaJson})
99155935 21 ovs.json.to_stream(schemaJson, sys.stdout)
292aefc4 22 sys.stdout.write('\n')
d879a707 23
02630ff2 24def constify(cType, const):
47058293
RB
25 if (const
26 and cType.endswith('*') and
27 (cType == 'char **' or not cType.endswith('**'))):
02630ff2
BP
28 return 'const %s' % cType
29 else:
30 return cType
31
4bb7f568 32def cMembers(prefix, tableName, columnName, column, const, refTable=True):
7cc398cb 33 comment = ""
475281c0 34 type = column.type
a699f614
EJ
35
36 if type.is_smap():
7cc398cb
JP
37 comment = """
38/* Sets the "%(c)s" column's value from the "%(t)s" table in 'row'
39 * to '%(c)s'.
40 *
41 * The caller retains ownership of '%(c)s' and everything in it. */""" \
42 % {'c': columnName,
43 't': tableName}
44 return (comment, [{'name': columnName,
45 'type': 'struct smap ',
46 'comment': ''}])
47
48 comment = """\n/* Sets the "%s" column from the "%s" table in """\
49 """'row' to\n""" % (columnName, tableName)
a699f614 50
99155935 51 if type.n_min == 1 and type.n_max == 1:
475281c0
BP
52 singleton = True
53 pointer = ''
54 else:
55 singleton = False
99155935 56 if type.is_optional_pointer():
475281c0
BP
57 pointer = ''
58 else:
59 pointer = '*'
60
7cc398cb 61
475281c0 62 if type.value:
7cc398cb
JP
63 keyName = "key_%s" % columnName
64 valueName = "value_%s" % columnName
65
66 key = {'name': keyName,
4bb7f568 67 'type': constify(type.key.toCType(prefix, refTable) + pointer, const),
475281c0 68 'comment': ''}
7cc398cb 69 value = {'name': valueName,
4bb7f568 70 'type': constify(type.value.toCType(prefix, refTable) + pointer, const),
475281c0 71 'comment': ''}
7cc398cb
JP
72
73 if singleton:
74 comment += " * the map with key '%s' and value '%s'\n *" \
75 % (keyName, valueName)
76 else:
77 comment += " * the map with keys '%s' and values '%s'\n *" \
78 % (keyName, valueName)
475281c0
BP
79 members = [key, value]
80 else:
81 m = {'name': columnName,
4bb7f568 82 'type': constify(type.key.toCType(prefix, refTable) + pointer, const),
bd76d25d 83 'comment': type.cDeclComment()}
7cc398cb
JP
84
85 if singleton:
86 comment += " * '%s'" % columnName
87 else:
88 comment += " * the '%s' set" % columnName
475281c0
BP
89 members = [m]
90
99155935 91 if not singleton and not type.is_optional_pointer():
7cc398cb
JP
92 sizeName = "n_%s" % columnName
93
94 comment += " with '%s' entries" % sizeName
95 members.append({'name': sizeName,
475281c0
BP
96 'type': 'size_t ',
97 'comment': ''})
7cc398cb
JP
98
99 comment += ".\n"
100
101 if type.is_optional() and not type.is_optional_pointer():
102 comment += """ *
103 * '%s' may be 0 or 1; if it is 0, then '%s'
104 * may be NULL.\n""" \
105 % ("n_%s" % columnName, columnName)
106
107 if type.is_optional_pointer():
108 comment += """ *
109 * If "%s" is null, the column will be the empty set,
110 * otherwise it will contain the specified value.\n""" % columnName
111
112 if type.constraintsToEnglish():
113 comment += """ *
114 * Argument constraints: %s\n""" \
115 % type.constraintsToEnglish(lambda s : '"%s"' % s)
116
117 comment += " *\n * The caller retains ownership of the arguments. */"
118
119 return (comment, members)
475281c0 120
e0b1744f
BP
121def sorted_columns(table):
122 return sorted(table.columns.items())
123
00732bf5
BP
124def printCIDLHeader(schemaFile):
125 schema = parseSchema(schemaFile)
c3bb4bd7 126 prefix = schema.idlPrefix
d34a1cc0 127 print('''\
d879a707
BP
128/* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
129
130#ifndef %(prefix)sIDL_HEADER
131#define %(prefix)sIDL_HEADER 1
132
133#include <stdbool.h>
134#include <stddef.h>
135#include <stdint.h>
a6ec9089 136#include "ovsdb-data.h"
c3bb4bd7 137#include "ovsdb-idl-provider.h"
a699f614 138#include "smap.h"
d34a1cc0 139#include "uuid.h"''' % {'prefix': prefix.upper()})
979821c0 140
bd76d25d 141 for tableName, table in sorted(schema.tables.iteritems()):
c3bb4bd7 142 structName = "%s%s" % (prefix, tableName.lower())
979821c0 143
d34a1cc0
JW
144 print("\f")
145 print("/* %s table. */" % tableName)
146 print("struct %s {" % structName)
147 print("\tstruct ovsdb_idl_row header_;")
e0b1744f 148 for columnName, column in sorted_columns(table):
d34a1cc0 149 print("\n\t/* %s column. */" % columnName)
7cc398cb
JP
150 comment, members = cMembers(prefix, tableName,
151 columnName, column, False)
152 for member in members:
d34a1cc0
JW
153 print("\t%(type)s%(name)s;%(comment)s" % member)
154 print("};")
c3bb4bd7 155
979821c0 156 # Column indexes.
32d37ce8 157 printEnum("%s_column_id" % structName.lower(), ["%s_COL_%s" % (structName.upper(), columnName.upper())
e0b1744f 158 for columnName, column in sorted_columns(table)]
979821c0
BP
159 + ["%s_N_COLUMNS" % structName.upper()])
160
d34a1cc0 161 print("")
979821c0 162 for columnName in table.columns:
d34a1cc0 163 print("#define %(s)s_col_%(c)s (%(s)s_columns[%(S)s_COL_%(C)s])" % {
979821c0
BP
164 's': structName,
165 'S': structName.upper(),
166 'c': columnName,
d34a1cc0 167 'C': columnName.upper()})
979821c0 168
d34a1cc0 169 print("\nextern struct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (structName, structName.upper()))
979821c0 170
d34a1cc0 171 print('''
8c6cf7b8 172const struct %(s)s *%(s)s_get_for_uuid(const struct ovsdb_idl *, const struct uuid *);
c3bb4bd7
BP
173const struct %(s)s *%(s)s_first(const struct ovsdb_idl *);
174const struct %(s)s *%(s)s_next(const struct %(s)s *);
58bc1a52
BP
175#define %(S)s_FOR_EACH(ROW, IDL) \\
176 for ((ROW) = %(s)s_first(IDL); \\
177 (ROW); \\
178 (ROW) = %(s)s_next(ROW))
179#define %(S)s_FOR_EACH_SAFE(ROW, NEXT, IDL) \\
180 for ((ROW) = %(s)s_first(IDL); \\
181 (ROW) ? ((NEXT) = %(s)s_next(ROW), 1) : 0; \\
182 (ROW) = (NEXT))
475281c0 183
932104f4
SA
184unsigned int %(s)s_get_seqno(const struct ovsdb_idl *);
185unsigned int %(s)s_row_get_seqno(const struct %(s)s *row, enum ovsdb_idl_change change);
186const struct %(s)s *%(s)s_track_get_first(const struct ovsdb_idl *);
187const struct %(s)s *%(s)s_track_get_next(const struct %(s)s *);
188#define %(S)s_FOR_EACH_TRACKED(ROW, IDL) \\
189 for ((ROW) = %(s)s_track_get_first(IDL); \\
190 (ROW); \\
191 (ROW) = %(s)s_track_get_next(ROW))
192
9a33cd70
BP
193/* Returns true if 'row' was inserted since the last change tracking reset. */
194static inline bool %(s)s_is_new(const struct %(s)s *row)
195{
196 return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_MODIFY) == 0;
197}
198
199/* Returns true if 'row' was deleted since the last change tracking reset. */
200static inline bool %(s)s_is_deleted(const struct %(s)s *row)
201{
202 return %(s)s_row_get_seqno(row, OVSDB_IDL_CHANGE_DELETE) > 0;
203}
204
a699f614 205void %(s)s_init(struct %(s)s *);
475281c0
BP
206void %(s)s_delete(const struct %(s)s *);
207struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *);
32d37ce8 208bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id);
d34a1cc0 209''' % {'s': structName, 'S': structName.upper()})
475281c0 210
e0b1744f 211 for columnName, column in sorted_columns(table):
d34a1cc0 212 print('void %(s)s_verify_%(c)s(const struct %(s)s *);' % {'s': structName, 'c': columnName})
475281c0 213
d34a1cc0 214 print("")
e0b1744f 215 for columnName, column in sorted_columns(table):
a6ec9089
BP
216 if column.type.value:
217 valueParam = ', enum ovsdb_atomic_type value_type'
218 else:
219 valueParam = ''
d34a1cc0
JW
220 print('const struct ovsdb_datum *%(s)s_get_%(c)s(const struct %(s)s *, enum ovsdb_atomic_type key_type%(v)s);' % {
221 's': structName, 'c': columnName, 'v': valueParam})
a6ec9089 222
d34a1cc0 223 print("")
e0b1744f 224 for columnName, column in sorted_columns(table):
d34a1cc0 225 print('void %(s)s_set_%(c)s(const struct %(s)s *,' % {'s': structName, 'c': columnName}, end=' ')
a699f614
EJ
226 if column.type.is_smap():
227 args = ['const struct smap *']
228 else:
7cc398cb
JP
229 comment, members = cMembers(prefix, tableName, columnName,
230 column, True)
231 args = ['%(type)s%(name)s' % member for member in members]
d34a1cc0 232 print('%s);' % ', '.join(args))
475281c0 233
d34a1cc0 234 print("")
e0b1744f 235 for columnName, column in sorted_columns(table):
16ebb90e 236 if column.type.is_map():
d34a1cc0
JW
237 print('void %(s)s_update_%(c)s_setkey(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
238 print('%(coltype)s, %(valtype)s);' % {'coltype':column.type.key.to_const_c_type(prefix), 'valtype':column.type.value.to_const_c_type(prefix)})
239 print('void %(s)s_update_%(c)s_delkey(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
240 print('%(coltype)s);' % {'coltype':column.type.key.to_const_c_type(prefix)})
f1ab6e06 241 if column.type.is_set():
d34a1cc0
JW
242 print('void %(s)s_update_%(c)s_addvalue(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
243 print('%(valtype)s);' % {'valtype':column.type.key.to_const_c_type(prefix)})
244 print('void %(s)s_update_%(c)s_delvalue(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ')
245 print('%(valtype)s);' % {'valtype':column.type.key.to_const_c_type(prefix)})
16ebb90e 246
d34a1cc0 247 print('void %(s)s_add_clause_%(c)s(struct ovsdb_idl_condition *, enum ovsdb_function function,' % {'s': structName, 'c': columnName}, end=' ')
16ebb90e
LS
248 if column.type.is_smap():
249 args = ['const struct smap *']
250 else:
251 comment, members = cMembers(prefix, tableName, columnName,
4bb7f568 252 column, True, refTable=False)
16ebb90e 253 args = ['%(type)s%(name)s' % member for member in members]
d34a1cc0 254 print('%s);' % ', '.join(args))
16ebb90e 255
d34a1cc0 256 print('void %(s)s_set_condition(struct ovsdb_idl *, struct ovsdb_idl_condition *);' % {'s': structName})
16ebb90e 257
d34a1cc0 258 print("")
f67f1354 259
979821c0 260 # Table indexes.
32d37ce8 261 printEnum("%stable_id" % prefix.lower(), ["%sTABLE_%s" % (prefix.upper(), tableName.upper()) for tableName in sorted(schema.tables)] + ["%sN_TABLES" % prefix.upper()])
d34a1cc0 262 print("")
979821c0 263 for tableName in schema.tables:
d34a1cc0 264 print("#define %(p)stable_%(t)s (%(p)stable_classes[%(P)sTABLE_%(T)s])" % {
979821c0
BP
265 'p': prefix,
266 'P': prefix.upper(),
267 't': tableName.lower(),
d34a1cc0
JW
268 'T': tableName.upper()})
269 print("\nextern struct ovsdb_idl_table_class %stable_classes[%sN_TABLES];" % (prefix, prefix.upper()))
979821c0 270
d34a1cc0 271 print("\nextern struct ovsdb_idl_class %sidl_class;" % prefix)
87412f02 272
d34a1cc0
JW
273 print("\nconst char * %sget_db_version(void);" % prefix)
274 print("\n#endif /* %(prefix)sIDL_HEADER */" % {'prefix': prefix.upper()})
c3bb4bd7 275
32d37ce8 276def printEnum(type, members):
c3bb4bd7
BP
277 if len(members) == 0:
278 return
279
d34a1cc0 280 print("\nenum %s {" % type)
c3bb4bd7 281 for member in members[:-1]:
d34a1cc0
JW
282 print(" %s," % member)
283 print(" %s" % members[-1])
284 print("};")
c3bb4bd7 285
00732bf5
BP
286def printCIDLSource(schemaFile):
287 schema = parseSchema(schemaFile)
c3bb4bd7 288 prefix = schema.idlPrefix
d34a1cc0 289 print('''\
c3bb4bd7
BP
290/* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
291
292#include <config.h>
293#include %s
294#include <limits.h>
558103f0 295#include "ovs-thread.h"
bd76d25d
BP
296#include "ovsdb-data.h"
297#include "ovsdb-error.h"
cb22974d 298#include "util.h"
bd76d25d 299
d34a1cc0 300''' % schema.idlHeader)
c3bb4bd7 301
66095e15 302 # Cast functions.
bd76d25d 303 for tableName, table in sorted(schema.tables.iteritems()):
66095e15 304 structName = "%s%s" % (prefix, tableName.lower())
d34a1cc0 305 print('''
66095e15 306static struct %(s)s *
979821c0 307%(s)s_cast(const struct ovsdb_idl_row *row)
66095e15
BP
308{
309 return row ? CONTAINER_OF(row, struct %(s)s, header_) : NULL;
310}\
d34a1cc0 311''' % {'s': structName})
66095e15
BP
312
313
bd76d25d 314 for tableName, table in sorted(schema.tables.iteritems()):
c3bb4bd7 315 structName = "%s%s" % (prefix, tableName.lower())
d34a1cc0
JW
316 print("\f")
317 print("/* %s table. */" % (tableName))
c3bb4bd7 318
979821c0 319 # Parse functions.
e0b1744f 320 for columnName, column in sorted_columns(table):
d34a1cc0 321 print('''
c3bb4bd7 322static void
979821c0 323%(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum)
c3bb4bd7 324{
979821c0 325 struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName,
d34a1cc0 326 'c': columnName})
c3bb4bd7 327 type = column.type
c3bb4bd7
BP
328 if type.value:
329 keyVar = "row->key_%s" % columnName
330 valueVar = "row->value_%s" % columnName
331 else:
332 keyVar = "row->%s" % columnName
333 valueVar = None
334
a699f614 335 if type.is_smap():
d34a1cc0
JW
336 print(" smap_init(&row->%s);" % columnName)
337 print(" for (size_t i = 0; i < datum->n; i++) {")
338 print(" smap_add(&row->%s," % columnName)
339 print(" datum->keys[i].string,")
340 print(" datum->values[i].string);")
341 print(" }")
a699f614 342 elif (type.n_min == 1 and type.n_max == 1) or type.is_optional_pointer():
d34a1cc0
JW
343 print("")
344 print(" if (datum->n >= 1) {")
99155935 345 if not type.key.ref_table:
d34a1cc0 346 print(" %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_string()))
c3bb4bd7 347 else:
d34a1cc0 348 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
349
350 if valueVar:
ae661470 351 if not type.value.ref_table:
d34a1cc0 352 print(" %s = datum->values[0].%s;" % (valueVar, type.value.type.to_string()))
c3bb4bd7 353 else:
d34a1cc0
JW
354 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()))
355 print(" } else {")
356 print(" %s" % type.key.initCDefault(keyVar, type.n_min == 0))
979821c0 357 if valueVar:
d34a1cc0
JW
358 print(" %s" % type.value.initCDefault(valueVar, type.n_min == 0))
359 print(" }")
c3bb4bd7 360 else:
99155935 361 if type.n_max != sys.maxint:
d34a1cc0 362 print(" size_t n = MIN(%d, datum->n);" % type.n_max)
979821c0 363 nMax = "n"
c3bb4bd7
BP
364 else:
365 nMax = "datum->n"
d34a1cc0 366 print(" %s = NULL;" % keyVar)
979821c0 367 if valueVar:
d34a1cc0
JW
368 print(" %s = NULL;" % valueVar)
369 print(" row->n_%s = 0;" % columnName)
370 print(" for (size_t i = 0; i < %s; i++) {" % nMax)
99155935 371 if type.key.ref_table:
d34a1cc0 372 print("""\
9478f52f 373 struct %s%s *keyRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->keys[i].uuid));
cff5afcf
BP
374 if (!keyRow) {
375 continue;
376 }\
d34a1cc0 377""" % (prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower(), prefix, type.key.ref_table.name.lower()))
c3bb4bd7 378 keySrc = "keyRow"
c3bb4bd7 379 else:
99155935
BP
380 keySrc = "datum->keys[i].%s" % type.key.type.to_string()
381 if type.value and type.value.ref_table:
d34a1cc0 382 print("""\
9478f52f 383 struct %s%s *valueRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_%s, &datum->values[i].uuid));
cff5afcf
BP
384 if (!valueRow) {
385 continue;
386 }\
d34a1cc0 387""" % (prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower(), prefix, type.value.ref_table.name.lower()))
c3bb4bd7 388 valueSrc = "valueRow"
c3bb4bd7 389 elif valueVar:
99155935 390 valueSrc = "datum->values[i].%s" % type.value.type.to_string()
d34a1cc0 391 print(" if (!row->n_%s) {" % (columnName))
1bf2c909 392
d34a1cc0
JW
393 print(" %s = xmalloc(%s * sizeof *%s);" % (
394 keyVar, nMax, keyVar))
c3bb4bd7 395 if valueVar:
d34a1cc0
JW
396 print(" %s = xmalloc(%s * sizeof *%s);" % (
397 valueVar, nMax, valueVar))
398 print(" }")
399 print(" %s[row->n_%s] = %s;" % (keyVar, columnName, keySrc))
c3bb4bd7 400 if valueVar:
d34a1cc0
JW
401 print(" %s[row->n_%s] = %s;" % (valueVar, columnName, valueSrc))
402 print(" row->n_%s++;" % columnName)
403 print(" }")
404 print("}")
c3bb4bd7 405
979821c0 406 # Unparse functions.
e0b1744f 407 for columnName, column in sorted_columns(table):
c3bb4bd7 408 type = column.type
a699f614 409 if type.is_smap() or (type.n_min != 1 or type.n_max != 1) and not type.is_optional_pointer():
d34a1cc0 410 print('''
c3bb4bd7 411static void
979821c0 412%(s)s_unparse_%(c)s(struct ovsdb_idl_row *row_)
c3bb4bd7 413{
74e98efd 414 struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName,
d34a1cc0 415 'c': columnName})
a699f614
EJ
416
417 if type.is_smap():
d34a1cc0 418 print(" smap_destroy(&row->%s);" % columnName)
c3bb4bd7 419 else:
a699f614
EJ
420 if type.value:
421 keyVar = "row->key_%s" % columnName
422 valueVar = "row->value_%s" % columnName
423 else:
424 keyVar = "row->%s" % columnName
425 valueVar = None
d34a1cc0 426 print(" free(%s);" % keyVar)
a699f614 427 if valueVar:
d34a1cc0
JW
428 print(" free(%s);" % valueVar)
429 print('}')
979821c0 430 else:
d34a1cc0 431 print('''
c3bb4bd7 432static void
c69ee87c 433%(s)s_unparse_%(c)s(struct ovsdb_idl_row *row OVS_UNUSED)
979821c0
BP
434{
435 /* Nothing to do. */
d34a1cc0 436}''' % {'s': structName, 'c': columnName})
c5c7c7c5 437
a699f614 438 # Generic Row Initialization function.
d34a1cc0 439 print("""
a699f614
EJ
440static void
441%(s)s_init__(struct ovsdb_idl_row *row)
442{
443 %(s)s_init(%(s)s_cast(row));
d34a1cc0 444}""" % {'s': structName})
a699f614
EJ
445
446 # Row Initialization function.
d34a1cc0 447 print("""
d797877d 448/* Clears the contents of 'row' in table "%(t)s". */
a699f614
EJ
449void
450%(s)s_init(struct %(s)s *row)
451{
d34a1cc0 452 memset(row, 0, sizeof *row); """ % {'s': structName, 't': tableName})
e0b1744f 453 for columnName, column in sorted_columns(table):
a699f614 454 if column.type.is_smap():
d34a1cc0 455 print(" smap_init(&row->%s);" % columnName)
5a98d741
BP
456 elif (column.type.n_min == 1 and
457 column.type.n_max == 1 and
458 column.type.key.type == ovs.db.types.StringType and
459 not column.type.value):
d34a1cc0
JW
460 print(" row->%s = \"\";" % columnName)
461 print("}")
a699f614 462
c3bb4bd7 463 # First, next functions.
d34a1cc0 464 print('''
d797877d
JP
465/* Searches table "%(t)s" in 'idl' for a row with UUID 'uuid'. Returns
466 * a pointer to the row if there is one, otherwise a null pointer. */
8c6cf7b8
BP
467const struct %(s)s *
468%(s)s_get_for_uuid(const struct ovsdb_idl *idl, const struct uuid *uuid)
469{
9478f52f 470 return %(s)s_cast(ovsdb_idl_get_row_for_uuid(idl, &%(p)stable_%(tl)s, uuid));
8c6cf7b8
BP
471}
472
d797877d
JP
473/* Returns a row in table "%(t)s" in 'idl', or a null pointer if that
474 * table is empty.
475 *
476 * Database tables are internally maintained as hash tables, so adding or
477 * removing rows while traversing the same table can cause some rows to be
478 * visited twice or not at apply. */
66095e15
BP
479const struct %(s)s *
480%(s)s_first(const struct ovsdb_idl *idl)
c3bb4bd7 481{
9478f52f 482 return %(s)s_cast(ovsdb_idl_first_row(idl, &%(p)stable_%(tl)s));
c3bb4bd7
BP
483}
484
d797877d
JP
485/* Returns a row following 'row' within its table, or a null pointer if 'row'
486 * is the last row in its table. */
66095e15
BP
487const struct %(s)s *
488%(s)s_next(const struct %(s)s *row)
c3bb4bd7 489{
66095e15 490 return %(s)s_cast(ovsdb_idl_next_row(&row->header_));
932104f4
SA
491}
492
493unsigned int %(s)s_get_seqno(const struct ovsdb_idl *idl)
494{
9478f52f 495 return ovsdb_idl_table_get_seqno(idl, &%(p)stable_%(tl)s);
932104f4
SA
496}
497
498unsigned int %(s)s_row_get_seqno(const struct %(s)s *row, enum ovsdb_idl_change change)
499{
500 return ovsdb_idl_row_get_seqno(&row->header_, change);
501}
502
503const struct %(s)s *
504%(s)s_track_get_first(const struct ovsdb_idl *idl)
505{
9478f52f 506 return %(s)s_cast(ovsdb_idl_track_get_first(idl, &%(p)stable_%(tl)s));
932104f4
SA
507}
508
509const struct %(s)s
510*%(s)s_track_get_next(const struct %(s)s *row)
511{
512 return %(s)s_cast(ovsdb_idl_track_get_next(&row->header_));
475281c0
BP
513}''' % {'s': structName,
514 'p': prefix,
515 'P': prefix.upper(),
d797877d 516 't': tableName,
9478f52f 517 'tl': tableName.lower(),
d34a1cc0 518 'T': tableName.upper()})
475281c0 519
d34a1cc0 520 print('''
932104f4 521
d797877d
JP
522/* Deletes 'row' from table "%(t)s". 'row' may be freed, so it must not be
523 * accessed afterward.
524 *
525 * The caller must have started a transaction with ovsdb_idl_txn_create(). */
475281c0 526void
9e336f49 527%(s)s_delete(const struct %(s)s *row)
475281c0 528{
475281c0
BP
529 ovsdb_idl_txn_delete(&row->header_);
530}
531
d797877d
JP
532/* Inserts and returns a new row in the table "%(t)s" in the database
533 * with open transaction 'txn'.
534 *
535 * The new row is assigned a randomly generated provisional UUID.
536 * ovsdb-server will assign a different UUID when 'txn' is committed,
537 * but the IDL will replace any uses of the provisional UUID in the
538 * data to be to be committed by the UUID assigned by ovsdb-server. */
475281c0
BP
539struct %(s)s *
540%(s)s_insert(struct ovsdb_idl_txn *txn)
541{
9478f52f 542 return %(s)s_cast(ovsdb_idl_txn_insert(txn, &%(p)stable_%(tl)s, NULL));
32d37ce8
SA
543}
544
545bool
546%(s)s_is_updated(const struct %(s)s *row, enum %(s)s_column_id column)
547{
548 return ovsdb_idl_track_is_updated(&row->header_, &%(s)s_columns[column]);
d797877d
JP
549}''' % {'s': structName,
550 'p': prefix,
551 'P': prefix.upper(),
552 't': tableName,
9478f52f 553 'tl': tableName.lower(),
d34a1cc0 554 'T': tableName.upper()})
475281c0
BP
555
556 # Verify functions.
e0b1744f 557 for columnName, column in sorted_columns(table):
d34a1cc0 558 print('''
d797877d
JP
559/* Causes the original contents of column "%(c)s" in 'row' to be
560 * verified as a prerequisite to completing the transaction. That is, if
561 * "%(c)s" in 'row' changed (or if 'row' was deleted) between the
562 * time that the IDL originally read its contents and the time that the
b17c8228 563 * transaction aborts and ovsdb_idl_txn_commit() returns TXN_TRY_AGAIN.
d797877d
JP
564 *
565 * The intention is that, to ensure that no transaction commits based on dirty
566 * reads, an application should call this function any time "%(c)s" is
567 * read as part of a read-modify-write operation.
568 *
569 * In some cases this function reduces to a no-op, because the current value
570 * of "%(c)s" is already known:
571 *
572 * - If 'row' is a row created by the current transaction (returned by
573 * %(s)s_insert()).
574 *
575 * - If "%(c)s" has already been modified (with
576 * %(s)s_set_%(c)s()) within the current transaction.
577 *
578 * Because of the latter property, always call this function *before*
579 * %(s)s_set_%(c)s() for a given read-modify-write.
580 *
581 * The caller must have started a transaction with ovsdb_idl_txn_create(). */
475281c0
BP
582void
583%(s)s_verify_%(c)s(const struct %(s)s *row)
584{
1f2d2557 585 ovsdb_idl_txn_verify(&row->header_, &%(s)s_col_%(c)s);
475281c0
BP
586}''' % {'s': structName,
587 'S': structName.upper(),
588 'c': columnName,
d34a1cc0 589 'C': columnName.upper()})
475281c0 590
a6ec9089 591 # Get functions.
e0b1744f 592 for columnName, column in sorted_columns(table):
a6ec9089
BP
593 if column.type.value:
594 valueParam = ',\n\tenum ovsdb_atomic_type value_type OVS_UNUSED'
cb22974d 595 valueType = '\n ovs_assert(value_type == %s);' % column.type.value.toAtomicType()
a6ec9089
BP
596 valueComment = "\n * 'value_type' must be %s." % column.type.value.toAtomicType()
597 else:
598 valueParam = ''
599 valueType = ''
600 valueComment = ''
d34a1cc0 601 print("""
d797877d
JP
602/* Returns the "%(c)s" column's value from the "%(t)s" table in 'row'
603 * as a struct ovsdb_datum. This is useful occasionally: for example,
604 * ovsdb_datum_find_key() is an easier and more efficient way to search
605 * for a given key than implementing the same operation on the "cooked"
606 * form in 'row'.
a6ec9089
BP
607 *
608 * 'key_type' must be %(kt)s.%(vc)s
609 * (This helps to avoid silent bugs if someone changes %(c)s's
610 * type without updating the caller.)
611 *
612 * The caller must not modify or free the returned value.
613 *
614 * Various kinds of changes can invalidate the returned value: modifying
615 * 'column' within 'row', deleting 'row', or completing an ongoing transaction.
616 * If the returned value is needed for a long time, it is best to make a copy
d797877d
JP
617 * of it with ovsdb_datum_clone().
618 *
619 * This function is rarely useful, since it is easier to access the value
620 * directly through the "%(c)s" member in %(s)s. */
a6ec9089
BP
621const struct ovsdb_datum *
622%(s)s_get_%(c)s(const struct %(s)s *row,
623\tenum ovsdb_atomic_type key_type OVS_UNUSED%(v)s)
624{
cb22974d 625 ovs_assert(key_type == %(kt)s);%(vt)s
a6ec9089 626 return ovsdb_idl_read(&row->header_, &%(s)s_col_%(c)s);
d797877d 627}""" % {'t': tableName, 's': structName, 'c': columnName,
a6ec9089 628 'kt': column.type.key.toAtomicType(),
d34a1cc0 629 'v': valueParam, 'vt': valueType, 'vc': valueComment})
a6ec9089 630
475281c0 631 # Set functions.
e0b1744f 632 for columnName, column in sorted_columns(table):
475281c0 633 type = column.type
a699f614 634
7cc398cb
JP
635 comment, members = cMembers(prefix, tableName, columnName,
636 column, True)
637
a699f614 638 if type.is_smap():
d34a1cc0
JW
639 print(comment)
640 print("""void
4946b41d 641%(s)s_set_%(c)s(const struct %(s)s *row, const struct smap *%(c)s)
a699f614
EJ
642{
643 struct ovsdb_datum datum;
644
4946b41d 645 if (%(c)s) {
9b03e59d 646 ovsdb_datum_from_smap(&datum, %(c)s);
a699f614
EJ
647 } else {
648 ovsdb_datum_init_empty(&datum);
649 }
650 ovsdb_idl_txn_write(&row->header_,
1f2d2557 651 &%(s)s_col_%(c)s,
a699f614
EJ
652 &datum);
653}
7cc398cb
JP
654""" % {'t': tableName,
655 's': structName,
a699f614
EJ
656 'S': structName.upper(),
657 'c': columnName,
d34a1cc0 658 'C': columnName.upper()})
a699f614
EJ
659 continue
660
475281c0
BP
661 keyVar = members[0]['name']
662 nVar = None
663 valueVar = None
664 if type.value:
665 valueVar = members[1]['name']
666 if len(members) > 2:
667 nVar = members[2]['name']
668 else:
669 if len(members) > 1:
670 nVar = members[1]['name']
7cc398cb 671
d34a1cc0
JW
672 print(comment)
673 print("""\
cad9a996
BP
674void
675%(s)s_set_%(c)s(const struct %(s)s *row, %(args)s)
676{
cad9a996 677 struct ovsdb_datum datum;""" % {'s': structName,
74e98efd
BP
678 'c': columnName,
679 'args': ', '.join(['%(type)s%(name)s'
d34a1cc0 680 % m for m in members])})
99155935 681 if type.n_min == 1 and type.n_max == 1:
d34a1cc0 682 print(" union ovsdb_atom key;")
fe19569a 683 if type.value:
d34a1cc0
JW
684 print(" union ovsdb_atom value;")
685 print("")
686 print(" datum.n = 1;")
687 print(" datum.keys = &key;")
688 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar))
475281c0 689 if type.value:
d34a1cc0
JW
690 print(" datum.values = &value;")
691 print(" "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar))
475281c0 692 else:
d34a1cc0 693 print(" datum.values = NULL;")
fe19569a 694 txn_write_func = "ovsdb_idl_txn_write_clone"
99155935 695 elif type.is_optional_pointer():
d34a1cc0
JW
696 print(" union ovsdb_atom key;")
697 print("")
698 print(" if (%s) {" % keyVar)
699 print(" datum.n = 1;")
700 print(" datum.keys = &key;")
701 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar))
702 print(" } else {")
703 print(" datum.n = 0;")
704 print(" datum.keys = NULL;")
705 print(" }")
706 print(" datum.values = NULL;")
fe19569a
BP
707 txn_write_func = "ovsdb_idl_txn_write_clone"
708 elif type.n_max == 1:
d34a1cc0
JW
709 print(" union ovsdb_atom key;")
710 print("")
711 print(" if (%s) {" % nVar)
712 print(" datum.n = 1;")
713 print(" datum.keys = &key;")
714 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar))
715 print(" } else {")
716 print(" datum.n = 0;")
717 print(" datum.keys = NULL;")
718 print(" }")
719 print(" datum.values = NULL;")
fe19569a 720 txn_write_func = "ovsdb_idl_txn_write_clone"
475281c0 721 else:
d34a1cc0
JW
722 print("")
723 print(" datum.n = %s;" % nVar)
724 print(" datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar))
475281c0 725 if type.value:
d34a1cc0 726 print(" datum.values = xmalloc(%s * sizeof *datum.values);" % nVar)
475281c0 727 else:
d34a1cc0
JW
728 print(" datum.values = NULL;")
729 print(" for (size_t i = 0; i < %s; i++) {" % nVar)
730 print(" " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar))
475281c0 731 if type.value:
d34a1cc0
JW
732 print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar))
733 print(" }")
a1ec42a3
BP
734 if type.value:
735 valueType = type.value.toAtomicType()
736 else:
737 valueType = "OVSDB_TYPE_VOID"
fe19569a 738 txn_write_func = "ovsdb_idl_txn_write"
d34a1cc0 739 print(" %(f)s(&row->header_, &%(s)s_col_%(c)s, &datum);" \
fe19569a
BP
740 % {'f': txn_write_func,
741 's': structName,
475281c0 742 'S': structName.upper(),
d34a1cc0
JW
743 'c': columnName})
744 print("}")
010fe7ae 745 # Update/Delete of partial map column functions
e0b1744f 746 for columnName, column in sorted_columns(table):
010fe7ae
EA
747 type = column.type
748 if type.is_map():
d34a1cc0 749 print('''
010fe7ae
EA
750/* Sets an element of the "%(c)s" map column from the "%(t)s" table in 'row'
751 * to 'new_value' given the key value 'new_key'.
752 *
753 */
754void
755%(s)s_update_%(c)s_setkey(const struct %(s)s *row, %(coltype)snew_key, %(valtype)snew_value)
756{
757 struct ovsdb_datum *datum;
758
010fe7ae
EA
759 datum = xmalloc(sizeof *datum);
760 datum->n = 1;
761 datum->keys = xmalloc(datum->n * sizeof *datum->keys);
762 datum->values = xmalloc(datum->n * sizeof *datum->values);
05ba459f
BP
763''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
764 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
d34a1cc0 765 'C': columnName.upper(), 't': tableName})
010fe7ae 766
d34a1cc0
JW
767 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "new_key"))
768 print(" "+ type.value.copyCValue("datum->values[0].%s" % type.value.type.to_string(), "new_value"))
769 print('''
010fe7ae 770 ovsdb_idl_txn_write_partial_map(&row->header_,
1f2d2557 771 &%(s)s_col_%(c)s,
010fe7ae 772 datum);
1f2d2557 773}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0
JW
774 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper()})
775 print('''
010fe7ae
EA
776/* Deletes an element of the "%(c)s" map column from the "%(t)s" table in 'row'
777 * given the key value 'delete_key'.
778 *
779 */
780void
781%(s)s_update_%(c)s_delkey(const struct %(s)s *row, %(coltype)sdelete_key)
782{
783 struct ovsdb_datum *datum;
784
010fe7ae
EA
785 datum = xmalloc(sizeof *datum);
786 datum->n = 1;
787 datum->keys = xmalloc(datum->n * sizeof *datum->keys);
788 datum->values = NULL;
05ba459f
BP
789''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
790 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
d34a1cc0 791 'C': columnName.upper(), 't': tableName})
010fe7ae 792
d34a1cc0
JW
793 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "delete_key"))
794 print('''
010fe7ae 795 ovsdb_idl_txn_delete_partial_map(&row->header_,
1f2d2557 796 &%(s)s_col_%(c)s,
010fe7ae 797 datum);
1f2d2557 798}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0 799 'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper()})
010fe7ae 800 # End Update/Delete of partial maps
f1ab6e06
RM
801 # Update/Delete of partial set column functions
802 if type.is_set():
d34a1cc0 803 print('''
f1ab6e06
RM
804/* Adds the value 'new_value' to the "%(c)s" set column from the "%(t)s" table
805 * in 'row'.
806 *
807 */
808void
809%(s)s_update_%(c)s_addvalue(const struct %(s)s *row, %(valtype)snew_value)
810{
811 struct ovsdb_datum *datum;
812
f1ab6e06
RM
813 datum = xmalloc(sizeof *datum);
814 datum->n = 1;
815 datum->keys = xmalloc(datum->n * sizeof *datum->values);
816 datum->values = NULL;
817''' % {'s': structName, 'c': columnName,
d34a1cc0 818 'valtype':column.type.key.to_const_c_type(prefix), 't': tableName})
f1ab6e06 819
d34a1cc0
JW
820 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "new_value"))
821 print('''
f1ab6e06 822 ovsdb_idl_txn_write_partial_set(&row->header_,
1f2d2557 823 &%(s)s_col_%(c)s,
f1ab6e06 824 datum);
1f2d2557 825}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0
JW
826 'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper()})
827 print('''
f1ab6e06
RM
828/* Deletes the value 'delete_value' from the "%(c)s" set column from the
829 * "%(t)s" table in 'row'.
830 *
831 */
832void
833%(s)s_update_%(c)s_delvalue(const struct %(s)s *row, %(valtype)sdelete_value)
834{
835 struct ovsdb_datum *datum;
836
f1ab6e06
RM
837 datum = xmalloc(sizeof *datum);
838 datum->n = 1;
839 datum->keys = xmalloc(datum->n * sizeof *datum->values);
840 datum->values = NULL;
05ba459f
BP
841''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
842 'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper(),
d34a1cc0 843 'C': columnName.upper(), 't': tableName})
f1ab6e06 844
d34a1cc0
JW
845 print(" "+ type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_string(), "delete_value"))
846 print('''
f1ab6e06 847 ovsdb_idl_txn_delete_partial_set(&row->header_,
1f2d2557 848 &%(s)s_col_%(c)s,
f1ab6e06 849 datum);
1f2d2557 850}''' % {'s': structName, 'c': columnName,'coltype':column.type.key.toCType(prefix),
d34a1cc0 851 'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper()})
f1ab6e06 852 # End Update/Delete of partial set
c3bb4bd7 853
16ebb90e 854 # Add clause functions.
e0b1744f 855 for columnName, column in sorted_columns(table):
16ebb90e
LS
856 type = column.type
857
858 comment, members = cMembers(prefix, tableName, columnName,
4bb7f568 859 column, True, refTable=False)
16ebb90e
LS
860
861 if type.is_smap():
d34a1cc0
JW
862 print(comment)
863 print("""void
0164e367 864%(s)s_add_clause_%(c)s(struct ovsdb_idl_condition *cond, enum ovsdb_function function, const struct smap *%(c)s)
16ebb90e
LS
865{
866 struct ovsdb_datum datum;
867
16ebb90e 868 if (%(c)s) {
9b03e59d 869 ovsdb_datum_from_smap(&datum, %(c)s);
16ebb90e
LS
870 } else {
871 ovsdb_datum_init_empty(&datum);
872 }
873
0164e367 874 ovsdb_idl_condition_add_clause(cond,
16ebb90e 875 function,
1f2d2557 876 &%(s)s_col_%(c)s,
16ebb90e 877 &datum);
a4e68acd
BP
878
879 ovsdb_datum_destroy(&datum, &%(s)s_col_%(c)s.type);
16ebb90e
LS
880}
881""" % {'t': tableName,
9478f52f 882 'tl': tableName.lower(),
16ebb90e
LS
883 'T': tableName.upper(),
884 'p': prefix,
885 'P': prefix.upper(),
886 's': structName,
887 'S': structName.upper(),
d34a1cc0 888 'c': columnName})
16ebb90e
LS
889 continue
890
891 keyVar = members[0]['name']
892 nVar = None
893 valueVar = None
894 if type.value:
895 valueVar = members[1]['name']
896 if len(members) > 2:
897 nVar = members[2]['name']
898 else:
899 if len(members) > 1:
900 nVar = members[1]['name']
901
d34a1cc0
JW
902 print(comment)
903 print('void')
904 print('%(s)s_add_clause_%(c)s(struct ovsdb_idl_condition *cond, enum ovsdb_function function, %(args)s)' % \
16ebb90e 905 {'s': structName, 'c': columnName,
d34a1cc0
JW
906 'args': ', '.join(['%(type)s%(name)s' % m for m in members])})
907 print("{")
908 print(" struct ovsdb_datum datum;")
a4e68acd 909 free = []
16ebb90e 910 if type.n_min == 1 and type.n_max == 1:
d34a1cc0 911 print(" union ovsdb_atom key;")
16ebb90e 912 if type.value:
d34a1cc0
JW
913 print(" union ovsdb_atom value;")
914 print("")
915 print(" datum.n = 1;")
916 print(" datum.keys = &key;")
917 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar, refTable=False))
16ebb90e 918 if type.value:
d34a1cc0
JW
919 print(" datum.values = &value;")
920 print(" "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar, refTable=False))
16ebb90e 921 else:
d34a1cc0 922 print(" datum.values = NULL;")
16ebb90e 923 elif type.is_optional_pointer():
d34a1cc0
JW
924 print(" union ovsdb_atom key;")
925 print("")
926 print(" if (%s) {" % keyVar)
927 print(" datum.n = 1;")
928 print(" datum.keys = &key;")
929 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar, refTable=False))
930 print(" } else {")
931 print(" datum.n = 0;")
932 print(" datum.keys = NULL;")
933 print(" }")
934 print(" datum.values = NULL;")
16ebb90e 935 elif type.n_max == 1:
d34a1cc0
JW
936 print(" union ovsdb_atom key;")
937 print("")
938 print(" if (%s) {" % nVar)
939 print(" datum.n = 1;")
940 print(" datum.keys = &key;")
941 print(" " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar, refTable=False))
942 print(" } else {")
943 print(" datum.n = 0;")
944 print(" datum.keys = NULL;")
945 print(" }")
946 print(" datum.values = NULL;")
16ebb90e 947 else:
d34a1cc0
JW
948 print(" datum.n = %s;" % nVar)
949 print(" datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar))
a4e68acd 950 free += ['datum.keys']
16ebb90e 951 if type.value:
d34a1cc0 952 print(" datum.values = xmalloc(%s * sizeof *datum.values);" % nVar)
a4e68acd 953 free += ['datum.values']
16ebb90e 954 else:
d34a1cc0
JW
955 print(" datum.values = NULL;")
956 print(" for (size_t i = 0; i < %s; i++) {" % nVar)
957 print(" " + type.key.assign_c_value_casting_away_const("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar, refTable=False))
16ebb90e 958 if type.value:
d34a1cc0
JW
959 print(" " + type.value.assign_c_value_casting_away_const("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar, refTable=False))
960 print(" }")
16ebb90e
LS
961 if type.value:
962 valueType = type.value.toAtomicType()
963 else:
964 valueType = "OVSDB_TYPE_VOID"
d34a1cc0
JW
965 print(" ovsdb_datum_sort_unique(&datum, %s, %s);" % (
966 type.key.toAtomicType(), valueType))
16ebb90e 967
d34a1cc0 968 print(""" ovsdb_idl_condition_add_clause(cond,
16ebb90e 969 function,
1f2d2557 970 &%(s)s_col_%(c)s,
a4e68acd 971 &datum);\
9478f52f 972""" % {'tl': tableName.lower(),
16ebb90e
LS
973 'T': tableName.upper(),
974 'p': prefix,
975 'P': prefix.upper(),
976 's': structName,
977 'S': structName.upper(),
d34a1cc0 978 'c': columnName})
a4e68acd 979 for var in free:
d34a1cc0
JW
980 print(" free(%s);" % var)
981 print("}")
16ebb90e 982
d34a1cc0 983 print("""
1f2d2557 984void
0164e367 985%(s)s_set_condition(struct ovsdb_idl *idl, struct ovsdb_idl_condition *condition)
16ebb90e 986{
0164e367
BP
987 ovsdb_idl_set_condition(idl, &%(p)stable_%(tl)s, condition);
988}""" % {'p': prefix,
989 's': structName,
d34a1cc0 990 'tl': tableName.lower()})
16ebb90e 991
c3bb4bd7 992 # Table columns.
74e98efd
BP
993 for columnName, column in sorted_columns(table):
994 prereqs = []
995 x = column.type.cInitType("%s_col_%s" % (tableName, columnName), prereqs)
996 if prereqs:
d34a1cc0
JW
997 print('\n'.join(prereqs))
998 print("\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS] = {" % (
999 structName, structName.upper()))
e0b1744f 1000 for columnName, column in sorted_columns(table):
341c4e59
BP
1001 if column.mutable:
1002 mutable = "true"
1003 else:
1004 mutable = "false"
74e98efd
BP
1005 type_init = '\n'.join(" " + x
1006 for x in column.type.cInitType("%s_col_%s" % (tableName, columnName), prereqs))
d34a1cc0 1007 print("""\
74e98efd
BP
1008 [%(P)s%(T)s_COL_%(C)s] = {
1009 .name = "%(c)s",
1010 .type = {
1011%(type)s
1012 },
1013 .mutable = %(mutable)s,
1014 .parse = %(s)s_parse_%(c)s,
1015 .unparse = %(s)s_unparse_%(c)s,
1016 },\n""" % {'P': prefix.upper(),
1017 'T': tableName.upper(),
1018 'c': columnName,
1019 'C': columnName.upper(),
1020 's': structName,
1021 'mutable': mutable,
d34a1cc0
JW
1022 'type': type_init})
1023 print("};")
c3bb4bd7
BP
1024
1025 # Table classes.
d34a1cc0
JW
1026 print("\f")
1027 print("struct ovsdb_idl_table_class %stable_classes[%sN_TABLES] = {" % (prefix, prefix.upper()))
bd76d25d 1028 for tableName, table in sorted(schema.tables.iteritems()):
c3bb4bd7 1029 structName = "%s%s" % (prefix, tableName.lower())
c5f341ab
BP
1030 if table.is_root:
1031 is_root = "true"
1032 else:
1033 is_root = "false"
d34a1cc0
JW
1034 print(" {\"%s\", %s," % (tableName, is_root))
1035 print(" %s_columns, ARRAY_SIZE(%s_columns)," % (
1036 structName, structName))
1037 print(" sizeof(struct %s), %s_init__}," % (structName, structName))
1038 print("};")
c3bb4bd7
BP
1039
1040 # IDL class.
d34a1cc0
JW
1041 print("\nstruct ovsdb_idl_class %sidl_class = {" % prefix)
1042 print(" \"%s\", %stable_classes, ARRAY_SIZE(%stable_classes)" % (
1043 schema.name, prefix, prefix))
1044 print("};")
d879a707 1045
d34a1cc0 1046 print("""
87412f02
JP
1047/* Return the schema version. The caller must not free the returned value. */
1048const char *
1049%sget_db_version(void)
1050{
1051 return "%s";
1052}
d34a1cc0 1053""" % (prefix, schema.version))
87412f02
JP
1054
1055
8cdf0349 1056
d879a707
BP
1057def ovsdb_escape(string):
1058 def escape(match):
1059 c = match.group(0)
1060 if c == '\0':
99155935 1061 raise ovs.db.error.Error("strings may not contain null bytes")
d879a707
BP
1062 elif c == '\\':
1063 return '\\\\'
1064 elif c == '\n':
1065 return '\\n'
1066 elif c == '\r':
1067 return '\\r'
1068 elif c == '\t':
1069 return '\\t'
1070 elif c == '\b':
1071 return '\\b'
1072 elif c == '\a':
1073 return '\\a'
1074 else:
1075 return '\\x%02x' % ord(c)
1076 return re.sub(r'["\\\000-\037]', escape, string)
1077
d879a707 1078def usage():
d34a1cc0 1079 print("""\
d879a707 1080%(argv0)s: ovsdb schema compiler
00732bf5 1081usage: %(argv0)s [OPTIONS] COMMAND ARG...
d879a707 1082
00732bf5
BP
1083The following commands are supported:
1084 annotate SCHEMA ANNOTATIONS print SCHEMA combined with ANNOTATIONS
1085 c-idl-header IDL print C header file for IDL
1086 c-idl-source IDL print C source file for IDL implementation
d879a707
BP
1087
1088The following options are also available:
1089 -h, --help display this help message
1090 -V, --version display version information\
d34a1cc0 1091""" % {'argv0': argv0})
d879a707
BP
1092 sys.exit(0)
1093
1094if __name__ == "__main__":
1095 try:
1096 try:
00732bf5
BP
1097 options, args = getopt.gnu_getopt(sys.argv[1:], 'C:hV',
1098 ['directory',
1099 'help',
d879a707 1100 'version'])
52e4a477 1101 except getopt.GetoptError as geo:
d879a707
BP
1102 sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
1103 sys.exit(1)
c5c7c7c5 1104
00732bf5
BP
1105 for key, value in options:
1106 if key in ['-h', '--help']:
1107 usage()
1108 elif key in ['-V', '--version']:
d34a1cc0 1109 print("ovsdb-idlc (Open vSwitch) @VERSION@")
00732bf5
BP
1110 elif key in ['-C', '--directory']:
1111 os.chdir(value)
1112 else:
1113 sys.exit(0)
c5c7c7c5 1114
d879a707 1115 optKeys = [key for key, value in options]
00732bf5
BP
1116
1117 if not args:
1118 sys.stderr.write("%s: missing command argument "
1119 "(use --help for help)\n" % argv0)
d879a707
BP
1120 sys.exit(1)
1121
00732bf5
BP
1122 commands = {"annotate": (annotateSchema, 2),
1123 "c-idl-header": (printCIDLHeader, 1),
2c84fdf2 1124 "c-idl-source": (printCIDLSource, 1)}
00732bf5
BP
1125
1126 if not args[0] in commands:
1127 sys.stderr.write("%s: unknown command \"%s\" "
1128 "(use --help for help)\n" % (argv0, args[0]))
d879a707 1129 sys.exit(1)
00732bf5
BP
1130
1131 func, n_args = commands[args[0]]
1132 if len(args) - 1 != n_args:
1133 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
1134 "provided\n"
1135 % (argv0, args[0], n_args, len(args) - 1))
1136 sys.exit(1)
1137
1138 func(*args[1:])
52e4a477 1139 except ovs.db.error.Error as e:
99155935 1140 sys.stderr.write("%s: %s\n" % (argv0, e))
d879a707
BP
1141 sys.exit(1)
1142
1143# Local variables:
1144# mode: python
1145# End: