Commit 98994460 authored by Robert Bradshaw's avatar Robert Bradshaw

Share utility code between modules.

parent 67c183d5
...@@ -9,6 +9,7 @@ cython.declare(os=object, re=object, operator=object, ...@@ -9,6 +9,7 @@ cython.declare(os=object, re=object, operator=object,
Utils=object, SourceDescriptor=object, StringIOTree=object, Utils=object, SourceDescriptor=object, StringIOTree=object,
DebugFlags=object, basestring=object) DebugFlags=object, basestring=object)
from md5 import md5
import os import os
import re import re
import sys import sys
...@@ -282,12 +283,22 @@ class UtilityCodeBase(object): ...@@ -282,12 +283,22 @@ class UtilityCodeBase(object):
proto, impl = util.proto, util.impl proto, impl = util.proto, util.impl
return util.format_code(proto), util.format_code(impl) return util.format_code(proto), util.format_code(impl)
def format_code(self, code_string, replace_empty_lines=re.compile(r'\n\n+').sub): common_include_dir = "/tmp/cython_includes"
def format_code(self, code_string, replace_empty_lines=re.compile(r'\n\n+').sub, type='unknown'):
""" """
Format a code section for output. Format a code section for output.
""" """
if code_string: if code_string:
code_string = replace_empty_lines('\n', code_string.strip()) + '\n\n' code_string = replace_empty_lines('\n', code_string.strip()) + '\n\n'
if self.common_include_dir and len(code_string) > 1024:
filename = "%s_%s_%s.h" % (self.name, type, md5(code_string).hexdigest())
path = os.path.join(self.common_include_dir, filename)
if not os.path.exists(path):
tmp_path = '%s.tmp%s' % (path, os.getpid())
open(tmp_path, 'w').write(code_string)
os.path.rename(tmp_path, path)
code_string = '#include "%s"\n' % path
return code_string return code_string
def __str__(self): def __str__(self):
...@@ -391,15 +402,15 @@ class UtilityCode(UtilityCodeBase): ...@@ -391,15 +402,15 @@ class UtilityCode(UtilityCodeBase):
for dependency in self.requires: for dependency in self.requires:
output.use_utility_code(dependency) output.use_utility_code(dependency)
if self.proto: if self.proto:
output[self.proto_block].put(self.format_code(self.proto)) output[self.proto_block].put(self.format_code(self.proto, type='proto'))
if self.impl: if self.impl:
output['utility_code_def'].put(self.format_code( output['utility_code_def'].put(self.format_code(
self.inject_string_constants(self.impl, output))) self.inject_string_constants(self.impl, output), type='impl'))
if self.init: if self.init:
writer = output['init_globals'] writer = output['init_globals']
writer.putln("/* %s.init */" % self.name) writer.putln("/* %s.init */" % self.name)
if isinstance(self.init, basestring): if isinstance(self.init, basestring):
writer.put(self.format_code(self.init)) writer.put(self.format_code(self.init, type='init'))
else: else:
self.init(writer, output.module_pos) self.init(writer, output.module_pos)
writer.putln(writer.error_goto_if_PyErr(output.module_pos)) writer.putln(writer.error_goto_if_PyErr(output.module_pos))
...@@ -407,7 +418,7 @@ class UtilityCode(UtilityCodeBase): ...@@ -407,7 +418,7 @@ class UtilityCode(UtilityCodeBase):
if self.cleanup and Options.generate_cleanup_code: if self.cleanup and Options.generate_cleanup_code:
writer = output['cleanup_globals'] writer = output['cleanup_globals']
if isinstance(self.cleanup, basestring): if isinstance(self.cleanup, basestring):
writer.put(self.format_code(self.cleanup)) writer.put(self.format_code(self.cleanup, type='cleanup'))
else: else:
self.cleanup(writer, output.module_pos) self.cleanup(writer, output.module_pos)
...@@ -868,7 +879,7 @@ class GlobalState(object): ...@@ -868,7 +879,7 @@ class GlobalState(object):
] ]
def __init__(self, writer, module_node, emit_linenums=False): def __init__(self, writer, module_node, emit_linenums=False, common_utility_include_dir=None):
self.filename_table = {} self.filename_table = {}
self.filename_list = [] self.filename_list = []
self.input_file_contents = {} self.input_file_contents = {}
...@@ -876,6 +887,7 @@ class GlobalState(object): ...@@ -876,6 +887,7 @@ class GlobalState(object):
self.declared_cnames = {} self.declared_cnames = {}
self.in_utility_code_generation = False self.in_utility_code_generation = False
self.emit_linenums = emit_linenums self.emit_linenums = emit_linenums
self.common_utility_include_dir = common_utility_include_dir
self.parts = {} self.parts = {}
self.module_node = module_node # because some utility code generation needs it self.module_node = module_node # because some utility code generation needs it
# (generating backwards-compatible Get/ReleaseBuffer # (generating backwards-compatible Get/ReleaseBuffer
......
...@@ -655,4 +655,5 @@ default_options = dict( ...@@ -655,4 +655,5 @@ default_options = dict(
language_level = 2, language_level = 2,
gdb_debug = False, gdb_debug = False,
compile_time_env = None, compile_time_env = None,
common_utility_include_dir = None,
) )
...@@ -300,7 +300,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -300,7 +300,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else: else:
emit_linenums = options.emit_linenums emit_linenums = options.emit_linenums
rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback) rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback)
globalstate = Code.GlobalState(rootwriter, self, emit_linenums) globalstate = Code.GlobalState(rootwriter, self, emit_linenums, options.common_utility_include_dir)
globalstate.initialize_main_c_code() globalstate.initialize_main_c_code()
h_code = globalstate['h_code'] h_code = globalstate['h_code']
......
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