diff --git a/scripts/make_errorcodes.py b/scripts/make_errorcodes.py index d2842932..fa45ea48 100755 --- a/scripts/make_errorcodes.py +++ b/scripts/make_errorcodes.py @@ -16,6 +16,7 @@ The script can be run at a new PostgreSQL release to refresh the module. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # License for more details. +import re import sys import urllib2 from collections import defaultdict @@ -48,7 +49,46 @@ def read_base_file(filename): raise ValueError("can't find the separator. Is this the right file?") -def parse_errors(url): +def parse_errors_txt(url): + classes = {} + errors = defaultdict(dict) + + page = urllib2.urlopen(url) + for line in page: + # Strip comments and skip blanks + line = line.split('#')[0].strip() + if not line: + continue + + # Parse a section + m = re.match(r"Section: (Class (..) - .+)", line) + if m: + label, class_ = m.groups() + classes[class_] = label + continue + + # Parse an error + m = re.match(r"(.....)\s+(?:E|W|S)\s+ERRCODE_(\S+)(?:\s+(\S+))?$", line) + if m: + errcode, macro, spec = m.groups() + # error 22008 has 2 macros and 1 def: give priority to the def + # as it's the one we used to parse from sgml + if not spec: + if errcode in errors[class_]: + continue + errlabel = macro.upper() + else: + errlabel = spec.upper() + + errors[class_][errcode] = errlabel + continue + + # We don't expect anything else + raise ValueError("unexpected line:\n%s" % line) + + return classes, errors + +def parse_errors_sgml(url): page = BS(urllib2.urlopen(url)) table = page('table')[1]('tbody')[0] @@ -87,14 +127,25 @@ def parse_errors(url): return classes, errors -errors_url="http://www.postgresql.org/docs/%s/static/errcodes-appendix.html" +errors_sgml_url = \ + "http://www.postgresql.org/docs/%s/static/errcodes-appendix.html" + +errors_txt_url = \ + "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;" \ + "f=src/backend/utils/errcodes.txt;hb=REL%s_STABLE" def fetch_errors(versions): classes = {} errors = defaultdict(dict) for version in versions: - c1, e1 = parse_errors(errors_url % version) + print >> sys.stderr, version + tver = tuple(map(int, version.split('.'))) + if tver < (9, 1): + c1, e1 = parse_errors_sgml(errors_sgml_url % version) + else: + c1, e1 = parse_errors_txt( + errors_txt_url % version.replace('.', '_')) classes.update(c1) for c, cerrs in e1.iteritems(): errors[c].update(cerrs)