#! @PYTHON@ import getopt import os import re import sys sys.path.insert(0, "@abs_top_srcdir@/ovsdb") import simplejson as json argv0 = sys.argv[0] class Error(Exception): def __init__(self, msg): Exception.__init__(self) self.msg = msg def getMember(json, name, validTypes, description, default=None): if name in json: member = json[name] if type(member) not in validTypes: raise Error("%s: type mismatch for '%s' member" % (description, name)) return member return default def mustGetMember(json, name, expectedType, description): member = getMember(json, name, expectedType, description) if member == None: raise Error("%s: missing '%s' member" % (description, name)) return member class DbSchema: def __init__(self, name, comment, tables, idlPrefix, idlHeader): self.name = name self.comment = comment self.tables = tables self.idlPrefix = idlPrefix self.idlHeader = idlHeader @staticmethod def fromJson(json): name = mustGetMember(json, 'name', [unicode], 'database') comment = getMember(json, 'comment', [unicode], 'database') tablesJson = mustGetMember(json, 'tables', [dict], 'database') tables = {} for tableName, tableJson in tablesJson.iteritems(): tables[tableName] = TableSchema.fromJson(tableJson, "%s table" % tableName) idlPrefix = mustGetMember(json, 'idlPrefix', [unicode], 'database') idlHeader = mustGetMember(json, 'idlHeader', [unicode], 'database') return DbSchema(name, comment, tables, idlPrefix, idlHeader) class TableSchema: def __init__(self, comment, columns): self.comment = comment self.columns = columns @staticmethod def fromJson(json, description): comment = getMember(json, 'comment', [unicode], description) columnsJson = mustGetMember(json, 'columns', [dict], description) columns = {} for name, json in columnsJson.iteritems(): columns[name] = ColumnSchema.fromJson( json, "column %s in %s" % (name, description)) return TableSchema(comment, columns) class ColumnSchema: def __init__(self, comment, type, persistent): self.comment = comment self.type = type self.persistent = persistent @staticmethod def fromJson(json, description): comment = getMember(json, 'comment', [unicode], description) type = Type.fromJson(mustGetMember(json, 'type', [dict, unicode], description), 'type of %s' % description) ephemeral = getMember(json, 'ephemeral', [bool], description) persistent = ephemeral != True return ColumnSchema(comment, type, persistent) def escapeCString(src): dst = "" for c in src: if c in "\\\"": dst += "\\" + c elif ord(c) < 32: if c == '\n': dst += '\\n' elif c == '\r': dst += '\\r' elif c == '\a': dst += '\\a' elif c == '\b': dst += '\\b' elif c == '\f': dst += '\\f' elif c == '\t': dst += '\\t' elif c == '\v': dst += '\\v' else: dst += '\\%03o' % ord(c) else: dst += c return dst class BaseType: def __init__(self, type, refTable=None, minInteger=None, maxInteger=None, minReal=None, maxReal=None, reMatch=None, reComment=None, minLength=None, maxLength=None): self.type = type self.refTable = refTable self.minInteger = minInteger self.maxInteger = maxInteger self.minReal = minReal self.maxReal = maxReal self.reMatch = reMatch self.reComment = reComment self.minLength = minLength self.maxLength = maxLength @staticmethod def fromJson(json, description): if type(json) == unicode: return BaseType(json) else: atomicType = mustGetMember(json, 'type', [unicode], description) refTable = getMember(json, 'refTable', [unicode], description) minInteger = getMember(json, 'minInteger', [int, long], description) maxInteger = getMember(json, 'maxInteger', [int, long], description) minReal = getMember(json, 'minReal', [int, long, float], description) maxReal = getMember(json, 'maxReal', [int, long, float], description) reMatch = getMember(json, 'reMatch', [unicode], description) reComment = getMember(json, 'reComment', [unicode], description) minLength = getMember(json, 'minLength', [int], description) maxLength = getMember(json, 'minLength', [int], description) return BaseType(atomicType, refTable, minInteger, maxInteger, minReal, maxReal, reMatch, reComment, minLength, maxLength) def toEnglish(self): if self.type == 'uuid' and self.refTable: return self.refTable else: return self.type def toCType(self, prefix): if self.refTable: return "struct %s%s *" % (prefix, self.refTable.lower()) else: return {'integer': 'int64_t ', 'real': 'double ', 'uuid': 'struct uuid ', 'boolean': 'bool ', 'string': 'char *'}[self.type] def copyCValue(self, dst, src): args = {'dst': dst, 'src': src} if self.refTable: return ("%(dst)s = %(src)s->header_.uuid;") % args elif self.type == 'string': return "%(dst)s = xstrdup(%(src)s);" % args else: return "%(dst)s = %(src)s;" % args def initCDefault(self, var, isOptional): if self.refTable: return "%s = NULL;" % var elif self.type == 'string' and not isOptional: return "%s = \"\";" % var else: return {'integer': '%s = 0;', 'real': '%s = 0.0;', 'uuid': 'uuid_zero(&%s);', 'boolean': '%s = false;', 'string': '%s = NULL;'}[self.type] % var def cInitBaseType(self, indent, var): stmts = [] stmts.append('ovsdb_base_type_init(&%s, OVSDB_TYPE_%s);' % ( var, self.type.upper()),) if self.type == 'integer': if self.minInteger != None: stmts.append('%s.u.integer.min = %d;' % (var, self.minInteger)) if self.maxInteger != None: stmts.append('%s.u.integer.max = %d;' % (var, self.maxInteger)) elif self.type == 'real': if self.minReal != None: stmts.append('%s.u.real.min = %d;' % (var, self.minReal)) if self.maxReal != None: stmts.append('%s.u.real.max = %d;' % (var, self.maxReal)) elif self.type == 'string': if self.reMatch != None: if self.reComment != None: reComment = '"%s"' % escapeCString(self.reComment) else: reComment = NULL stmts.append('do_set_regex(&%s, "%s", %s);' % ( var, escapeCString(self.reMatch), reComment)) if self.minLength != None: stmts.append('%s.u.string.minLen = %d;' % (var, self.minLength)) if self.maxLength != None: stmts.append('%s.u.string.maxLen = %d;' % (var, self.maxLength)) elif self.type == 'uuid': if self.refTable != None: stmts.append('%s.u.uuid.refTableName = "%s";' % (var, escapeCString(self.refTable))) return '\n'.join([indent + stmt for stmt in stmts]) class Type: def __init__(self, key, value=None, min=1, max=1): self.key = key self.value = value self.min = min self.max = max @staticmethod def fromJson(json, description): if type(json) == unicode: return Type(BaseType(json)) else: keyJson = mustGetMember(json, 'key', [dict, unicode], description) key = BaseType.fromJson(keyJson, 'key in %s' % description) valueJson = getMember(json, 'value', [dict, unicode], description) if valueJson: value = BaseType.fromJson(valueJson, 'value in %s' % description) else: value = None min = getMember(json, 'min', [int], description, 1) max = getMember(json, 'max', [int, unicode], description, 1) return Type(key, value, min, max) def isScalar(self): return self.min == 1 and self.max == 1 and not self.value def isOptional(self): return self.min == 0 and self.max == 1 def isOptionalPointer(self): return (self.min == 0 and self.max == 1 and not self.value and (self.key.type == 'string' or self.key.refTable)) def toEnglish(self): keyName = self.key.toEnglish() if self.value: valueName = self.value.toEnglish() if self.isScalar(): return keyName elif self.isOptional(): if self.value: return "optional %s-%s pair" % (keyName, valueName) else: return "optional %s" % keyName else: if self.max == "unlimited": if self.min: quantity = "%d or more " % self.min else: quantity = "" elif self.min: quantity = "%d to %d " % (self.min, self.max) else: quantity = "up to %d " % self.max if self.value: return "map of %s%s-%s pairs" % (quantity, keyName, valueName) else: return "set of %s%s" % (quantity, keyName) def cDeclComment(self): if self.min == 1 and self.max == 1 and self.key.type == "string": return "\t/* Always nonnull. */" else: return "" def cInitType(self, indent, var): initKey = self.key.cInitBaseType(indent, "%s.key" % var) if self.value: initValue = self.value.cInitBaseType(indent, "%s.value" % var) else: initValue = ('%sovsdb_base_type_init(&%s.value, ' 'OVSDB_TYPE_VOID);' % (indent, var)) initMin = "%s%s.n_min = %s;" % (indent, var, self.min) if self.max == "unlimited": max = "UINT_MAX" else: max = self.max initMax = "%s%s.n_max = %s;" % (indent, var, max) return "\n".join((initKey, initValue, initMin, initMax)) def parseSchema(filename): return DbSchema.fromJson(json.load(open(filename, "r"))) def annotateSchema(schemaFile, annotationFile): schemaJson = json.load(open(schemaFile, "r")) execfile(annotationFile, globals(), {"s": schemaJson}) json.dump(schemaJson, sys.stdout) def constify(cType, const): if (const and cType.endswith('*') and not cType.endswith('**') and (cType.startswith('struct uuid') or cType.startswith('char'))): return 'const %s' % cType else: return cType def cMembers(prefix, columnName, column, const): type = column.type if type.min == 1 and type.max == 1: singleton = True pointer = '' else: singleton = False if type.isOptionalPointer(): pointer = '' else: pointer = '*' if type.value: key = {'name': "key_%s" % columnName, 'type': constify(type.key.toCType(prefix) + pointer, const), 'comment': ''} value = {'name': "value_%s" % columnName, 'type': constify(type.value.toCType(prefix) + pointer, const), 'comment': ''} members = [key, value] else: m = {'name': columnName, 'type': constify(type.key.toCType(prefix) + pointer, const), 'comment': type.cDeclComment()} members = [m] if not singleton and not type.isOptionalPointer(): members.append({'name': 'n_%s' % columnName, 'type': 'size_t ', 'comment': ''}) return members def printCIDLHeader(schemaFile): schema = parseSchema(schemaFile) prefix = schema.idlPrefix print '''\ /* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */ #ifndef %(prefix)sIDL_HEADER #define %(prefix)sIDL_HEADER 1 #include #include #include #include "ovsdb-idl-provider.h" #include "uuid.h"''' % {'prefix': prefix.upper()} for tableName, table in sorted(schema.tables.iteritems()): structName = "%s%s" % (prefix, tableName.lower()) print " " print "/* %s table. */" % tableName print "struct %s {" % structName print "\tstruct ovsdb_idl_row header_;" for columnName, column in sorted(table.columns.iteritems()): print "\n\t/* %s column. */" % columnName 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)) 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 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 printCIDLSource(schemaFile): schema = parseSchema(schemaFile) prefix = schema.idlPrefix print '''\ /* Generated automatically -- do not modify! -*- buffer-read-only: t -*- */ #include #include %s #include #include #include "ovsdb-data.h" #include "ovsdb-error.h" static bool inited; static void OVS_UNUSED do_set_regex(struct ovsdb_base_type *base, const char *reMatch, const char *reComment) { struct ovsdb_error *error; error = ovsdb_base_type_set_regex(base, reMatch, reComment); if (error) { char *s = ovsdb_error_to_string(error); ovs_error(0, "%%s", s); free(s); ovsdb_error_destroy(error); } }''' % 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 " " if table.comment != None: print "/* %s table (%s). */" % (tableName, table.comment) else: 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 (type.min == 1 and type.max == 1) or type.isOptionalPointer(): print print " assert(inited);" print " if (datum->n >= 1) {" if not type.key.refTable: print " %s = datum->keys[0].%s;" % (keyVar, type.key.type) else: print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->keys[0].uuid));" % (keyVar, prefix, type.key.refTable.lower(), prefix, prefix.upper(), type.key.refTable.upper()) if valueVar: if type.value.refTable: print " %s = datum->values[0].%s;" % (valueVar, type.value.type) else: print " %s = %s%s_cast(ovsdb_idl_get_row_arc(row_, &%stable_classes[%sTABLE_%s], &datum->values[0].uuid));" % (valueVar, prefix, type.value.refTable.lower(), prefix, prefix.upper(), type.value.refTable.upper()) print " } else {" print " %s" % type.key.initCDefault(keyVar, type.min == 0) if valueVar: print " %s" % type.value.initCDefault(valueVar, type.min == 0) print " }" else: if type.max != 'unlimited': print " size_t n = MIN(%d, datum->n);" % type.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.refTable: 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.refTable.lower(), prefix, type.key.refTable.lower(), prefix, prefix.upper(), type.key.refTable.upper()) keySrc = "keyRow" refs.append('keyRow') else: keySrc = "datum->keys[i].%s" % type.key.type if type.value and type.value.refTable: 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.refTable.lower(), prefix, type.value.refTable.lower(), prefix, prefix.upper(), type.value.refTable.upper()) valueSrc = "valueRow" refs.append('valueRow') elif valueVar: valueSrc = "datum->values[i].%s" % type.value.type 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.min != 1 or type.max != 1) and not type.isOptionalPointer(): 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])); } ''' % {'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()} # 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 if type.value: valueVar = members[1]['name'] if len(members) > 2: nVar = members[2]['name'] else: if len(members) > 1: nVar = members[1]['name'] print '%(s)s_set_%(c)s(const struct %(s)s *row, %(args)s)' % \ {'s': structName, 'c': columnName, 'args': ', '.join(['%(type)s%(name)s' % m for m in members])} print "{" print " struct ovsdb_datum datum;" if type.min == 1 and type.max == 1: print print " assert(inited);" print " datum.n = 1;" print " datum.keys = xmalloc(sizeof *datum.keys);" print " " + type.key.copyCValue("datum.keys[0].%s" % type.key.type, keyVar) if type.value: print " datum.values = xmalloc(sizeof *datum.values);" print " "+ type.value.copyCValue("datum.values[0].%s" % type.value.type, valueVar) else: print " datum.values = NULL;" elif type.isOptionalPointer(): print print " assert(inited);" print " if (%s) {" % keyVar print " datum.n = 1;" print " datum.keys = xmalloc(sizeof *datum.keys);" print " " + type.key.copyCValue("datum.keys[0].%s" % type.key.type, keyVar) print " } else {" print " datum.n = 0;" print " datum.keys = NULL;" print " }" print " datum.values = NULL;" else: print " size_t i;" print print " assert(inited);" print " datum.n = %s;" % nVar print " datum.keys = xmalloc(%s * sizeof *datum.keys);" % nVar if type.value: print " datum.values = xmalloc(%s * sizeof *datum.values);" % nVar else: print " datum.values = NULL;" print " for (i = 0; i < %s; i++) {" % nVar print " " + type.key.copyCValue("datum.keys[i].%s" % type.key.type, "%s[i]" % keyVar) if type.value: print " " + type.value.copyCValue("datum.values[i].%s" % type.value.type, "%s[i]" % valueVar) print " }" print " ovsdb_idl_txn_write(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s], &datum);" \ % {'s': structName, 'S': structName.upper(), 'C': columnName.upper()} print "}" # Table columns. print "\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % ( structName, structName.upper()) print """ static void\n%s_columns_init(void) { struct ovsdb_idl_column *c;\ """ % structName for columnName, column in sorted(table.columns.iteritems()): cs = "%s_col_%s" % (structName, columnName) d = {'cs': cs, 'c': columnName, 's': structName} print print " /* Initialize %(cs)s. */" % d print " c = &%(cs)s;" % d print " c->name = \"%(c)s\";" % d print column.type.cInitType(" ", "c->type") print " c->parse = %(s)s_parse_%(c)s;" % d print " c->unparse = %(s)s_unparse_%(c)s;" % d print "}" # Table classes. print " " print "struct ovsdb_idl_table_class %stable_classes[%sN_TABLES] = {" % (prefix, prefix.upper()) for tableName, table in sorted(schema.tables.iteritems()): structName = "%s%s" % (prefix, tableName.lower()) print " {\"%s\"," % tableName print " %s_columns, ARRAY_SIZE(%s_columns)," % ( structName, structName) print " sizeof(struct %s)}," % structName print "};" # IDL class. print "\nstruct ovsdb_idl_class %sidl_class = {" % prefix print " \"%s\", %stable_classes, ARRAY_SIZE(%stable_classes)" % ( schema.name, prefix, prefix) print "};" # global init function print """ void %sinit(void) { if (inited) { return; } inited = true; """ % prefix for tableName, table in sorted(schema.tables.iteritems()): structName = "%s%s" % (prefix, tableName.lower()) print " %s_columns_init();" % structName print "}" def ovsdb_escape(string): def escape(match): c = match.group(0) if c == '\0': raise Error("strings may not contain null bytes") elif c == '\\': return '\\\\' elif c == '\n': return '\\n' elif c == '\r': return '\\r' elif c == '\t': return '\\t' elif c == '\b': return '\\b' elif c == '\a': return '\\a' else: return '\\x%02x' % ord(c) return re.sub(r'["\\\000-\037]', escape, string) def printDoc(schemaFile): schema = parseSchema(schemaFile) print schema.name if schema.comment: print schema.comment for tableName, table in sorted(schema.tables.iteritems()): title = "%s table" % tableName print print title print '-' * len(title) if table.comment: print table.comment for columnName, column in sorted(table.columns.iteritems()): print print "%s (%s)" % (columnName, column.type.toEnglish()) if column.comment: print "\t%s" % column.comment def usage(): print """\ %(argv0)s: ovsdb schema compiler usage: %(argv0)s [OPTIONS] COMMAND ARG... The following commands are supported: annotate SCHEMA ANNOTATIONS print SCHEMA combined with ANNOTATIONS c-idl-header IDL print C header file for IDL c-idl-source IDL print C source file for IDL implementation doc IDL print schema documentation The following options are also available: -h, --help display this help message -V, --version display version information\ """ % {'argv0': argv0} sys.exit(0) if __name__ == "__main__": try: try: options, args = getopt.gnu_getopt(sys.argv[1:], 'C:hV', ['directory', 'help', 'version']) except getopt.GetoptError, geo: sys.stderr.write("%s: %s\n" % (argv0, geo.msg)) sys.exit(1) for key, value in options: if key in ['-h', '--help']: usage() elif key in ['-V', '--version']: print "ovsdb-idlc (Open vSwitch) @VERSION@" elif key in ['-C', '--directory']: os.chdir(value) else: sys.exit(0) optKeys = [key for key, value in options] if not args: sys.stderr.write("%s: missing command argument " "(use --help for help)\n" % argv0) sys.exit(1) commands = {"annotate": (annotateSchema, 2), "c-idl-header": (printCIDLHeader, 1), "c-idl-source": (printCIDLSource, 1), "doc": (printDoc, 1)} if not args[0] in commands: sys.stderr.write("%s: unknown command \"%s\" " "(use --help for help)\n" % (argv0, args[0])) sys.exit(1) func, n_args = commands[args[0]] if len(args) - 1 != n_args: sys.stderr.write("%s: \"%s\" requires %d arguments but %d " "provided\n" % (argv0, args[0], n_args, len(args) - 1)) sys.exit(1) func(*args[1:]) except Error, e: sys.stderr.write("%s: %s\n" % (argv0, e.msg)) sys.exit(1) # Local variables: # mode: python # End: