+ for member in cMembers(prefix, columnName, column, False):
+ print "\t%(type)s%(name)s;%(comment)s" % member
+ print "};"
+
+ # Column indexes.
+ printEnum(["%s_COL_%s" % (structName.upper(), columnName.upper())
+ for columnName in sorted(table.columns)]
+ + ["%s_N_COLUMNS" % structName.upper()])
+
+ print
+ for columnName in table.columns:
+ print "#define %(s)s_col_%(c)s (%(s)s_columns[%(S)s_COL_%(C)s])" % {
+ 's': structName,
+ 'S': structName.upper(),
+ 'c': columnName,
+ 'C': columnName.upper()}
+
+ print "\nextern struct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (structName, structName.upper())
+
+ print '''
+const struct %(s)s *%(s)s_first(const struct ovsdb_idl *);
+const struct %(s)s *%(s)s_next(const struct %(s)s *);
+#define %(S)s_FOR_EACH(ROW, IDL) \\
+ for ((ROW) = %(s)s_first(IDL); \\
+ (ROW); \\
+ (ROW) = %(s)s_next(ROW))
+#define %(S)s_FOR_EACH_SAFE(ROW, NEXT, IDL) \\
+ for ((ROW) = %(s)s_first(IDL); \\
+ (ROW) ? ((NEXT) = %(s)s_next(ROW), 1) : 0; \\
+ (ROW) = (NEXT))
+
+void %(s)s_delete(const struct %(s)s *);
+struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *);
+''' % {'s': structName, 'S': structName.upper()}
+
+ for columnName, column in sorted(table.columns.iteritems()):
+ print 'void %(s)s_verify_%(c)s(const struct %(s)s *);' % {'s': structName, 'c': columnName}
+
+ print """
+/* Functions for fetching columns as \"struct ovsdb_datum\"s. (This is
+ rarely useful. More often, it is easier to access columns by using
+ the members of %(s)s directly.) */""" % {'s': structName}
+ for columnName, column in sorted(table.columns.iteritems()):
+ if column.type.value:
+ valueParam = ', enum ovsdb_atomic_type value_type'
+ else:
+ valueParam = ''
+ print 'const struct ovsdb_datum *%(s)s_get_%(c)s(const struct %(s)s *, enum ovsdb_atomic_type key_type%(v)s);' % {
+ 's': structName, 'c': columnName, 'v': valueParam}
+
+ print
+ for columnName, column in sorted(table.columns.iteritems()):
+
+ print 'void %(s)s_set_%(c)s(const struct %(s)s *,' % {'s': structName, 'c': columnName},
+ args = ['%(type)s%(name)s' % member for member
+ in cMembers(prefix, columnName, column, True)]
+ print '%s);' % ', '.join(args)
+
+ # Table indexes.
+ printEnum(["%sTABLE_%s" % (prefix.upper(), tableName.upper()) for tableName in sorted(schema.tables)] + ["%sN_TABLES" % prefix.upper()])
+ print
+ for tableName in schema.tables:
+ print "#define %(p)stable_%(t)s (%(p)stable_classes[%(P)sTABLE_%(T)s])" % {
+ 'p': prefix,
+ 'P': prefix.upper(),
+ 't': tableName.lower(),
+ 'T': tableName.upper()}
+ print "\nextern struct ovsdb_idl_table_class %stable_classes[%sN_TABLES];" % (prefix, prefix.upper())
+
+ print "\nextern struct ovsdb_idl_class %sidl_class;" % prefix
+ print "\nvoid %sinit(void);" % prefix
+ print "\n#endif /* %(prefix)sIDL_HEADER */" % {'prefix': prefix.upper()}
+
+def printEnum(members):
+ if len(members) == 0:
+ return
+
+ print "\nenum {";
+ for member in members[:-1]:
+ print " %s," % member
+ print " %s" % members[-1]
+ print "};"
+
+def is_optional_bool(type):
+ return (type.key.type == ovs.db.types.BooleanType and not type.value
+ and type.n_min == 0 and type.n_max == 1)
+
+def printCIDLSource(schemaFile):
+ schema = parseSchema(schemaFile)
+ prefix = schema.idlPrefix
+ print '''\
+/* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
+
+#include <config.h>
+#include %s
+#include <assert.h>
+#include <limits.h>
+#include "ovsdb-data.h"
+#include "ovsdb-error.h"
+
+static bool inited;
+''' % schema.idlHeader
+
+ # Cast functions.
+ for tableName, table in sorted(schema.tables.iteritems()):
+ structName = "%s%s" % (prefix, tableName.lower())
+ print '''
+static struct %(s)s *
+%(s)s_cast(const struct ovsdb_idl_row *row)
+{
+ return row ? CONTAINER_OF(row, struct %(s)s, header_) : NULL;
+}\
+''' % {'s': structName}
+
+
+ for tableName, table in sorted(schema.tables.iteritems()):
+ structName = "%s%s" % (prefix, tableName.lower())
+ print "\f"
+ print "/* %s table. */" % (tableName)
+
+ # Parse functions.
+ for columnName, column in sorted(table.columns.iteritems()):
+ print '''
+static void
+%(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum)
+{
+ struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName,
+ 'c': columnName}
+
+ type = column.type
+ if type.value:
+ keyVar = "row->key_%s" % columnName
+ valueVar = "row->value_%s" % columnName
+ else:
+ keyVar = "row->%s" % columnName
+ valueVar = None
+
+ if is_optional_bool(type):
+ # Special case for an optional bool. This is only here because
+ # sparse does not like the "normal" case below ("warning:
+ # expression using sizeof bool").
+ print
+ print " assert(inited);"
+ print " if (datum->n >= 1) {"
+ print " static const bool false_value = false;"
+ print " static const bool true_value = true;"
+ print
+ print " row->n_%s = 1;" % columnName
+ print " %s = datum->keys[0].boolean ? &true_value : &false_value;" % keyVar
+ print " } else {"
+ print " row->n_%s = 0;" % columnName
+ print " %s = NULL;" % keyVar
+ print " }"
+ elif (type.n_min == 1 and type.n_max == 1) or type.is_optional_pointer():
+ print
+ print " assert(inited);"
+ print " if (datum->n >= 1) {"
+ if not type.key.ref_table:
+ print " %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_string())
+ else:
+ 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.lower(), prefix, prefix.upper(), type.key.ref_table.upper())
+
+ if valueVar:
+ if type.value.ref_table:
+ print " %s = datum->values[0].%s;" % (valueVar, type.value.type.to_string())
+ else:
+ 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.lower(), prefix, prefix.upper(), type.value.ref_table.upper())
+ print " } else {"
+ print " %s" % type.key.initCDefault(keyVar, type.n_min == 0)
+ if valueVar:
+ print " %s" % type.value.initCDefault(valueVar, type.n_min == 0)
+ print " }"
+ else:
+ if type.n_max != sys.maxint:
+ print " size_t n = MIN(%d, datum->n);" % type.n_max
+ nMax = "n"
+ else:
+ nMax = "datum->n"
+ print " size_t i;"
+ print
+ print " assert(inited);"
+ print " %s = NULL;" % keyVar
+ if valueVar:
+ print " %s = NULL;" % valueVar
+ print " row->n_%s = 0;" % columnName
+ print " for (i = 0; i < %s; i++) {" % nMax
+ refs = []
+ if type.key.ref_table:
+ 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.lower(), prefix, type.key.ref_table.lower(), prefix, prefix.upper(), type.key.ref_table.upper())
+ keySrc = "keyRow"
+ refs.append('keyRow')
+ else:
+ keySrc = "datum->keys[i].%s" % type.key.type.to_string()
+ if type.value and type.value.ref_table:
+ 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.lower(), prefix, type.value.ref_table.lower(), prefix, prefix.upper(), type.value.ref_table.upper())
+ valueSrc = "valueRow"
+ refs.append('valueRow')
+ elif valueVar:
+ valueSrc = "datum->values[i].%s" % type.value.type.to_string()
+ if refs:
+ print " if (%s) {" % ' && '.join(refs)
+ indent = " "
+ else:
+ indent = " "
+ print "%sif (!row->n_%s) {" % (indent, columnName)
+ print "%s %s = xmalloc(%s * sizeof *%s);" % (indent, keyVar, nMax, keyVar)
+ if valueVar:
+ print "%s %s = xmalloc(%s * sizeof *%s);" % (indent, valueVar, nMax, valueVar)
+ print "%s}" % indent
+ print "%s%s[row->n_%s] = %s;" % (indent, keyVar, columnName, keySrc)
+ if valueVar:
+ print "%s%s[row->n_%s] = %s;" % (indent, valueVar, columnName, valueSrc)
+ print "%srow->n_%s++;" % (indent, columnName)
+ if refs:
+ print " }"
+ print " }"
+ print "}"
+
+ # Unparse functions.
+ for columnName, column in sorted(table.columns.iteritems()):