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