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