summaryrefslogtreecommitdiff
path: root/update-error-constants.py
diff options
context:
space:
mode:
authorscoder <none@none>2006-06-02 12:01:01 +0200
committerscoder <none@none>2006-06-02 12:01:01 +0200
commit938c96cae5bd54169e4a27d0a6243c53586491cb (patch)
tree83d22c7aa86813857e96bb3d0c06bcb6554f30a9 /update-error-constants.py
parent38dc947e8d29f3694113c38fd2a11906113fb898 (diff)
downloadpython-lxml-938c96cae5bd54169e4a27d0a6243c53586491cb.tar.gz
[svn r1379] support regenerating constants in xmlerror.px? automatically with a script, split long strings to support MSVC
--HG-- branch : trunk
Diffstat (limited to 'update-error-constants.py')
-rw-r--r--update-error-constants.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/update-error-constants.py b/update-error-constants.py
new file mode 100644
index 00000000..ac6449ce
--- /dev/null
+++ b/update-error-constants.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+import sys, os, os.path, re
+
+BUILD_SOURCE_FILE = os.path.join("src", "lxml", "xmlerror.pxi")
+BUILD_DEF_FILE = os.path.join("src", "lxml", "xmlerror.pxd")
+
+if len(sys.argv) < 2 or sys.argv[1].lower() in ('-h', '--help'):
+ print "This script generates the constants in file", BUILD_SOURCE_FILE
+ print "Call as"
+ print sys.argv[0], "/path/to/libxml2-source-dir"
+ sys.exit(len(sys.argv) > 1)
+
+HTML_FILE = os.path.join(sys.argv[1], 'doc', 'html', 'libxml-xmlerror.html')
+
+sys.path.insert(0, 'src')
+from lxml import etree
+
+ENUM_MAP = {
+ 'xmlErrorLevel' : '__ERROR_LEVELS',
+ 'xmlErrorDomain' : '__ERROR_DOMAINS',
+ 'xmlParserErrors' : '__ERROR_TYPES'
+ }
+
+ENUM_ORDER = ('xmlErrorLevel', 'xmlErrorDomain', 'xmlParserErrors')
+
+def split(lines):
+ lines = iter(lines)
+ pre = []
+ for line in lines:
+ pre.append(line)
+ if line.startswith('#') and "BEGIN: GENERATED CONSTANTS" in line:
+ break
+ pre.append('')
+ for line in lines:
+ if line.startswith('#') and "END: GENERATED CONSTANTS" in line:
+ break
+ post = ['', line]
+ post.extend(lines)
+ post.append('')
+ return pre, post
+
+def regenerate_file(filename, result):
+ # read .pxi source file
+ f = open(filename, 'r')
+ pre, post = split(f)
+ f.close()
+
+ # write .pxi source file
+ f = open(filename, 'w')
+ f.write(''.join(pre))
+ f.write('\n'.join(result))
+ f.write(''.join(post))
+ f.close()
+
+def parse_enums(html_file):
+ PARSE_ENUM_NAME = re.compile('\s*enum\s+(\w+)\s*{', re.I).match
+ PARSE_ENUM_VALUE = re.compile('\s*=\s+([0-9]+)\s*(?::\s*(.*))?').match
+ tree = etree.parse(html_file)
+ xpath = etree.XPathEvaluator(tree, {'html' : 'http://www.w3.org/1999/xhtml'})
+
+ enum_dict = {}
+ enums = xpath.evaluate("//html:pre[@class = 'programlisting' and contains(text(), 'Enum') and html:a[@name]]")
+ for enum in enums:
+ enum_name = PARSE_ENUM_NAME(enum.text).group(1)
+ print "Found enum", enum_name
+ entries = []
+ enum_dict[enum_name] = entries
+ for child in enum:
+ name = child.text
+ value, descr = PARSE_ENUM_VALUE(child.tail).groups()
+ entries.append((name, int(value), descr))
+ return enum_dict
+
+enum_dict = parse_enums(HTML_FILE)
+
+# regenerate source files
+pxi_result = []
+append_pxi = pxi_result.append
+pxd_result = []
+append_pxd = pxd_result.append
+
+ctypedef_indent = ' '*4
+constant_indent = ' '*8
+
+append_pxd('cdef extern from "libxml/xmlerror.h":')
+for enum_name in ENUM_ORDER:
+ constants = enum_dict[enum_name]
+ pxi_name = ENUM_MAP[enum_name]
+
+ append_pxd(ctypedef_indent + 'ctypedef enum %s:' % enum_name)
+ append_pxi('cdef object %s' % pxi_name)
+ append_pxi('%s = """\\' % pxi_name)
+ length = 0
+ for name, val, descr in constants:
+ if descr:
+ line = "%-50s = %7d # %s" % (name, val, descr)
+ else:
+ line = "%-50s = %7d" % (name, val)
+
+ append_pxd(constant_indent + line)
+
+ if length + len(line) > 2000: # max string length in MSVC
+ append_pxi('""" + \\')
+ append_pxi('"""\\')
+ length = 0
+ append_pxi(line)
+ length += len(line) + 1
+
+ append_pxd('')
+ append_pxi('"""')
+ append_pxi('')
+
+# write source files
+regenerate_file(BUILD_SOURCE_FILE, pxi_result)
+regenerate_file(BUILD_DEF_FILE, pxd_result)