Commit bf7f5441 authored by Stefan Behnel's avatar Stefan Behnel

parse and annotate the C code in one pass instead of repeated parse+replace operations

parent be431b49
......@@ -131,18 +131,19 @@ function toggleDiv(id) {
f.write(u'<p>Generated by Cython %s\n' % Version.watermark)
c_file = Utils.decode_filename(os.path.basename(target_filename))
f.write(u'<p>Raw output: <a href="%s">%s</a>\n' % (c_file, c_file))
k = 0
replace_py_c_api = re.compile(u'(Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)\(').subn
replace_py_marco_api = re.compile(u'(Py[A-Z][a-z]+_[A-Z][A-Z_]+)\(').subn
replace_pyx_c_api = re.compile(u'(__Pyx_[A-Z][a-z_][A-Za-z_]+)\(').subn
replace_pyx_macro_api = re.compile(u'(__Pyx_[A-Z][A-Z_]+)\(').subn
replace_error_goto = re.compile(ur'((; *if .*)? \{__pyx_filename = .*goto __pyx_L\w+;\})').subn
replace_refnanny = re.compile(u'(__Pyx_X?(GOT|GIVE)REF|__Pyx_RefNanny[A-Za-z]+)').subn
calls = dict((name, 0) for name in
'refnanny py_macro_api py_c_api pyx_macro_api pyx_c_api error_goto'.split())
def annotate(match):
group_name = match.lastgroup
calls[group_name] += 1
return ur"<span class='%s'>%s</span>" % (
group_name, match.group(group_name))
k = 0
code_source_file = self.code.get(source_filename, {})
for line in lines:
k += 1
try:
code = code_source_file[k]
......@@ -152,16 +153,9 @@ function toggleDiv(id) {
for c, cc, html in special_chars:
code = code.replace(c, html)
code, py_c_api_calls = replace_py_c_api(ur"<span class='py_c_api'>\1</span>(", code)
code, pyx_c_api_calls = replace_pyx_c_api(ur"<span class='pyx_c_api'>\1</span>(", code)
code, py_macro_api_calls = replace_py_marco_api(ur"<span class='py_macro_api'>\1</span>(", code)
code, pyx_macro_api_calls = replace_pyx_macro_api(ur"<span class='pyx_macro_api'>\1</span>(", code)
code, refnanny_calls = replace_refnanny(ur"<span class='refnanny'>\1</span>", code)
code, error_goto_calls = replace_error_goto(ur"<span class='error_goto'>\1</span>", code)
code = code.replace(u"<span class='error_goto'>;", u";<span class='error_goto'>")
score = 5*py_c_api_calls + 2*pyx_c_api_calls + py_macro_api_calls + pyx_macro_api_calls - refnanny_calls
code = _parse_code(annotate, code)
score = (5 * calls['py_c_api'] + 2 * calls['pyx_c_api'] +
calls['py_macro_api'] + calls['pyx_macro_api'] - calls['refnanny'])
color = u"FFFF%02x" % int(255/(1+score/10.0))
f.write(u"<pre class='line' style='background-color: #%s' onclick='toggleDiv(\"line%s\")'>" % (color, k))
......@@ -177,6 +171,18 @@ function toggleDiv(id) {
f.close()
_parse_code = re.compile(
ur'(?P<refnanny>__Pyx_X?(?:GOT|GIVE)REF|__Pyx_RefNanny[A-Za-z]+)|'
ur'(?:'
ur'(?P<pyx_macro_api>__Pyx_[A-Z][A-Z_]+)|'
ur'(?P<pyx_c_api>__Pyx_[A-Z][a-z_][A-Za-z_]+)'
ur'(?P<py_macro_api>Py[A-Z][a-z]+_[A-Z][A-Z_]+)|'
ur'(?P<py_c_api>Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]+)|'
ur')(?=\()|' # look-ahead to exclude subsequent '(' from replacement
ur'(?P<error_goto>(?:(?<=;) *if .* +)?\{__pyx_filename = .*goto __pyx_L\w+;\})'
).sub
# TODO: make this cleaner
def escape(raw_string):
raw_string = raw_string.replace(u"\'", ur"&#146;")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment