| #! /usr/bin/env python3 |
| |
| """ |
| This script should be called *manually* when we want to upgrade SSLError |
| `library` and `reason` mnemnonics to a more recent OpenSSL version. |
| |
| It takes two arguments: |
| - the path to the OpenSSL include files' directory |
| (e.g. openssl-1.0.1-beta3/include/openssl/) |
| - the path to the C file to be generated |
| (probably Modules/_ssl_data.h) |
| """ |
| |
| import datetime |
| import os |
| import re |
| import sys |
| |
| |
| def parse_error_codes(h_file, prefix): |
| pat = re.compile(r"#define\W+(%s([\w]+))\W+(\d+)\b" % re.escape(prefix)) |
| codes = [] |
| with open(h_file, "r", encoding="latin1") as f: |
| for line in f: |
| match = pat.search(line) |
| if match: |
| code, name, num = match.groups() |
| num = int(num) |
| codes.append((code, name, num)) |
| return codes |
| |
| if __name__ == "__main__": |
| openssl_inc = sys.argv[1] |
| outfile = sys.argv[2] |
| use_stdout = outfile == '-' |
| f = sys.stdout if use_stdout else open(outfile, "w") |
| error_libraries = ( |
| # (library code, mnemonic, error prefix, header file) |
| ('ERR_LIB_PEM', 'PEM', 'PEM_R_', 'pem.h'), |
| ('ERR_LIB_SSL', 'SSL', 'SSL_R_', 'ssl.h'), |
| ('ERR_LIB_X509', 'X509', 'X509_R_', 'x509.h'), |
| ) |
| def w(l): |
| f.write(l + "\n") |
| w("/* File generated by Tools/ssl/make_ssl_data.py */") |
| w("/* Generated on %s */" % datetime.datetime.now().isoformat()) |
| w("") |
| |
| w("static struct py_ssl_library_code library_codes[] = {") |
| for libcode, mnemo, _, _ in error_libraries: |
| w(' {"%s", %s},' % (mnemo, libcode)) |
| w(' { NULL }') |
| w('};') |
| w("") |
| |
| w("static struct py_ssl_error_code error_codes[] = {") |
| for libcode, _, prefix, h_file in error_libraries: |
| codes = parse_error_codes(os.path.join(openssl_inc, h_file), prefix) |
| for code, name, num in sorted(codes): |
| w(' #ifdef %s' % (code)) |
| w(' {"%s", %s, %s},' % (name, libcode, code)) |
| w(' #else') |
| w(' {"%s", %s, %d},' % (name, libcode, num)) |
| w(' #endif') |
| w(' { NULL }') |
| w('};') |
| if not use_stdout: |
| f.close() |