Imported Upstream version 1.37.4
[platform/upstream/gobject-introspection.git] / giscanner / sectionparser.py
1 # -*- Mode: Python -*-
2 # Copyright (C) 2013 Hat, Inc.
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the
16 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 # Boston, MA 02111-1307, USA.
18 #
19
20 import re
21 from . import ast
22 from .utils import to_underscores
23
24
25 class SectionsFile(object):
26     def __init__(self, sections):
27         self.sections = sections
28
29
30 class Section(object):
31     def __init__(self):
32         self.file = None
33         self.title = None
34         self.includes = None
35         self.subsections = []
36
37
38 class Subsection(object):
39     def __init__(self, name):
40         self.name = name
41         self.symbols = []
42
43
44 def parse_sections_file(lines):
45     sections = []
46     current_section = None
47     current_subsection = None
48
49     for line in lines:
50         line = line.rstrip()
51
52         if not line or line.isspace():
53             continue
54
55         if line == "<SECTION>":
56             current_section = Section()
57             sections.append(current_section)
58             current_subsection = Subsection(None)
59             current_section.subsections.append(current_subsection)
60             continue
61
62         if line == "</SECTION>":
63             current_section = None
64             continue
65
66         match = re.match(r"<FILE>(?P<contents>.*)</FILE>", line)
67         if match:
68             current_section.file = match.groupdict['contents']
69             continue
70
71         match = re.match(r"<TITLE>(?P<contents>.*)</TITLE>", line)
72         if match:
73             current_section.title = match.groupdict['contents']
74             continue
75
76         match = re.match(r"<INCLUDE>(?P<contents>.*)</INCLUDE>", line)
77         if match:
78             current_section.includes = match.groupdict['contents']
79             continue
80
81         match = re.match(r"<SUBSECTION(?: (?P<name>.*))?>", line)
82         if match:
83             current_subsection = Subsection(match.groupdict.get('name', None))
84             current_section.subsections.append(current_subsection)
85             continue
86
87         if line.startswith("<") and line.endswith(">"):
88             # Other directive to gtk-doc, not a symbol.
89             continue
90
91         current_subsection.symbols.append(line)
92
93     return SectionsFile(sections)
94
95
96 def write_sections_file(f, sections_file):
97     for section in sections_file.sections:
98         f.write("\n<SECTION>\n")
99         if section.file is not None:
100             f.write("<FILE>%s</FILE>\n" % (section.file, ))
101         if section.title is not None:
102             f.write("<TITLE>%s</TITLE>\n" % (section.title, ))
103         if section.includes is not None:
104             f.write("<INCLUDE>%s</INCLUDE>\n" % (section.includes, ))
105
106         is_first_subsection = True
107         for subsection in section.subsections:
108             if subsection.name is not None:
109                 f.write("<SUBSECTION %s>\n" % (subsection.name, ))
110             elif not is_first_subsection:
111                 f.write("\n<SUBSECTION>\n")
112
113             is_first_subsection = False
114
115             for symbol in subsection.symbols:
116                 f.write(symbol + "\n")
117
118
119 def generate_sections_file(transformer):
120     ns = transformer.namespace
121
122     sections = []
123
124     def new_section(file_, title):
125         section = Section()
126         section.file = file_
127         section.title = title
128         section.subsections.append(Subsection(None))
129         sections.append(section)
130         return section
131
132     def append_symbol(section, sym):
133         section.subsections[0].symbols.append(sym)
134
135     general_section = new_section("main", "Main")
136
137     for node in ns.itervalues():
138         if isinstance(node, ast.Function):
139             append_symbol(general_section, node.symbol)
140         elif isinstance(node, (ast.Class, ast.Interface)):
141             gtype_name = node.gtype_name
142             file_name = to_underscores(gtype_name).replace('_', '-').lower()
143             section = new_section(file_name, gtype_name)
144             append_symbol(section, gtype_name)
145             append_symbol(section, node.glib_type_struct.target_giname.replace('.', ''))
146
147             for meth in node.methods:
148                 append_symbol(section, meth.symbol)
149             for meth in node.static_methods:
150                 append_symbol(section, meth.symbol)
151
152     return SectionsFile(sections)