X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Fovsdb-idlc.in;h=6a0303dbbfa770590e665d6b38a9ccd4797cae51;hb=76f105d9be03588c2d5ec0b94ff769a1d269f2e4;hp=2426e2dacc9d966052e4c3075d0eca6d60dedcb7;hpb=bfc96d9b50ae119fcbf39a9511bd9f662e7ad390;p=openvswitch diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in index 2426e2da..6a0303db 100755 --- a/ovsdb/ovsdb-idlc.in +++ b/ovsdb/ovsdb-idlc.in @@ -8,365 +8,9 @@ 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 len(validTypes) and 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 UUID: - x = "[0-9a-fA-f]" - uuidRE = re.compile("^(%s{8})-(%s{4})-(%s{4})-(%s{4})-(%s{4})(%s{8})$" - % (x, x, x, x, x, x)) - - def __init__(self, value): - self.value = value - - @staticmethod - def fromString(s): - if not uuidRE.match(s): - raise Error("%s is not a valid UUID" % s) - return UUID(s) - - @staticmethod - def fromJson(json): - if UUID.isValidJson(json): - return UUID(json[1]) - else: - raise Error("%s is not valid JSON for a UUID" % json) - - @staticmethod - def isValidJson(json): - return len(json) == 2 and json[0] == "uuid" and uuidRE.match(json[1]) - - def toJson(self): - return ["uuid", self.value] - - def cInitUUID(self, var): - m = re.match(self.value) - return ["%s.parts[0] = 0x%s;" % (var, m.group(1)), - "%s.parts[1] = 0x%s%s;" % (var, m.group(2), m.group(3)), - "%s.parts[2] = 0x%s%s;" % (var, m.group(4), m.group(5)), - "%s.parts[3] = 0x%s;" % (var, m.group(6))] - -class Atom: - def __init__(self, type, value): - self.type = type - self.value = value - - @staticmethod - def fromJson(type_, json): - if ((type_ == 'integer' and type(json) in [int, long]) - or (type_ == 'real' and type(json) in [int, long, float]) - or (type_ == 'boolean' and json in [True, False]) - or (type_ == 'string' and type(json) in [str, unicode])): - return Atom(type_, json) - elif type_ == 'uuid': - return UUID.fromJson(json) - else: - raise Error("%s is not valid JSON for type %s" % (json, type_)) - - def toJson(self): - if self.type == 'uuid': - return self.value.toString() - else: - return self.value - - def cInitAtom(self, var): - if self.type == 'integer': - return ['%s.integer = %d;' % (var, self.value)] - elif self.type == 'real': - return ['%s.real = %.15g;' % (var, self.value)] - elif self.type == 'boolean': - if self.value: - return ['%s.boolean = true;'] - else: - return ['%s.boolean = false;'] - elif self.type == 'string': - return ['%s.string = xstrdup("%s");' - % (var, escapeCString(self.value))] - elif self.type == 'uuid': - return self.value.cInitUUID(var) - -class BaseType: - def __init__(self, type, - enum=None, - refTable=None, - minInteger=None, maxInteger=None, - minReal=None, maxReal=None, - minLength=None, maxLength=None): - self.type = type - self.enum = enum - self.refTable = refTable - self.minInteger = minInteger - self.maxInteger = maxInteger - self.minReal = minReal - self.maxReal = maxReal - 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) - enum = getMember(json, 'enum', [], description) - if enum: - enumType = Type(atomicType, None, 0, 'unlimited') - enum = Datum.fromJson(enumType, enum) - 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) - minLength = getMember(json, 'minLength', [int], description) - maxLength = getMember(json, 'minLength', [int], description) - return BaseType(atomicType, enum, refTable, minInteger, maxInteger, minReal, maxReal, minLength, maxLength) - - def toEnglish(self): - if self.type == 'uuid' and self.refTable: - return self.refTable - else: - return self.type +from OVSDB import * - 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.enum: - stmts.append("%s.enum_ = xmalloc(sizeof *%s.enum_);" - % (var, var)) - stmts += self.enum.cInitDatum("%s.enum_" % var) - 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.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)) +argv0 = sys.argv[0] class Datum: def __init__(self, type, values): @@ -421,7 +65,7 @@ class Datum: return s def parseSchema(filename): - return DbSchema.fromJson(json.load(open(filename, "r"))) + return IdlSchema.fromJson(json.load(open(filename, "r"))) def annotateSchema(schemaFile, annotationFile): schemaJson = json.load(open(schemaFile, "r")) @@ -587,10 +231,7 @@ static struct %(s)s * 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) + print "/* %s table. */" % (tableName) # Parse functions. for columnName, column in sorted(table.columns.iteritems()): @@ -887,25 +528,7 @@ def ovsdb_escape(string): 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 """\ @@ -916,7 +539,7 @@ 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 + nroff IDL print schema documentation in nroff format The following options are also available: -h, --help display this help message @@ -954,8 +577,7 @@ if __name__ == "__main__": commands = {"annotate": (annotateSchema, 2), "c-idl-header": (printCIDLHeader, 1), - "c-idl-source": (printCIDLSource, 1), - "doc": (printDoc, 1)} + "c-idl-source": (printCIDLSource, 1)} if not args[0] in commands: sys.stderr.write("%s: unknown command \"%s\" "