예제 #1
0
def check(args):
    filename = args[0]

    output = ChunkedIO()
    namespace = Namespace('Test', '1.0')
    logger = MessageLogger.get(namespace=namespace, output=output)
    logger.enable_warnings(True)

    transformer = Transformer(namespace)
    transformer.set_include_paths([
        os.path.join(top_srcdir, 'gir'),
        top_builddir,
        os.path.join(top_builddir, 'gir'),
    ])
    transformer.register_include(Include.from_string('GObject-2.0'))

    ss = SourceScanner()

    options = Options()
    exit_code = process_packages(options, ['gobject-2.0'])
    if exit_code:
        sys.exit(exit_code)
    ss.set_cpp_options(options.cpp_includes, options.cpp_defines,
                       options.cpp_undefines)
    ss.parse_files([filename])
    ss.parse_macros([filename])
    transformer.parse(ss.get_symbols())

    cbp = GtkDocCommentBlockParser()
    blocks = cbp.parse_comment_blocks(ss.get_comments())

    main = MainTransformer(transformer, blocks)
    main.transform()

    final = IntrospectablePass(transformer, blocks)
    final.validate()

    emitted_warnings = [w[w.find(':') + 1:] for w in output.getvalue()]

    expected_warnings = _extract_expected(filename)

    sortkey = lambda x: int(x.split(':')[0])
    expected_warnings.sort(key=sortkey)
    emitted_warnings.sort(key=sortkey)

    if len(expected_warnings) != len(emitted_warnings):
        raise SystemExit("ERROR in '%s': %d warnings were emitted, "
                         "expected %d:\n%s" %
                         (os.path.basename(filename), len(emitted_warnings),
                          len(expected_warnings),
                          _diff(expected_warnings, emitted_warnings)))

    for emitted_warning, expected_warning in zip(emitted_warnings,
                                                 expected_warnings):
        if expected_warning != emitted_warning:
            raise SystemExit(
                "ERROR in '%s': expected warning does not match emitted "
                "warning:\n%s" %
                (filename, _diff([expected_warning], [emitted_warning])))
예제 #2
0
def load_namespace_from_source_string(namespace, source):
    ss = create_scanner_from_source_string(source)
    transformer = Transformer(namespace)
    transformer.parse(ss.get_symbols())
    cbp = GtkDocCommentBlockParser()
    blocks = cbp.parse_comment_blocks(ss.get_comments())
    main = MainTransformer(transformer, blocks)
    main.transform()
예제 #3
0
def annotation_main(args):
    parser = optparse.OptionParser('%prog [options] sources')

    group = optparse.OptionGroup(parser, "Tool modes, one is required")
    group.add_option("-e",
                     "--extract",
                     action="store_true",
                     dest="extract",
                     help="Extract annotations from the input files")
    parser.add_option_group(group)

    group = get_preprocessor_option_group(parser)
    group.add_option("-L",
                     "--library-path",
                     action="append",
                     dest="library_paths",
                     default=[],
                     help="directories to search for libraries")
    group.add_option("",
                     "--pkg",
                     action="append",
                     dest="packages",
                     default=[],
                     help="pkg-config packages to get cflags from")
    parser.add_option_group(group)

    options, args = parser.parse_args(args)

    if not options.extract:
        raise SystemExit("ERROR: Nothing to do")

    if options.packages:
        process_packages(options, options.packages)

    logger = message.MessageLogger.get(namespace=None)

    ss = create_source_scanner(options, args)

    if options.extract:
        parser = GtkDocCommentBlockParser()
        writer = GtkDocCommentBlockWriter(indent=False)
        blocks = parser.parse_comment_blocks(ss.get_comments())

        with encode_stdout('utf-8'):
            print('/' + ('*' * 60) + '/')
            print('/* THIS FILE IS GENERATED DO NOT EDIT */')
            print('/' + ('*' * 60) + '/')
            print('')
            for block in sorted(blocks.values()):
                print(writer.write(block))
                print('')
            print('')
            print('/' + ('*' * 60) + '/')
            print('/* THIS FILE IS GENERATED DO NOT EDIT */')
            print('/' + ('*' * 60) + '/')

    return 0
예제 #4
0
def check(args):
    filename = args[0]

    output = ChunkedIO()
    namespace = Namespace('Test', '1.0')
    logger = MessageLogger.get(namespace=namespace, output=output)
    logger.enable_warnings((WARNING, ERROR, FATAL))

    transformer = Transformer(namespace)
    transformer.set_include_paths([os.path.join(top_srcdir, 'gir'), top_builddir])
    transformer.register_include(Include.from_string('GObject-2.0'))

    ss = SourceScanner()

    options = Options()
    exit_code = process_packages(options, ['gobject-2.0'])
    if exit_code:
        sys.exit(exit_code)
    ss.set_cpp_options(options.cpp_includes, options.cpp_defines, options.cpp_undefines)
    ss.parse_files([filename])
    ss.parse_macros([filename])
    transformer.parse(ss.get_symbols())

    cbp = GtkDocCommentBlockParser()
    blocks = cbp.parse_comment_blocks(ss.get_comments())

    main = MainTransformer(transformer, blocks)
    main.transform()

    final = IntrospectablePass(transformer, blocks)
    final.validate()

    emitted_warnings = [w[w.find(':') + 1:] for w in output.getvalue()]

    expected_warnings = _extract_expected(filename)

    sortkey = lambda x: int(x.split(':')[0])
    expected_warnings.sort(key=sortkey)
    emitted_warnings.sort(key=sortkey)

    if len(expected_warnings) != len(emitted_warnings):
        raise SystemExit("ERROR in '%s': %d warnings were emitted, "
                         "expected %d:\n%s" % (os.path.basename(filename),
                                               len(emitted_warnings),
                                               len(expected_warnings),
                                               _diff(expected_warnings, emitted_warnings)))

    for emitted_warning, expected_warning in zip(emitted_warnings, expected_warnings):
        if expected_warning != emitted_warning:
            raise SystemExit("ERROR in '%s': expected warning does not match emitted "
                             "warning:\n%s" % (filename,
                                               _diff([expected_warning], [emitted_warning])))
def annotation_main(args):
    parser = optparse.OptionParser('%prog [options] sources')

    group = optparse.OptionGroup(parser, "Tool modes, one is required")
    group.add_option("-e", "--extract",
                     action="store_true", dest="extract",
                     help="Extract annotations from the input files")
    parser.add_option_group(group)

    group = get_preprocessor_option_group(parser)
    group.add_option("-L", "--library-path",
                     action="append", dest="library_paths", default=[],
                     help="directories to search for libraries")
    group.add_option("", "--pkg",
                     action="append", dest="packages", default=[],
                     help="pkg-config packages to get cflags from")
    parser.add_option_group(group)

    options, args = parser.parse_args(args)

    if not options.extract:
        raise SystemExit("ERROR: Nothing to do")

    if options.packages:
        process_packages(options, options.packages)

    logger = message.MessageLogger.get(namespace=None)

    ss = create_source_scanner(options, args)

    if options.extract:
        parser = GtkDocCommentBlockParser()
        writer = GtkDocCommentBlockWriter(indent=False)
        blocks = parser.parse_comment_blocks(ss.get_comments())

        with encode_stdout('utf-8'):
            print('/' + ('*' * 60) + '/')
            print('/* THIS FILE IS GENERATED DO NOT EDIT */')
            print('/' + ('*' * 60) + '/')
            print('')
            for block in sorted(blocks.values()):
                print(writer.write(block))
                print('')
            print('')
            print('/' + ('*' * 60) + '/')
            print('/* THIS FILE IS GENERATED DO NOT EDIT */')
            print('/' + ('*' * 60) + '/')

    return 0
예제 #6
0
def scanner_main(args):
    parser = _get_option_parser()
    (options, args) = parser.parse_args(args)

    if options.passthrough_gir:
        passthrough_gir(options.passthrough_gir, sys.stdout)
    if options.test_codegen:
        return test_codegen(options.test_codegen,
                            options.function_decoration,
                            options.include_first_header,
                            options.include_last_header,
                            options.include_first_src,
                            options.include_last_src)

    if hasattr(options, 'filelist') and not options.filelist:
        if len(args) <= 1:
            _error('Need at least one filename')

    if not options.namespace_name:
        _error('Namespace name missing')

    if options.format == 'gir':
        from giscanner.girwriter import GIRWriter as Writer
    else:
        _error("Unknown format: %s" % (options.format, ))

    if not (options.libraries
            or options.program
            or options.header_only):
        _error("Must specify --program or --library")

    namespace = create_namespace(options)
    logger = message.MessageLogger.get(namespace=namespace)
    if options.warn_all:
        logger.enable_warnings((message.WARNING, message.ERROR, message.FATAL))

    transformer = create_transformer(namespace, options)

    packages = set(options.packages)
    packages.update(transformer.get_pkgconfig_packages())
    if packages:
        exit_code = process_packages(options, packages)
        if exit_code:
            return exit_code

    ss = create_source_scanner(options, args)

    cbp = GtkDocCommentBlockParser()
    blocks = cbp.parse_comment_blocks(ss.get_comments())

    # Transform the C symbols into AST nodes
    transformer.parse(ss.get_symbols())

    if not options.header_only:
        shlibs = create_binary(transformer, options, args)
    else:
        shlibs = []

    transformer.namespace.shared_libraries = shlibs

    main = MainTransformer(transformer, blocks)
    main.transform()

    utils.break_on_debug_flag('tree')

    final = IntrospectablePass(transformer, blocks)
    final.validate()

    warning_count = logger.get_warning_count()
    if options.warn_fatal and warning_count > 0:
        message.fatal("warnings configured as fatal")
        return 1
    elif warning_count > 0 and options.warn_all is False:
        print ("g-ir-scanner: %s: warning: %d warnings suppressed (use --warn-all to see them)"
               % (transformer.namespace.name, warning_count, ))

    # Write out AST
    if options.packages_export:
        exported_packages = options.packages_export
    else:
        exported_packages = options.packages

    transformer.namespace.c_includes = options.c_includes
    transformer.namespace.exported_packages = exported_packages
    writer = Writer(transformer.namespace)
    data = writer.get_xml()

    write_output(data, options)

    return 0
예제 #7
0
def doc_translate (args):
    parser = argparse.ArgumentParser()

    parser.add_argument("--packages", nargs="+",
                      action="store", dest="packages",
                      help="CFlags for source scanning")
    parser.add_argument("-I", nargs="+",
                      action="store", dest="cpp_includes", default=[],
                      help="Pre processor include files")
    parser.add_argument("-D", nargs="+",
                      action="store", dest="cpp_defines",
                      help="Pre processor defines")
    parser.add_argument("-U", nargs="+",
                      action="store", dest="cpp_undefines",
                      help="Pre processor undefines")
    parser.add_argument ("-f", "--filenames", action="store", nargs="+",
            dest="filenames")
    parser.add_argument ("-i", "--inplace", action="store_true",
            dest="inplace")

    logger = MessageLogger.get(namespace=None)

    args = parser.parse_args(args[1:])

    filename_block_map = {}

    translator = LegacyTranslator ()

    cflags = []
    if args.packages:
        for p in args.packages:
            includes = PkgConfig ("--cflags %s" % p)
            for include in includes:
                if include:
                    cflags.append (include)

    cpp_includes = []
    for i in args.cpp_includes:
        cpp_includes.append (os.path.realpath (i))
    args.cpp_includes = cpp_includes

    ss = create_source_scanner (args, args.filenames, cflags)
    print "sources scanned"
    cbp = GtkDocCommentBlockParser()
    blocks = cbp.parse_comment_blocks(ss.get_comments())
    for name, block in blocks.iteritems():
        try:
            blocklist = filename_block_map[block.position.filename]
        except:
            blocklist = []
            filename_block_map[block.position.filename] = blocklist
        blocklist.append ((name, block))

    for filename, blocks in filename_block_map.iteritems():
        if args.inplace:
            print "Translating %s" % filename
        res = translate_one (filename, translator, blocks)
        if args.inplace:
            with open (filename, 'w') as f:
                f.write (res)
        else:
            print res
            pass
예제 #8
0
def scanner_main(args):
    parser = _get_option_parser()
    (options, args) = parser.parse_args(args)

    if options.verbose:
        import distutils
        distutils.log.set_threshold(distutils.log.DEBUG)
    if options.passthrough_gir:
        passthrough_gir(options.passthrough_gir, sys.stdout)
    if options.test_codegen:
        return test_codegen(options.test_codegen,
                            options.function_decoration,
                            options.include_first_header,
                            options.include_last_header,
                            options.include_first_src,
                            options.include_last_src)

    if hasattr(options, 'filelist') and not options.filelist:
        if len(args) <= 1:
            _error('Need at least one filename')

    if not options.namespace_name:
        _error('Namespace name missing')

    if options.format == 'gir':
        from giscanner.girwriter import GIRWriter as Writer
    else:
        _error("Unknown format: %s" % (options.format, ))

    if not (options.libraries
            or options.program
            or options.header_only):
        _error("Must specify --program or --library")

    namespace = create_namespace(options)
    logger = message.MessageLogger.get(namespace=namespace)
    if options.warn_all:
        logger.enable_warnings(True)

    transformer = create_transformer(namespace, options)

    packages = set(options.packages)
    packages.update(transformer.get_pkgconfig_packages())
    if packages:
        try:
            process_packages(options, packages)
        except pkgconfig.PkgConfigError as e:
            _error(str(e))

    ss, filenames = create_source_scanner(options, args)

    cbp = GtkDocCommentBlockParser()
    blocks = cbp.parse_comment_blocks(ss.get_comments())

    # Transform the C symbols into AST nodes
    transformer.parse(ss.get_symbols())

    if not options.header_only:
        shlibs = create_binary(transformer, options, args)
    else:
        shlibs = []

    transformer.namespace.shared_libraries = shlibs

    main = MainTransformer(transformer, blocks)
    main.transform()

    utils.break_on_debug_flag('tree')

    final = IntrospectablePass(transformer, blocks)
    final.validate()

    warning_count = logger.get_warning_count()
    if options.warn_fatal and warning_count > 0:
        message.fatal("warnings configured as fatal")
        return 1
    elif warning_count > 0 and options.warn_all is False and options.quiet is False:
        print("g-ir-scanner: %s: warning: %d warnings suppressed "
              "(use --warn-all to see them)" %
              (transformer.namespace.name, warning_count, ))

    # Write out AST
    if options.packages_export:
        exported_packages = options.packages_export
    else:
        exported_packages = options.packages

    transformer.namespace.c_includes = options.c_includes
    transformer.namespace.exported_packages = exported_packages

    sources_top_dirs = get_source_root_dirs(options, filenames)
    writer = Writer(transformer.namespace, sources_top_dirs)
    data = writer.get_encoded_xml()

    write_output(data, options)

    return 0
        def do_test(self):
            output = ChunkedIO()
            logger._output = output

            # Parse GTK-Doc comment block
            commentblock = testcase.find(ns('{}input')).text
            parsed_docblock = GtkDocCommentBlockParser().parse_comment_block(
                commentblock, 'test.c', 1)
            parsed_tree = self.parsed2tree(parsed_docblock).split('\n')
            emitted_messages = [
                w[w.find(':') + 1:].strip() for w in output.getvalue()
            ]

            # Get expected parser output
            expected_docblock = testcase.find(ns('{}parser/{}docblock'))
            expected_tree = self.expected2tree(expected_docblock).split('\n')

            expected_messages = []
            for w in testcase.findall(ns('{}parser/{}messages/{}message')):
                expected_messages.append(w.text.strip())

            # Compare parsed with expected GtkDocCommentBlock
            msg = 'Parsed GtkDocCommentBlock object tree does not match expected output:\n\n'
            msg += '%s\n\n' % (commentblock, )

            diff = difflib.unified_diff(expected_tree,
                                        parsed_tree,
                                        'Expected GtkDocCommentBlock',
                                        'Parsed GtkDocCommentBlock',
                                        n=max(len(expected_tree),
                                              len(parsed_tree)),
                                        lineterm='')
            for line in diff:
                msg += '%s\n' % (line, )

            self.assertTrue(parsed_tree == expected_tree, msg)

            # Compare emitted with expected messages
            msg = 'Emitted messages do not match expected messages:\n\n'
            msg += '%s\n\n' % (commentblock, )
            msg += self._diff_messages(expected_messages, emitted_messages)
            self.assertTrue(
                len(expected_messages) == len(emitted_messages), msg)

            for emitted_message, expected_message in zip(
                    emitted_messages, expected_messages):
                msg = 'Emitted message does not match expected message:\n\n'
                msg += '%s\n\n' % (commentblock, )
                msg += self._diff_messages([expected_message],
                                           [emitted_message])
                self.assertTrue(expected_message == emitted_message, msg)

            # Compare serialized with expected comment block
            expected_serialized = testcase.find(ns('{}output'))
            indent = True

            if expected_serialized is None:
                expected_serialized = ''
            else:
                if 'indent' in expected_serialized.attrib:
                    indent = expected_serialized.attrib['indent']
                    if indent.lower() in ('false', '0'):
                        indent = False
                    elif indent.lower() in ('true', '1'):
                        indent = True
                    else:
                        self.assert_(
                            False, 'Unknown value for "indent" attribute: %s' %
                            (indent))

                expected_serialized = expected_serialized.text + '\n' or None

            commentblockwriter = GtkDocCommentBlockWriter(indent=indent)
            serialized = commentblockwriter.write(parsed_docblock)

            msg = 'Serialized comment block does not match expected output:\n\n'
            msg += self._diff_messages(expected_serialized.split('\n'),
                                       serialized.split('\n'))
            self.assertTrue(expected_serialized == serialized, msg)
예제 #10
0
        sys.exit(1)
    else:
        print('Using GTK-Doc source directory "%s"' % gtkdoc_tests)

    for root, dirs, files in os.walk(gtkdoc_tests):
        for inputfile in files:
            ext = os.path.splitext(inputfile)[-1].lower()
            if 'src' in root and ext in ['.c', '.h']:
                path = os.path.join(root, inputfile)
                print('Reading "%s"' % path)

                relpath = os.path.relpath(path, gtkdoc_tests).split(os.sep)
                relpath = os.path.join(relpath[0], relpath[len(relpath) - 1])

                logger = MessageLogger.get(namespace=None)
                parser = GtkDocCommentBlockParser()
                writer = GtkDocCommentBlockWriter(indent=True)
                logger.enable_warnings(True)

                with io.open(path, 'r') as f:
                    lines = f.readlines()

                chunks = []
                in_comment = False
                chunk_start = 0
                chunk_end = 0

                for line_index, line in enumerate(lines):
                    if not in_comment:
                        if COMMENT_BLOCK_START_RE.match(line):
                            # We are at a line that starts a GTK-Doc comment block
        sys.exit(1)
    else:
        print('Using GTK-Doc source directory "%s"' % gtkdoc_tests)

    for root, dirs, files in os.walk(gtkdoc_tests):
        for inputfile in files:
            ext = os.path.splitext(inputfile)[-1].lower()
            if 'src' in root and ext in ['.c', '.h']:
                path = os.path.join(root, inputfile)
                print('Reading "%s"' % path)

                relpath = os.path.relpath(path, gtkdoc_tests).split(os.sep)
                relpath = os.path.join(relpath[0], relpath[len(relpath) - 1])

                logger = MessageLogger.get(namespace=None)
                parser = GtkDocCommentBlockParser()
                writer = GtkDocCommentBlockWriter(indent=True)
                logger.enable_warnings((ERROR, FATAL))

                with io.open(path, 'rU') as f:
                    lines = f.readlines()

                chunks = []
                in_comment = False
                chunk_start = 0
                chunk_end = 0

                for line_index, line in enumerate(lines):
                    if not in_comment:
                        if COMMENT_BLOCK_START_RE.match(line):
                            # We are at a line that starts a GTK-Doc comment block