2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 05:02:17 +00:00
Files
python/pyste/src/Pyste/CppParser.py
Bruno da Silva de Oliveira ba0fcd27c3 - Various bug fixes
- Changed the internal code to the way it was


[SVN r18941]
2003-07-04 22:47:27 +00:00

95 lines
3.3 KiB
Python

from GCCXMLParser import ParseDeclarations
import tempfile
import shutil
import os
import os.path
import settings
class CppParserError(Exception): pass
class CppParser:
'Parses a header file and returns a list of declarations'
def __init__(self, includes=None, defines=None):
'includes and defines ar the directives given to gcc'
if includes is None:
includes = []
if defines is None:
defines = []
self.includes = includes
self.defines = defines
def _includeparams(self, filename):
includes = self.includes[:]
filedir = os.path.dirname(filename)
if not filedir:
filedir = '.'
includes.insert(0, filedir)
includes = ['-I "%s"' % x for x in includes]
return ' '.join(includes)
def _defineparams(self):
defines = ['-D "%s"' % x for x in self.defines]
return ' '.join(defines)
def FindFileName(self, include):
if os.path.isfile(include):
return include
for path in self.includes:
filename = os.path.join(path, include)
if os.path.isfile(filename):
return filename
name = os.path.basename(include)
raise RuntimeError, 'Header file "%s" not found!' % name
def parse(self, include, tail=None, decl_name=None):
'''Parses the given filename, and returns (declaration, header). The
header returned is normally the same as the given to this method,
except if tail is not None: in this case, the header is copied to a temp
filename and the tail code is appended to it before being passed on to gcc.
This temp filename is then returned.
'''
filename = self.FindFileName(include)
# copy file to temp folder, if needed
if tail:
tempfilename = tempfile.mktemp('.h')
infilename = tempfilename
shutil.copyfile(filename, infilename)
f = file(infilename, 'a')
f.write('\n\n'+tail)
f.close()
else:
infilename = filename
xmlfile = tempfile.mktemp('.xml')
try:
# get the params
includes = self._includeparams(filename)
defines = self._defineparams()
# call gccxml
cmd = 'gccxml %s %s %s -fxml=%s' \
% (includes, defines, infilename, xmlfile)
if decl_name is not None:
cmd += ' "-fxml-start=%s"' % decl_name
status = os.system(cmd)
if status != 0 or not os.path.isfile(xmlfile):
raise CppParserError, 'Error executing gccxml'
# parse the resulting xml
declarations = ParseDeclarations(xmlfile)
# return the declarations
return declarations, infilename
finally:
if settings.DEBUG and os.path.isfile(xmlfile):
filename = os.path.basename(include)
shutil.copy(xmlfile, os.path.splitext(filename)[0] + '.xml')
# delete the temporary files
try:
os.remove(xmlfile)
if tail:
os.remove(tempfilename)
except OSError: pass