X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=python%2Fovs%2Fdb%2Ftypes.py;h=fc9fc0a231d8a463a48f5c2d3b3d18d038e6d05d;hb=746cb7604e734c6e220c7a68218d8df50e692a56;hp=f31318625e4c00aea5b918ad1bd54c993a104912;hpb=7cba02e442012a7ae6cfdfe67f858a18057e5470;p=openvswitch diff --git a/python/ovs/db/types.py b/python/ovs/db/types.py index f3131862..fc9fc0a2 100644 --- a/python/ovs/db/types.py +++ b/python/ovs/db/types.py @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010, 2011 Nicira Networks +# Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,16 +13,19 @@ # limitations under the License. import sys +import uuid from ovs.db import error import ovs.db.parser import ovs.db.data import ovs.ovsuuid + class AtomicType(object): - def __init__(self, name, default): + def __init__(self, name, default, python_types): self.name = name self.default = default + self.python_types = python_types @staticmethod def from_string(s): @@ -51,16 +54,17 @@ class AtomicType(object): def default_atom(self): return ovs.db.data.Atom(self, self.default) -VoidType = AtomicType("void", None) -IntegerType = AtomicType("integer", 0) -RealType = AtomicType("real", 0.0) -BooleanType = AtomicType("boolean", False) -StringType = AtomicType("string", "") -UuidType = AtomicType("uuid", ovs.ovsuuid.zero()) +VoidType = AtomicType("void", None, ()) +IntegerType = AtomicType("integer", 0, (int, long)) +RealType = AtomicType("real", 0.0, (int, long, float)) +BooleanType = AtomicType("boolean", False, (bool,)) +StringType = AtomicType("string", "", (str, unicode)) +UuidType = AtomicType("uuid", ovs.ovsuuid.zero(), (uuid.UUID,)) ATOMIC_TYPES = [VoidType, IntegerType, RealType, BooleanType, StringType, UuidType] + def escapeCString(src): dst = "" for c in src: @@ -87,10 +91,13 @@ def escapeCString(src): dst += c return dst + def commafy(x): """Returns integer x formatted in decimal with thousands set off by commas.""" return _commafy("%d" % x) + + def _commafy(s): if s.startswith('-'): return '-' + _commafy(s[1:]) @@ -99,12 +106,14 @@ def _commafy(s): else: return _commafy(s[:-3]) + ',' + _commafy(s[-3:]) + def returnUnchanged(x): return x + class BaseType(object): def __init__(self, type_, enum=None, min=None, max=None, - min_length = 0, max_length=sys.maxint, ref_table_name=None): + min_length=0, max_length=sys.maxint, ref_table_name=None): assert isinstance(type_, AtomicType) self.type = type_ self.enum = enum @@ -143,7 +152,7 @@ class BaseType(object): if value is None: value = default else: - max_value = 2**32 - 1 + max_value = 2 ** 32 - 1 if not (0 <= value <= max_value): raise error.Error("%s out of valid range 0 to %d" % (name, max_value), value) @@ -161,16 +170,19 @@ class BaseType(object): enum = parser.get_optional("enum", []) if enum is not None: - base.enum = ovs.db.data.Datum.from_json(BaseType.get_enum_type(base.type), enum) + base.enum = ovs.db.data.Datum.from_json( + BaseType.get_enum_type(base.type), enum) elif base.type == IntegerType: base.min = parser.get_optional("minInteger", [int, long]) base.max = parser.get_optional("maxInteger", [int, long]) - if base.min is not None and base.max is not None and base.min > base.max: + if (base.min is not None and base.max is not None + and base.min > base.max): raise error.Error("minInteger exceeds maxInteger", json) elif base.type == RealType: base.min = parser.get_optional("minReal", [int, long, float]) base.max = parser.get_optional("maxReal", [int, long, float]) - if base.min is not None and base.max is not None and base.min > base.max: + if (base.min is not None and base.max is not None + and base.min > base.max): raise error.Error("minReal exceeds maxReal", json) elif base.type == StringType: base.min_length = BaseType.__parse_uint(parser, "minLength", 0) @@ -238,7 +250,8 @@ class BaseType(object): return False def has_constraints(self): - return (self.enum is not None or self.min is not None or self.max is not None or + return (self.enum is not None or self.min is not None or + self.max is not None or self.min_length != 0 or self.max_length != sys.maxint or self.ref_table_name is not None) @@ -250,7 +263,7 @@ class BaseType(object): """Returns the type of the 'enum' member for a BaseType whose 'type' is 'atomic_type'.""" return Type(BaseType(atomic_type), None, 1, sys.maxint) - + def is_ref(self): return self.type == UuidType and self.ref_table_name is not None @@ -269,43 +282,52 @@ class BaseType(object): else: return self.type.to_string() - def constraintsToEnglish(self, escapeLiteral=returnUnchanged): + def constraintsToEnglish(self, escapeLiteral=returnUnchanged, + escapeNumber=returnUnchanged): if self.enum: literals = [value.toEnglish(escapeLiteral) for value in self.enum.values] if len(literals) == 2: - return 'either %s or %s' % (literals[0], literals[1]) + english = 'either %s or %s' % (literals[0], literals[1]) else: - return 'one of %s, %s, or %s' % (literals[0], - ', '.join(literals[1:-1]), - literals[-1]) + english = 'one of %s, %s, or %s' % (literals[0], + ', '.join(literals[1:-1]), + literals[-1]) elif self.min is not None and self.max is not None: if self.type == IntegerType: - return 'in range %s to %s' % (commafy(self.min), - commafy(self.max)) + english = 'in range %s to %s' % ( + escapeNumber(commafy(self.min)), + escapeNumber(commafy(self.max))) else: - return 'in range %g to %g' % (self.min, self.max) + english = 'in range %s to %s' % ( + escapeNumber("%g" % self.min), + escapeNumber("%g" % self.max)) elif self.min is not None: if self.type == IntegerType: - return 'at least %s' % commafy(self.min) + english = 'at least %s' % escapeNumber(commafy(self.min)) else: - return 'at least %g' % self.min + english = 'at least %s' % escapeNumber("%g" % self.min) elif self.max is not None: if self.type == IntegerType: - return 'at most %s' % commafy(self.max) + english = 'at most %s' % escapeNumber(commafy(self.max)) else: - return 'at most %g' % self.max + english = 'at most %s' % escapeNumber("%g" % self.max) elif self.min_length != 0 and self.max_length != sys.maxint: if self.min_length == self.max_length: - return 'exactly %d characters long' % (self.min_length) + english = ('exactly %s characters long' + % commafy(self.min_length)) else: - return 'between %d and %d characters long' % (self.min_length, self.max_length) + english = ('between %s and %s characters long' + % (commafy(self.min_length), + commafy(self.max_length))) elif self.min_length != 0: - return 'at least %d characters long' % self.min_length + return 'at least %s characters long' % commafy(self.min_length) elif self.max_length != sys.maxint: - return 'at most %d characters long' % self.max_length + english = 'at most %s characters long' % commafy(self.max_length) else: - return '' + english = '' + + return english def toCType(self, prefix): if self.ref_table_name: @@ -341,7 +363,7 @@ class BaseType(object): BooleanType: '%s = false;', StringType: '%s = NULL;'}[self.type] return pattern % var - + def cInitBaseType(self, indent, var): stmts = [] stmts.append('ovsdb_base_type_init(&%s, %s);' % ( @@ -352,9 +374,11 @@ class BaseType(object): stmts += self.enum.cInitDatum("%s.enum_" % var) if self.type == IntegerType: if self.min is not None: - stmts.append('%s.u.integer.min = INT64_C(%d);' % (var, self.min)) + stmts.append('%s.u.integer.min = INT64_C(%d);' + % (var, self.min)) if self.max is not None: - stmts.append('%s.u.integer.max = INT64_C(%d);' % (var, self.max)) + stmts.append('%s.u.integer.max = INT64_C(%d);' + % (var, self.max)) elif self.type == RealType: if self.min is not None: stmts.append('%s.u.real.min = %d;' % (var, self.min)) @@ -362,15 +386,20 @@ class BaseType(object): stmts.append('%s.u.real.max = %d;' % (var, self.max)) elif self.type == StringType: if self.min_length is not None: - stmts.append('%s.u.string.minLen = %d;' % (var, self.min_length)) + stmts.append('%s.u.string.minLen = %d;' + % (var, self.min_length)) if self.max_length != sys.maxint: - stmts.append('%s.u.string.maxLen = %d;' % (var, self.max_length)) + stmts.append('%s.u.string.maxLen = %d;' + % (var, self.max_length)) elif self.type == UuidType: if self.ref_table_name is not None: - stmts.append('%s.u.uuid.refTableName = "%s";' % (var, escapeCString(self.ref_table_name))) - stmts.append('%s.u.uuid.refType = OVSDB_REF_%s;' % (var, self.ref_type.upper())) + stmts.append('%s.u.uuid.refTableName = "%s";' + % (var, escapeCString(self.ref_table_name))) + stmts.append('%s.u.uuid.refType = OVSDB_REF_%s;' + % (var, self.ref_type.upper())) return '\n'.join([indent + stmt for stmt in stmts]) + class Type(object): DEFAULT_MIN = 1 DEFAULT_MAX = 1 @@ -433,7 +462,7 @@ class Type(object): return json else: raise error.Error("bad min or max value", json) - + @staticmethod def from_json(json): if type(json) in [str, unicode]: @@ -494,13 +523,14 @@ class Type(object): else: if self.n_max == sys.maxint: if self.n_min: - quantity = "%d or more " % self.n_min + quantity = "%s or more " % commafy(self.n_min) else: quantity = "" elif self.n_min: - quantity = "%d to %d " % (self.n_min, self.n_max) + quantity = "%s to %s " % (commafy(self.n_min), + commafy(self.n_max)) else: - quantity = "up to %d " % self.n_max + quantity = "up to %s " % commafy(self.n_max) if self.value: return "map of %s%s-%s pairs" % (quantity, keyName, valueName) @@ -511,9 +541,11 @@ class Type(object): plural = keyName + "s" return "set of %s%s" % (quantity, plural) - def constraintsToEnglish(self, escapeLiteral=returnUnchanged): + def constraintsToEnglish(self, escapeLiteral=returnUnchanged, + escapeNumber=returnUnchanged): constraints = [] - keyConstraints = self.key.constraintsToEnglish(escapeLiteral) + keyConstraints = self.key.constraintsToEnglish(escapeLiteral, + escapeNumber) if keyConstraints: if self.value: constraints.append('key %s' % keyConstraints) @@ -521,12 +553,13 @@ class Type(object): constraints.append(keyConstraints) if self.value: - valueConstraints = self.value.constraintsToEnglish(escapeLiteral) + valueConstraints = self.value.constraintsToEnglish(escapeLiteral, + escapeNumber) if valueConstraints: constraints.append('value %s' % valueConstraints) return ', '.join(constraints) - + def cDeclComment(self): if self.n_min == 1 and self.n_max == 1 and self.key.type == StringType: return "\t/* Always nonnull. */" @@ -547,4 +580,3 @@ class Type(object): n_max = self.n_max initMax = "%s%s.n_max = %s;" % (indent, var, n_max) return "\n".join((initKey, initValue, initMin, initMax)) -