- while getToken():
- if token in ("#ifdef", "#ifndef", "#include",
- "#endif", "#elif", "#else", '#define'):
- skipDirective()
- elif match('enum'):
- forceId()
- enum_tag = token
- getToken()
-
- forceMatch("{")
-
- constants = []
- while isId(token):
- constants.append(token)
- getToken()
- if match('='):
- while token != ',' and token != '}':
- getToken()
- match(',')
-
- forceMatch('}')
-
- if enum_tag == "ofp_error_type":
- error_types = {}
- for error_type in constants:
- error_types[error_type] = []
- elif enum_tag == 'nx_vendor_code':
- pass
- elif enum_tag.endswith('_code'):
- error_type = 'OFPET_%s' % '_'.join(enum_tag.split('_')[1:-1]).upper()
- if error_type not in error_types:
- fatal("enum %s looks like an error code enumeration but %s is unknown" % (enum_tag, error_type))
- error_types[error_type] += constants
- elif token in ('struct', 'union'):
- getToken()
- forceId()
- getToken()
- forceMatch('{')
- while not match('}'):
- getToken()
- elif match('OFP_ASSERT') or match('BOOST_STATIC_ASSERT'):
- while token != ';':
- getToken()
- else:
- fatal("parse error")
+
+ while True:
+ getLine()
+ if re.match('enum ofperr', line):
+ break
+
+ while True:
+ getLine()
+ if line.startswith('/*') or not line or line.isspace():
+ continue
+ elif re.match('}', line):
+ break
+
+ if not line.lstrip().startswith('/*'):
+ fatal("unexpected syntax between errors")
+
+ comment = line.lstrip()[2:].strip()
+ while not comment.endswith('*/'):
+ getLine()
+ if line.startswith('/*') or not line or line.isspace():
+ fatal("unexpected syntax within error")
+ comment += ' %s' % line.lstrip('* \t').rstrip(' \t\r\n')
+ comment = comment[:-2].rstrip()
+
+ m = re.match('Expected: (.*)\.$', comment)
+ if m:
+ expected_errors[m.group(1)] = (fileName, lineNumber)
+ continue
+
+ m = re.match('((?:.(?!\. ))+.)\. (.*)$', comment)
+ if not m:
+ fatal("unexpected syntax between errors")
+
+ dsts, comment = m.groups()
+
+ getLine()
+ m = re.match('\s+(?:OFPERR_((?:OFP|NX)[A-Z0-9_]+))(\s*=\s*OFPERR_OFS)?,',
+ line)
+ if not m:
+ fatal("syntax error expecting enum value")
+
+ enum = m.group(1)
+
+ comments.append(re.sub('\[[^]]*\]', '', comment))
+ names.append(enum)
+
+ for dst in dsts.split(', '):
+ m = re.match(r'([A-Z0-9.+]+)\((\d+|(0x)[0-9a-fA-F]+)(?:,(\d+))?\)$', dst)
+ if not m:
+ fatal("%s: syntax error in destination" % dst)
+ targets = m.group(1)
+ if m.group(3):
+ base = 16
+ else:
+ base = 10
+ type_ = int(m.group(2), base)
+ if m.group(4):
+ code = int(m.group(4))
+ else:
+ code = None
+
+ target_map = {"OF1.0+": ("OF1.0", "OF1.1", "OF1.2", "OF1.3"),
+ "OF1.1+": ("OF1.1", "OF1.2", "OF1.3"),
+ "OF1.2+": ("OF1.2", "OF1.3"),
+ "OF1.3+": ("OF1.3",),
+ "OF1.0": ("OF1.0",),
+ "OF1.1": ("OF1.1",),
+ "OF1.2": ("OF1.2",),
+ "OF1.3": ("OF1.3",),
+ "NX1.0+": ("OF1.0", "OF1.1", "OF1.2", "OF1.3"),
+ "NX1.1+": ("OF1.1", "OF1.2", "OF1.3"),
+ "NX1.2+": ("OF1.2", "OF1.3"),
+ "NX1.3+": ("OF1.3",),
+ "NX1.0": ("OF1.0",),
+ "NX1.1": ("OF1.1",),
+ "NX1.2": ("OF1.2",),
+ "NX1.3": ("OF1.3",)}
+ if targets not in target_map:
+ fatal("%s: unknown error domain" % targets)
+ if targets.startswith('NX') and code < 0x100:
+ fatal("%s: NX domain code cannot be less than 0x100" % dst)
+ if targets.startswith('OF') and code >= 0x100:
+ fatal("%s: OF domain code cannot be greater than 0x100"
+ % dst)
+ for target in target_map[targets]:
+ domain[target].setdefault(type_, {})
+ if code in domain[target][type_]:
+ msg = "%d,%d in %s means both %s and %s" % (
+ type_, code, target,
+ domain[target][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[target][type_][code][1],
+ domain[target][type_][code][2],
+ dst))
+ else:
+ domain[target][type_][code] = (enum, fileName,
+ lineNumber)
+
+ if enum in reverse[target]:
+ error("%s: %s in %s means both %d,%d and %d,%d." %
+ (dst, enum, target,
+ reverse[target][enum][0],
+ reverse[target][enum][1],
+ type_, code))
+ reverse[target][enum] = (type_, code)
+