Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated parser, renderers, and generator. The extern declaration gene…
…rator is probably at 90% complete with minor bug fixing and #include->cimport left to do.
- Loading branch information
Showing
5 changed files
with
364 additions
and
314 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,52 @@ | ||
from collections import defaultdict | ||
from cStringIO import StringIO | ||
import os | ||
import re | ||
import subprocess | ||
import tempfile | ||
|
||
import pycparser | ||
|
||
import cy_ast | ||
import translate | ||
import parser | ||
import renderers | ||
|
||
|
||
class CodeGenerator(object): | ||
|
||
def __init__(self, config): | ||
self.config = config | ||
self._translator = translate.ASTTranslator() | ||
self._extern_renderer = renderers.ExternRenderer() | ||
|
||
def _preprocess(self, header): | ||
cmds = ['gcc'] | ||
for inc_dir in self.config.include_dirs: | ||
cmds.append('-I' + inc_dir) | ||
cmds.append('-E') | ||
cmds.append(header.path) | ||
p = subprocess.Popen(cmds, stdout=subprocess.PIPE) | ||
c_code, _ = p.communicate() | ||
|
||
# we need to remove any gcc __attribute__ declarations | ||
# from the code as this will cause PyCParser to fail. | ||
c_code = re.sub('__attribute__\(\(.*?\)\)', '', c_code) | ||
|
||
return c_code | ||
|
||
def _parse(self, c_code): | ||
parser = pycparser.CParser() | ||
ast = parser.parse(c_code) | ||
return ast | ||
|
||
def _translate(self, c_ast): | ||
module_ast = self._translator.translate(c_ast) | ||
return module_ast | ||
|
||
def _render_extern(self, module_ast, header): | ||
return self._extern_renderer.render(module_ast, header) | ||
|
||
def generate(self): | ||
save_dir = self.config.save_dir | ||
for header in self.config.headers: | ||
c_code = self._preprocess(header) | ||
c_ast = self._parse(c_code) | ||
module_ast = self._translate(c_ast) | ||
|
||
extern_code = self._render_extern(module_ast, header) | ||
extern_name = '_' + header.mod_name + '.pxd' | ||
extern_save_pth = os.path.join(save_dir, extern_name) | ||
|
||
with open(extern_save_pth, 'w') as f: | ||
f.write(extern_code) | ||
def _parse(header, include_dirs): | ||
""" Parse the given header file into and ast. The include | ||
dirs are passed along to gccxml. | ||
""" | ||
# A temporary file to store the xml generated by gccxml | ||
xml_file = tempfile.NamedTemporaryFile(suffix='.xml', delete=False) | ||
xml_file.close() | ||
|
||
# buildup the gccxml command | ||
cmds = ['gccxml'] | ||
for inc_dir in include_dirs: | ||
cmds.append('-I' + inc_dir) | ||
cmds.append(header.path) | ||
cmds.append('-fxml=%s' % xml_file.name) | ||
|
||
# we pipe stdout so the preprocessing doesn't dump to the | ||
# shell. We really don't care about it. | ||
p = subprocess.Popen(cmds, stdout=subprocess.PIPE) | ||
cpp, _ = p.communicate() | ||
|
||
# Parse the xml into the ast then delete the temp file | ||
ast = parser.parse(xml_file.name) | ||
os.remove(xml_file.name) | ||
|
||
return ast | ||
|
||
|
||
def _render_extern(ast, header, config): | ||
renderer = renderers.ExternRenderer() | ||
return renderer.render(ast, header.path, config) | ||
|
||
|
||
def generate(config): | ||
save_dir = config.save_dir | ||
include_dirs = config.include_dirs | ||
for header in config.headers: | ||
items = _parse(header, include_dirs) | ||
extern_code = _render_extern(items, header, config) | ||
extern_path = os.path.join(save_dir, header.pxd + '.pxd') | ||
with open(extern_path, 'wb') as f: | ||
f.write(extern_code) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.