Solaris doesn't deliver a /usr/bin/cpp. We have our own cpp in
/usr/lib/cpp, and we deliver GNU cpp in /usr/bin/gcpp, but we might not
find those simply by looking in $PATH. So if we fail, try extra hard to
execute another cpp. We try GNU's first, since it's more likely what folks
using pycparser will expect (for instance, it handles C++-style comments).
--- pycparser-2.10/pycparser/__init__.py Sat Aug 3 06:05:22 2013
+++ pycparser-2.10/pycparser/__init__.py Fri Apr 11 14:58:36 2014
@@ -10,6 +10,7 @@
__all__ = ['c_lexer', 'c_parser', 'c_ast']
__version__ = '2.10'
+import errno
from subprocess import Popen, PIPE
from .c_parser import CParser
@@ -28,29 +29,41 @@
When successful, returns the preprocessed file's contents.
Errors from cpp will be printed out.
"""
- path_list = [cpp_path]
- if isinstance(cpp_args, list):
- path_list += cpp_args
- elif cpp_args != '':
- path_list += [cpp_args]
- path_list += [filename]
+ cpp_list = [cpp_path, "/usr/bin/gcpp", "/usr/lib/cpp"]
- try:
- # Note the use of universal_newlines to treat all newlines
- # as \n for Python's purpose
- #
- pipe = Popen( path_list,
- stdout=PIPE,
- universal_newlines=True)
- text = pipe.communicate()[0]
- except OSError as e:
+ for cpp_path in cpp_list:
+ path_list = [cpp_path]
+ if isinstance(cpp_args, list):
+ path_list += cpp_args
+ elif cpp_args != '':
+ path_list += [cpp_args]
+ path_list += [filename]
+
+ try:
+ # Note the use of universal_newlines to treat all newlines
+ # as \n for Python's purpose
+ #
+ pipe = Popen( path_list,
+ stdout=PIPE,
+ universal_newlines=True)
+ text = pipe.communicate()[0]
+ except OSError as e:
+ # If cpp couldn't be found, just try the next one.
+ if e.errno == errno.ENOENT:
+ continue
+ # If we ran into some other error, raise a RuntimeError.
+ raise RuntimeError("Unable to invoke 'cpp'.\n" +
+ ('Original error: %s' % e))
+
+ return text
+
+ else:
+ # If we couldn't find a cpp, then raise a RuntimeError.
raise RuntimeError("Unable to invoke 'cpp'. " +
'Make sure its path was passed correctly\n' +
('Original error: %s' % e))
- return text
-
def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='',
parser=None):
""" Parse a C file using pycparser.