+ for dst in dsts.split(', '):
+ m = re.match(r'([A-Z]+)([0-9.]+)(\+|-[0-9.]+)?\((\d+)(?:,(\d+))?\)$', dst)
+ if not m:
+ fatal("%r: syntax error in destination" % dst)
+ vendor_name = m.group(1)
+ version1_name = m.group(2)
+ version2_name = m.group(3)
+ type_ = int(m.group(4))
+ if m.group(5):
+ code = int(m.group(5))
+ else:
+ code = None
+
+ if vendor_name not in vendor_map:
+ fatal("%s: unknown vendor" % vendor_name)
+ vendor = vendor_map[vendor_name]
+
+ if version1_name not in version_map:
+ fatal("%s: unknown OpenFlow version" % version1_name)
+ v1 = version_map[version1_name]
+
+ if version2_name is None:
+ v2 = v1
+ elif version2_name == "+":
+ v2 = max(version_map.values())
+ elif version2_name[1:] not in version_map:
+ fatal("%s: unknown OpenFlow version" % version2_name[1:])
+ else:
+ v2 = version_map[version2_name[1:]]
+
+ if v2 < v1:
+ fatal("%s%s: %s precedes %s"
+ % (version1_name, version2_name,
+ version2_name, version1_name))
+
+ if vendor == vendor_map['NX']:
+ if v1 >= version_map['1.2'] or v2 >= version_map['1.2']:
+ if code is not None:
+ fatal("%s: NX1.2+ domains do not have codes" % dst)
+ code = 0
+ elif vendor != vendor_map['OF']:
+ if code is not None:
+ fatal("%s: %s domains do not have codes" % vendor_name)
+
+ for version in range(v1, v2 + 1):
+ domain[version].setdefault(vendor, {})
+ domain[version][vendor].setdefault(type_, {})
+ if code in domain[version][vendor][type_]:
+ msg = "%#x,%d,%d in OF%s means both %s and %s" % (
+ vendor, type_, code, version_reverse_map[version],
+ domain[version][vendor][type_][code][0], enum)
+ if msg in expected_errors:
+ del expected_errors[msg]
+ else:
+ error("%s: %s." % (dst, msg))
+ sys.stderr.write("%s:%d: %s: Here is the location "
+ "of the previous definition.\n"
+ % (domain[version][vendor][type_][code][1],
+ domain[version][vendor][type_][code][2],
+ dst))