+
+ # Column indexes.
+ printEnum(["%s_COL_%s" % (structName.upper(), columnName.upper())
+ for columnName in table.columns]
+ + ["%s_N_COLUMNS" % structName.upper()])
+
+ print "\nstatic struct ovsdb_idl_column %s_columns[];" % structName
+
+ # Parse function.
+ print '''
+static void
+%s_parse(struct ovsdb_idl_row *row_)
+{
+ struct %s *row = %s_cast(row_);
+ const struct ovsdb_datum *datum;
+ size_t i UNUSED;
+
+ memset(row_ + 1, 0, sizeof *row - sizeof *row_);''' % (structName, structName, structName)
+
+
+ for columnName, column in table.columns.iteritems():
+ type = column.type
+ refKey = type.key == "uuid" and type.keyRefTable
+ refValue = type.value == "uuid" and type.valueRefTable
+ print
+ print " datum = &row_->old[%s_COL_%s];" % (structName.upper(), columnName.upper())
+ if type.value:
+ keyVar = "row->key_%s" % columnName
+ valueVar = "row->value_%s" % columnName
+ else:
+ keyVar = "row->%s" % columnName
+ valueVar = None
+
+ if (type.min == 1 and type.max == 1) or typeIsOptionalPointer(type):
+ print " if (datum->n >= 1) {"
+ if not refKey:
+ print " %s = datum->keys[0].%s;" % (keyVar, type.key)
+ else:
+ print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[0].uuid));" % (keyVar, prefix, type.keyRefTable.lower(), prefix, prefix.upper(), type.keyRefTable.upper())
+
+ if valueVar:
+ if refValue:
+ print " %s = datum->values[0].%s;" % (valueVar, type.value)
+ else:
+ print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[0].uuid));" % (valueVar, prefix, type.valueRefTable.lower(), prefix, prefix.upper(), type.valueRefTable.upper())
+ if (not typeIsOptionalPointer(type) and
+ (type.key == "string" or type.value == "string")):
+ print " } else {"
+ if type.key == "string":
+ print " %s = \"\";" % keyVar
+ if type.value == "string":
+ print " %s = \"\";" % valueVar
+ print " }"
+
+ else:
+ if type.max != 'unlimited':
+ nMax = "MIN(%d, datum->n)" % type.max
+ else:
+ nMax = "datum->n"
+ print " for (i = 0; i < %s; i++) {" % nMax
+ refs = []
+ if refKey:
+ print " struct %s%s *keyRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[i].uuid));" % (prefix, type.keyRefTable.lower(), prefix, type.keyRefTable.lower(), prefix, prefix.upper(), type.keyRefTable.upper())
+ keySrc = "keyRow"
+ refs.append('keyRow')
+ else:
+ keySrc = "datum->keys[i].%s" % type.key
+ if refValue:
+ print " struct %s%s *valueRow = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[i].uuid));" % (prefix, type.valueRefTable.lower(), prefix, type.valueRefTable.lower(), prefix, prefix.upper(), type.valueRefTable.upper())
+ valueSrc = "valueRow"
+ refs.append('valueRow')
+ elif valueVar:
+ valueSrc = "datum->values[i].%s" % type.value
+ 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 function.
+ nArrays = 0
+ for columnName, column in table.columns.iteritems():
+ type = column.type
+ if (type.min != 1 or type.max != 1) and not typeIsOptionalPointer(type):
+ if not nArrays:
+ print '''
+static void
+%s_unparse(struct ovsdb_idl_row *row_)
+{
+ struct %s *row = %s_cast(row_);
+''' % (structName, structName, structName)
+ 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
+ nArrays += 1
+ if not nArrays:
+ print '''
+static void
+%s_unparse(struct ovsdb_idl_row *row UNUSED)
+{''' % (structName)
+ print "}"
+
+ # 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_)
+{
+ struct %(s)s *row = (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]));
+}
+''' % {'s': structName,
+ 'p': prefix,
+ 'P': prefix.upper(),
+ 'T': tableName.upper()}
+
+ # Verify functions.
+ for columnName, column in table.columns.iteritems():
+ print '''
+void
+%(s)s_verify_%(c)s(const struct %(s)s *row)
+{
+ ovsdb_idl_txn_verify(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s]);
+}''' % {'s': structName,
+ 'S': structName.upper(),
+ 'c': columnName,
+ 'C': columnName.upper()}
+
+ # Set functions.