Imported Upstream version 1.47.1
[platform/upstream/gobject-introspection.git] / giscanner / annotationmain.py
1 # -*- Mode: Python -*-
2 # GObject-Introspection - a framework for introspecting GObject libraries
3 # Copyright (C) 2010 Johan Dahlin
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
19 #
20
21 from __future__ import absolute_import
22 from __future__ import division
23 from __future__ import print_function
24 from __future__ import unicode_literals
25
26 import sys
27 import optparse
28 import codecs
29 from contextlib import contextmanager
30
31 from giscanner import message
32 from giscanner.annotationparser import GtkDocCommentBlockParser, GtkDocCommentBlockWriter
33 from giscanner.scannermain import (get_preprocessor_option_group,
34                                    create_source_scanner,
35                                    process_packages)
36
37
38 @contextmanager
39 def encode_stdout(encoding):
40     """Force stdout into a specific encoding."""
41     # Python 2 does not encode stdout writes so wrap it with 'encoding' encoded writer.
42     # Python 3 uses a io.TextIOBase wrapped stdout with the system default encoding.
43     # Re-wrap the underlying buffer with a new writer with the given 'encoding'.
44     # See: https://docs.python.org/3/library/sys.html#sys.stdout
45     old_stdout = sys.stdout
46     if sys.version_info.major < 3:
47         binary_stdout = sys.stdout
48     else:
49         binary_stdout = sys.stdout.buffer
50
51     sys.stdout = codecs.getwriter(encoding)(binary_stdout)
52     yield
53     sys.stdout = old_stdout
54
55
56 def annotation_main(args):
57     parser = optparse.OptionParser('%prog [options] sources')
58
59     group = optparse.OptionGroup(parser, "Tool modes, one is required")
60     group.add_option("-e", "--extract",
61                      action="store_true", dest="extract",
62                      help="Extract annotations from the input files")
63     parser.add_option_group(group)
64
65     group = get_preprocessor_option_group(parser)
66     group.add_option("-L", "--library-path",
67                      action="append", dest="library_paths", default=[],
68                      help="directories to search for libraries")
69     group.add_option("", "--pkg",
70                      action="append", dest="packages", default=[],
71                      help="pkg-config packages to get cflags from")
72     parser.add_option_group(group)
73
74     options, args = parser.parse_args(args)
75
76     if not options.extract:
77         raise SystemExit("ERROR: Nothing to do")
78
79     if options.packages:
80         process_packages(options, options.packages)
81
82     logger = message.MessageLogger.get(namespace=None)
83
84     ss = create_source_scanner(options, args)
85
86     if options.extract:
87         parser = GtkDocCommentBlockParser()
88         writer = GtkDocCommentBlockWriter(indent=False)
89         blocks = parser.parse_comment_blocks(ss.get_comments())
90
91         with encode_stdout('utf-8'):
92             print('/' + ('*' * 60) + '/')
93             print('/* THIS FILE IS GENERATED DO NOT EDIT */')
94             print('/' + ('*' * 60) + '/')
95             print('')
96             for block in sorted(blocks.values()):
97                 print(writer.write(block))
98                 print('')
99             print('')
100             print('/' + ('*' * 60) + '/')
101             print('/* THIS FILE IS GENERATED DO NOT EDIT */')
102             print('/' + ('*' * 60) + '/')
103
104     return 0