+ 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()):
+ type = column.type
+ if (type.n_min != 1 or type.n_max != 1) and not type.is_optional_pointer():
+ print '''
+static void
+%(s)s_unparse_%(c)s(struct ovsdb_idl_row *row_)
+{
+ struct %(s)s *row = %(s)s_cast(row_);
+
+ assert(inited);''' % {'s': structName, 'c': columnName}
+ if type.value:
+ keyVar = "row->key_%s" % columnName
+ valueVar = "row->value_%s" % columnName
+ else:
+ keyVar = "row->%s" % columnName
+ valueVar = None
+ print " free(%s);" % keyVar
+ if valueVar:
+ print " free(%s);" % valueVar
+ print '}'
+ else:
+ print '''
+static void
+%(s)s_unparse_%(c)s(struct ovsdb_idl_row *row OVS_UNUSED)
+{
+ /* Nothing to do. */
+}''' % {'s': structName, 'c': columnName}
+
+ # First, next functions.
+ print '''
+const struct %(s)s *
+%(s)s_first(const struct ovsdb_idl *idl)
+{
+ return %(s)s_cast(ovsdb_idl_first_row(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s]));
+}
+
+const struct %(s)s *
+%(s)s_next(const struct %(s)s *row)
+{
+ return %(s)s_cast(ovsdb_idl_next_row(&row->header_));
+}''' % {'s': structName,
+ 'p': prefix,
+ 'P': prefix.upper(),
+ 'T': tableName.upper()}
+
+ print '''
+void
+%(s)s_delete(const struct %(s)s *row)
+{
+ ovsdb_idl_txn_delete(&row->header_);
+}
+
+struct %(s)s *
+%(s)s_insert(struct ovsdb_idl_txn *txn)
+{
+ return %(s)s_cast(ovsdb_idl_txn_insert(txn, &%(p)stable_classes[%(P)sTABLE_%(T)s], NULL));
+}
+''' % {'s': structName,
+ 'p': prefix,
+ 'P': prefix.upper(),
+ 'T': tableName.upper()}
+
+ # Verify functions.
+ for columnName, column in sorted(table.columns.iteritems()):
+ print '''
+void
+%(s)s_verify_%(c)s(const struct %(s)s *row)
+{
+ assert(inited);
+ ovsdb_idl_txn_verify(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s]);
+}''' % {'s': structName,
+ 'S': structName.upper(),
+ 'c': columnName,
+ 'C': columnName.upper()}
+
+ # Get functions.
+ for columnName, column in sorted(table.columns.iteritems()):
+ if column.type.value:
+ valueParam = ',\n\tenum ovsdb_atomic_type value_type OVS_UNUSED'
+ valueType = '\n assert(value_type == %s);' % column.type.value.toAtomicType()
+ valueComment = "\n * 'value_type' must be %s." % column.type.value.toAtomicType()
+ else:
+ valueParam = ''
+ valueType = ''
+ valueComment = ''
+ print """
+/* Returns the %(c)s column's value in 'row' as a struct ovsdb_datum.
+ * This is useful occasionally: for example, ovsdb_datum_find_key() is an
+ * easier and more efficient way to search for a given key than implementing
+ * the same operation on the "cooked" form in 'row'.
+ *
+ * 'key_type' must be %(kt)s.%(vc)s
+ * (This helps to avoid silent bugs if someone changes %(c)s's
+ * type without updating the caller.)
+ *
+ * The caller must not modify or free the returned value.
+ *
+ * Various kinds of changes can invalidate the returned value: modifying
+ * 'column' within 'row', deleting 'row', or completing an ongoing transaction.
+ * If the returned value is needed for a long time, it is best to make a copy
+ * of it with ovsdb_datum_clone(). */
+const struct ovsdb_datum *
+%(s)s_get_%(c)s(const struct %(s)s *row,
+\tenum ovsdb_atomic_type key_type OVS_UNUSED%(v)s)
+{
+ assert(key_type == %(kt)s);%(vt)s
+ return ovsdb_idl_read(&row->header_, &%(s)s_col_%(c)s);
+}""" % {'s': structName, 'c': columnName,
+ 'kt': column.type.key.toAtomicType(),
+ 'v': valueParam, 'vt': valueType, 'vc': valueComment}
+
+ # Set functions.
+ for columnName, column in sorted(table.columns.iteritems()):
+ type = column.type
+ print '\nvoid'
+ members = cMembers(prefix, columnName, column, True)
+ keyVar = members[0]['name']
+ nVar = None
+ valueVar = None