]>
Commit | Line | Data |
---|---|---|
d879a707 BP |
1 | #! @PYTHON@ |
2 | ||
d34a1cc0 | 3 | from __future__ import print_function |
d879a707 | 4 | import getopt |
00732bf5 | 5 | import os |
d879a707 | 6 | import re |
d879a707 BP |
7 | import sys |
8 | ||
99155935 BP |
9 | import ovs.json |
10 | import ovs.db.error | |
11 | import ovs.db.schema | |
d879a707 | 12 | |
89365653 | 13 | argv0 = sys.argv[0] |
45a7de56 | 14 | |
d879a707 | 15 | def parseSchema(filename): |
99155935 | 16 | return ovs.db.schema.IdlSchema.from_json(ovs.json.from_file(filename)) |
00732bf5 BP |
17 | |
18 | def 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 | 24 | def 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 | 32 | def 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 |
121 | def sorted_columns(table): |
122 | return sorted(table.columns.items()) | |
123 | ||
00732bf5 BP |
124 | def 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 | 172 | const struct %(s)s *%(s)s_get_for_uuid(const struct ovsdb_idl *, const struct uuid *); |
c3bb4bd7 BP |
173 | const struct %(s)s *%(s)s_first(const struct ovsdb_idl *); |
174 | const 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 |
184 | unsigned int %(s)s_get_seqno(const struct ovsdb_idl *); |
185 | unsigned int %(s)s_row_get_seqno(const struct %(s)s *row, enum ovsdb_idl_change change); | |
186 | const struct %(s)s *%(s)s_track_get_first(const struct ovsdb_idl *); | |
187 | const 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. */ |
194 | static 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. */ | |
200 | static 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 | 205 | void %(s)s_init(struct %(s)s *); |
475281c0 BP |
206 | void %(s)s_delete(const struct %(s)s *); |
207 | struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *); | |
32d37ce8 | 208 | bool %(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 | 276 | def 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 |
286 | def 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 | 306 | static 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 | 322 | static 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 | 411 | static 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 | 432 | static 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 |
440 | static 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 |
449 | void |
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 |
467 | const 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 |
479 | const 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 |
487 | const 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 | ||
493 | unsigned 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 | ||
498 | unsigned 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 | ||
503 | const 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 | ||
509 | const 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 | 526 | void |
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 |
539 | struct %(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 | ||
545 | bool | |
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 |
582 | void |
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 |
621 | const 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 |
674 | void |
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 | */ | |
754 | void | |
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 | */ | |
780 | void | |
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 | */ | |
808 | void | |
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 | */ | |
832 | void | |
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 | 984 | void |
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. */ |
1048 | const char * | |
1049 | %sget_db_version(void) | |
1050 | { | |
1051 | return "%s"; | |
1052 | } | |
d34a1cc0 | 1053 | """ % (prefix, schema.version)) |
87412f02 JP |
1054 | |
1055 | ||
8cdf0349 | 1056 | |
d879a707 BP |
1057 | def 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 | 1078 | def usage(): |
d34a1cc0 | 1079 | print("""\ |
d879a707 | 1080 | %(argv0)s: ovsdb schema compiler |
00732bf5 | 1081 | usage: %(argv0)s [OPTIONS] COMMAND ARG... |
d879a707 | 1082 | |
00732bf5 BP |
1083 | The 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 | |
1088 | The 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 | ||
1094 | if __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: |