class SourceScanner(object):
    def __init__(self):
        self._scanner = CSourceScanner()
        self._filenames = []
        self._cpp_options = []

    # Public API

    def set_cpp_options(self, includes, defines, undefines, cflags=[]):
        self._cpp_options.extend(cflags)
        for prefix, args in [('-I', [os.path.realpath(f) for f in includes]),
                             ('-D', defines), ('-U', undefines)]:
            for arg in (args or []):
                opt = prefix + arg
                if opt not in self._cpp_options:
                    self._cpp_options.append(opt)

    def parse_files(self, filenames):
        for filename in filenames:
            # self._scanner expects file names to be canonicalized and symlinks to be resolved
            filename = os.path.realpath(filename)
            self._scanner.append_filename(filename)
            self._filenames.append(filename)

        headers = []
        for filename in self._filenames:
            if os.path.splitext(filename)[1] in SOURCE_EXTS:
                self._scanner.lex_filename(filename)
            else:
                headers.append(filename)

        self._parse(headers)

    def parse_macros(self, filenames):
        self._scanner.set_macro_scan(True)
        # self._scanner expects file names to be canonicalized and symlinks to be resolved
        self._scanner.parse_macros([os.path.realpath(f) for f in filenames])
        self._scanner.set_macro_scan(False)

    def get_symbols(self):
        for symbol in self._scanner.get_symbols():
            yield SourceSymbol(self._scanner, symbol)

    def get_comments(self):
        return self._scanner.get_comments()

    def get_errors(self):
        return self._scanner.get_errors()

    def dump(self):
        print('-' * 30)
        for symbol in self._scanner.get_symbols():
            print(symbol.ident, symbol.base_type.name, symbol.type)

    # Private

    def _parse(self, filenames):
        if not filenames:
            return

        defines = ['__GI_SCANNER__']
        undefs = []

        cc = CCompiler()

        tmp_fd_cpp, tmp_name_cpp = tempfile.mkstemp(prefix='g-ir-cpp-',
                                                    suffix='.c',
                                                    dir=os.getcwd())
        with os.fdopen(tmp_fd_cpp, 'wb') as fp_cpp:
            self._write_preprocess_src(fp_cpp, defines, undefs, filenames)

        tmpfile_basename = os.path.basename(os.path.splitext(tmp_name_cpp)[0])

        # Output file name of the preprocessor, only really used on non-MSVC,
        # so we want the name to match the output file name of the MSVC preprocessor
        tmpfile_output = tmpfile_basename + '.i'

        cc.preprocess(tmp_name_cpp, tmpfile_output, self._cpp_options)

        if not have_debug_flag('save-temps'):
            os.unlink(tmp_name_cpp)
        self._scanner.parse_file(tmpfile_output)
        if not have_debug_flag('save-temps'):
            os.unlink(tmpfile_output)

    def _write_preprocess_src(self, fp, defines, undefs, filenames):
        # Write to the temp file for feeding into the preprocessor
        for define in defines:
            fp.write(('#ifndef %s\n' % (define, )).encode())
            fp.write(('# define %s\n' % (define, )).encode())
            fp.write('#endif\n'.encode())
        for undef in undefs:
            fp.write(('#undef %s\n' % (undef, )).encode())
        for filename in filenames:
            fp.write(('#include <%s>\n' % (filename, )).encode())
 def __init__(self):
     self._scanner = CSourceScanner()
     self._filenames = []
     self._cpp_options = []
class SourceScanner(object):

    def __init__(self):
        self._scanner = CSourceScanner()
        self._filenames = []
        self._cpp_options = []

    # Public API

    def set_cpp_options(self, includes, defines, undefines, cflags=[]):
        self._cpp_options.extend(cflags)
        for prefix, args in [('-I', includes),
                             ('-D', defines),
                             ('-U', undefines)]:
            for arg in (args or []):
                opt = prefix + arg
                if not opt in self._cpp_options:
                    self._cpp_options.append(opt)

    def parse_files(self, filenames):
        for filename in filenames:
            filename = os.path.abspath(filename)
            self._scanner.append_filename(filename)
            self._filenames.append(filename)

        headers = []
        for filename in filenames:
            if os.path.splitext(filename)[1] in SOURCE_EXTS:
                filename = os.path.abspath(filename)
                self._scanner.lex_filename(filename)
            else:
                headers.append(filename)

        self._parse(headers)

    def parse_macros(self, filenames):
        self._scanner.set_macro_scan(True)
        self._scanner.parse_macros(filenames)
        self._scanner.set_macro_scan(False)

    def get_symbols(self):
        for symbol in self._scanner.get_symbols():
            yield SourceSymbol(self._scanner, symbol)

    def get_comments(self):
        return self._scanner.get_comments()

    def dump(self):
        print '-' * 30
        for symbol in self._scanner.get_symbols():
            print symbol.ident, symbol.base_type.name, symbol.type

    # Private

    def _parse(self, filenames):
        if not filenames:
            return

        defines = ['__GI_SCANNER__']
        undefs = []
        cpp_args = os.environ.get('CC', 'cc').split()  # support CC="ccache gcc"
        if 'cl' in cpp_args:
            # The Microsoft compiler/preprocessor (cl) does not accept
            # source input from stdin (the '-' flag), so we need
            # some help from gcc from MinGW/Cygwin or so.
            # Note that the generated dumper program is
            # still built and linked by Visual C++.
            cpp_args = ['gcc']
        cpp_args += ['-E', '-C', '-I.', '-']
        cpp_args += self._cpp_options

        proc = subprocess.Popen(cpp_args,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE)

        for define in defines:
            proc.stdin.write('#ifndef %s\n' % (define, ))
            proc.stdin.write('# define %s\n' % (define, ))
            proc.stdin.write('#endif\n')
        for undef in undefs:
            proc.stdin.write('#undef %s\n' % (undef, ))
        for filename in filenames:
            filename = os.path.abspath(filename)
            proc.stdin.write('#include <%s>\n' % (filename, ))
        proc.stdin.close()

        tmp_fd, tmp_name = tempfile.mkstemp()
        fp = os.fdopen(tmp_fd, 'w+b')
        while True:
            data = proc.stdout.read(4096)
            if data is None:
                break
            fp.write(data)
            if len(data) < 4096:
                break
        fp.seek(0, 0)

        assert proc, 'Proc was none'
        proc.wait()
        if proc.returncode != 0:
            raise SystemExit('Error while processing the source.')

        self._scanner.parse_file(fp.fileno())
        fp.close()
        os.unlink(tmp_name)
 def __init__(self):
     self._scanner = CSourceScanner()
     self._filenames = []
     self._cpp_options = []
class SourceScanner(object):
    def __init__(self):
        self._scanner = CSourceScanner()
        self._filenames = []
        self._cpp_options = []

    # Public API

    def set_cpp_options(self, includes, defines, undefines, cflags=[]):
        self._cpp_options.extend(cflags)
        for prefix, args in [('-I', [os.path.realpath(f) for f in includes]),
                             ('-D', defines), ('-U', undefines)]:
            for arg in (args or []):
                opt = prefix + arg
                if not opt in self._cpp_options:
                    self._cpp_options.append(opt)

    def parse_files(self, filenames):
        for filename in filenames:
            # self._scanner expects file names to be canonicalized and symlinks to be resolved
            filename = os.path.realpath(filename)
            self._scanner.append_filename(filename)
            self._filenames.append(filename)

        headers = []
        for filename in self._filenames:
            if os.path.splitext(filename)[1] in SOURCE_EXTS:
                self._scanner.lex_filename(filename)
            else:
                headers.append(filename)

        self._parse(headers)

    def parse_macros(self, filenames):
        self._scanner.set_macro_scan(True)
        # self._scanner expects file names to be canonicalized and symlinks to be resolved
        self._scanner.parse_macros([os.path.realpath(f) for f in filenames])
        self._scanner.set_macro_scan(False)

    def get_symbols(self):
        for symbol in self._scanner.get_symbols():
            yield SourceSymbol(self._scanner, symbol)

    def get_comments(self):
        return self._scanner.get_comments()

    def dump(self):
        print '-' * 30
        for symbol in self._scanner.get_symbols():
            print symbol.ident, symbol.base_type.name, symbol.type

    # Private

    def _parse(self, filenames):
        if not filenames:
            return

        defines = ['__GI_SCANNER__']
        undefs = []
        cpp_args = os.environ.get('CC',
                                  'cc').split()  # support CC="ccache gcc"
        if 'cl' in cpp_args:
            # The Microsoft compiler/preprocessor (cl) does not accept
            # source input from stdin (the '-' flag), so we need
            # some help from gcc from MinGW/Cygwin or so.
            # Note that the generated dumper program is
            # still built and linked by Visual C++.
            cpp_args = ['gcc']
        cpp_args += os.environ.get('CPPFLAGS', '').split()
        cpp_args += os.environ.get('CFLAGS', '').split()
        cpp_args += ['-E', '-C', '-I.', '-']
        cpp_args += self._cpp_options

        proc = subprocess.Popen(cpp_args,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE)

        for define in defines:
            proc.stdin.write('#ifndef %s\n' % (define, ))
            proc.stdin.write('# define %s\n' % (define, ))
            proc.stdin.write('#endif\n')
        for undef in undefs:
            proc.stdin.write('#undef %s\n' % (undef, ))
        for filename in filenames:
            proc.stdin.write('#include <%s>\n' % (filename, ))
        proc.stdin.close()

        tmp_fd, tmp_name = tempfile.mkstemp()
        fp = os.fdopen(tmp_fd, 'w+b')
        while True:
            data = proc.stdout.read(4096)
            if data is None:
                break
            fp.write(data)
            if len(data) < 4096:
                break
        fp.seek(0, 0)

        assert proc, 'Proc was none'
        proc.wait()
        if proc.returncode != 0:
            raise SystemExit('Error while processing the source.')

        self._scanner.parse_file(fp.fileno())
        fp.close()
        os.unlink(tmp_name)
class SourceScanner(object):

    def __init__(self):
        self._scanner = CSourceScanner()
        self._filenames = []
        self._cpp_options = []

    # Public API

    def set_cpp_options(self, includes, defines, undefines):
        for prefix, args in [('-I', includes),
                             ('-D', defines),
                             ('-U', undefines)]:
            for arg in (args or []):
                opt = prefix + arg
                if not opt in self._cpp_options:
                    self._cpp_options.append(opt)

    def parse_files(self, filenames):
        for filename in filenames:
            filename = os.path.abspath(filename)
            self._scanner.append_filename(filename)
            self._filenames.append(filename)

        headers = []
        for filename in filenames:
            if (filename.endswith('.c') or filename.endswith('.cpp') or
                filename.endswith('.cc') or filename.endswith('.cxx')):
                filename = os.path.abspath(filename)
                self._scanner.lex_filename(filename)
            else:
                headers.append(filename)

        self._parse(headers)

    def parse_macros(self, filenames):
        self._scanner.set_macro_scan(True)
        self._scanner.parse_macros(filenames)
        self._scanner.set_macro_scan(False)

    def get_symbols(self):
        for symbol in self._scanner.get_symbols():
            yield SourceSymbol(self._scanner, symbol)

    def get_comments(self):
        return self._scanner.get_comments()

    def dump(self):
        print '-'*30
        for symbol in self._scanner.get_symbols():
            print symbol.ident, symbol.base_type.name, symbol.type

    # Private

    def _parse(self, filenames):
        if not filenames:
            return

        defines = ['__GI_SCANNER__']
        undefs = []
        cpp_args = os.environ.get('CC', 'cc').split()
        cpp_args += ['-E', '-C', '-I.', '-']

        cpp_args += self._cpp_options
        proc = subprocess.Popen(cpp_args,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE)

        for define in defines:
            proc.stdin.write('#ifndef %s\n' % (define, ))
            proc.stdin.write('# define %s\n' % (define, ))
            proc.stdin.write('#endif\n')
        for undef in undefs:
            proc.stdin.write('#undef %s\n' % (undef, ))
        for filename in filenames:
            filename = os.path.abspath(filename)
            proc.stdin.write('#include <%s>\n' % (filename, ))
        proc.stdin.close()

        tmp = tempfile.mktemp()
        fp = open(tmp, 'w+')
        while True:
            data = proc.stdout.read(4096)
            if data is None:
                break
            fp.write(data)
            if len(data) < 4096:
                break
        fp.seek(0, 0)

        assert proc, 'Proc was none'
        proc.wait()
        if proc.returncode != 0:
            raise SystemExit('Error while processing the source.')

        self._scanner.parse_file(fp.fileno())
        fp.close()
        os.unlink(tmp)
Exemple #7
0
class SourceScanner(object):

    def __init__(self):
        self._scanner = CSourceScanner()
        self._filenames = []
        self._cpp_options = []

    # Public API

    def set_cpp_options(self, includes, defines, undefines, cflags=[]):
        self._cpp_options.extend(cflags)
        for prefix, args in [('-I', [os.path.realpath(f) for f in includes]),
                             ('-D', defines),
                             ('-U', undefines)]:
            for arg in (args or []):
                opt = prefix + arg
                if opt not in self._cpp_options:
                    self._cpp_options.append(opt)

    def parse_files(self, filenames):
        for filename in filenames:
            # self._scanner expects file names to be canonicalized and symlinks to be resolved
            filename = os.path.realpath(filename)
            self._scanner.append_filename(filename)
            self._filenames.append(filename)

        headers = []
        for filename in self._filenames:
            if os.path.splitext(filename)[1] in SOURCE_EXTS:
                self._scanner.lex_filename(filename)
            else:
                headers.append(filename)

        self._parse(headers)

    def parse_macros(self, filenames):
        self._scanner.set_macro_scan(True)
        # self._scanner expects file names to be canonicalized and symlinks to be resolved
        self._scanner.parse_macros([os.path.realpath(f) for f in filenames])
        self._scanner.set_macro_scan(False)

    def get_symbols(self):
        for symbol in self._scanner.get_symbols():
            yield SourceSymbol(self._scanner, symbol)

    def get_comments(self):
        return self._scanner.get_comments()

    def dump(self):
        print '-' * 30
        for symbol in self._scanner.get_symbols():
            print symbol.ident, symbol.base_type.name, symbol.type

    # Private

    def _parse(self, filenames):
        if not filenames:
            return

        defines = ['__GI_SCANNER__']
        undefs = []

        cc = CCompiler()

        tmp_fd_cpp, tmp_name_cpp = tempfile.mkstemp(prefix='g-ir-cpp-', suffix='.c')
        fp_cpp = os.fdopen(tmp_fd_cpp, 'w')
        self._write_preprocess_src(fp_cpp, defines, undefs, filenames)
        fp_cpp.close()

        tmpfile_basename = os.path.basename(os.path.splitext(tmp_name_cpp)[0])

        # Output file name of the preprocessor, only really used on non-MSVC,
        # so we want the name to match the output file name of the MSVC preprocessor
        tmpfile_output = tmpfile_basename + '.i'

        cc.preprocess(tmp_name_cpp,
                      tmpfile_output,
                      self._cpp_options)

        os.unlink(tmp_name_cpp)
        fp = open(tmpfile_output, 'r')

        self._scanner.parse_file(fp.fileno())
        fp.close()
        os.unlink(tmpfile_output)

    def _write_preprocess_src(self, fp, defines, undefs, filenames):
        # Write to the temp file for feeding into the preprocessor
        for define in defines:
            fp.write('#ifndef %s\n' % (define, ))
            fp.write('# define %s\n' % (define, ))
            fp.write('#endif\n')
        for undef in undefs:
            fp.write('#undef %s\n' % (undef, ))
        for filename in filenames:
            fp.write('#include <%s>\n' % (filename, ))
class SourceScanner(object):
    def __init__(self):
        self._scanner = CSourceScanner()
        self._filenames = []
        self._cpp_options = []

    # Public API

    def set_cpp_options(self, includes, defines, undefines):
        for prefix, args in [('-I', includes), ('-D', defines),
                             ('-U', undefines)]:
            for arg in (args or []):
                opt = prefix + arg
                if not opt in self._cpp_options:
                    self._cpp_options.append(opt)

    def parse_files(self, filenames):
        for filename in filenames:
            filename = os.path.abspath(filename)
            self._scanner.append_filename(filename)

        headers = []
        for filename in filenames:
            if (filename.endswith('.c') or filename.endswith('.cpp')
                    or filename.endswith('.cc') or filename.endswith('.cxx')):
                filename = os.path.abspath(filename)
                self._scanner.lex_filename(filename)
            else:
                headers.append(filename)

        self._parse(headers)
        self._filenames.extend(headers)

    def parse_macros(self, filenames):
        self._scanner.set_macro_scan(True)
        self._scanner.parse_macros(filenames)
        self._scanner.set_macro_scan(False)

    def get_symbols(self):
        for symbol in self._scanner.get_symbols():
            yield SourceSymbol(self._scanner, symbol)

    def get_comments(self):
        return self._scanner.get_comments()

    def dump(self):
        print '-' * 30
        for symbol in self._scanner.get_symbols():
            print symbol.ident, symbol.base_type.name, symbol.type

    # Private

    def _parse(self, filenames):
        if not filenames:
            return

        defines = ['__GI_SCANNER__']
        undefs = []
        cpp_args = os.environ.get('CC', 'cc').split()
        cpp_args += ['-E', '-C', '-I.', '-']

        cpp_args += self._cpp_options
        proc = subprocess.Popen(cpp_args,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE)

        for define in defines:
            proc.stdin.write('#ifndef %s\n' % (define, ))
            proc.stdin.write('# define %s\n' % (define, ))
            proc.stdin.write('#endif\n')
        for undef in undefs:
            proc.stdin.write('#undef %s\n' % (undef, ))
        for filename in filenames:
            filename = os.path.abspath(filename)
            proc.stdin.write('#include <%s>\n' % (filename, ))
        proc.stdin.close()

        tmp = tempfile.mktemp()
        fp = open(tmp, 'w+')
        while True:
            data = proc.stdout.read(4096)
            if data is None:
                break
            fp.write(data)
            if len(data) < 4096:
                break
        fp.seek(0, 0)

        assert proc, 'Proc was none'
        proc.wait()
        if proc.returncode != 0:
            raise SystemExit('Error while processing the source.')

        self._scanner.parse_file(fp.fileno())
        fp.close()
        os.unlink(tmp)
class SourceScanner(object):
    def __init__(self):
        self._scanner = CSourceScanner()
        self._filenames = []
        self._cpp_options = []

    # Public API

    def set_cpp_options(self, includes, defines, undefines):
        for prefix, args in [("-I", includes), ("-D", defines), ("-U", undefines)]:
            for arg in args or []:
                opt = prefix + arg
                if not opt in self._cpp_options:
                    self._cpp_options.append(opt)

    def parse_files(self, filenames):
        for filename in filenames:
            filename = os.path.abspath(filename)
            self._scanner.append_filename(filename)

        headers = []
        for filename in filenames:
            if (
                filename.endswith(".c")
                or filename.endswith(".cpp")
                or filename.endswith(".cc")
                or filename.endswith(".cxx")
            ):
                filename = os.path.abspath(filename)
                self._scanner.lex_filename(filename)
            else:
                headers.append(filename)

        self._parse(headers)
        self._filenames.extend(headers)

    def parse_macros(self, filenames):
        self._scanner.set_macro_scan(True)
        self._scanner.parse_macros(filenames)
        self._scanner.set_macro_scan(False)

    def get_symbols(self):
        for symbol in self._scanner.get_symbols():
            yield SourceSymbol(self._scanner, symbol)

    def get_comments(self):
        return self._scanner.get_comments()

    def dump(self):
        print "-" * 30
        for symbol in self._scanner.get_symbols():
            print symbol.ident, symbol.base_type.name, symbol.type

    # Private

    def _parse(self, filenames):
        if not filenames:
            return

        defines = ["__GI_SCANNER__"]
        undefs = []
        cpp_args = [os.environ.get("CC", "cc"), "-E", "-C", "-I.", "-"]

        cpp_args += self._cpp_options
        proc = subprocess.Popen(cpp_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)

        for define in defines:
            proc.stdin.write("#ifndef %s\n" % (define,))
            proc.stdin.write("# define %s\n" % (define,))
            proc.stdin.write("#endif\n")
        for undef in undefs:
            proc.stdin.write("#undef %s\n" % (undef,))
        for filename in filenames:
            filename = os.path.abspath(filename)
            proc.stdin.write("#include <%s>\n" % (filename,))
        proc.stdin.close()

        tmp = tempfile.mktemp()
        fp = open(tmp, "w+")
        while True:
            data = proc.stdout.read(4096)
            if data is None:
                break
            fp.write(data)
            if len(data) < 4096:
                break
        fp.seek(0, 0)

        assert proc, "Proc was none"
        proc.wait()
        if proc.returncode != 0:
            raise SystemExit("Error while processing the source.")

        self._scanner.parse_file(fp.fileno())
        fp.close()
        os.unlink(tmp)