You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.1 KiB

  1. #! /usr/bin/env python3
  2. """
  3. This script should be called *manually* when we want to upgrade SSLError
  4. `library` and `reason` mnemnonics to a more recent OpenSSL version.
  5. It takes two arguments:
  6. - the path to the OpenSSL include files' directory
  7. (e.g. openssl-1.0.1-beta3/include/openssl/)
  8. - the path to the C file to be generated
  9. (probably Modules/_ssl_data.h)
  10. """
  11. import datetime
  12. import os
  13. import re
  14. import sys
  15. def parse_error_codes(h_file, prefix):
  16. pat = re.compile(r"#define\W+(%s([\w]+))\W+(\d+)\b" % re.escape(prefix))
  17. codes = []
  18. with open(h_file, "r", encoding="latin1") as f:
  19. for line in f:
  20. match = pat.search(line)
  21. if match:
  22. code, name, num = match.groups()
  23. num = int(num)
  24. codes.append((code, name, num))
  25. return codes
  26. if __name__ == "__main__":
  27. openssl_inc = sys.argv[1]
  28. outfile = sys.argv[2]
  29. use_stdout = outfile == '-'
  30. f = sys.stdout if use_stdout else open(outfile, "w")
  31. error_libraries = (
  32. # (library code, mnemonic, error prefix, header file)
  33. ('ERR_LIB_PEM', 'PEM', 'PEM_R_', 'pem.h'),
  34. ('ERR_LIB_SSL', 'SSL', 'SSL_R_', 'ssl.h'),
  35. ('ERR_LIB_X509', 'X509', 'X509_R_', 'x509.h'),
  36. )
  37. def w(l):
  38. f.write(l + "\n")
  39. w("/* File generated by Tools/ssl/make_ssl_data.py */")
  40. w("/* Generated on %s */" % datetime.datetime.now().isoformat())
  41. w("")
  42. w("static struct py_ssl_library_code library_codes[] = {")
  43. for libcode, mnemo, _, _ in error_libraries:
  44. w(' {"%s", %s},' % (mnemo, libcode))
  45. w(' { NULL }')
  46. w('};')
  47. w("")
  48. w("static struct py_ssl_error_code error_codes[] = {")
  49. for libcode, _, prefix, h_file in error_libraries:
  50. codes = parse_error_codes(os.path.join(openssl_inc, h_file), prefix)
  51. for code, name, num in sorted(codes):
  52. w(' #ifdef %s' % (code))
  53. w(' {"%s", %s, %s},' % (name, libcode, code))
  54. w(' #else')
  55. w(' {"%s", %s, %d},' % (name, libcode, num))
  56. w(' #endif')
  57. w(' { NULL }')
  58. w('};')
  59. if not use_stdout:
  60. f.close()