14 def parseSchema(filename):
15 return ovs.db.schema.IdlSchema.from_json(ovs.json.from_file(filename))
17 def annotateSchema(schemaFile, annotationFile):
18 schemaJson = ovs.json.from_file(schemaFile)
19 execfile(annotationFile, globals(), {"s": schemaJson})
20 ovs.json.to_stream(schemaJson, sys.stdout)
21 sys.stdout.write('\n')
23 def constify(cType, const):
25 and cType.endswith('*') and
26 (cType == 'char **' or not cType.endswith('**'))):
27 return 'const %s' % cType
31 def cMembers(prefix, columnName, column, const):
35 return [{'name': columnName,
36 'type': 'struct smap ',
39 if type.n_min == 1 and type.n_max == 1:
44 if type.is_optional_pointer():
50 key = {'name': "key_%s" % columnName,
51 'type': constify(type.key.toCType(prefix) + pointer, const),
53 value = {'name': "value_%s" % columnName,
54 'type': constify(type.value.toCType(prefix) + pointer, const),
56 members = [key, value]
58 m = {'name': columnName,
59 'type': constify(type.key.toCType(prefix) + pointer, const),
60 'comment': type.cDeclComment()}
63 if not singleton and not type.is_optional_pointer():
64 members.append({'name': 'n_%s' % columnName,
69 def printCIDLHeader(schemaFile):
70 schema = parseSchema(schemaFile)
71 prefix = schema.idlPrefix
73 /* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
75 #ifndef %(prefix)sIDL_HEADER
76 #define %(prefix)sIDL_HEADER 1
81 #include "ovsdb-data.h"
82 #include "ovsdb-idl-provider.h"
84 #include "uuid.h"''' % {'prefix': prefix.upper()}
86 for tableName, table in sorted(schema.tables.iteritems()):
87 structName = "%s%s" % (prefix, tableName.lower())
90 print "/* %s table. */" % tableName
91 print "struct %s {" % structName
92 print "\tstruct ovsdb_idl_row header_;"
93 for columnName, column in sorted(table.columns.iteritems()):
94 print "\n\t/* %s column. */" % columnName
95 for member in cMembers(prefix, columnName, column, False):
96 print "\t%(type)s%(name)s;%(comment)s" % member
100 printEnum(["%s_COL_%s" % (structName.upper(), columnName.upper())
101 for columnName in sorted(table.columns)]
102 + ["%s_N_COLUMNS" % structName.upper()])
105 for columnName in table.columns:
106 print "#define %(s)s_col_%(c)s (%(s)s_columns[%(S)s_COL_%(C)s])" % {
108 'S': structName.upper(),
110 'C': columnName.upper()}
112 print "\nextern struct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (structName, structName.upper())
115 const struct %(s)s *%(s)s_get_for_uuid(const struct ovsdb_idl *, const struct uuid *);
116 const struct %(s)s *%(s)s_first(const struct ovsdb_idl *);
117 const struct %(s)s *%(s)s_next(const struct %(s)s *);
118 #define %(S)s_FOR_EACH(ROW, IDL) \\
119 for ((ROW) = %(s)s_first(IDL); \\
121 (ROW) = %(s)s_next(ROW))
122 #define %(S)s_FOR_EACH_SAFE(ROW, NEXT, IDL) \\
123 for ((ROW) = %(s)s_first(IDL); \\
124 (ROW) ? ((NEXT) = %(s)s_next(ROW), 1) : 0; \\
127 void %(s)s_init(struct %(s)s *);
128 void %(s)s_delete(const struct %(s)s *);
129 struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *);
130 ''' % {'s': structName, 'S': structName.upper()}
132 for columnName, column in sorted(table.columns.iteritems()):
133 print 'void %(s)s_verify_%(c)s(const struct %(s)s *);' % {'s': structName, 'c': columnName}
136 for columnName, column in sorted(table.columns.iteritems()):
137 if column.type.value:
138 valueParam = ', enum ovsdb_atomic_type value_type'
141 print 'const struct ovsdb_datum *%(s)s_get_%(c)s(const struct %(s)s *, enum ovsdb_atomic_type key_type%(v)s);' % {
142 's': structName, 'c': columnName, 'v': valueParam}
145 for columnName, column in sorted(table.columns.iteritems()):
146 print 'void %(s)s_set_%(c)s(const struct %(s)s *,' % {'s': structName, 'c': columnName},
147 if column.type.is_smap():
148 args = ['const struct smap *']
150 args = ['%(type)s%(name)s' % member for member
151 in cMembers(prefix, columnName, column, True)]
152 print '%s);' % ', '.join(args)
157 printEnum(["%sTABLE_%s" % (prefix.upper(), tableName.upper()) for tableName in sorted(schema.tables)] + ["%sN_TABLES" % prefix.upper()])
159 for tableName in schema.tables:
160 print "#define %(p)stable_%(t)s (%(p)stable_classes[%(P)sTABLE_%(T)s])" % {
163 't': tableName.lower(),
164 'T': tableName.upper()}
165 print "\nextern struct ovsdb_idl_table_class %stable_classes[%sN_TABLES];" % (prefix, prefix.upper())
167 print "\nextern struct ovsdb_idl_class %sidl_class;" % prefix
168 print "\nvoid %sinit(void);" % prefix
170 print "\nconst char * %sget_db_version(void);" % prefix
171 print "\n#endif /* %(prefix)sIDL_HEADER */" % {'prefix': prefix.upper()}
173 def printEnum(members):
174 if len(members) == 0:
178 for member in members[:-1]:
179 print " %s," % member
180 print " %s" % members[-1]
183 def printCIDLSource(schemaFile):
184 schema = parseSchema(schemaFile)
185 prefix = schema.idlPrefix
187 /* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */
192 #include "ovs-thread.h"
193 #include "ovsdb-data.h"
194 #include "ovsdb-error.h"
198 /* Sparse dislikes sizeof(bool) ("warning: expression using sizeof bool"). */
199 enum { sizeof_bool = 1 };
201 enum { sizeof_bool = sizeof(bool) };
205 ''' % schema.idlHeader
208 for tableName, table in sorted(schema.tables.iteritems()):
209 structName = "%s%s" % (prefix, tableName.lower())
211 static struct %(s)s *
212 %(s)s_cast(const struct ovsdb_idl_row *row)
214 return row ? CONTAINER_OF(row, struct %(s)s, header_) : NULL;
216 ''' % {'s': structName}
219 for tableName, table in sorted(schema.tables.iteritems()):
220 structName = "%s%s" % (prefix, tableName.lower())
222 print "/* %s table. */" % (tableName)
225 for columnName, column in sorted(table.columns.iteritems()):
228 %(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum)
230 struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName,
234 keyVar = "row->key_%s" % columnName
235 valueVar = "row->value_%s" % columnName
237 keyVar = "row->%s" % columnName
243 print " ovs_assert(inited);"
244 print " smap_init(&row->%s);" % columnName
245 print " for (i = 0; i < datum->n; i++) {"
246 print " smap_add(&row->%s," % columnName
247 print " datum->keys[i].string,"
248 print " datum->values[i].string);"
250 elif (type.n_min == 1 and type.n_max == 1) or type.is_optional_pointer():
252 print " ovs_assert(inited);"
253 print " if (datum->n >= 1) {"
254 if not type.key.ref_table:
255 print " %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_string())
257 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())
260 if type.value.ref_table:
261 print " %s = datum->values[0].%s;" % (valueVar, type.value.type.to_string())
263 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())
265 print " %s" % type.key.initCDefault(keyVar, type.n_min == 0)
267 print " %s" % type.value.initCDefault(valueVar, type.n_min == 0)
270 if type.n_max != sys.maxint:
271 print " size_t n = MIN(%d, datum->n);" % type.n_max
277 print " ovs_assert(inited);"
278 print " %s = NULL;" % keyVar
280 print " %s = NULL;" % valueVar
281 print " row->n_%s = 0;" % columnName
282 print " for (i = 0; i < %s; i++) {" % nMax
284 if type.key.ref_table:
285 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())
287 refs.append('keyRow')
289 keySrc = "datum->keys[i].%s" % type.key.type.to_string()
290 if type.value and type.value.ref_table:
291 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())
292 valueSrc = "valueRow"
293 refs.append('valueRow')
295 valueSrc = "datum->values[i].%s" % type.value.type.to_string()
297 print " if (%s) {" % ' && '.join(refs)
301 print "%sif (!row->n_%s) {" % (indent, columnName)
303 # Special case for boolean types. This is only here because
304 # sparse does not like the "normal" case ("warning: expression
305 # using sizeof bool").
306 if type.key.type == ovs.db.types.BooleanType:
307 sizeof = "sizeof_bool"
309 sizeof = "sizeof *%s" % keyVar
310 print "%s %s = xmalloc(%s * %s);" % (indent, keyVar, nMax,
313 # Special case for boolean types (see above).
314 if type.value.type == ovs.db.types.BooleanType:
315 sizeof = " * sizeof_bool"
317 sizeof = "sizeof *%s" % valueVar
318 print "%s %s = xmalloc(%s * %s);" % (indent, valueVar,
321 print "%s%s[row->n_%s] = %s;" % (indent, keyVar, columnName, keySrc)
323 print "%s%s[row->n_%s] = %s;" % (indent, valueVar, columnName, valueSrc)
324 print "%srow->n_%s++;" % (indent, columnName)
331 for columnName, column in sorted(table.columns.iteritems()):
333 if type.is_smap() or (type.n_min != 1 or type.n_max != 1) and not type.is_optional_pointer():
336 %(s)s_unparse_%(c)s(struct ovsdb_idl_row *row_)
338 struct %(s)s *row = %(s)s_cast(row_);
340 ovs_assert(inited);''' % {'s': structName, 'c': columnName}
343 print " smap_destroy(&row->%s);" % columnName
346 keyVar = "row->key_%s" % columnName
347 valueVar = "row->value_%s" % columnName
349 keyVar = "row->%s" % columnName
351 print " free(%s);" % keyVar
353 print " free(%s);" % valueVar
358 %(s)s_unparse_%(c)s(struct ovsdb_idl_row *row OVS_UNUSED)
361 }''' % {'s': structName, 'c': columnName}
363 # Generic Row Initialization function.
366 %(s)s_init__(struct ovsdb_idl_row *row)
368 %(s)s_init(%(s)s_cast(row));
369 }""" % {'s': structName}
371 # Row Initialization function.
373 /* Clears the contents of 'row' in table "%(t)s". */
375 %(s)s_init(struct %(s)s *row)
377 memset(row, 0, sizeof *row); """ % {'s': structName, 't': tableName}
378 for columnName, column in sorted(table.columns.iteritems()):
379 if column.type.is_smap():
380 print " smap_init(&row->%s);" % columnName
383 # First, next functions.
385 /* Searches table "%(t)s" in 'idl' for a row with UUID 'uuid'. Returns
386 * a pointer to the row if there is one, otherwise a null pointer. */
388 %(s)s_get_for_uuid(const struct ovsdb_idl *idl, const struct uuid *uuid)
390 return %(s)s_cast(ovsdb_idl_get_row_for_uuid(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s], uuid));
393 /* Returns a row in table "%(t)s" in 'idl', or a null pointer if that
396 * Database tables are internally maintained as hash tables, so adding or
397 * removing rows while traversing the same table can cause some rows to be
398 * visited twice or not at apply. */
400 %(s)s_first(const struct ovsdb_idl *idl)
402 return %(s)s_cast(ovsdb_idl_first_row(idl, &%(p)stable_classes[%(P)sTABLE_%(T)s]));
405 /* Returns a row following 'row' within its table, or a null pointer if 'row'
406 * is the last row in its table. */
408 %(s)s_next(const struct %(s)s *row)
410 return %(s)s_cast(ovsdb_idl_next_row(&row->header_));
411 }''' % {'s': structName,
415 'T': tableName.upper()}
418 /* Deletes 'row' from table "%(t)s". 'row' may be freed, so it must not be
419 * accessed afterward.
421 * The caller must have started a transaction with ovsdb_idl_txn_create(). */
423 %(s)s_delete(const struct %(s)s *row)
425 ovsdb_idl_txn_delete(&row->header_);
428 /* Inserts and returns a new row in the table "%(t)s" in the database
429 * with open transaction 'txn'.
431 * The new row is assigned a randomly generated provisional UUID.
432 * ovsdb-server will assign a different UUID when 'txn' is committed,
433 * but the IDL will replace any uses of the provisional UUID in the
434 * data to be to be committed by the UUID assigned by ovsdb-server. */
436 %(s)s_insert(struct ovsdb_idl_txn *txn)
438 return %(s)s_cast(ovsdb_idl_txn_insert(txn, &%(p)stable_classes[%(P)sTABLE_%(T)s], NULL));
439 }''' % {'s': structName,
443 'T': tableName.upper()}
446 for columnName, column in sorted(table.columns.iteritems()):
448 /* Causes the original contents of column "%(c)s" in 'row' to be
449 * verified as a prerequisite to completing the transaction. That is, if
450 * "%(c)s" in 'row' changed (or if 'row' was deleted) between the
451 * time that the IDL originally read its contents and the time that the
452 * transaction commits, then the transaction aborts and ovsdb_idl_txn_commit()
453 * returns TXN_AGAIN_WAIT or TXN_AGAIN_NOW (depending on whether the database
454 * change has already been received).
456 * The intention is that, to ensure that no transaction commits based on dirty
457 * reads, an application should call this function any time "%(c)s" is
458 * read as part of a read-modify-write operation.
460 * In some cases this function reduces to a no-op, because the current value
461 * of "%(c)s" is already known:
463 * - If 'row' is a row created by the current transaction (returned by
466 * - If "%(c)s" has already been modified (with
467 * %(s)s_set_%(c)s()) within the current transaction.
469 * Because of the latter property, always call this function *before*
470 * %(s)s_set_%(c)s() for a given read-modify-write.
472 * The caller must have started a transaction with ovsdb_idl_txn_create(). */
474 %(s)s_verify_%(c)s(const struct %(s)s *row)
477 ovsdb_idl_txn_verify(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s]);
478 }''' % {'s': structName,
479 'S': structName.upper(),
481 'C': columnName.upper()}
484 for columnName, column in sorted(table.columns.iteritems()):
485 if column.type.value:
486 valueParam = ',\n\tenum ovsdb_atomic_type value_type OVS_UNUSED'
487 valueType = '\n ovs_assert(value_type == %s);' % column.type.value.toAtomicType()
488 valueComment = "\n * 'value_type' must be %s." % column.type.value.toAtomicType()
494 /* Returns the "%(c)s" column's value from the "%(t)s" table in 'row'
495 * as a struct ovsdb_datum. This is useful occasionally: for example,
496 * ovsdb_datum_find_key() is an easier and more efficient way to search
497 * for a given key than implementing the same operation on the "cooked"
500 * 'key_type' must be %(kt)s.%(vc)s
501 * (This helps to avoid silent bugs if someone changes %(c)s's
502 * type without updating the caller.)
504 * The caller must not modify or free the returned value.
506 * Various kinds of changes can invalidate the returned value: modifying
507 * 'column' within 'row', deleting 'row', or completing an ongoing transaction.
508 * If the returned value is needed for a long time, it is best to make a copy
509 * of it with ovsdb_datum_clone().
511 * This function is rarely useful, since it is easier to access the value
512 * directly through the "%(c)s" member in %(s)s. */
513 const struct ovsdb_datum *
514 %(s)s_get_%(c)s(const struct %(s)s *row,
515 \tenum ovsdb_atomic_type key_type OVS_UNUSED%(v)s)
517 ovs_assert(key_type == %(kt)s);%(vt)s
518 return ovsdb_idl_read(&row->header_, &%(s)s_col_%(c)s);
519 }""" % {'t': tableName, 's': structName, 'c': columnName,
520 'kt': column.type.key.toAtomicType(),
521 'v': valueParam, 'vt': valueType, 'vc': valueComment}
524 for columnName, column in sorted(table.columns.iteritems()):
530 %(s)s_set_%(c)s(const struct %(s)s *row, const struct smap *%(c)s)
532 struct ovsdb_datum datum;
536 struct smap_node *node;
539 datum.n = smap_count(%(c)s);
540 datum.keys = xmalloc(datum.n * sizeof *datum.keys);
541 datum.values = xmalloc(datum.n * sizeof *datum.values);
544 SMAP_FOR_EACH (node, %(c)s) {
545 datum.keys[i].string = xstrdup(node->key);
546 datum.values[i].string = xstrdup(node->value);
549 ovsdb_datum_sort_unique(&datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
551 ovsdb_datum_init_empty(&datum);
553 ovsdb_idl_txn_write(&row->header_,
554 &%(s)s_columns[%(S)s_COL_%(C)s],
557 """ % {'s': structName,
558 'S': structName.upper(),
560 'C': columnName.upper()}
565 members = cMembers(prefix, columnName, column, True)
566 keyVar = members[0]['name']
570 valueVar = members[1]['name']
572 nVar = members[2]['name']
575 nVar = members[1]['name']
576 print '%(s)s_set_%(c)s(const struct %(s)s *row, %(args)s)' % \
577 {'s': structName, 'c': columnName,
578 'args': ', '.join(['%(type)s%(name)s' % m for m in members])}
580 print " struct ovsdb_datum datum;"
581 if type.n_min == 1 and type.n_max == 1:
582 print " union ovsdb_atom key;"
584 print " union ovsdb_atom value;"
586 print " ovs_assert(inited);"
587 print " datum.n = 1;"
588 print " datum.keys = &key;"
589 print " " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar)
591 print " datum.values = &value;"
592 print " "+ type.value.assign_c_value_casting_away_const("value.%s" % type.value.type.to_string(), valueVar)
594 print " datum.values = NULL;"
595 txn_write_func = "ovsdb_idl_txn_write_clone"
596 elif type.is_optional_pointer():
597 print " union ovsdb_atom key;"
599 print " ovs_assert(inited);"
600 print " if (%s) {" % keyVar
601 print " datum.n = 1;"
602 print " datum.keys = &key;"
603 print " " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), keyVar)
605 print " datum.n = 0;"
606 print " datum.keys = NULL;"
608 print " datum.values = NULL;"
609 txn_write_func = "ovsdb_idl_txn_write_clone"
610 elif type.n_max == 1:
611 print " union ovsdb_atom key;"
613 print " ovs_assert(inited);"
614 print " if (%s) {" % nVar
615 print " datum.n = 1;"
616 print " datum.keys = &key;"
617 print " " + type.key.assign_c_value_casting_away_const("key.%s" % type.key.type.to_string(), "*" + keyVar)
619 print " datum.n = 0;"
620 print " datum.keys = NULL;"
622 print " datum.values = NULL;"
623 txn_write_func = "ovsdb_idl_txn_write_clone"
627 print " ovs_assert(inited);"
628 print " datum.n = %s;" % nVar
629 print " datum.keys = %s ? xmalloc(%s * sizeof *datum.keys) : NULL;" % (nVar, nVar)
631 print " datum.values = xmalloc(%s * sizeof *datum.values);" % nVar
633 print " datum.values = NULL;"
634 print " for (i = 0; i < %s; i++) {" % nVar
635 print " " + type.key.copyCValue("datum.keys[i].%s" % type.key.type.to_string(), "%s[i]" % keyVar)
637 print " " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_string(), "%s[i]" % valueVar)
640 valueType = type.value.toAtomicType()
642 valueType = "OVSDB_TYPE_VOID"
643 print " ovsdb_datum_sort_unique(&datum, %s, %s);" % (
644 type.key.toAtomicType(), valueType)
645 txn_write_func = "ovsdb_idl_txn_write"
646 print " %(f)s(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s], &datum);" \
647 % {'f': txn_write_func,
649 'S': structName.upper(),
650 'C': columnName.upper()}
654 print "\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % (
655 structName, structName.upper())
657 static void\n%s_columns_init(void)
659 struct ovsdb_idl_column *c;\
661 for columnName, column in sorted(table.columns.iteritems()):
662 cs = "%s_col_%s" % (structName, columnName)
663 d = {'cs': cs, 'c': columnName, 's': structName}
669 print " /* Initialize %(cs)s. */" % d
670 print " c = &%(cs)s;" % d
671 print " c->name = \"%(c)s\";" % d
672 print column.type.cInitType(" ", "c->type")
673 print " c->mutable = %s;" % mutable
674 print " c->parse = %(s)s_parse_%(c)s;" % d
675 print " c->unparse = %(s)s_unparse_%(c)s;" % d
680 print "struct ovsdb_idl_table_class %stable_classes[%sN_TABLES] = {" % (prefix, prefix.upper())
681 for tableName, table in sorted(schema.tables.iteritems()):
682 structName = "%s%s" % (prefix, tableName.lower())
687 print " {\"%s\", %s," % (tableName, is_root)
688 print " %s_columns, ARRAY_SIZE(%s_columns)," % (
689 structName, structName)
690 print " sizeof(struct %s), %s_init__}," % (structName, structName)
694 print "\nstruct ovsdb_idl_class %sidl_class = {" % prefix
695 print " \"%s\", %stable_classes, ARRAY_SIZE(%stable_classes)" % (
696 schema.name, prefix, prefix)
699 # global init function
707 assert_single_threaded();
710 for tableName, table in sorted(schema.tables.iteritems()):
711 structName = "%s%s" % (prefix, tableName.lower())
712 print " %s_columns_init();" % structName
716 /* Return the schema version. The caller must not free the returned value. */
718 %sget_db_version(void)
722 """ % (prefix, schema.version)
726 def ovsdb_escape(string):
730 raise ovs.db.error.Error("strings may not contain null bytes")
744 return '\\x%02x' % ord(c)
745 return re.sub(r'["\\\000-\037]', escape, string)
749 %(argv0)s: ovsdb schema compiler
750 usage: %(argv0)s [OPTIONS] COMMAND ARG...
752 The following commands are supported:
753 annotate SCHEMA ANNOTATIONS print SCHEMA combined with ANNOTATIONS
754 c-idl-header IDL print C header file for IDL
755 c-idl-source IDL print C source file for IDL implementation
756 nroff IDL print schema documentation in nroff format
758 The following options are also available:
759 -h, --help display this help message
760 -V, --version display version information\
761 """ % {'argv0': argv0}
764 if __name__ == "__main__":
767 options, args = getopt.gnu_getopt(sys.argv[1:], 'C:hV',
771 except getopt.GetoptError, geo:
772 sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
775 for key, value in options:
776 if key in ['-h', '--help']:
778 elif key in ['-V', '--version']:
779 print "ovsdb-idlc (Open vSwitch) @VERSION@"
780 elif key in ['-C', '--directory']:
785 optKeys = [key for key, value in options]
788 sys.stderr.write("%s: missing command argument "
789 "(use --help for help)\n" % argv0)
792 commands = {"annotate": (annotateSchema, 2),
793 "c-idl-header": (printCIDLHeader, 1),
794 "c-idl-source": (printCIDLSource, 1)}
796 if not args[0] in commands:
797 sys.stderr.write("%s: unknown command \"%s\" "
798 "(use --help for help)\n" % (argv0, args[0]))
801 func, n_args = commands[args[0]]
802 if len(args) - 1 != n_args:
803 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
805 % (argv0, args[0], n_args, len(args) - 1))
809 except ovs.db.error.Error, e:
810 sys.stderr.write("%s: %s\n" % (argv0, e))