xref: /aosp_15_r20/external/libxml2/doc/apibuild.py (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*7c568831SAndroid Build Coastguard Worker#
3*7c568831SAndroid Build Coastguard Worker# This is the API builder, it parses the C sources and build the
4*7c568831SAndroid Build Coastguard Worker# API formal description in XML.
5*7c568831SAndroid Build Coastguard Worker#
6*7c568831SAndroid Build Coastguard Worker# See Copyright for the status of this software.
7*7c568831SAndroid Build Coastguard Worker#
8*7c568831SAndroid Build Coastguard Worker# [email protected]
9*7c568831SAndroid Build Coastguard Worker#
10*7c568831SAndroid Build Coastguard Workerimport os, sys
11*7c568831SAndroid Build Coastguard Workerimport string
12*7c568831SAndroid Build Coastguard Workerimport glob
13*7c568831SAndroid Build Coastguard Worker
14*7c568831SAndroid Build Coastguard Workerdebug=0
15*7c568831SAndroid Build Coastguard Worker#debugsym='ignorableWhitespaceSAXFunc'
16*7c568831SAndroid Build Coastguard Workerdebugsym=None
17*7c568831SAndroid Build Coastguard Worker
18*7c568831SAndroid Build Coastguard Worker#
19*7c568831SAndroid Build Coastguard Worker# C parser analysis code
20*7c568831SAndroid Build Coastguard Worker#
21*7c568831SAndroid Build Coastguard Workerignored_files = {
22*7c568831SAndroid Build Coastguard Worker  "config.h": "generated portability layer",
23*7c568831SAndroid Build Coastguard Worker  "libxml.h": "internal only",
24*7c568831SAndroid Build Coastguard Worker  "testModule.c": "test tool",
25*7c568831SAndroid Build Coastguard Worker  "testapi.c": "generated regression tests",
26*7c568831SAndroid Build Coastguard Worker  "runtest.c": "regression tests program",
27*7c568831SAndroid Build Coastguard Worker  "runsuite.c": "regression tests program",
28*7c568831SAndroid Build Coastguard Worker  "tst.c": "not part of the library",
29*7c568831SAndroid Build Coastguard Worker  "test.c": "not part of the library",
30*7c568831SAndroid Build Coastguard Worker  "testdso.c": "test for dynamid shared libraries",
31*7c568831SAndroid Build Coastguard Worker  "testrecurse.c": "test for entities recursions",
32*7c568831SAndroid Build Coastguard Worker  "timsort.h": "Internal header only for xpath.c 2.9.0",
33*7c568831SAndroid Build Coastguard Worker  "nanoftp.h": "empty",
34*7c568831SAndroid Build Coastguard Worker  "SAX.h": "empty",
35*7c568831SAndroid Build Coastguard Worker}
36*7c568831SAndroid Build Coastguard Worker
37*7c568831SAndroid Build Coastguard Workerignored_words = {
38*7c568831SAndroid Build Coastguard Worker  "WINAPI": (0, "Windows keyword"),
39*7c568831SAndroid Build Coastguard Worker  "LIBXML_DLL_IMPORT": (0, "Special macro to flag external keywords"),
40*7c568831SAndroid Build Coastguard Worker  "XMLPUBVAR": (0, "Special macro for extern vars for win32"),
41*7c568831SAndroid Build Coastguard Worker  "XSLTPUBVAR": (0, "Special macro for extern vars for win32"),
42*7c568831SAndroid Build Coastguard Worker  "EXSLTPUBVAR": (0, "Special macro for extern vars for win32"),
43*7c568831SAndroid Build Coastguard Worker  "XMLPUBFUN": (0, "Special macro for extern funcs for win32"),
44*7c568831SAndroid Build Coastguard Worker  "XSLTPUBFUN": (0, "Special macro for extern funcs for win32"),
45*7c568831SAndroid Build Coastguard Worker  "EXSLTPUBFUN": (0, "Special macro for extern funcs for win32"),
46*7c568831SAndroid Build Coastguard Worker  "XSLTCALL": (0, "Special macro for win32 calls"),
47*7c568831SAndroid Build Coastguard Worker  "EXSLTCALL": (0, "Special macro for win32 calls"),
48*7c568831SAndroid Build Coastguard Worker  "__declspec": (3, "Windows keyword"),
49*7c568831SAndroid Build Coastguard Worker  "__stdcall": (0, "Windows keyword"),
50*7c568831SAndroid Build Coastguard Worker  "ATTRIBUTE_UNUSED": (0, "macro keyword"),
51*7c568831SAndroid Build Coastguard Worker  "ATTRIBUTE_DESTRUCTOR": (0, "macro keyword"),
52*7c568831SAndroid Build Coastguard Worker  "LIBEXSLT_PUBLIC": (0, "macro keyword"),
53*7c568831SAndroid Build Coastguard Worker  "X_IN_Y": (5, "macro function builder"),
54*7c568831SAndroid Build Coastguard Worker  "ATTRIBUTE_ALLOC_SIZE": (3, "macro for gcc checking extension"),
55*7c568831SAndroid Build Coastguard Worker  "ATTRIBUTE_PRINTF": (5, "macro for gcc printf args checking extension"),
56*7c568831SAndroid Build Coastguard Worker  "LIBXML_ATTR_FORMAT": (5, "macro for gcc printf args checking extension"),
57*7c568831SAndroid Build Coastguard Worker  "LIBXML_ATTR_ALLOC_SIZE": (3, "macro for gcc checking extension"),
58*7c568831SAndroid Build Coastguard Worker  "ATTRIBUTE_NO_SANITIZE": (3, "macro keyword"),
59*7c568831SAndroid Build Coastguard Worker  "ATTRIBUTE_NO_SANITIZE_INTEGER": (0, "macro keyword"),
60*7c568831SAndroid Build Coastguard Worker  "XML_DEPRECATED": (0, "macro keyword"),
61*7c568831SAndroid Build Coastguard Worker  "XML_DEPRECATED_MEMBER": (0, "macro keyword"),
62*7c568831SAndroid Build Coastguard Worker  "XML_GLOBALS_ALLOC": (0, "macro keyword"),
63*7c568831SAndroid Build Coastguard Worker  "XML_GLOBALS_ERROR": (0, "macro keyword"),
64*7c568831SAndroid Build Coastguard Worker  "XML_GLOBALS_IO": (0, "macro keyword"),
65*7c568831SAndroid Build Coastguard Worker  "XML_GLOBALS_PARSER": (0, "macro keyword"),
66*7c568831SAndroid Build Coastguard Worker  "XML_GLOBALS_TREE": (0, "macro keyword"),
67*7c568831SAndroid Build Coastguard Worker  "XML_THREAD_LOCAL": (0, "macro keyword"),
68*7c568831SAndroid Build Coastguard Worker}
69*7c568831SAndroid Build Coastguard Worker
70*7c568831SAndroid Build Coastguard Workerdef escape(raw):
71*7c568831SAndroid Build Coastguard Worker    raw = raw.replace('&', '&')
72*7c568831SAndroid Build Coastguard Worker    raw = raw.replace('<', '&lt;')
73*7c568831SAndroid Build Coastguard Worker    raw = raw.replace('>', '&gt;')
74*7c568831SAndroid Build Coastguard Worker    raw = raw.replace("'", '&apos;')
75*7c568831SAndroid Build Coastguard Worker    raw = raw.replace('"', '&quot;')
76*7c568831SAndroid Build Coastguard Worker    return raw
77*7c568831SAndroid Build Coastguard Worker
78*7c568831SAndroid Build Coastguard Workerclass identifier:
79*7c568831SAndroid Build Coastguard Worker    def __init__(self, name, header=None, module=None, type=None, lineno = 0,
80*7c568831SAndroid Build Coastguard Worker                 info=None, extra=None, conditionals = None):
81*7c568831SAndroid Build Coastguard Worker        self.name = name
82*7c568831SAndroid Build Coastguard Worker        self.header = header
83*7c568831SAndroid Build Coastguard Worker        self.module = module
84*7c568831SAndroid Build Coastguard Worker        self.type = type
85*7c568831SAndroid Build Coastguard Worker        self.info = info
86*7c568831SAndroid Build Coastguard Worker        self.extra = extra
87*7c568831SAndroid Build Coastguard Worker        self.lineno = lineno
88*7c568831SAndroid Build Coastguard Worker        self.static = 0
89*7c568831SAndroid Build Coastguard Worker        if conditionals == None or len(conditionals) == 0:
90*7c568831SAndroid Build Coastguard Worker            self.conditionals = None
91*7c568831SAndroid Build Coastguard Worker        else:
92*7c568831SAndroid Build Coastguard Worker            self.conditionals = conditionals[:]
93*7c568831SAndroid Build Coastguard Worker        if self.name == debugsym:
94*7c568831SAndroid Build Coastguard Worker            print("=> define %s : %s" % (debugsym, (module, type, info,
95*7c568831SAndroid Build Coastguard Worker                                         extra, conditionals)))
96*7c568831SAndroid Build Coastguard Worker
97*7c568831SAndroid Build Coastguard Worker    def __repr__(self):
98*7c568831SAndroid Build Coastguard Worker        r = "%s %s:" % (self.type, self.name)
99*7c568831SAndroid Build Coastguard Worker        if self.static:
100*7c568831SAndroid Build Coastguard Worker            r = r + " static"
101*7c568831SAndroid Build Coastguard Worker        if self.module != None:
102*7c568831SAndroid Build Coastguard Worker            r = r + " from %s" % (self.module)
103*7c568831SAndroid Build Coastguard Worker        if self.info != None:
104*7c568831SAndroid Build Coastguard Worker            r = r + " " +  repr(self.info)
105*7c568831SAndroid Build Coastguard Worker        if self.extra != None:
106*7c568831SAndroid Build Coastguard Worker            r = r + " " + repr(self.extra)
107*7c568831SAndroid Build Coastguard Worker        if self.conditionals != None:
108*7c568831SAndroid Build Coastguard Worker            r = r + " " + repr(self.conditionals)
109*7c568831SAndroid Build Coastguard Worker        return r
110*7c568831SAndroid Build Coastguard Worker
111*7c568831SAndroid Build Coastguard Worker
112*7c568831SAndroid Build Coastguard Worker    def set_header(self, header):
113*7c568831SAndroid Build Coastguard Worker        self.header = header
114*7c568831SAndroid Build Coastguard Worker    def set_module(self, module):
115*7c568831SAndroid Build Coastguard Worker        self.module = module
116*7c568831SAndroid Build Coastguard Worker    def set_type(self, type):
117*7c568831SAndroid Build Coastguard Worker        self.type = type
118*7c568831SAndroid Build Coastguard Worker    def set_info(self, info):
119*7c568831SAndroid Build Coastguard Worker        self.info = info
120*7c568831SAndroid Build Coastguard Worker    def set_extra(self, extra):
121*7c568831SAndroid Build Coastguard Worker        self.extra = extra
122*7c568831SAndroid Build Coastguard Worker    def set_lineno(self, lineno):
123*7c568831SAndroid Build Coastguard Worker        self.lineno = lineno
124*7c568831SAndroid Build Coastguard Worker    def set_static(self, static):
125*7c568831SAndroid Build Coastguard Worker        self.static = static
126*7c568831SAndroid Build Coastguard Worker    def set_conditionals(self, conditionals):
127*7c568831SAndroid Build Coastguard Worker        if conditionals == None or len(conditionals) == 0:
128*7c568831SAndroid Build Coastguard Worker            self.conditionals = None
129*7c568831SAndroid Build Coastguard Worker        else:
130*7c568831SAndroid Build Coastguard Worker            self.conditionals = conditionals[:]
131*7c568831SAndroid Build Coastguard Worker
132*7c568831SAndroid Build Coastguard Worker    def get_name(self):
133*7c568831SAndroid Build Coastguard Worker        return self.name
134*7c568831SAndroid Build Coastguard Worker    def get_header(self):
135*7c568831SAndroid Build Coastguard Worker        return self.module
136*7c568831SAndroid Build Coastguard Worker    def get_module(self):
137*7c568831SAndroid Build Coastguard Worker        return self.module
138*7c568831SAndroid Build Coastguard Worker    def get_type(self):
139*7c568831SAndroid Build Coastguard Worker        return self.type
140*7c568831SAndroid Build Coastguard Worker    def get_info(self):
141*7c568831SAndroid Build Coastguard Worker        return self.info
142*7c568831SAndroid Build Coastguard Worker    def get_lineno(self):
143*7c568831SAndroid Build Coastguard Worker        return self.lineno
144*7c568831SAndroid Build Coastguard Worker    def get_extra(self):
145*7c568831SAndroid Build Coastguard Worker        return self.extra
146*7c568831SAndroid Build Coastguard Worker    def get_static(self):
147*7c568831SAndroid Build Coastguard Worker        return self.static
148*7c568831SAndroid Build Coastguard Worker    def get_conditionals(self):
149*7c568831SAndroid Build Coastguard Worker        return self.conditionals
150*7c568831SAndroid Build Coastguard Worker
151*7c568831SAndroid Build Coastguard Worker    def update(self, header, module, type = None, info = None, extra=None,
152*7c568831SAndroid Build Coastguard Worker               conditionals=None):
153*7c568831SAndroid Build Coastguard Worker        if self.name == debugsym:
154*7c568831SAndroid Build Coastguard Worker            print("=> update %s : %s" % (debugsym, (module, type, info,
155*7c568831SAndroid Build Coastguard Worker                                         extra, conditionals)))
156*7c568831SAndroid Build Coastguard Worker        if header != None and self.header == None:
157*7c568831SAndroid Build Coastguard Worker            self.set_header(module)
158*7c568831SAndroid Build Coastguard Worker        if module != None and (self.module == None or self.header == self.module):
159*7c568831SAndroid Build Coastguard Worker            self.set_module(module)
160*7c568831SAndroid Build Coastguard Worker        if type != None and self.type == None:
161*7c568831SAndroid Build Coastguard Worker            self.set_type(type)
162*7c568831SAndroid Build Coastguard Worker        if info != None:
163*7c568831SAndroid Build Coastguard Worker            self.set_info(info)
164*7c568831SAndroid Build Coastguard Worker        if extra != None:
165*7c568831SAndroid Build Coastguard Worker            self.set_extra(extra)
166*7c568831SAndroid Build Coastguard Worker        if conditionals != None:
167*7c568831SAndroid Build Coastguard Worker            self.set_conditionals(conditionals)
168*7c568831SAndroid Build Coastguard Worker
169*7c568831SAndroid Build Coastguard Workerclass index:
170*7c568831SAndroid Build Coastguard Worker    def __init__(self, name = "noname"):
171*7c568831SAndroid Build Coastguard Worker        self.name = name
172*7c568831SAndroid Build Coastguard Worker        self.identifiers = {}
173*7c568831SAndroid Build Coastguard Worker        self.functions = {}
174*7c568831SAndroid Build Coastguard Worker        self.variables = {}
175*7c568831SAndroid Build Coastguard Worker        self.includes = {}
176*7c568831SAndroid Build Coastguard Worker        self.structs = {}
177*7c568831SAndroid Build Coastguard Worker        self.enums = {}
178*7c568831SAndroid Build Coastguard Worker        self.typedefs = {}
179*7c568831SAndroid Build Coastguard Worker        self.macros = {}
180*7c568831SAndroid Build Coastguard Worker        self.references = {}
181*7c568831SAndroid Build Coastguard Worker        self.info = {}
182*7c568831SAndroid Build Coastguard Worker
183*7c568831SAndroid Build Coastguard Worker    def add_ref(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None):
184*7c568831SAndroid Build Coastguard Worker        if name[0:2] == '__':
185*7c568831SAndroid Build Coastguard Worker            return None
186*7c568831SAndroid Build Coastguard Worker        d = None
187*7c568831SAndroid Build Coastguard Worker        if name in self.identifiers:
188*7c568831SAndroid Build Coastguard Worker           d = self.identifiers[name]
189*7c568831SAndroid Build Coastguard Worker           d.update(header, module, type, info, extra, conditionals)
190*7c568831SAndroid Build Coastguard Worker        else:
191*7c568831SAndroid Build Coastguard Worker           d = identifier(name, header, module, type, lineno, info, extra, conditionals)
192*7c568831SAndroid Build Coastguard Worker           self.identifiers[name] = d
193*7c568831SAndroid Build Coastguard Worker
194*7c568831SAndroid Build Coastguard Worker        if d != None and static == 1:
195*7c568831SAndroid Build Coastguard Worker            d.set_static(1)
196*7c568831SAndroid Build Coastguard Worker
197*7c568831SAndroid Build Coastguard Worker        if d != None and name != None and type != None:
198*7c568831SAndroid Build Coastguard Worker            self.references[name] = d
199*7c568831SAndroid Build Coastguard Worker
200*7c568831SAndroid Build Coastguard Worker        if name == debugsym:
201*7c568831SAndroid Build Coastguard Worker            print("New ref: %s" % (d))
202*7c568831SAndroid Build Coastguard Worker
203*7c568831SAndroid Build Coastguard Worker        return d
204*7c568831SAndroid Build Coastguard Worker
205*7c568831SAndroid Build Coastguard Worker    def add(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None):
206*7c568831SAndroid Build Coastguard Worker        if name[0:2] == '__':
207*7c568831SAndroid Build Coastguard Worker            return None
208*7c568831SAndroid Build Coastguard Worker        d = None
209*7c568831SAndroid Build Coastguard Worker        if name in self.identifiers:
210*7c568831SAndroid Build Coastguard Worker           d = self.identifiers[name]
211*7c568831SAndroid Build Coastguard Worker           d.update(header, module, type, info, extra, conditionals)
212*7c568831SAndroid Build Coastguard Worker        else:
213*7c568831SAndroid Build Coastguard Worker           d = identifier(name, header, module, type, lineno, info, extra, conditionals)
214*7c568831SAndroid Build Coastguard Worker           self.identifiers[name] = d
215*7c568831SAndroid Build Coastguard Worker
216*7c568831SAndroid Build Coastguard Worker        if d != None and static == 1:
217*7c568831SAndroid Build Coastguard Worker            d.set_static(1)
218*7c568831SAndroid Build Coastguard Worker
219*7c568831SAndroid Build Coastguard Worker        if d != None and name != None and type != None:
220*7c568831SAndroid Build Coastguard Worker            if type == "function":
221*7c568831SAndroid Build Coastguard Worker                self.functions[name] = d
222*7c568831SAndroid Build Coastguard Worker            elif type == "functype":
223*7c568831SAndroid Build Coastguard Worker                self.functions[name] = d
224*7c568831SAndroid Build Coastguard Worker            elif type == "variable":
225*7c568831SAndroid Build Coastguard Worker                self.variables[name] = d
226*7c568831SAndroid Build Coastguard Worker            elif type == "include":
227*7c568831SAndroid Build Coastguard Worker                self.includes[name] = d
228*7c568831SAndroid Build Coastguard Worker            elif type == "struct":
229*7c568831SAndroid Build Coastguard Worker                self.structs[name] = d
230*7c568831SAndroid Build Coastguard Worker            elif type == "enum":
231*7c568831SAndroid Build Coastguard Worker                self.enums[name] = d
232*7c568831SAndroid Build Coastguard Worker            elif type == "typedef":
233*7c568831SAndroid Build Coastguard Worker                self.typedefs[name] = d
234*7c568831SAndroid Build Coastguard Worker            elif type == "macro":
235*7c568831SAndroid Build Coastguard Worker                self.macros[name] = d
236*7c568831SAndroid Build Coastguard Worker            else:
237*7c568831SAndroid Build Coastguard Worker                print("Unable to register type ", type)
238*7c568831SAndroid Build Coastguard Worker
239*7c568831SAndroid Build Coastguard Worker        if name == debugsym:
240*7c568831SAndroid Build Coastguard Worker            print("New symbol: %s" % (d))
241*7c568831SAndroid Build Coastguard Worker
242*7c568831SAndroid Build Coastguard Worker        return d
243*7c568831SAndroid Build Coastguard Worker
244*7c568831SAndroid Build Coastguard Worker    def merge(self, idx):
245*7c568831SAndroid Build Coastguard Worker        for id in list(idx.functions.keys()):
246*7c568831SAndroid Build Coastguard Worker              #
247*7c568831SAndroid Build Coastguard Worker              # macro might be used to override functions or variables
248*7c568831SAndroid Build Coastguard Worker              # definitions
249*7c568831SAndroid Build Coastguard Worker              #
250*7c568831SAndroid Build Coastguard Worker             if id in self.macros:
251*7c568831SAndroid Build Coastguard Worker                 del self.macros[id]
252*7c568831SAndroid Build Coastguard Worker             if id in self.functions:
253*7c568831SAndroid Build Coastguard Worker                 print("function %s from %s redeclared in %s" % (
254*7c568831SAndroid Build Coastguard Worker                    id, self.functions[id].header, idx.functions[id].header))
255*7c568831SAndroid Build Coastguard Worker             else:
256*7c568831SAndroid Build Coastguard Worker                 self.functions[id] = idx.functions[id]
257*7c568831SAndroid Build Coastguard Worker                 self.identifiers[id] = idx.functions[id]
258*7c568831SAndroid Build Coastguard Worker        for id in list(idx.variables.keys()):
259*7c568831SAndroid Build Coastguard Worker              #
260*7c568831SAndroid Build Coastguard Worker              # macro might be used to override functions or variables
261*7c568831SAndroid Build Coastguard Worker              # definitions
262*7c568831SAndroid Build Coastguard Worker              #
263*7c568831SAndroid Build Coastguard Worker             if id in self.macros:
264*7c568831SAndroid Build Coastguard Worker                 del self.macros[id]
265*7c568831SAndroid Build Coastguard Worker             if id in self.variables:
266*7c568831SAndroid Build Coastguard Worker                 print("variable %s from %s redeclared in %s" % (
267*7c568831SAndroid Build Coastguard Worker                    id, self.variables[id].header, idx.variables[id].header))
268*7c568831SAndroid Build Coastguard Worker             else:
269*7c568831SAndroid Build Coastguard Worker                 self.variables[id] = idx.variables[id]
270*7c568831SAndroid Build Coastguard Worker                 self.identifiers[id] = idx.variables[id]
271*7c568831SAndroid Build Coastguard Worker        for id in list(idx.structs.keys()):
272*7c568831SAndroid Build Coastguard Worker             if id in self.structs:
273*7c568831SAndroid Build Coastguard Worker                 print("struct %s from %s redeclared in %s" % (
274*7c568831SAndroid Build Coastguard Worker                    id, self.structs[id].header, idx.structs[id].header))
275*7c568831SAndroid Build Coastguard Worker             else:
276*7c568831SAndroid Build Coastguard Worker                 self.structs[id] = idx.structs[id]
277*7c568831SAndroid Build Coastguard Worker                 self.identifiers[id] = idx.structs[id]
278*7c568831SAndroid Build Coastguard Worker        for id in list(idx.typedefs.keys()):
279*7c568831SAndroid Build Coastguard Worker             if id in self.typedefs:
280*7c568831SAndroid Build Coastguard Worker                 print("typedef %s from %s redeclared in %s" % (
281*7c568831SAndroid Build Coastguard Worker                    id, self.typedefs[id].header, idx.typedefs[id].header))
282*7c568831SAndroid Build Coastguard Worker             else:
283*7c568831SAndroid Build Coastguard Worker                 self.typedefs[id] = idx.typedefs[id]
284*7c568831SAndroid Build Coastguard Worker                 self.identifiers[id] = idx.typedefs[id]
285*7c568831SAndroid Build Coastguard Worker        for id in list(idx.macros.keys()):
286*7c568831SAndroid Build Coastguard Worker              #
287*7c568831SAndroid Build Coastguard Worker              # macro might be used to override functions or variables
288*7c568831SAndroid Build Coastguard Worker              # definitions
289*7c568831SAndroid Build Coastguard Worker              #
290*7c568831SAndroid Build Coastguard Worker             if id in self.variables:
291*7c568831SAndroid Build Coastguard Worker                 continue
292*7c568831SAndroid Build Coastguard Worker             if id in self.functions:
293*7c568831SAndroid Build Coastguard Worker                 continue
294*7c568831SAndroid Build Coastguard Worker             if id in self.enums:
295*7c568831SAndroid Build Coastguard Worker                 continue
296*7c568831SAndroid Build Coastguard Worker             if id in self.macros and id != 'XML_OP':
297*7c568831SAndroid Build Coastguard Worker                 print("macro %s from %s redeclared in %s" % (
298*7c568831SAndroid Build Coastguard Worker                    id, self.macros[id].header, idx.macros[id].header))
299*7c568831SAndroid Build Coastguard Worker             else:
300*7c568831SAndroid Build Coastguard Worker                 self.macros[id] = idx.macros[id]
301*7c568831SAndroid Build Coastguard Worker                 self.identifiers[id] = idx.macros[id]
302*7c568831SAndroid Build Coastguard Worker        for id in list(idx.enums.keys()):
303*7c568831SAndroid Build Coastguard Worker             if id in self.enums:
304*7c568831SAndroid Build Coastguard Worker                 print("enum %s from %s redeclared in %s" % (
305*7c568831SAndroid Build Coastguard Worker                    id, self.enums[id].header, idx.enums[id].header))
306*7c568831SAndroid Build Coastguard Worker             else:
307*7c568831SAndroid Build Coastguard Worker                 self.enums[id] = idx.enums[id]
308*7c568831SAndroid Build Coastguard Worker                 self.identifiers[id] = idx.enums[id]
309*7c568831SAndroid Build Coastguard Worker
310*7c568831SAndroid Build Coastguard Worker    def merge_public(self, idx):
311*7c568831SAndroid Build Coastguard Worker        for id in list(idx.functions.keys()):
312*7c568831SAndroid Build Coastguard Worker             if id in self.functions:
313*7c568831SAndroid Build Coastguard Worker                 # check that function condition agrees with header
314*7c568831SAndroid Build Coastguard Worker                 if idx.functions[id].conditionals != \
315*7c568831SAndroid Build Coastguard Worker                    self.functions[id].conditionals:
316*7c568831SAndroid Build Coastguard Worker                     print("Header condition differs from Function for %s:" \
317*7c568831SAndroid Build Coastguard Worker                        % id)
318*7c568831SAndroid Build Coastguard Worker                     print("  H: %s" % self.functions[id].conditionals)
319*7c568831SAndroid Build Coastguard Worker                     print("  C: %s" % idx.functions[id].conditionals)
320*7c568831SAndroid Build Coastguard Worker                 up = idx.functions[id]
321*7c568831SAndroid Build Coastguard Worker                 self.functions[id].update(None, up.module, up.type, up.info, up.extra)
322*7c568831SAndroid Build Coastguard Worker         #     else:
323*7c568831SAndroid Build Coastguard Worker         #         print "Function %s from %s is not declared in headers" % (
324*7c568831SAndroid Build Coastguard Worker         #                id, idx.functions[id].module)
325*7c568831SAndroid Build Coastguard Worker
326*7c568831SAndroid Build Coastguard Worker        for id in list(idx.variables.keys()):
327*7c568831SAndroid Build Coastguard Worker            if id in self.variables:
328*7c568831SAndroid Build Coastguard Worker                # check that variable condition agrees with header
329*7c568831SAndroid Build Coastguard Worker                # TODO: produces many false positives
330*7c568831SAndroid Build Coastguard Worker                #if idx.variables[id].conditionals != \
331*7c568831SAndroid Build Coastguard Worker                #   self.variables[id].conditionals:
332*7c568831SAndroid Build Coastguard Worker                #    print("Header condition differs from Variable for %s:" \
333*7c568831SAndroid Build Coastguard Worker                #       % id)
334*7c568831SAndroid Build Coastguard Worker                #    print("  H: %s" % self.variables[id].conditionals)
335*7c568831SAndroid Build Coastguard Worker                #    print("  C: %s" % idx.variables[id].conditionals)
336*7c568831SAndroid Build Coastguard Worker                up = idx.variables[id]
337*7c568831SAndroid Build Coastguard Worker                self.variables[id].update(None, up.module, up.type, up.info, up.extra)
338*7c568831SAndroid Build Coastguard Worker
339*7c568831SAndroid Build Coastguard Worker    def analyze_dict(self, type, dict):
340*7c568831SAndroid Build Coastguard Worker        count = 0
341*7c568831SAndroid Build Coastguard Worker        public = 0
342*7c568831SAndroid Build Coastguard Worker        for name in list(dict.keys()):
343*7c568831SAndroid Build Coastguard Worker            id = dict[name]
344*7c568831SAndroid Build Coastguard Worker            count = count + 1
345*7c568831SAndroid Build Coastguard Worker            if id.static == 0:
346*7c568831SAndroid Build Coastguard Worker                public = public + 1
347*7c568831SAndroid Build Coastguard Worker        if count != public:
348*7c568831SAndroid Build Coastguard Worker            print("  %d %s , %d public" % (count, type, public))
349*7c568831SAndroid Build Coastguard Worker        elif count != 0:
350*7c568831SAndroid Build Coastguard Worker            print("  %d public %s" % (count, type))
351*7c568831SAndroid Build Coastguard Worker
352*7c568831SAndroid Build Coastguard Worker
353*7c568831SAndroid Build Coastguard Worker    def analyze(self):
354*7c568831SAndroid Build Coastguard Worker        self.analyze_dict("functions", self.functions)
355*7c568831SAndroid Build Coastguard Worker        self.analyze_dict("variables", self.variables)
356*7c568831SAndroid Build Coastguard Worker        self.analyze_dict("structs", self.structs)
357*7c568831SAndroid Build Coastguard Worker        self.analyze_dict("typedefs", self.typedefs)
358*7c568831SAndroid Build Coastguard Worker        self.analyze_dict("macros", self.macros)
359*7c568831SAndroid Build Coastguard Worker
360*7c568831SAndroid Build Coastguard Workerclass CLexer:
361*7c568831SAndroid Build Coastguard Worker    """A lexer for the C language, tokenize the input by reading and
362*7c568831SAndroid Build Coastguard Worker       analyzing it line by line"""
363*7c568831SAndroid Build Coastguard Worker    def __init__(self, input):
364*7c568831SAndroid Build Coastguard Worker        self.input = input
365*7c568831SAndroid Build Coastguard Worker        self.tokens = []
366*7c568831SAndroid Build Coastguard Worker        self.line = ""
367*7c568831SAndroid Build Coastguard Worker        self.lineno = 0
368*7c568831SAndroid Build Coastguard Worker
369*7c568831SAndroid Build Coastguard Worker    def getline(self):
370*7c568831SAndroid Build Coastguard Worker        line = ''
371*7c568831SAndroid Build Coastguard Worker        while line == '':
372*7c568831SAndroid Build Coastguard Worker            line = self.input.readline()
373*7c568831SAndroid Build Coastguard Worker            if not line:
374*7c568831SAndroid Build Coastguard Worker                return None
375*7c568831SAndroid Build Coastguard Worker            self.lineno = self.lineno + 1
376*7c568831SAndroid Build Coastguard Worker            line = line.lstrip()
377*7c568831SAndroid Build Coastguard Worker            line = line.rstrip()
378*7c568831SAndroid Build Coastguard Worker            if line == '':
379*7c568831SAndroid Build Coastguard Worker                continue
380*7c568831SAndroid Build Coastguard Worker            while line[-1] == '\\':
381*7c568831SAndroid Build Coastguard Worker                line = line[:-1]
382*7c568831SAndroid Build Coastguard Worker                n = self.input.readline()
383*7c568831SAndroid Build Coastguard Worker                self.lineno = self.lineno + 1
384*7c568831SAndroid Build Coastguard Worker                n = n.lstrip()
385*7c568831SAndroid Build Coastguard Worker                n = n.rstrip()
386*7c568831SAndroid Build Coastguard Worker                if not n:
387*7c568831SAndroid Build Coastguard Worker                    break
388*7c568831SAndroid Build Coastguard Worker                else:
389*7c568831SAndroid Build Coastguard Worker                    line = line + n
390*7c568831SAndroid Build Coastguard Worker        return line
391*7c568831SAndroid Build Coastguard Worker
392*7c568831SAndroid Build Coastguard Worker    def getlineno(self):
393*7c568831SAndroid Build Coastguard Worker        return self.lineno
394*7c568831SAndroid Build Coastguard Worker
395*7c568831SAndroid Build Coastguard Worker    def push(self, token):
396*7c568831SAndroid Build Coastguard Worker        self.tokens.insert(0, token);
397*7c568831SAndroid Build Coastguard Worker
398*7c568831SAndroid Build Coastguard Worker    def debug(self):
399*7c568831SAndroid Build Coastguard Worker        print("Last token: ", self.last)
400*7c568831SAndroid Build Coastguard Worker        print("Token queue: ", self.tokens)
401*7c568831SAndroid Build Coastguard Worker        print("Line %d end: " % (self.lineno), self.line)
402*7c568831SAndroid Build Coastguard Worker
403*7c568831SAndroid Build Coastguard Worker    def token(self):
404*7c568831SAndroid Build Coastguard Worker        while self.tokens == []:
405*7c568831SAndroid Build Coastguard Worker            if self.line == "":
406*7c568831SAndroid Build Coastguard Worker                line = self.getline()
407*7c568831SAndroid Build Coastguard Worker            else:
408*7c568831SAndroid Build Coastguard Worker                line = self.line
409*7c568831SAndroid Build Coastguard Worker                self.line = ""
410*7c568831SAndroid Build Coastguard Worker            if line == None:
411*7c568831SAndroid Build Coastguard Worker                return None
412*7c568831SAndroid Build Coastguard Worker
413*7c568831SAndroid Build Coastguard Worker            if line[0] == '#':
414*7c568831SAndroid Build Coastguard Worker                self.tokens = list(map((lambda x: ('preproc', x)),
415*7c568831SAndroid Build Coastguard Worker                                  line.split()))
416*7c568831SAndroid Build Coastguard Worker                break;
417*7c568831SAndroid Build Coastguard Worker            l = len(line)
418*7c568831SAndroid Build Coastguard Worker            if line[0] == '"' or line[0] == "'":
419*7c568831SAndroid Build Coastguard Worker                end = line[0]
420*7c568831SAndroid Build Coastguard Worker                line = line[1:]
421*7c568831SAndroid Build Coastguard Worker                found = 0
422*7c568831SAndroid Build Coastguard Worker                tok = ""
423*7c568831SAndroid Build Coastguard Worker                while found == 0:
424*7c568831SAndroid Build Coastguard Worker                    i = 0
425*7c568831SAndroid Build Coastguard Worker                    l = len(line)
426*7c568831SAndroid Build Coastguard Worker                    while i < l:
427*7c568831SAndroid Build Coastguard Worker                        if line[i] == end:
428*7c568831SAndroid Build Coastguard Worker                            self.line = line[i+1:]
429*7c568831SAndroid Build Coastguard Worker                            line = line[:i]
430*7c568831SAndroid Build Coastguard Worker                            l = i
431*7c568831SAndroid Build Coastguard Worker                            found = 1
432*7c568831SAndroid Build Coastguard Worker                            break
433*7c568831SAndroid Build Coastguard Worker                        if line[i] == '\\':
434*7c568831SAndroid Build Coastguard Worker                            i = i + 1
435*7c568831SAndroid Build Coastguard Worker                        i = i + 1
436*7c568831SAndroid Build Coastguard Worker                    tok = tok + line
437*7c568831SAndroid Build Coastguard Worker                    if found == 0:
438*7c568831SAndroid Build Coastguard Worker                        line = self.getline()
439*7c568831SAndroid Build Coastguard Worker                        if line == None:
440*7c568831SAndroid Build Coastguard Worker                            return None
441*7c568831SAndroid Build Coastguard Worker                self.last = ('string', tok)
442*7c568831SAndroid Build Coastguard Worker                return self.last
443*7c568831SAndroid Build Coastguard Worker
444*7c568831SAndroid Build Coastguard Worker            if l >= 2 and line[0] == '/' and line[1] == '*':
445*7c568831SAndroid Build Coastguard Worker                line = line[2:]
446*7c568831SAndroid Build Coastguard Worker                found = 0
447*7c568831SAndroid Build Coastguard Worker                tok = ""
448*7c568831SAndroid Build Coastguard Worker                while found == 0:
449*7c568831SAndroid Build Coastguard Worker                    i = 0
450*7c568831SAndroid Build Coastguard Worker                    l = len(line)
451*7c568831SAndroid Build Coastguard Worker                    while i < l:
452*7c568831SAndroid Build Coastguard Worker                        if line[i] == '*' and i+1 < l and line[i+1] == '/':
453*7c568831SAndroid Build Coastguard Worker                            self.line = line[i+2:]
454*7c568831SAndroid Build Coastguard Worker                            line = line[:i-1]
455*7c568831SAndroid Build Coastguard Worker                            l = i
456*7c568831SAndroid Build Coastguard Worker                            found = 1
457*7c568831SAndroid Build Coastguard Worker                            break
458*7c568831SAndroid Build Coastguard Worker                        i = i + 1
459*7c568831SAndroid Build Coastguard Worker                    if tok != "":
460*7c568831SAndroid Build Coastguard Worker                        tok = tok + "\n"
461*7c568831SAndroid Build Coastguard Worker                    tok = tok + line
462*7c568831SAndroid Build Coastguard Worker                    if found == 0:
463*7c568831SAndroid Build Coastguard Worker                        line = self.getline()
464*7c568831SAndroid Build Coastguard Worker                        if line == None:
465*7c568831SAndroid Build Coastguard Worker                            return None
466*7c568831SAndroid Build Coastguard Worker                self.last = ('comment', tok)
467*7c568831SAndroid Build Coastguard Worker                return self.last
468*7c568831SAndroid Build Coastguard Worker            if l >= 2 and line[0] == '/' and line[1] == '/':
469*7c568831SAndroid Build Coastguard Worker                line = line[2:]
470*7c568831SAndroid Build Coastguard Worker                self.last = ('comment', line)
471*7c568831SAndroid Build Coastguard Worker                return self.last
472*7c568831SAndroid Build Coastguard Worker            i = 0
473*7c568831SAndroid Build Coastguard Worker            while i < l:
474*7c568831SAndroid Build Coastguard Worker                if line[i] == '/' and i+1 < l and line[i+1] == '/':
475*7c568831SAndroid Build Coastguard Worker                    self.line = line[i:]
476*7c568831SAndroid Build Coastguard Worker                    line = line[:i]
477*7c568831SAndroid Build Coastguard Worker                    break
478*7c568831SAndroid Build Coastguard Worker                if line[i] == '/' and i+1 < l and line[i+1] == '*':
479*7c568831SAndroid Build Coastguard Worker                    self.line = line[i:]
480*7c568831SAndroid Build Coastguard Worker                    line = line[:i]
481*7c568831SAndroid Build Coastguard Worker                    break
482*7c568831SAndroid Build Coastguard Worker                if line[i] == '"' or line[i] == "'":
483*7c568831SAndroid Build Coastguard Worker                    self.line = line[i:]
484*7c568831SAndroid Build Coastguard Worker                    line = line[:i]
485*7c568831SAndroid Build Coastguard Worker                    break
486*7c568831SAndroid Build Coastguard Worker                i = i + 1
487*7c568831SAndroid Build Coastguard Worker            l = len(line)
488*7c568831SAndroid Build Coastguard Worker            i = 0
489*7c568831SAndroid Build Coastguard Worker            while i < l:
490*7c568831SAndroid Build Coastguard Worker                if line[i] == ' ' or line[i] == '\t':
491*7c568831SAndroid Build Coastguard Worker                    i = i + 1
492*7c568831SAndroid Build Coastguard Worker                    continue
493*7c568831SAndroid Build Coastguard Worker                o = ord(line[i])
494*7c568831SAndroid Build Coastguard Worker                if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
495*7c568831SAndroid Build Coastguard Worker                   (o >= 48 and o <= 57):
496*7c568831SAndroid Build Coastguard Worker                    s = i
497*7c568831SAndroid Build Coastguard Worker                    while i < l:
498*7c568831SAndroid Build Coastguard Worker                        o = ord(line[i])
499*7c568831SAndroid Build Coastguard Worker                        if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
500*7c568831SAndroid Build Coastguard Worker                           (o >= 48 and o <= 57) or \
501*7c568831SAndroid Build Coastguard Worker			   (" \t(){}:;,+-*/%&!|[]=><".find(line[i])) == -1:
502*7c568831SAndroid Build Coastguard Worker                            i = i + 1
503*7c568831SAndroid Build Coastguard Worker                        else:
504*7c568831SAndroid Build Coastguard Worker                            break
505*7c568831SAndroid Build Coastguard Worker                    self.tokens.append(('name', line[s:i]))
506*7c568831SAndroid Build Coastguard Worker                    continue
507*7c568831SAndroid Build Coastguard Worker                if "(){}:;,[]".find(line[i]) != -1:
508*7c568831SAndroid Build Coastguard Worker#                 if line[i] == '(' or line[i] == ')' or line[i] == '{' or \
509*7c568831SAndroid Build Coastguard Worker#                    line[i] == '}' or line[i] == ':' or line[i] == ';' or \
510*7c568831SAndroid Build Coastguard Worker#                    line[i] == ',' or line[i] == '[' or line[i] == ']':
511*7c568831SAndroid Build Coastguard Worker                    self.tokens.append(('sep', line[i]))
512*7c568831SAndroid Build Coastguard Worker                    i = i + 1
513*7c568831SAndroid Build Coastguard Worker                    continue
514*7c568831SAndroid Build Coastguard Worker                if "+-*><=/%&!|.".find(line[i]) != -1:
515*7c568831SAndroid Build Coastguard Worker#                 if line[i] == '+' or line[i] == '-' or line[i] == '*' or \
516*7c568831SAndroid Build Coastguard Worker#                    line[i] == '>' or line[i] == '<' or line[i] == '=' or \
517*7c568831SAndroid Build Coastguard Worker#                    line[i] == '/' or line[i] == '%' or line[i] == '&' or \
518*7c568831SAndroid Build Coastguard Worker#                    line[i] == '!' or line[i] == '|' or line[i] == '.':
519*7c568831SAndroid Build Coastguard Worker                    if line[i] == '.' and  i + 2 < l and \
520*7c568831SAndroid Build Coastguard Worker                       line[i+1] == '.' and line[i+2] == '.':
521*7c568831SAndroid Build Coastguard Worker                        self.tokens.append(('name', '...'))
522*7c568831SAndroid Build Coastguard Worker                        i = i + 3
523*7c568831SAndroid Build Coastguard Worker                        continue
524*7c568831SAndroid Build Coastguard Worker
525*7c568831SAndroid Build Coastguard Worker                    j = i + 1
526*7c568831SAndroid Build Coastguard Worker                    if j < l and (
527*7c568831SAndroid Build Coastguard Worker                       "+-*><=/%&!|".find(line[j]) != -1):
528*7c568831SAndroid Build Coastguard Worker#                        line[j] == '+' or line[j] == '-' or line[j] == '*' or \
529*7c568831SAndroid Build Coastguard Worker#                        line[j] == '>' or line[j] == '<' or line[j] == '=' or \
530*7c568831SAndroid Build Coastguard Worker#                        line[j] == '/' or line[j] == '%' or line[j] == '&' or \
531*7c568831SAndroid Build Coastguard Worker#                        line[j] == '!' or line[j] == '|'):
532*7c568831SAndroid Build Coastguard Worker                        self.tokens.append(('op', line[i:j+1]))
533*7c568831SAndroid Build Coastguard Worker                        i = j + 1
534*7c568831SAndroid Build Coastguard Worker                    else:
535*7c568831SAndroid Build Coastguard Worker                        self.tokens.append(('op', line[i]))
536*7c568831SAndroid Build Coastguard Worker                        i = i + 1
537*7c568831SAndroid Build Coastguard Worker                    continue
538*7c568831SAndroid Build Coastguard Worker                s = i
539*7c568831SAndroid Build Coastguard Worker                while i < l:
540*7c568831SAndroid Build Coastguard Worker                    o = ord(line[i])
541*7c568831SAndroid Build Coastguard Worker                    if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
542*7c568831SAndroid Build Coastguard Worker                       (o >= 48 and o <= 57) or (
543*7c568831SAndroid Build Coastguard Worker                        " \t(){}:;,+-*/%&!|[]=><".find(line[i]) == -1):
544*7c568831SAndroid Build Coastguard Worker#                         line[i] != ' ' and line[i] != '\t' and
545*7c568831SAndroid Build Coastguard Worker#                         line[i] != '(' and line[i] != ')' and
546*7c568831SAndroid Build Coastguard Worker#                         line[i] != '{'  and line[i] != '}' and
547*7c568831SAndroid Build Coastguard Worker#                         line[i] != ':' and line[i] != ';' and
548*7c568831SAndroid Build Coastguard Worker#                         line[i] != ',' and line[i] != '+' and
549*7c568831SAndroid Build Coastguard Worker#                         line[i] != '-' and line[i] != '*' and
550*7c568831SAndroid Build Coastguard Worker#                         line[i] != '/' and line[i] != '%' and
551*7c568831SAndroid Build Coastguard Worker#                         line[i] != '&' and line[i] != '!' and
552*7c568831SAndroid Build Coastguard Worker#                         line[i] != '|' and line[i] != '[' and
553*7c568831SAndroid Build Coastguard Worker#                         line[i] != ']' and line[i] != '=' and
554*7c568831SAndroid Build Coastguard Worker#                         line[i] != '*' and line[i] != '>' and
555*7c568831SAndroid Build Coastguard Worker#                         line[i] != '<'):
556*7c568831SAndroid Build Coastguard Worker                        i = i + 1
557*7c568831SAndroid Build Coastguard Worker                    else:
558*7c568831SAndroid Build Coastguard Worker                        break
559*7c568831SAndroid Build Coastguard Worker                self.tokens.append(('name', line[s:i]))
560*7c568831SAndroid Build Coastguard Worker
561*7c568831SAndroid Build Coastguard Worker        tok = self.tokens[0]
562*7c568831SAndroid Build Coastguard Worker        self.tokens = self.tokens[1:]
563*7c568831SAndroid Build Coastguard Worker        self.last = tok
564*7c568831SAndroid Build Coastguard Worker        return tok
565*7c568831SAndroid Build Coastguard Worker
566*7c568831SAndroid Build Coastguard Workerclass CParser:
567*7c568831SAndroid Build Coastguard Worker    """The C module parser"""
568*7c568831SAndroid Build Coastguard Worker    def __init__(self, filename, idx = None):
569*7c568831SAndroid Build Coastguard Worker        self.filename = filename
570*7c568831SAndroid Build Coastguard Worker        if len(filename) > 2 and filename[-2:] == '.h':
571*7c568831SAndroid Build Coastguard Worker            self.is_header = 1
572*7c568831SAndroid Build Coastguard Worker        else:
573*7c568831SAndroid Build Coastguard Worker            self.is_header = 0
574*7c568831SAndroid Build Coastguard Worker        self.input = open(filename)
575*7c568831SAndroid Build Coastguard Worker        self.lexer = CLexer(self.input)
576*7c568831SAndroid Build Coastguard Worker        if idx == None:
577*7c568831SAndroid Build Coastguard Worker            self.index = index()
578*7c568831SAndroid Build Coastguard Worker        else:
579*7c568831SAndroid Build Coastguard Worker            self.index = idx
580*7c568831SAndroid Build Coastguard Worker        self.top_comment = ""
581*7c568831SAndroid Build Coastguard Worker        self.last_comment = ""
582*7c568831SAndroid Build Coastguard Worker        self.comment = None
583*7c568831SAndroid Build Coastguard Worker        self.collect_ref = 0
584*7c568831SAndroid Build Coastguard Worker        self.doc_disable = 0
585*7c568831SAndroid Build Coastguard Worker        self.conditionals = []
586*7c568831SAndroid Build Coastguard Worker        self.defines = []
587*7c568831SAndroid Build Coastguard Worker
588*7c568831SAndroid Build Coastguard Worker    def collect_references(self):
589*7c568831SAndroid Build Coastguard Worker        self.collect_ref = 1
590*7c568831SAndroid Build Coastguard Worker
591*7c568831SAndroid Build Coastguard Worker    def disable(self):
592*7c568831SAndroid Build Coastguard Worker        self.doc_disable = 1
593*7c568831SAndroid Build Coastguard Worker
594*7c568831SAndroid Build Coastguard Worker    def enable(self):
595*7c568831SAndroid Build Coastguard Worker        self.doc_disable = 0
596*7c568831SAndroid Build Coastguard Worker
597*7c568831SAndroid Build Coastguard Worker    def lineno(self):
598*7c568831SAndroid Build Coastguard Worker        return self.lexer.getlineno()
599*7c568831SAndroid Build Coastguard Worker
600*7c568831SAndroid Build Coastguard Worker    def index_add(self, name, module, static, type, info=None, extra = None):
601*7c568831SAndroid Build Coastguard Worker        if self.doc_disable:
602*7c568831SAndroid Build Coastguard Worker            return
603*7c568831SAndroid Build Coastguard Worker        if self.is_header == 1:
604*7c568831SAndroid Build Coastguard Worker            self.index.add(name, module, module, static, type, self.lineno(),
605*7c568831SAndroid Build Coastguard Worker                           info, extra, self.conditionals)
606*7c568831SAndroid Build Coastguard Worker        else:
607*7c568831SAndroid Build Coastguard Worker            self.index.add(name, None, module, static, type, self.lineno(),
608*7c568831SAndroid Build Coastguard Worker                           info, extra, self.conditionals)
609*7c568831SAndroid Build Coastguard Worker
610*7c568831SAndroid Build Coastguard Worker    def index_add_ref(self, name, module, static, type, info=None,
611*7c568831SAndroid Build Coastguard Worker                      extra = None):
612*7c568831SAndroid Build Coastguard Worker        if self.is_header == 1:
613*7c568831SAndroid Build Coastguard Worker            self.index.add_ref(name, module, module, static, type,
614*7c568831SAndroid Build Coastguard Worker                               self.lineno(), info, extra, self.conditionals)
615*7c568831SAndroid Build Coastguard Worker        else:
616*7c568831SAndroid Build Coastguard Worker            self.index.add_ref(name, None, module, static, type, self.lineno(),
617*7c568831SAndroid Build Coastguard Worker                               info, extra, self.conditionals)
618*7c568831SAndroid Build Coastguard Worker
619*7c568831SAndroid Build Coastguard Worker    def warning(self, msg):
620*7c568831SAndroid Build Coastguard Worker        if self.doc_disable:
621*7c568831SAndroid Build Coastguard Worker            return
622*7c568831SAndroid Build Coastguard Worker        print(msg)
623*7c568831SAndroid Build Coastguard Worker
624*7c568831SAndroid Build Coastguard Worker    def error(self, msg, token=-1):
625*7c568831SAndroid Build Coastguard Worker        if self.doc_disable:
626*7c568831SAndroid Build Coastguard Worker            return
627*7c568831SAndroid Build Coastguard Worker
628*7c568831SAndroid Build Coastguard Worker        print("Parse Error: " + msg)
629*7c568831SAndroid Build Coastguard Worker        if token != -1:
630*7c568831SAndroid Build Coastguard Worker            print("Got token ", token)
631*7c568831SAndroid Build Coastguard Worker        self.lexer.debug()
632*7c568831SAndroid Build Coastguard Worker        sys.exit(1)
633*7c568831SAndroid Build Coastguard Worker
634*7c568831SAndroid Build Coastguard Worker    def debug(self, msg, token=-1):
635*7c568831SAndroid Build Coastguard Worker        print("Debug: " + msg)
636*7c568831SAndroid Build Coastguard Worker        if token != -1:
637*7c568831SAndroid Build Coastguard Worker            print("Got token ", token)
638*7c568831SAndroid Build Coastguard Worker        self.lexer.debug()
639*7c568831SAndroid Build Coastguard Worker
640*7c568831SAndroid Build Coastguard Worker    def parseTopComment(self, comment):
641*7c568831SAndroid Build Coastguard Worker        res = {}
642*7c568831SAndroid Build Coastguard Worker        lines = comment.split("\n")
643*7c568831SAndroid Build Coastguard Worker        item = None
644*7c568831SAndroid Build Coastguard Worker        for line in lines:
645*7c568831SAndroid Build Coastguard Worker            while line != "" and (line[0] == ' ' or line[0] == '\t'):
646*7c568831SAndroid Build Coastguard Worker                line = line[1:]
647*7c568831SAndroid Build Coastguard Worker            while line != "" and line[0] == '*':
648*7c568831SAndroid Build Coastguard Worker                line = line[1:]
649*7c568831SAndroid Build Coastguard Worker            while line != "" and (line[0] == ' ' or line[0] == '\t'):
650*7c568831SAndroid Build Coastguard Worker                line = line[1:]
651*7c568831SAndroid Build Coastguard Worker            try:
652*7c568831SAndroid Build Coastguard Worker                (it, line) = line.split(":", 1)
653*7c568831SAndroid Build Coastguard Worker                item = it
654*7c568831SAndroid Build Coastguard Worker                while line != "" and (line[0] == ' ' or line[0] == '\t'):
655*7c568831SAndroid Build Coastguard Worker                    line = line[1:]
656*7c568831SAndroid Build Coastguard Worker                if item in res:
657*7c568831SAndroid Build Coastguard Worker                    res[item] = res[item] + " " + line
658*7c568831SAndroid Build Coastguard Worker                else:
659*7c568831SAndroid Build Coastguard Worker                    res[item] = line
660*7c568831SAndroid Build Coastguard Worker            except:
661*7c568831SAndroid Build Coastguard Worker                if item != None:
662*7c568831SAndroid Build Coastguard Worker                    if item in res:
663*7c568831SAndroid Build Coastguard Worker                        res[item] = res[item] + " " + line
664*7c568831SAndroid Build Coastguard Worker                    else:
665*7c568831SAndroid Build Coastguard Worker                        res[item] = line
666*7c568831SAndroid Build Coastguard Worker        self.index.info = res
667*7c568831SAndroid Build Coastguard Worker
668*7c568831SAndroid Build Coastguard Worker    def parseComment(self, token):
669*7c568831SAndroid Build Coastguard Worker        if self.top_comment == "":
670*7c568831SAndroid Build Coastguard Worker            self.top_comment = token[1]
671*7c568831SAndroid Build Coastguard Worker        if self.comment == None or token[1][0] == '*':
672*7c568831SAndroid Build Coastguard Worker            self.comment = token[1];
673*7c568831SAndroid Build Coastguard Worker        else:
674*7c568831SAndroid Build Coastguard Worker            self.comment = self.comment + token[1]
675*7c568831SAndroid Build Coastguard Worker        token = self.lexer.token()
676*7c568831SAndroid Build Coastguard Worker
677*7c568831SAndroid Build Coastguard Worker        if self.comment.find("DOC_DISABLE") != -1:
678*7c568831SAndroid Build Coastguard Worker            self.disable()
679*7c568831SAndroid Build Coastguard Worker
680*7c568831SAndroid Build Coastguard Worker        if self.comment.find("DOC_ENABLE") != -1:
681*7c568831SAndroid Build Coastguard Worker            self.enable()
682*7c568831SAndroid Build Coastguard Worker
683*7c568831SAndroid Build Coastguard Worker        return token
684*7c568831SAndroid Build Coastguard Worker
685*7c568831SAndroid Build Coastguard Worker    #
686*7c568831SAndroid Build Coastguard Worker    # Parse a simple comment block for typedefs or global variables
687*7c568831SAndroid Build Coastguard Worker    #
688*7c568831SAndroid Build Coastguard Worker    def parseSimpleComment(self, name, quiet = False):
689*7c568831SAndroid Build Coastguard Worker        if name[0:2] == '__':
690*7c568831SAndroid Build Coastguard Worker            quiet = 1
691*7c568831SAndroid Build Coastguard Worker
692*7c568831SAndroid Build Coastguard Worker        args = []
693*7c568831SAndroid Build Coastguard Worker        desc = ""
694*7c568831SAndroid Build Coastguard Worker
695*7c568831SAndroid Build Coastguard Worker        if self.comment == None:
696*7c568831SAndroid Build Coastguard Worker            if not quiet:
697*7c568831SAndroid Build Coastguard Worker                self.warning("Missing comment for %s" % (name))
698*7c568831SAndroid Build Coastguard Worker            return(None)
699*7c568831SAndroid Build Coastguard Worker        if self.comment[0] != '*':
700*7c568831SAndroid Build Coastguard Worker            if not quiet:
701*7c568831SAndroid Build Coastguard Worker                self.warning("Missing * in comment for %s" % (name))
702*7c568831SAndroid Build Coastguard Worker            return(None)
703*7c568831SAndroid Build Coastguard Worker        lines = self.comment.split('\n')
704*7c568831SAndroid Build Coastguard Worker        if lines[0] == '*':
705*7c568831SAndroid Build Coastguard Worker            del lines[0]
706*7c568831SAndroid Build Coastguard Worker        if lines[0] != "* %s:" % (name):
707*7c568831SAndroid Build Coastguard Worker            if not quiet:
708*7c568831SAndroid Build Coastguard Worker                self.warning("Misformatted comment for %s" % (name))
709*7c568831SAndroid Build Coastguard Worker                self.warning("  Expecting '* %s:' got '%s'" % (name, lines[0]))
710*7c568831SAndroid Build Coastguard Worker            return(None)
711*7c568831SAndroid Build Coastguard Worker        del lines[0]
712*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0 and lines[0] == '*':
713*7c568831SAndroid Build Coastguard Worker            del lines[0]
714*7c568831SAndroid Build Coastguard Worker        desc = ""
715*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0:
716*7c568831SAndroid Build Coastguard Worker            l = lines[0]
717*7c568831SAndroid Build Coastguard Worker            while len(l) > 0 and l[0] == '*':
718*7c568831SAndroid Build Coastguard Worker                l = l[1:]
719*7c568831SAndroid Build Coastguard Worker            l = l.strip()
720*7c568831SAndroid Build Coastguard Worker            desc = desc + " " + l
721*7c568831SAndroid Build Coastguard Worker            del lines[0]
722*7c568831SAndroid Build Coastguard Worker
723*7c568831SAndroid Build Coastguard Worker        desc = desc.strip()
724*7c568831SAndroid Build Coastguard Worker
725*7c568831SAndroid Build Coastguard Worker        if quiet == 0:
726*7c568831SAndroid Build Coastguard Worker            if desc == "":
727*7c568831SAndroid Build Coastguard Worker                self.warning("Comment for %s lacks description" % (name))
728*7c568831SAndroid Build Coastguard Worker
729*7c568831SAndroid Build Coastguard Worker        return(desc)
730*7c568831SAndroid Build Coastguard Worker    #
731*7c568831SAndroid Build Coastguard Worker    # Parse a comment block associate to a macro
732*7c568831SAndroid Build Coastguard Worker    #
733*7c568831SAndroid Build Coastguard Worker    def parseMacroComment(self, name, quiet = 0):
734*7c568831SAndroid Build Coastguard Worker        if name[0:2] == '__':
735*7c568831SAndroid Build Coastguard Worker            quiet = 1
736*7c568831SAndroid Build Coastguard Worker
737*7c568831SAndroid Build Coastguard Worker        args = []
738*7c568831SAndroid Build Coastguard Worker        desc = ""
739*7c568831SAndroid Build Coastguard Worker
740*7c568831SAndroid Build Coastguard Worker        if self.comment == None:
741*7c568831SAndroid Build Coastguard Worker            if not quiet:
742*7c568831SAndroid Build Coastguard Worker                self.warning("Missing comment for macro %s" % (name))
743*7c568831SAndroid Build Coastguard Worker            return((args, desc))
744*7c568831SAndroid Build Coastguard Worker        if self.comment[0] != '*':
745*7c568831SAndroid Build Coastguard Worker            if not quiet:
746*7c568831SAndroid Build Coastguard Worker                self.warning("Missing * in macro comment for %s" % (name))
747*7c568831SAndroid Build Coastguard Worker            return((args, desc))
748*7c568831SAndroid Build Coastguard Worker        lines = self.comment.split('\n')
749*7c568831SAndroid Build Coastguard Worker        if lines[0] == '*':
750*7c568831SAndroid Build Coastguard Worker            del lines[0]
751*7c568831SAndroid Build Coastguard Worker        if lines[0] != "* %s:" % (name):
752*7c568831SAndroid Build Coastguard Worker            if not quiet:
753*7c568831SAndroid Build Coastguard Worker                self.warning("Misformatted macro comment for %s" % (name))
754*7c568831SAndroid Build Coastguard Worker                self.warning("  Expecting '* %s:' got '%s'" % (name, lines[0]))
755*7c568831SAndroid Build Coastguard Worker            return((args, desc))
756*7c568831SAndroid Build Coastguard Worker        del lines[0]
757*7c568831SAndroid Build Coastguard Worker        while lines[0] == '*':
758*7c568831SAndroid Build Coastguard Worker            del lines[0]
759*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0 and lines[0][0:3] == '* @':
760*7c568831SAndroid Build Coastguard Worker            l = lines[0][3:]
761*7c568831SAndroid Build Coastguard Worker            try:
762*7c568831SAndroid Build Coastguard Worker                (arg, desc) = l.split(':', 1)
763*7c568831SAndroid Build Coastguard Worker                desc=desc.strip()
764*7c568831SAndroid Build Coastguard Worker                arg=arg.strip()
765*7c568831SAndroid Build Coastguard Worker            except:
766*7c568831SAndroid Build Coastguard Worker                if not quiet:
767*7c568831SAndroid Build Coastguard Worker                    self.warning("Misformatted macro comment for %s" % (name))
768*7c568831SAndroid Build Coastguard Worker                    self.warning("  problem with '%s'" % (lines[0]))
769*7c568831SAndroid Build Coastguard Worker                del lines[0]
770*7c568831SAndroid Build Coastguard Worker                continue
771*7c568831SAndroid Build Coastguard Worker            del lines[0]
772*7c568831SAndroid Build Coastguard Worker            l = lines[0].strip()
773*7c568831SAndroid Build Coastguard Worker            while len(l) > 2 and l[0:3] != '* @':
774*7c568831SAndroid Build Coastguard Worker                while l[0] == '*':
775*7c568831SAndroid Build Coastguard Worker                    l = l[1:]
776*7c568831SAndroid Build Coastguard Worker                desc = desc + ' ' + l.strip()
777*7c568831SAndroid Build Coastguard Worker                del lines[0]
778*7c568831SAndroid Build Coastguard Worker                if len(lines) == 0:
779*7c568831SAndroid Build Coastguard Worker                    break
780*7c568831SAndroid Build Coastguard Worker                l = lines[0]
781*7c568831SAndroid Build Coastguard Worker            args.append((arg, desc))
782*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0 and lines[0] == '*':
783*7c568831SAndroid Build Coastguard Worker            del lines[0]
784*7c568831SAndroid Build Coastguard Worker        desc = ""
785*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0:
786*7c568831SAndroid Build Coastguard Worker            l = lines[0]
787*7c568831SAndroid Build Coastguard Worker            while len(l) > 0 and l[0] == '*':
788*7c568831SAndroid Build Coastguard Worker                l = l[1:]
789*7c568831SAndroid Build Coastguard Worker            l = l.strip()
790*7c568831SAndroid Build Coastguard Worker            desc = desc + " " + l
791*7c568831SAndroid Build Coastguard Worker            del lines[0]
792*7c568831SAndroid Build Coastguard Worker
793*7c568831SAndroid Build Coastguard Worker        desc = desc.strip()
794*7c568831SAndroid Build Coastguard Worker
795*7c568831SAndroid Build Coastguard Worker        if quiet == 0:
796*7c568831SAndroid Build Coastguard Worker            if desc == "":
797*7c568831SAndroid Build Coastguard Worker                self.warning("Macro comment for %s lack description of the macro" % (name))
798*7c568831SAndroid Build Coastguard Worker
799*7c568831SAndroid Build Coastguard Worker        return((args, desc))
800*7c568831SAndroid Build Coastguard Worker
801*7c568831SAndroid Build Coastguard Worker     #
802*7c568831SAndroid Build Coastguard Worker     # Parse a comment block and merge the information found in the
803*7c568831SAndroid Build Coastguard Worker     # parameters descriptions, finally returns a block as complete
804*7c568831SAndroid Build Coastguard Worker     # as possible
805*7c568831SAndroid Build Coastguard Worker     #
806*7c568831SAndroid Build Coastguard Worker    def mergeFunctionComment(self, name, description, quiet = 0):
807*7c568831SAndroid Build Coastguard Worker        if name == 'main':
808*7c568831SAndroid Build Coastguard Worker            quiet = 1
809*7c568831SAndroid Build Coastguard Worker        if name[0:2] == '__':
810*7c568831SAndroid Build Coastguard Worker            quiet = 1
811*7c568831SAndroid Build Coastguard Worker
812*7c568831SAndroid Build Coastguard Worker        (ret, args) = description
813*7c568831SAndroid Build Coastguard Worker        desc = ""
814*7c568831SAndroid Build Coastguard Worker        retdesc = ""
815*7c568831SAndroid Build Coastguard Worker
816*7c568831SAndroid Build Coastguard Worker        if self.comment == None:
817*7c568831SAndroid Build Coastguard Worker            if not quiet:
818*7c568831SAndroid Build Coastguard Worker                self.warning("Missing comment for function %s" % (name))
819*7c568831SAndroid Build Coastguard Worker            return(((ret[0], retdesc), args, desc))
820*7c568831SAndroid Build Coastguard Worker        if self.comment[0] != '*':
821*7c568831SAndroid Build Coastguard Worker            if not quiet:
822*7c568831SAndroid Build Coastguard Worker                self.warning("Missing * in function comment for %s" % (name))
823*7c568831SAndroid Build Coastguard Worker            return(((ret[0], retdesc), args, desc))
824*7c568831SAndroid Build Coastguard Worker        lines = self.comment.split('\n')
825*7c568831SAndroid Build Coastguard Worker        if lines[0] == '*':
826*7c568831SAndroid Build Coastguard Worker            del lines[0]
827*7c568831SAndroid Build Coastguard Worker        if lines[0] != "* %s:" % (name):
828*7c568831SAndroid Build Coastguard Worker            if not quiet:
829*7c568831SAndroid Build Coastguard Worker                self.warning("Misformatted function comment for %s" % (name))
830*7c568831SAndroid Build Coastguard Worker                self.warning("  Expecting '* %s:' got '%s'" % (name, lines[0]))
831*7c568831SAndroid Build Coastguard Worker            return(((ret[0], retdesc), args, desc))
832*7c568831SAndroid Build Coastguard Worker        del lines[0]
833*7c568831SAndroid Build Coastguard Worker        while lines[0] == '*':
834*7c568831SAndroid Build Coastguard Worker            del lines[0]
835*7c568831SAndroid Build Coastguard Worker        nbargs = len(args)
836*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0 and lines[0][0:3] == '* @':
837*7c568831SAndroid Build Coastguard Worker            l = lines[0][3:]
838*7c568831SAndroid Build Coastguard Worker            try:
839*7c568831SAndroid Build Coastguard Worker                (arg, desc) = l.split(':', 1)
840*7c568831SAndroid Build Coastguard Worker                desc=desc.strip()
841*7c568831SAndroid Build Coastguard Worker                arg=arg.strip()
842*7c568831SAndroid Build Coastguard Worker            except:
843*7c568831SAndroid Build Coastguard Worker                if not quiet:
844*7c568831SAndroid Build Coastguard Worker                    self.warning("Misformatted function comment for %s" % (name))
845*7c568831SAndroid Build Coastguard Worker                    self.warning("  problem with '%s'" % (lines[0]))
846*7c568831SAndroid Build Coastguard Worker                del lines[0]
847*7c568831SAndroid Build Coastguard Worker                continue
848*7c568831SAndroid Build Coastguard Worker            del lines[0]
849*7c568831SAndroid Build Coastguard Worker            l = lines[0].strip()
850*7c568831SAndroid Build Coastguard Worker            while len(l) > 2 and l[0:3] != '* @':
851*7c568831SAndroid Build Coastguard Worker                while l[0] == '*':
852*7c568831SAndroid Build Coastguard Worker                    l = l[1:]
853*7c568831SAndroid Build Coastguard Worker                desc = desc + ' ' + l.strip()
854*7c568831SAndroid Build Coastguard Worker                del lines[0]
855*7c568831SAndroid Build Coastguard Worker                if len(lines) == 0:
856*7c568831SAndroid Build Coastguard Worker                    break
857*7c568831SAndroid Build Coastguard Worker                l = lines[0]
858*7c568831SAndroid Build Coastguard Worker            i = 0
859*7c568831SAndroid Build Coastguard Worker            while i < nbargs:
860*7c568831SAndroid Build Coastguard Worker                if args[i][1] == arg:
861*7c568831SAndroid Build Coastguard Worker                    args[i] = (args[i][0], arg, desc)
862*7c568831SAndroid Build Coastguard Worker                    break;
863*7c568831SAndroid Build Coastguard Worker                i = i + 1
864*7c568831SAndroid Build Coastguard Worker            if i >= nbargs:
865*7c568831SAndroid Build Coastguard Worker                if not quiet:
866*7c568831SAndroid Build Coastguard Worker                    self.warning("Unable to find arg %s from function comment for %s" % (
867*7c568831SAndroid Build Coastguard Worker                       arg, name))
868*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0 and lines[0] == '*':
869*7c568831SAndroid Build Coastguard Worker            del lines[0]
870*7c568831SAndroid Build Coastguard Worker        desc = ""
871*7c568831SAndroid Build Coastguard Worker        while len(lines) > 0:
872*7c568831SAndroid Build Coastguard Worker            l = lines[0]
873*7c568831SAndroid Build Coastguard Worker            while len(l) > 0 and l[0] == '*':
874*7c568831SAndroid Build Coastguard Worker                l = l[1:]
875*7c568831SAndroid Build Coastguard Worker            l = l.strip()
876*7c568831SAndroid Build Coastguard Worker            if len(l) >= 6 and  l[0:6] == "return" or l[0:6] == "Return":
877*7c568831SAndroid Build Coastguard Worker                try:
878*7c568831SAndroid Build Coastguard Worker                    l = l.split(' ', 1)[1]
879*7c568831SAndroid Build Coastguard Worker                except:
880*7c568831SAndroid Build Coastguard Worker                    l = ""
881*7c568831SAndroid Build Coastguard Worker                retdesc = l.strip()
882*7c568831SAndroid Build Coastguard Worker                del lines[0]
883*7c568831SAndroid Build Coastguard Worker                while len(lines) > 0:
884*7c568831SAndroid Build Coastguard Worker                    l = lines[0]
885*7c568831SAndroid Build Coastguard Worker                    while len(l) > 0 and l[0] == '*':
886*7c568831SAndroid Build Coastguard Worker                        l = l[1:]
887*7c568831SAndroid Build Coastguard Worker                    l = l.strip()
888*7c568831SAndroid Build Coastguard Worker                    retdesc = retdesc + " " + l
889*7c568831SAndroid Build Coastguard Worker                    del lines[0]
890*7c568831SAndroid Build Coastguard Worker            else:
891*7c568831SAndroid Build Coastguard Worker                desc = desc + " " + l
892*7c568831SAndroid Build Coastguard Worker                del lines[0]
893*7c568831SAndroid Build Coastguard Worker
894*7c568831SAndroid Build Coastguard Worker        retdesc = retdesc.strip()
895*7c568831SAndroid Build Coastguard Worker        desc = desc.strip()
896*7c568831SAndroid Build Coastguard Worker
897*7c568831SAndroid Build Coastguard Worker        if quiet == 0:
898*7c568831SAndroid Build Coastguard Worker             #
899*7c568831SAndroid Build Coastguard Worker             # report missing comments
900*7c568831SAndroid Build Coastguard Worker             #
901*7c568831SAndroid Build Coastguard Worker            i = 0
902*7c568831SAndroid Build Coastguard Worker            while i < nbargs:
903*7c568831SAndroid Build Coastguard Worker                if args[i][2] == None and args[i][0] != "void" and \
904*7c568831SAndroid Build Coastguard Worker                   ((args[i][1] != None) or (args[i][1] == '')):
905*7c568831SAndroid Build Coastguard Worker                    self.warning("Function comment for %s lacks description of arg %s" % (name, args[i][1]))
906*7c568831SAndroid Build Coastguard Worker                i = i + 1
907*7c568831SAndroid Build Coastguard Worker            if retdesc == "" and ret[0] != "void":
908*7c568831SAndroid Build Coastguard Worker                self.warning("Function comment for %s lacks description of return value" % (name))
909*7c568831SAndroid Build Coastguard Worker            if desc == "" and retdesc == "":
910*7c568831SAndroid Build Coastguard Worker                self.warning("Function comment for %s lacks description of the function" % (name))
911*7c568831SAndroid Build Coastguard Worker
912*7c568831SAndroid Build Coastguard Worker        return(((ret[0], retdesc), args, desc))
913*7c568831SAndroid Build Coastguard Worker
914*7c568831SAndroid Build Coastguard Worker    def parsePreproc(self, token):
915*7c568831SAndroid Build Coastguard Worker        if debug:
916*7c568831SAndroid Build Coastguard Worker            print("=> preproc ", token, self.lexer.tokens)
917*7c568831SAndroid Build Coastguard Worker        name = token[1]
918*7c568831SAndroid Build Coastguard Worker        if name == "#include":
919*7c568831SAndroid Build Coastguard Worker            token = self.lexer.token()
920*7c568831SAndroid Build Coastguard Worker            if token == None:
921*7c568831SAndroid Build Coastguard Worker                return None
922*7c568831SAndroid Build Coastguard Worker            if token[0] == 'preproc':
923*7c568831SAndroid Build Coastguard Worker                self.index_add(token[1], self.filename, not self.is_header,
924*7c568831SAndroid Build Coastguard Worker                                "include")
925*7c568831SAndroid Build Coastguard Worker                return self.lexer.token()
926*7c568831SAndroid Build Coastguard Worker            return token
927*7c568831SAndroid Build Coastguard Worker        if name == "#define":
928*7c568831SAndroid Build Coastguard Worker            token = self.lexer.token()
929*7c568831SAndroid Build Coastguard Worker            if token == None:
930*7c568831SAndroid Build Coastguard Worker                return None
931*7c568831SAndroid Build Coastguard Worker            if token[0] == 'preproc':
932*7c568831SAndroid Build Coastguard Worker                 # TODO macros with arguments
933*7c568831SAndroid Build Coastguard Worker                name = token[1]
934*7c568831SAndroid Build Coastguard Worker                lst = []
935*7c568831SAndroid Build Coastguard Worker                token = self.lexer.token()
936*7c568831SAndroid Build Coastguard Worker                while token != None and token[0] == 'preproc' and \
937*7c568831SAndroid Build Coastguard Worker                      token[1][0] != '#':
938*7c568831SAndroid Build Coastguard Worker                    lst.append(token[1])
939*7c568831SAndroid Build Coastguard Worker                    token = self.lexer.token()
940*7c568831SAndroid Build Coastguard Worker                try:
941*7c568831SAndroid Build Coastguard Worker                    name = name.split('(') [0]
942*7c568831SAndroid Build Coastguard Worker                except:
943*7c568831SAndroid Build Coastguard Worker                    pass
944*7c568831SAndroid Build Coastguard Worker                info = self.parseMacroComment(name, True)
945*7c568831SAndroid Build Coastguard Worker                self.index_add(name, self.filename, not self.is_header,
946*7c568831SAndroid Build Coastguard Worker                                "macro", info)
947*7c568831SAndroid Build Coastguard Worker                return token
948*7c568831SAndroid Build Coastguard Worker
949*7c568831SAndroid Build Coastguard Worker        #
950*7c568831SAndroid Build Coastguard Worker        # Processing of conditionals modified by Bill 1/1/05
951*7c568831SAndroid Build Coastguard Worker        #
952*7c568831SAndroid Build Coastguard Worker        # We process conditionals (i.e. tokens from #ifdef, #ifndef,
953*7c568831SAndroid Build Coastguard Worker        # #if, #else and #endif) for headers and mainline code,
954*7c568831SAndroid Build Coastguard Worker        # store the ones from the header in libxml2-api.xml, and later
955*7c568831SAndroid Build Coastguard Worker        # (in the routine merge_public) verify that the two (header and
956*7c568831SAndroid Build Coastguard Worker        # mainline code) agree.
957*7c568831SAndroid Build Coastguard Worker        #
958*7c568831SAndroid Build Coastguard Worker        # There is a small problem with processing the headers. Some of
959*7c568831SAndroid Build Coastguard Worker        # the variables are not concerned with enabling / disabling of
960*7c568831SAndroid Build Coastguard Worker        # library functions (e.g. '__XML_PARSER_H__'), and we don't want
961*7c568831SAndroid Build Coastguard Worker        # them to be included in libxml2-api.xml, or involved in
962*7c568831SAndroid Build Coastguard Worker        # the check between the header and the mainline code.  To
963*7c568831SAndroid Build Coastguard Worker        # accomplish this, we ignore any conditional which doesn't include
964*7c568831SAndroid Build Coastguard Worker        # the string 'ENABLED'
965*7c568831SAndroid Build Coastguard Worker        #
966*7c568831SAndroid Build Coastguard Worker        if name == "#ifdef":
967*7c568831SAndroid Build Coastguard Worker            apstr = self.lexer.tokens[0][1]
968*7c568831SAndroid Build Coastguard Worker            try:
969*7c568831SAndroid Build Coastguard Worker                self.defines.append(apstr)
970*7c568831SAndroid Build Coastguard Worker                if apstr.find('ENABLED') != -1:
971*7c568831SAndroid Build Coastguard Worker                    self.conditionals.append("defined(%s)" % apstr)
972*7c568831SAndroid Build Coastguard Worker            except:
973*7c568831SAndroid Build Coastguard Worker                pass
974*7c568831SAndroid Build Coastguard Worker        elif name == "#ifndef":
975*7c568831SAndroid Build Coastguard Worker            apstr = self.lexer.tokens[0][1]
976*7c568831SAndroid Build Coastguard Worker            try:
977*7c568831SAndroid Build Coastguard Worker                self.defines.append(apstr)
978*7c568831SAndroid Build Coastguard Worker                if apstr.find('ENABLED') != -1:
979*7c568831SAndroid Build Coastguard Worker                    self.conditionals.append("!defined(%s)" % apstr)
980*7c568831SAndroid Build Coastguard Worker            except:
981*7c568831SAndroid Build Coastguard Worker                pass
982*7c568831SAndroid Build Coastguard Worker        elif name == "#if":
983*7c568831SAndroid Build Coastguard Worker            apstr = ""
984*7c568831SAndroid Build Coastguard Worker            for tok in self.lexer.tokens:
985*7c568831SAndroid Build Coastguard Worker                if apstr != "":
986*7c568831SAndroid Build Coastguard Worker                    apstr = apstr + " "
987*7c568831SAndroid Build Coastguard Worker                apstr = apstr + tok[1]
988*7c568831SAndroid Build Coastguard Worker            try:
989*7c568831SAndroid Build Coastguard Worker                self.defines.append(apstr)
990*7c568831SAndroid Build Coastguard Worker                if apstr.find('ENABLED') != -1:
991*7c568831SAndroid Build Coastguard Worker                    self.conditionals.append(apstr)
992*7c568831SAndroid Build Coastguard Worker            except:
993*7c568831SAndroid Build Coastguard Worker                pass
994*7c568831SAndroid Build Coastguard Worker        elif name == "#else":
995*7c568831SAndroid Build Coastguard Worker            if self.conditionals != [] and \
996*7c568831SAndroid Build Coastguard Worker               self.defines[-1].find('ENABLED') != -1:
997*7c568831SAndroid Build Coastguard Worker                self.conditionals[-1] = "!(%s)" % self.conditionals[-1]
998*7c568831SAndroid Build Coastguard Worker        elif name == "#endif":
999*7c568831SAndroid Build Coastguard Worker            if self.conditionals != [] and \
1000*7c568831SAndroid Build Coastguard Worker               self.defines[-1].find('ENABLED') != -1:
1001*7c568831SAndroid Build Coastguard Worker                self.conditionals = self.conditionals[:-1]
1002*7c568831SAndroid Build Coastguard Worker            self.defines = self.defines[:-1]
1003*7c568831SAndroid Build Coastguard Worker        token = self.lexer.token()
1004*7c568831SAndroid Build Coastguard Worker        while token != None and token[0] == 'preproc' and \
1005*7c568831SAndroid Build Coastguard Worker            token[1][0] != '#':
1006*7c568831SAndroid Build Coastguard Worker            token = self.lexer.token()
1007*7c568831SAndroid Build Coastguard Worker        return token
1008*7c568831SAndroid Build Coastguard Worker
1009*7c568831SAndroid Build Coastguard Worker     #
1010*7c568831SAndroid Build Coastguard Worker     # token acquisition on top of the lexer, it handle internally
1011*7c568831SAndroid Build Coastguard Worker     # preprocessor and comments since they are logically not part of
1012*7c568831SAndroid Build Coastguard Worker     # the program structure.
1013*7c568831SAndroid Build Coastguard Worker     #
1014*7c568831SAndroid Build Coastguard Worker    def token(self):
1015*7c568831SAndroid Build Coastguard Worker        global ignored_words
1016*7c568831SAndroid Build Coastguard Worker
1017*7c568831SAndroid Build Coastguard Worker        token = self.lexer.token()
1018*7c568831SAndroid Build Coastguard Worker        while token != None:
1019*7c568831SAndroid Build Coastguard Worker            if token[0] == 'comment':
1020*7c568831SAndroid Build Coastguard Worker                token = self.parseComment(token)
1021*7c568831SAndroid Build Coastguard Worker                continue
1022*7c568831SAndroid Build Coastguard Worker            elif token[0] == 'preproc':
1023*7c568831SAndroid Build Coastguard Worker                token = self.parsePreproc(token)
1024*7c568831SAndroid Build Coastguard Worker                continue
1025*7c568831SAndroid Build Coastguard Worker            elif token[0] == "name" and token[1] == "__const":
1026*7c568831SAndroid Build Coastguard Worker                token = ("name", "const")
1027*7c568831SAndroid Build Coastguard Worker                return token
1028*7c568831SAndroid Build Coastguard Worker            elif token[0] == "name" and token[1] == "__attribute":
1029*7c568831SAndroid Build Coastguard Worker                token = self.lexer.token()
1030*7c568831SAndroid Build Coastguard Worker                while token != None and token[1] != ";":
1031*7c568831SAndroid Build Coastguard Worker                    token = self.lexer.token()
1032*7c568831SAndroid Build Coastguard Worker                return token
1033*7c568831SAndroid Build Coastguard Worker            elif token[0] == "name" and token[1] in ignored_words:
1034*7c568831SAndroid Build Coastguard Worker                (n, info) = ignored_words[token[1]]
1035*7c568831SAndroid Build Coastguard Worker                i = 0
1036*7c568831SAndroid Build Coastguard Worker                while i < n:
1037*7c568831SAndroid Build Coastguard Worker                    token = self.lexer.token()
1038*7c568831SAndroid Build Coastguard Worker                    i = i + 1
1039*7c568831SAndroid Build Coastguard Worker                token = self.lexer.token()
1040*7c568831SAndroid Build Coastguard Worker                continue
1041*7c568831SAndroid Build Coastguard Worker            else:
1042*7c568831SAndroid Build Coastguard Worker                if debug:
1043*7c568831SAndroid Build Coastguard Worker                    print("=> ", token)
1044*7c568831SAndroid Build Coastguard Worker                return token
1045*7c568831SAndroid Build Coastguard Worker        return None
1046*7c568831SAndroid Build Coastguard Worker
1047*7c568831SAndroid Build Coastguard Worker     #
1048*7c568831SAndroid Build Coastguard Worker     # Parse a typedef, it records the type and its name.
1049*7c568831SAndroid Build Coastguard Worker     #
1050*7c568831SAndroid Build Coastguard Worker    def parseTypedef(self, token):
1051*7c568831SAndroid Build Coastguard Worker        if token == None:
1052*7c568831SAndroid Build Coastguard Worker            return None
1053*7c568831SAndroid Build Coastguard Worker        token = self.parseType(token)
1054*7c568831SAndroid Build Coastguard Worker        if token == None:
1055*7c568831SAndroid Build Coastguard Worker            self.error("parsing typedef")
1056*7c568831SAndroid Build Coastguard Worker            return None
1057*7c568831SAndroid Build Coastguard Worker        base_type = self.type
1058*7c568831SAndroid Build Coastguard Worker        type = base_type
1059*7c568831SAndroid Build Coastguard Worker         #self.debug("end typedef type", token)
1060*7c568831SAndroid Build Coastguard Worker        while token != None:
1061*7c568831SAndroid Build Coastguard Worker            if token[0] == "name":
1062*7c568831SAndroid Build Coastguard Worker                name = token[1]
1063*7c568831SAndroid Build Coastguard Worker                signature = self.signature
1064*7c568831SAndroid Build Coastguard Worker                if signature != None:
1065*7c568831SAndroid Build Coastguard Worker                    type = type.split('(')[0]
1066*7c568831SAndroid Build Coastguard Worker                    d = self.mergeFunctionComment(name,
1067*7c568831SAndroid Build Coastguard Worker                            ((type, None), signature), 1)
1068*7c568831SAndroid Build Coastguard Worker                    self.index_add(name, self.filename, not self.is_header,
1069*7c568831SAndroid Build Coastguard Worker                                    "functype", d)
1070*7c568831SAndroid Build Coastguard Worker                else:
1071*7c568831SAndroid Build Coastguard Worker                    if base_type == "struct":
1072*7c568831SAndroid Build Coastguard Worker                        self.index_add(name, self.filename, not self.is_header,
1073*7c568831SAndroid Build Coastguard Worker                                        "struct", type)
1074*7c568831SAndroid Build Coastguard Worker                        base_type = "struct " + name
1075*7c568831SAndroid Build Coastguard Worker                    else:
1076*7c568831SAndroid Build Coastguard Worker                        # TODO report missing or misformatted comments
1077*7c568831SAndroid Build Coastguard Worker                        info = self.parseSimpleComment(name, True)
1078*7c568831SAndroid Build Coastguard Worker                        self.index_add(name, self.filename, not self.is_header,
1079*7c568831SAndroid Build Coastguard Worker                                    "typedef", type, info)
1080*7c568831SAndroid Build Coastguard Worker                token = self.token()
1081*7c568831SAndroid Build Coastguard Worker            else:
1082*7c568831SAndroid Build Coastguard Worker                self.error("parsing typedef: expecting a name")
1083*7c568831SAndroid Build Coastguard Worker                return token
1084*7c568831SAndroid Build Coastguard Worker             #self.debug("end typedef", token)
1085*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == 'sep' and token[1] == ',':
1086*7c568831SAndroid Build Coastguard Worker                type = base_type
1087*7c568831SAndroid Build Coastguard Worker                token = self.token()
1088*7c568831SAndroid Build Coastguard Worker                while token != None and token[0] == "op":
1089*7c568831SAndroid Build Coastguard Worker                    type = type + token[1]
1090*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1091*7c568831SAndroid Build Coastguard Worker            elif token != None and token[0] == 'sep' and token[1] == ';':
1092*7c568831SAndroid Build Coastguard Worker                break;
1093*7c568831SAndroid Build Coastguard Worker            elif token != None and token[0] == 'name':
1094*7c568831SAndroid Build Coastguard Worker                type = base_type
1095*7c568831SAndroid Build Coastguard Worker                continue;
1096*7c568831SAndroid Build Coastguard Worker            else:
1097*7c568831SAndroid Build Coastguard Worker                self.error("parsing typedef: expecting ';'", token)
1098*7c568831SAndroid Build Coastguard Worker                return token
1099*7c568831SAndroid Build Coastguard Worker        token = self.token()
1100*7c568831SAndroid Build Coastguard Worker        return token
1101*7c568831SAndroid Build Coastguard Worker
1102*7c568831SAndroid Build Coastguard Worker     #
1103*7c568831SAndroid Build Coastguard Worker     # Parse a C code block, used for functions it parse till
1104*7c568831SAndroid Build Coastguard Worker     # the balancing } included
1105*7c568831SAndroid Build Coastguard Worker     #
1106*7c568831SAndroid Build Coastguard Worker    def parseBlock(self, token):
1107*7c568831SAndroid Build Coastguard Worker        while token != None:
1108*7c568831SAndroid Build Coastguard Worker            if token[0] == "sep" and token[1] == "{":
1109*7c568831SAndroid Build Coastguard Worker                token = self.token()
1110*7c568831SAndroid Build Coastguard Worker                token = self.parseBlock(token)
1111*7c568831SAndroid Build Coastguard Worker            elif token[0] == "sep" and token[1] == "}":
1112*7c568831SAndroid Build Coastguard Worker                token = self.token()
1113*7c568831SAndroid Build Coastguard Worker                return token
1114*7c568831SAndroid Build Coastguard Worker            else:
1115*7c568831SAndroid Build Coastguard Worker                if self.collect_ref == 1:
1116*7c568831SAndroid Build Coastguard Worker                    oldtok = token
1117*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1118*7c568831SAndroid Build Coastguard Worker                    if oldtok[0] == "name" and oldtok[1][0:3] == "xml":
1119*7c568831SAndroid Build Coastguard Worker                        if token[0] == "sep" and token[1] == "(":
1120*7c568831SAndroid Build Coastguard Worker                            self.index_add_ref(oldtok[1], self.filename,
1121*7c568831SAndroid Build Coastguard Worker                                                0, "function")
1122*7c568831SAndroid Build Coastguard Worker                            token = self.token()
1123*7c568831SAndroid Build Coastguard Worker                        elif token[0] == "name":
1124*7c568831SAndroid Build Coastguard Worker                            token = self.token()
1125*7c568831SAndroid Build Coastguard Worker                            if token[0] == "sep" and (token[1] == ";" or
1126*7c568831SAndroid Build Coastguard Worker                               token[1] == "," or token[1] == "="):
1127*7c568831SAndroid Build Coastguard Worker                                self.index_add_ref(oldtok[1], self.filename,
1128*7c568831SAndroid Build Coastguard Worker                                                    0, "type")
1129*7c568831SAndroid Build Coastguard Worker                    elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_":
1130*7c568831SAndroid Build Coastguard Worker                        self.index_add_ref(oldtok[1], self.filename,
1131*7c568831SAndroid Build Coastguard Worker                                            0, "typedef")
1132*7c568831SAndroid Build Coastguard Worker                    elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_":
1133*7c568831SAndroid Build Coastguard Worker                        self.index_add_ref(oldtok[1], self.filename,
1134*7c568831SAndroid Build Coastguard Worker                                            0, "typedef")
1135*7c568831SAndroid Build Coastguard Worker
1136*7c568831SAndroid Build Coastguard Worker                else:
1137*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1138*7c568831SAndroid Build Coastguard Worker        return token
1139*7c568831SAndroid Build Coastguard Worker
1140*7c568831SAndroid Build Coastguard Worker     #
1141*7c568831SAndroid Build Coastguard Worker     # Parse a C struct definition till the balancing }
1142*7c568831SAndroid Build Coastguard Worker     #
1143*7c568831SAndroid Build Coastguard Worker    def parseStruct(self, token):
1144*7c568831SAndroid Build Coastguard Worker        fields = []
1145*7c568831SAndroid Build Coastguard Worker         #self.debug("start parseStruct", token)
1146*7c568831SAndroid Build Coastguard Worker        while token != None:
1147*7c568831SAndroid Build Coastguard Worker            if token[0] == "sep" and token[1] == "{":
1148*7c568831SAndroid Build Coastguard Worker                token = self.token()
1149*7c568831SAndroid Build Coastguard Worker                token = self.parseTypeBlock(token)
1150*7c568831SAndroid Build Coastguard Worker            elif token[0] == "sep" and token[1] == "}":
1151*7c568831SAndroid Build Coastguard Worker                self.struct_fields = fields
1152*7c568831SAndroid Build Coastguard Worker                 #self.debug("end parseStruct", token)
1153*7c568831SAndroid Build Coastguard Worker                 #print fields
1154*7c568831SAndroid Build Coastguard Worker                token = self.token()
1155*7c568831SAndroid Build Coastguard Worker                return token
1156*7c568831SAndroid Build Coastguard Worker            else:
1157*7c568831SAndroid Build Coastguard Worker                base_type = self.type
1158*7c568831SAndroid Build Coastguard Worker                 #self.debug("before parseType", token)
1159*7c568831SAndroid Build Coastguard Worker                token = self.parseType(token)
1160*7c568831SAndroid Build Coastguard Worker                 #self.debug("after parseType", token)
1161*7c568831SAndroid Build Coastguard Worker                if token != None and token[0] == "name":
1162*7c568831SAndroid Build Coastguard Worker                    fname = token[1]
1163*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1164*7c568831SAndroid Build Coastguard Worker                    if token[0] == "sep" and token[1] == ";":
1165*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1166*7c568831SAndroid Build Coastguard Worker                        fields.append((self.type, fname))
1167*7c568831SAndroid Build Coastguard Worker                    else:
1168*7c568831SAndroid Build Coastguard Worker                        self.error("parseStruct: expecting ;", token)
1169*7c568831SAndroid Build Coastguard Worker                elif token != None and token[0] == "sep" and token[1] == "{":
1170*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1171*7c568831SAndroid Build Coastguard Worker                    token = self.parseTypeBlock(token)
1172*7c568831SAndroid Build Coastguard Worker                    if token != None and token[0] == "name":
1173*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1174*7c568831SAndroid Build Coastguard Worker                    if token != None and token[0] == "sep" and token[1] == ";":
1175*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1176*7c568831SAndroid Build Coastguard Worker                    else:
1177*7c568831SAndroid Build Coastguard Worker                        self.error("parseStruct: expecting ;", token)
1178*7c568831SAndroid Build Coastguard Worker                else:
1179*7c568831SAndroid Build Coastguard Worker                    self.error("parseStruct: name", token)
1180*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1181*7c568831SAndroid Build Coastguard Worker                self.type = base_type;
1182*7c568831SAndroid Build Coastguard Worker        self.struct_fields = fields
1183*7c568831SAndroid Build Coastguard Worker         #self.debug("end parseStruct", token)
1184*7c568831SAndroid Build Coastguard Worker         #print fields
1185*7c568831SAndroid Build Coastguard Worker        return token
1186*7c568831SAndroid Build Coastguard Worker
1187*7c568831SAndroid Build Coastguard Worker     #
1188*7c568831SAndroid Build Coastguard Worker     # Parse a C enum block, parse till the balancing }
1189*7c568831SAndroid Build Coastguard Worker     #
1190*7c568831SAndroid Build Coastguard Worker    def parseEnumBlock(self, token):
1191*7c568831SAndroid Build Coastguard Worker        self.enums = []
1192*7c568831SAndroid Build Coastguard Worker        name = None
1193*7c568831SAndroid Build Coastguard Worker        self.comment = None
1194*7c568831SAndroid Build Coastguard Worker        comment = ""
1195*7c568831SAndroid Build Coastguard Worker        value = "0"
1196*7c568831SAndroid Build Coastguard Worker        while token != None:
1197*7c568831SAndroid Build Coastguard Worker            if token[0] == "sep" and token[1] == "{":
1198*7c568831SAndroid Build Coastguard Worker                token = self.token()
1199*7c568831SAndroid Build Coastguard Worker                token = self.parseTypeBlock(token)
1200*7c568831SAndroid Build Coastguard Worker            elif token[0] == "sep" and token[1] == "}":
1201*7c568831SAndroid Build Coastguard Worker                if name != None:
1202*7c568831SAndroid Build Coastguard Worker                    if self.comment != None:
1203*7c568831SAndroid Build Coastguard Worker                        comment = self.comment
1204*7c568831SAndroid Build Coastguard Worker                        self.comment = None
1205*7c568831SAndroid Build Coastguard Worker                    self.enums.append((name, value, comment))
1206*7c568831SAndroid Build Coastguard Worker                token = self.token()
1207*7c568831SAndroid Build Coastguard Worker                return token
1208*7c568831SAndroid Build Coastguard Worker            elif token[0] == "name":
1209*7c568831SAndroid Build Coastguard Worker                    if name != None:
1210*7c568831SAndroid Build Coastguard Worker                        if self.comment != None:
1211*7c568831SAndroid Build Coastguard Worker                            comment = self.comment.strip()
1212*7c568831SAndroid Build Coastguard Worker                            self.comment = None
1213*7c568831SAndroid Build Coastguard Worker                        self.enums.append((name, value, comment))
1214*7c568831SAndroid Build Coastguard Worker                    name = token[1]
1215*7c568831SAndroid Build Coastguard Worker                    comment = ""
1216*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1217*7c568831SAndroid Build Coastguard Worker                    if token[0] == "op" and token[1][0] == "=":
1218*7c568831SAndroid Build Coastguard Worker                        value = ""
1219*7c568831SAndroid Build Coastguard Worker                        if len(token[1]) > 1:
1220*7c568831SAndroid Build Coastguard Worker                            value = token[1][1:]
1221*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1222*7c568831SAndroid Build Coastguard Worker                        while token[0] != "sep" or (token[1] != ',' and
1223*7c568831SAndroid Build Coastguard Worker                              token[1] != '}'):
1224*7c568831SAndroid Build Coastguard Worker                            value = value + token[1]
1225*7c568831SAndroid Build Coastguard Worker                            token = self.token()
1226*7c568831SAndroid Build Coastguard Worker                    else:
1227*7c568831SAndroid Build Coastguard Worker                        try:
1228*7c568831SAndroid Build Coastguard Worker                            value = "%d" % (int(value) + 1)
1229*7c568831SAndroid Build Coastguard Worker                        except:
1230*7c568831SAndroid Build Coastguard Worker                            self.warning("Failed to compute value of enum %s" % (name))
1231*7c568831SAndroid Build Coastguard Worker                            value=""
1232*7c568831SAndroid Build Coastguard Worker                    if token[0] == "sep" and token[1] == ",":
1233*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1234*7c568831SAndroid Build Coastguard Worker            else:
1235*7c568831SAndroid Build Coastguard Worker                token = self.token()
1236*7c568831SAndroid Build Coastguard Worker        return token
1237*7c568831SAndroid Build Coastguard Worker
1238*7c568831SAndroid Build Coastguard Worker     #
1239*7c568831SAndroid Build Coastguard Worker     # Parse a C definition block, used for structs it parse till
1240*7c568831SAndroid Build Coastguard Worker     # the balancing }
1241*7c568831SAndroid Build Coastguard Worker     #
1242*7c568831SAndroid Build Coastguard Worker    def parseTypeBlock(self, token):
1243*7c568831SAndroid Build Coastguard Worker        while token != None:
1244*7c568831SAndroid Build Coastguard Worker            if token[0] == "sep" and token[1] == "{":
1245*7c568831SAndroid Build Coastguard Worker                token = self.token()
1246*7c568831SAndroid Build Coastguard Worker                token = self.parseTypeBlock(token)
1247*7c568831SAndroid Build Coastguard Worker            elif token[0] == "sep" and token[1] == "}":
1248*7c568831SAndroid Build Coastguard Worker                token = self.token()
1249*7c568831SAndroid Build Coastguard Worker                return token
1250*7c568831SAndroid Build Coastguard Worker            else:
1251*7c568831SAndroid Build Coastguard Worker                token = self.token()
1252*7c568831SAndroid Build Coastguard Worker        return token
1253*7c568831SAndroid Build Coastguard Worker
1254*7c568831SAndroid Build Coastguard Worker     #
1255*7c568831SAndroid Build Coastguard Worker     # Parse a type: the fact that the type name can either occur after
1256*7c568831SAndroid Build Coastguard Worker     #    the definition or within the definition makes it a little harder
1257*7c568831SAndroid Build Coastguard Worker     #    if inside, the name token is pushed back before returning
1258*7c568831SAndroid Build Coastguard Worker     #
1259*7c568831SAndroid Build Coastguard Worker    def parseType(self, token):
1260*7c568831SAndroid Build Coastguard Worker        self.type = ""
1261*7c568831SAndroid Build Coastguard Worker        self.struct_fields = []
1262*7c568831SAndroid Build Coastguard Worker        self.signature = None
1263*7c568831SAndroid Build Coastguard Worker        if token == None:
1264*7c568831SAndroid Build Coastguard Worker            return token
1265*7c568831SAndroid Build Coastguard Worker
1266*7c568831SAndroid Build Coastguard Worker        have_sign = 0
1267*7c568831SAndroid Build Coastguard Worker        done = 0
1268*7c568831SAndroid Build Coastguard Worker
1269*7c568831SAndroid Build Coastguard Worker        while token[0] == "name" and (
1270*7c568831SAndroid Build Coastguard Worker              token[1] == "const" or \
1271*7c568831SAndroid Build Coastguard Worker              token[1] == "unsigned" or \
1272*7c568831SAndroid Build Coastguard Worker              token[1] == "signed"):
1273*7c568831SAndroid Build Coastguard Worker            if token[1] == "unsigned" or token[1] == "signed":
1274*7c568831SAndroid Build Coastguard Worker                have_sign = 1
1275*7c568831SAndroid Build Coastguard Worker            if self.type == "":
1276*7c568831SAndroid Build Coastguard Worker                self.type = token[1]
1277*7c568831SAndroid Build Coastguard Worker            else:
1278*7c568831SAndroid Build Coastguard Worker                self.type = self.type + " " + token[1]
1279*7c568831SAndroid Build Coastguard Worker            token = self.token()
1280*7c568831SAndroid Build Coastguard Worker
1281*7c568831SAndroid Build Coastguard Worker        if token[0] == "name" and token[1] in ("char", "short", "int", "long"):
1282*7c568831SAndroid Build Coastguard Worker            if self.type == "":
1283*7c568831SAndroid Build Coastguard Worker                self.type = token[1]
1284*7c568831SAndroid Build Coastguard Worker            else:
1285*7c568831SAndroid Build Coastguard Worker                self.type = self.type + " " + token[1]
1286*7c568831SAndroid Build Coastguard Worker
1287*7c568831SAndroid Build Coastguard Worker        elif have_sign:
1288*7c568831SAndroid Build Coastguard Worker            done = 1
1289*7c568831SAndroid Build Coastguard Worker
1290*7c568831SAndroid Build Coastguard Worker        elif token[0] == "name" and token[1] == "struct":
1291*7c568831SAndroid Build Coastguard Worker            if self.type == "":
1292*7c568831SAndroid Build Coastguard Worker                self.type = token[1]
1293*7c568831SAndroid Build Coastguard Worker            else:
1294*7c568831SAndroid Build Coastguard Worker                self.type = self.type + " " + token[1]
1295*7c568831SAndroid Build Coastguard Worker            token = self.token()
1296*7c568831SAndroid Build Coastguard Worker            nametok = None
1297*7c568831SAndroid Build Coastguard Worker            if token[0] == "name":
1298*7c568831SAndroid Build Coastguard Worker                nametok = token
1299*7c568831SAndroid Build Coastguard Worker                token = self.token()
1300*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "sep" and token[1] == "{":
1301*7c568831SAndroid Build Coastguard Worker                token = self.token()
1302*7c568831SAndroid Build Coastguard Worker                token = self.parseStruct(token)
1303*7c568831SAndroid Build Coastguard Worker            elif token != None and token[0] == "op" and token[1] == "*":
1304*7c568831SAndroid Build Coastguard Worker                self.type = self.type + " " + nametok[1] + " *"
1305*7c568831SAndroid Build Coastguard Worker                token = self.token()
1306*7c568831SAndroid Build Coastguard Worker                while token != None and token[0] == "op" and token[1] == "*":
1307*7c568831SAndroid Build Coastguard Worker                    self.type = self.type + " *"
1308*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1309*7c568831SAndroid Build Coastguard Worker                if token[0] == "name":
1310*7c568831SAndroid Build Coastguard Worker                    nametok = token
1311*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1312*7c568831SAndroid Build Coastguard Worker                else:
1313*7c568831SAndroid Build Coastguard Worker                    self.error("struct : expecting name", token)
1314*7c568831SAndroid Build Coastguard Worker                    return token
1315*7c568831SAndroid Build Coastguard Worker            elif token != None and token[0] == "name" and nametok != None:
1316*7c568831SAndroid Build Coastguard Worker                self.type = self.type + " " + nametok[1]
1317*7c568831SAndroid Build Coastguard Worker                return token
1318*7c568831SAndroid Build Coastguard Worker
1319*7c568831SAndroid Build Coastguard Worker            if nametok != None:
1320*7c568831SAndroid Build Coastguard Worker                self.lexer.push(token)
1321*7c568831SAndroid Build Coastguard Worker                token = nametok
1322*7c568831SAndroid Build Coastguard Worker            return token
1323*7c568831SAndroid Build Coastguard Worker
1324*7c568831SAndroid Build Coastguard Worker        elif token[0] == "name" and token[1] == "enum":
1325*7c568831SAndroid Build Coastguard Worker            if self.type == "":
1326*7c568831SAndroid Build Coastguard Worker                self.type = token[1]
1327*7c568831SAndroid Build Coastguard Worker            else:
1328*7c568831SAndroid Build Coastguard Worker                self.type = self.type + " " + token[1]
1329*7c568831SAndroid Build Coastguard Worker            self.enums = []
1330*7c568831SAndroid Build Coastguard Worker            token = self.token()
1331*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "sep" and token[1] == "{":
1332*7c568831SAndroid Build Coastguard Worker                token = self.token()
1333*7c568831SAndroid Build Coastguard Worker                token = self.parseEnumBlock(token)
1334*7c568831SAndroid Build Coastguard Worker            else:
1335*7c568831SAndroid Build Coastguard Worker                self.error("parsing enum: expecting '{'", token)
1336*7c568831SAndroid Build Coastguard Worker            enum_type = None
1337*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] != "name":
1338*7c568831SAndroid Build Coastguard Worker                self.lexer.push(token)
1339*7c568831SAndroid Build Coastguard Worker                token = ("name", "enum")
1340*7c568831SAndroid Build Coastguard Worker            else:
1341*7c568831SAndroid Build Coastguard Worker                enum_type = token[1]
1342*7c568831SAndroid Build Coastguard Worker            for enum in self.enums:
1343*7c568831SAndroid Build Coastguard Worker                self.index_add(enum[0], self.filename,
1344*7c568831SAndroid Build Coastguard Worker                               not self.is_header, "enum",
1345*7c568831SAndroid Build Coastguard Worker                               (enum[1], enum[2], enum_type))
1346*7c568831SAndroid Build Coastguard Worker            return token
1347*7c568831SAndroid Build Coastguard Worker
1348*7c568831SAndroid Build Coastguard Worker        elif token[0] == "name":
1349*7c568831SAndroid Build Coastguard Worker            if self.type == "":
1350*7c568831SAndroid Build Coastguard Worker                self.type = token[1]
1351*7c568831SAndroid Build Coastguard Worker            else:
1352*7c568831SAndroid Build Coastguard Worker                self.type = self.type + " " + token[1]
1353*7c568831SAndroid Build Coastguard Worker        else:
1354*7c568831SAndroid Build Coastguard Worker            self.error("parsing type %s: expecting a name" % (self.type),
1355*7c568831SAndroid Build Coastguard Worker                       token)
1356*7c568831SAndroid Build Coastguard Worker            return token
1357*7c568831SAndroid Build Coastguard Worker        if not done:
1358*7c568831SAndroid Build Coastguard Worker            token = self.token()
1359*7c568831SAndroid Build Coastguard Worker        while token != None and (token[0] == "op" or
1360*7c568831SAndroid Build Coastguard Worker              token[0] == "name" and token[1] == "const"):
1361*7c568831SAndroid Build Coastguard Worker            self.type = self.type + " " + token[1]
1362*7c568831SAndroid Build Coastguard Worker            token = self.token()
1363*7c568831SAndroid Build Coastguard Worker
1364*7c568831SAndroid Build Coastguard Worker         #
1365*7c568831SAndroid Build Coastguard Worker         # if there is a parenthesis here, this means a function type
1366*7c568831SAndroid Build Coastguard Worker         #
1367*7c568831SAndroid Build Coastguard Worker        if token != None and token[0] == "sep" and token[1] == '(':
1368*7c568831SAndroid Build Coastguard Worker            self.type = self.type + token[1]
1369*7c568831SAndroid Build Coastguard Worker            token = self.token()
1370*7c568831SAndroid Build Coastguard Worker            while token != None and token[0] == "op" and token[1] == '*':
1371*7c568831SAndroid Build Coastguard Worker                self.type = self.type + token[1]
1372*7c568831SAndroid Build Coastguard Worker                token = self.token()
1373*7c568831SAndroid Build Coastguard Worker            if token == None or token[0] != "name" :
1374*7c568831SAndroid Build Coastguard Worker                self.error("parsing function type, name expected", token);
1375*7c568831SAndroid Build Coastguard Worker                return token
1376*7c568831SAndroid Build Coastguard Worker            self.type = self.type + token[1]
1377*7c568831SAndroid Build Coastguard Worker            nametok = token
1378*7c568831SAndroid Build Coastguard Worker            token = self.token()
1379*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "sep" and token[1] == ')':
1380*7c568831SAndroid Build Coastguard Worker                self.type = self.type + token[1]
1381*7c568831SAndroid Build Coastguard Worker                token = self.token()
1382*7c568831SAndroid Build Coastguard Worker                if token != None and token[0] == "sep" and token[1] == '(':
1383*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1384*7c568831SAndroid Build Coastguard Worker                    type = self.type;
1385*7c568831SAndroid Build Coastguard Worker                    token = self.parseSignature(token);
1386*7c568831SAndroid Build Coastguard Worker                    self.type = type;
1387*7c568831SAndroid Build Coastguard Worker                else:
1388*7c568831SAndroid Build Coastguard Worker                    self.error("parsing function type, '(' expected", token);
1389*7c568831SAndroid Build Coastguard Worker                    return token
1390*7c568831SAndroid Build Coastguard Worker            else:
1391*7c568831SAndroid Build Coastguard Worker                self.error("parsing function type, ')' expected", token);
1392*7c568831SAndroid Build Coastguard Worker                return token
1393*7c568831SAndroid Build Coastguard Worker            self.lexer.push(token)
1394*7c568831SAndroid Build Coastguard Worker            token = nametok
1395*7c568831SAndroid Build Coastguard Worker            return token
1396*7c568831SAndroid Build Coastguard Worker
1397*7c568831SAndroid Build Coastguard Worker         #
1398*7c568831SAndroid Build Coastguard Worker         # do some lookahead for arrays
1399*7c568831SAndroid Build Coastguard Worker         #
1400*7c568831SAndroid Build Coastguard Worker        if token != None and token[0] == "name":
1401*7c568831SAndroid Build Coastguard Worker            nametok = token
1402*7c568831SAndroid Build Coastguard Worker            token = self.token()
1403*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "sep" and token[1] == '[':
1404*7c568831SAndroid Build Coastguard Worker                self.type = self.type + nametok[1]
1405*7c568831SAndroid Build Coastguard Worker                while token != None and token[0] == "sep" and token[1] == '[':
1406*7c568831SAndroid Build Coastguard Worker                    self.type = self.type + token[1]
1407*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1408*7c568831SAndroid Build Coastguard Worker                    while token != None and token[0] != 'sep' and \
1409*7c568831SAndroid Build Coastguard Worker                          token[1] != ']' and token[1] != ';':
1410*7c568831SAndroid Build Coastguard Worker                        self.type = self.type + token[1]
1411*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1412*7c568831SAndroid Build Coastguard Worker                if token != None and token[0] == 'sep' and token[1] == ']':
1413*7c568831SAndroid Build Coastguard Worker                    self.type = self.type + token[1]
1414*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1415*7c568831SAndroid Build Coastguard Worker                else:
1416*7c568831SAndroid Build Coastguard Worker                    self.error("parsing array type, ']' expected", token);
1417*7c568831SAndroid Build Coastguard Worker                    return token
1418*7c568831SAndroid Build Coastguard Worker            elif token != None and token[0] == "sep" and token[1] == ':':
1419*7c568831SAndroid Build Coastguard Worker                 # remove :12 in case it's a limited int size
1420*7c568831SAndroid Build Coastguard Worker                token = self.token()
1421*7c568831SAndroid Build Coastguard Worker                token = self.token()
1422*7c568831SAndroid Build Coastguard Worker            self.lexer.push(token)
1423*7c568831SAndroid Build Coastguard Worker            token = nametok
1424*7c568831SAndroid Build Coastguard Worker
1425*7c568831SAndroid Build Coastguard Worker        return token
1426*7c568831SAndroid Build Coastguard Worker
1427*7c568831SAndroid Build Coastguard Worker     #
1428*7c568831SAndroid Build Coastguard Worker     # Parse a signature: '(' has been parsed and we scan the type definition
1429*7c568831SAndroid Build Coastguard Worker     #    up to the ')' included
1430*7c568831SAndroid Build Coastguard Worker    def parseSignature(self, token):
1431*7c568831SAndroid Build Coastguard Worker        signature = []
1432*7c568831SAndroid Build Coastguard Worker        if token != None and token[0] == "sep" and token[1] == ')':
1433*7c568831SAndroid Build Coastguard Worker            self.signature = []
1434*7c568831SAndroid Build Coastguard Worker            token = self.token()
1435*7c568831SAndroid Build Coastguard Worker            return token
1436*7c568831SAndroid Build Coastguard Worker        while token != None:
1437*7c568831SAndroid Build Coastguard Worker            token = self.parseType(token)
1438*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "name":
1439*7c568831SAndroid Build Coastguard Worker                signature.append((self.type, token[1], None))
1440*7c568831SAndroid Build Coastguard Worker                token = self.token()
1441*7c568831SAndroid Build Coastguard Worker            elif token != None and token[0] == "sep" and token[1] == ',':
1442*7c568831SAndroid Build Coastguard Worker                token = self.token()
1443*7c568831SAndroid Build Coastguard Worker                continue
1444*7c568831SAndroid Build Coastguard Worker            elif token != None and token[0] == "sep" and token[1] == ')':
1445*7c568831SAndroid Build Coastguard Worker                 # only the type was provided
1446*7c568831SAndroid Build Coastguard Worker                if self.type == "...":
1447*7c568831SAndroid Build Coastguard Worker                    signature.append((self.type, "...", None))
1448*7c568831SAndroid Build Coastguard Worker                else:
1449*7c568831SAndroid Build Coastguard Worker                    signature.append((self.type, None, None))
1450*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "sep":
1451*7c568831SAndroid Build Coastguard Worker                if token[1] == ',':
1452*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1453*7c568831SAndroid Build Coastguard Worker                    continue
1454*7c568831SAndroid Build Coastguard Worker                elif token[1] == ')':
1455*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1456*7c568831SAndroid Build Coastguard Worker                    break
1457*7c568831SAndroid Build Coastguard Worker        self.signature = signature
1458*7c568831SAndroid Build Coastguard Worker        return token
1459*7c568831SAndroid Build Coastguard Worker
1460*7c568831SAndroid Build Coastguard Worker     #
1461*7c568831SAndroid Build Coastguard Worker     # Parse a global definition, be it a type, variable or function
1462*7c568831SAndroid Build Coastguard Worker     # the extern "C" blocks are a bit nasty and require it to recurse.
1463*7c568831SAndroid Build Coastguard Worker     #
1464*7c568831SAndroid Build Coastguard Worker    def parseGlobal(self, token):
1465*7c568831SAndroid Build Coastguard Worker        static = 0
1466*7c568831SAndroid Build Coastguard Worker        if token[1] == 'extern':
1467*7c568831SAndroid Build Coastguard Worker            token = self.token()
1468*7c568831SAndroid Build Coastguard Worker            if token == None:
1469*7c568831SAndroid Build Coastguard Worker                return token
1470*7c568831SAndroid Build Coastguard Worker            if token[0] == 'string':
1471*7c568831SAndroid Build Coastguard Worker                if token[1] == 'C':
1472*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1473*7c568831SAndroid Build Coastguard Worker                    if token == None:
1474*7c568831SAndroid Build Coastguard Worker                        return token
1475*7c568831SAndroid Build Coastguard Worker                    if token[0] == 'sep' and token[1] == "{":
1476*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1477*7c568831SAndroid Build Coastguard Worker#                         print 'Entering extern "C line ', self.lineno()
1478*7c568831SAndroid Build Coastguard Worker                        while token != None and (token[0] != 'sep' or
1479*7c568831SAndroid Build Coastguard Worker                              token[1] != "}"):
1480*7c568831SAndroid Build Coastguard Worker                            if token[0] == 'name':
1481*7c568831SAndroid Build Coastguard Worker                                token = self.parseGlobal(token)
1482*7c568831SAndroid Build Coastguard Worker                            else:
1483*7c568831SAndroid Build Coastguard Worker                                self.error(
1484*7c568831SAndroid Build Coastguard Worker                                 "token %s %s unexpected at the top level" % (
1485*7c568831SAndroid Build Coastguard Worker                                        token[0], token[1]))
1486*7c568831SAndroid Build Coastguard Worker                                token = self.parseGlobal(token)
1487*7c568831SAndroid Build Coastguard Worker#                         print 'Exiting extern "C" line', self.lineno()
1488*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1489*7c568831SAndroid Build Coastguard Worker                        return token
1490*7c568831SAndroid Build Coastguard Worker                else:
1491*7c568831SAndroid Build Coastguard Worker                    return token
1492*7c568831SAndroid Build Coastguard Worker        elif token[1] == 'static':
1493*7c568831SAndroid Build Coastguard Worker            static = 1
1494*7c568831SAndroid Build Coastguard Worker            token = self.token()
1495*7c568831SAndroid Build Coastguard Worker            if token == None or  token[0] != 'name':
1496*7c568831SAndroid Build Coastguard Worker                return token
1497*7c568831SAndroid Build Coastguard Worker
1498*7c568831SAndroid Build Coastguard Worker        if token[1] == 'typedef':
1499*7c568831SAndroid Build Coastguard Worker            token = self.token()
1500*7c568831SAndroid Build Coastguard Worker            return self.parseTypedef(token)
1501*7c568831SAndroid Build Coastguard Worker        else:
1502*7c568831SAndroid Build Coastguard Worker            token = self.parseType(token)
1503*7c568831SAndroid Build Coastguard Worker            type_orig = self.type
1504*7c568831SAndroid Build Coastguard Worker        if token == None or token[0] != "name":
1505*7c568831SAndroid Build Coastguard Worker            return token
1506*7c568831SAndroid Build Coastguard Worker        type = type_orig
1507*7c568831SAndroid Build Coastguard Worker        self.name = token[1]
1508*7c568831SAndroid Build Coastguard Worker        token = self.token()
1509*7c568831SAndroid Build Coastguard Worker        while token != None and (token[0] == "sep" or token[0] == "op"):
1510*7c568831SAndroid Build Coastguard Worker            if token[0] == "sep":
1511*7c568831SAndroid Build Coastguard Worker                if token[1] == "[":
1512*7c568831SAndroid Build Coastguard Worker                    type = type + token[1]
1513*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1514*7c568831SAndroid Build Coastguard Worker                    while token != None and (token[0] != "sep" or \
1515*7c568831SAndroid Build Coastguard Worker                          token[1] != ";"):
1516*7c568831SAndroid Build Coastguard Worker                        type = type + token[1]
1517*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1518*7c568831SAndroid Build Coastguard Worker
1519*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "op" and token[1] == "=":
1520*7c568831SAndroid Build Coastguard Worker                 #
1521*7c568831SAndroid Build Coastguard Worker                 # Skip the initialization of the variable
1522*7c568831SAndroid Build Coastguard Worker                 #
1523*7c568831SAndroid Build Coastguard Worker                token = self.token()
1524*7c568831SAndroid Build Coastguard Worker                if token[0] == 'sep' and token[1] == '{':
1525*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1526*7c568831SAndroid Build Coastguard Worker                    token = self.parseBlock(token)
1527*7c568831SAndroid Build Coastguard Worker                else:
1528*7c568831SAndroid Build Coastguard Worker                    while token != None and (token[0] != "sep" or \
1529*7c568831SAndroid Build Coastguard Worker                          (token[1] != ';' and token[1] != ',')):
1530*7c568831SAndroid Build Coastguard Worker                            token = self.token()
1531*7c568831SAndroid Build Coastguard Worker                if token == None or token[0] != "sep" or (token[1] != ';' and
1532*7c568831SAndroid Build Coastguard Worker                   token[1] != ','):
1533*7c568831SAndroid Build Coastguard Worker                    self.error("missing ';' or ',' after value")
1534*7c568831SAndroid Build Coastguard Worker
1535*7c568831SAndroid Build Coastguard Worker            if token != None and token[0] == "sep":
1536*7c568831SAndroid Build Coastguard Worker                if token[1] == ";":
1537*7c568831SAndroid Build Coastguard Worker                    if type == "struct":
1538*7c568831SAndroid Build Coastguard Worker                        self.index_add(self.name, self.filename,
1539*7c568831SAndroid Build Coastguard Worker                             not self.is_header, "struct", self.struct_fields)
1540*7c568831SAndroid Build Coastguard Worker                    else:
1541*7c568831SAndroid Build Coastguard Worker                        info = self.parseSimpleComment(self.name, True)
1542*7c568831SAndroid Build Coastguard Worker                        self.index_add(self.name, self.filename,
1543*7c568831SAndroid Build Coastguard Worker                             not self.is_header, "variable", type, info)
1544*7c568831SAndroid Build Coastguard Worker                    self.comment = None
1545*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1546*7c568831SAndroid Build Coastguard Worker                    break
1547*7c568831SAndroid Build Coastguard Worker                elif token[1] == "(":
1548*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1549*7c568831SAndroid Build Coastguard Worker                    token = self.parseSignature(token)
1550*7c568831SAndroid Build Coastguard Worker                    if token == None:
1551*7c568831SAndroid Build Coastguard Worker                        return None
1552*7c568831SAndroid Build Coastguard Worker                    if token[0] == "sep" and token[1] == ";":
1553*7c568831SAndroid Build Coastguard Worker                        d = self.mergeFunctionComment(self.name,
1554*7c568831SAndroid Build Coastguard Worker                                ((type, None), self.signature), 1)
1555*7c568831SAndroid Build Coastguard Worker                        self.index_add(self.name, self.filename, static,
1556*7c568831SAndroid Build Coastguard Worker                                        "function", d)
1557*7c568831SAndroid Build Coastguard Worker                        self.comment = None
1558*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1559*7c568831SAndroid Build Coastguard Worker                    elif token[0] == "sep" and token[1] == "{":
1560*7c568831SAndroid Build Coastguard Worker                        d = self.mergeFunctionComment(self.name,
1561*7c568831SAndroid Build Coastguard Worker                                ((type, None), self.signature), static)
1562*7c568831SAndroid Build Coastguard Worker                        self.index_add(self.name, self.filename, static,
1563*7c568831SAndroid Build Coastguard Worker                                        "function", d)
1564*7c568831SAndroid Build Coastguard Worker                        self.comment = None
1565*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1566*7c568831SAndroid Build Coastguard Worker                        token = self.parseBlock(token);
1567*7c568831SAndroid Build Coastguard Worker                elif token[1] == ',':
1568*7c568831SAndroid Build Coastguard Worker                    self.index_add(self.name, self.filename, static,
1569*7c568831SAndroid Build Coastguard Worker                                    "variable", type)
1570*7c568831SAndroid Build Coastguard Worker                    self.comment = None
1571*7c568831SAndroid Build Coastguard Worker                    type = type_orig
1572*7c568831SAndroid Build Coastguard Worker                    token = self.token()
1573*7c568831SAndroid Build Coastguard Worker                    while token != None and token[0] == "sep":
1574*7c568831SAndroid Build Coastguard Worker                        type = type + token[1]
1575*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1576*7c568831SAndroid Build Coastguard Worker                    if token != None and token[0] == "name":
1577*7c568831SAndroid Build Coastguard Worker                        self.name = token[1]
1578*7c568831SAndroid Build Coastguard Worker                        token = self.token()
1579*7c568831SAndroid Build Coastguard Worker                else:
1580*7c568831SAndroid Build Coastguard Worker                    break
1581*7c568831SAndroid Build Coastguard Worker
1582*7c568831SAndroid Build Coastguard Worker        return token
1583*7c568831SAndroid Build Coastguard Worker
1584*7c568831SAndroid Build Coastguard Worker    def parse(self):
1585*7c568831SAndroid Build Coastguard Worker        self.warning("Parsing %s" % (self.filename))
1586*7c568831SAndroid Build Coastguard Worker        token = self.token()
1587*7c568831SAndroid Build Coastguard Worker        while token != None:
1588*7c568831SAndroid Build Coastguard Worker            if token[0] == 'name':
1589*7c568831SAndroid Build Coastguard Worker                token = self.parseGlobal(token)
1590*7c568831SAndroid Build Coastguard Worker            else:
1591*7c568831SAndroid Build Coastguard Worker                self.error("token %s %s unexpected at the top level" % (
1592*7c568831SAndroid Build Coastguard Worker                       token[0], token[1]))
1593*7c568831SAndroid Build Coastguard Worker                token = self.parseGlobal(token)
1594*7c568831SAndroid Build Coastguard Worker                return
1595*7c568831SAndroid Build Coastguard Worker        self.parseTopComment(self.top_comment)
1596*7c568831SAndroid Build Coastguard Worker        return self.index
1597*7c568831SAndroid Build Coastguard Worker
1598*7c568831SAndroid Build Coastguard Worker
1599*7c568831SAndroid Build Coastguard Workerclass docBuilder:
1600*7c568831SAndroid Build Coastguard Worker    """A documentation builder"""
1601*7c568831SAndroid Build Coastguard Worker    def __init__(self, name, directories=['.'], excludes=[]):
1602*7c568831SAndroid Build Coastguard Worker        self.name = name
1603*7c568831SAndroid Build Coastguard Worker        self.directories = directories
1604*7c568831SAndroid Build Coastguard Worker        self.excludes = excludes + list(ignored_files.keys())
1605*7c568831SAndroid Build Coastguard Worker        self.modules = {}
1606*7c568831SAndroid Build Coastguard Worker        self.headers = {}
1607*7c568831SAndroid Build Coastguard Worker        self.idx = index()
1608*7c568831SAndroid Build Coastguard Worker        self.index = {}
1609*7c568831SAndroid Build Coastguard Worker        if name == 'libxml2':
1610*7c568831SAndroid Build Coastguard Worker            self.basename = 'libxml'
1611*7c568831SAndroid Build Coastguard Worker        else:
1612*7c568831SAndroid Build Coastguard Worker            self.basename = name
1613*7c568831SAndroid Build Coastguard Worker
1614*7c568831SAndroid Build Coastguard Worker    def analyze(self):
1615*7c568831SAndroid Build Coastguard Worker        print("Project %s : %d headers, %d modules" % (self.name, len(list(self.headers.keys())), len(list(self.modules.keys()))))
1616*7c568831SAndroid Build Coastguard Worker        self.idx.analyze()
1617*7c568831SAndroid Build Coastguard Worker
1618*7c568831SAndroid Build Coastguard Worker    def scanHeaders(self):
1619*7c568831SAndroid Build Coastguard Worker        for header in list(self.headers.keys()):
1620*7c568831SAndroid Build Coastguard Worker            parser = CParser(header)
1621*7c568831SAndroid Build Coastguard Worker            idx = parser.parse()
1622*7c568831SAndroid Build Coastguard Worker            self.headers[header] = idx;
1623*7c568831SAndroid Build Coastguard Worker            self.idx.merge(idx)
1624*7c568831SAndroid Build Coastguard Worker
1625*7c568831SAndroid Build Coastguard Worker    def scanModules(self):
1626*7c568831SAndroid Build Coastguard Worker        for module in list(self.modules.keys()):
1627*7c568831SAndroid Build Coastguard Worker            parser = CParser(module)
1628*7c568831SAndroid Build Coastguard Worker            idx = parser.parse()
1629*7c568831SAndroid Build Coastguard Worker            # idx.analyze()
1630*7c568831SAndroid Build Coastguard Worker            self.modules[module] = idx
1631*7c568831SAndroid Build Coastguard Worker            self.idx.merge_public(idx)
1632*7c568831SAndroid Build Coastguard Worker
1633*7c568831SAndroid Build Coastguard Worker    def scan(self):
1634*7c568831SAndroid Build Coastguard Worker        for directory in self.directories:
1635*7c568831SAndroid Build Coastguard Worker            files = glob.glob(directory + "/*.c")
1636*7c568831SAndroid Build Coastguard Worker            for file in files:
1637*7c568831SAndroid Build Coastguard Worker                skip = 0
1638*7c568831SAndroid Build Coastguard Worker                for excl in self.excludes:
1639*7c568831SAndroid Build Coastguard Worker                    if file.find(excl) != -1:
1640*7c568831SAndroid Build Coastguard Worker                        print("Skipping %s" % file)
1641*7c568831SAndroid Build Coastguard Worker                        skip = 1
1642*7c568831SAndroid Build Coastguard Worker                        break
1643*7c568831SAndroid Build Coastguard Worker                if skip == 0:
1644*7c568831SAndroid Build Coastguard Worker                    self.modules[file] = None;
1645*7c568831SAndroid Build Coastguard Worker            files = glob.glob(directory + "/*.h")
1646*7c568831SAndroid Build Coastguard Worker            for file in files:
1647*7c568831SAndroid Build Coastguard Worker                skip = 0
1648*7c568831SAndroid Build Coastguard Worker                for excl in self.excludes:
1649*7c568831SAndroid Build Coastguard Worker                    if file.find(excl) != -1:
1650*7c568831SAndroid Build Coastguard Worker                        print("Skipping %s" % file)
1651*7c568831SAndroid Build Coastguard Worker                        skip = 1
1652*7c568831SAndroid Build Coastguard Worker                        break
1653*7c568831SAndroid Build Coastguard Worker                if skip == 0:
1654*7c568831SAndroid Build Coastguard Worker                    self.headers[file] = None;
1655*7c568831SAndroid Build Coastguard Worker        self.scanHeaders()
1656*7c568831SAndroid Build Coastguard Worker        self.scanModules()
1657*7c568831SAndroid Build Coastguard Worker
1658*7c568831SAndroid Build Coastguard Worker    def modulename_file(self, file):
1659*7c568831SAndroid Build Coastguard Worker        module = os.path.basename(file)
1660*7c568831SAndroid Build Coastguard Worker        if module[-2:] == '.h':
1661*7c568831SAndroid Build Coastguard Worker            module = module[:-2]
1662*7c568831SAndroid Build Coastguard Worker        elif module[-2:] == '.c':
1663*7c568831SAndroid Build Coastguard Worker            module = module[:-2]
1664*7c568831SAndroid Build Coastguard Worker        return module
1665*7c568831SAndroid Build Coastguard Worker
1666*7c568831SAndroid Build Coastguard Worker    def serialize_enum(self, output, name):
1667*7c568831SAndroid Build Coastguard Worker        id = self.idx.enums[name]
1668*7c568831SAndroid Build Coastguard Worker        output.write("    <enum name='%s' file='%s'" % (name,
1669*7c568831SAndroid Build Coastguard Worker                     self.modulename_file(id.header)))
1670*7c568831SAndroid Build Coastguard Worker        if id.info != None:
1671*7c568831SAndroid Build Coastguard Worker            info = id.info
1672*7c568831SAndroid Build Coastguard Worker            if info[0] != None and info[0] != '':
1673*7c568831SAndroid Build Coastguard Worker                try:
1674*7c568831SAndroid Build Coastguard Worker                    val = eval(info[0])
1675*7c568831SAndroid Build Coastguard Worker                except:
1676*7c568831SAndroid Build Coastguard Worker                    val = info[0]
1677*7c568831SAndroid Build Coastguard Worker                output.write(" value='%s'" % (val));
1678*7c568831SAndroid Build Coastguard Worker            if info[2] != None and info[2] != '':
1679*7c568831SAndroid Build Coastguard Worker                output.write(" type='%s'" % info[2]);
1680*7c568831SAndroid Build Coastguard Worker            if info[1] != None and info[1] != '':
1681*7c568831SAndroid Build Coastguard Worker                output.write(" info='%s'" % escape(info[1]));
1682*7c568831SAndroid Build Coastguard Worker        output.write("/>\n")
1683*7c568831SAndroid Build Coastguard Worker
1684*7c568831SAndroid Build Coastguard Worker    def serialize_macro(self, output, name):
1685*7c568831SAndroid Build Coastguard Worker        id = self.idx.macros[name]
1686*7c568831SAndroid Build Coastguard Worker        output.write("    <macro name='%s' file='%s'>\n" % (name,
1687*7c568831SAndroid Build Coastguard Worker                     self.modulename_file(id.header)))
1688*7c568831SAndroid Build Coastguard Worker        if id.info != None:
1689*7c568831SAndroid Build Coastguard Worker            try:
1690*7c568831SAndroid Build Coastguard Worker                (args, desc) = id.info
1691*7c568831SAndroid Build Coastguard Worker                if desc != None and desc != "":
1692*7c568831SAndroid Build Coastguard Worker                    output.write("      <info>%s</info>\n" % (escape(desc)))
1693*7c568831SAndroid Build Coastguard Worker                for arg in args:
1694*7c568831SAndroid Build Coastguard Worker                    (name, desc) = arg
1695*7c568831SAndroid Build Coastguard Worker                    if desc != None and desc != "":
1696*7c568831SAndroid Build Coastguard Worker                        output.write("      <arg name='%s' info='%s'/>\n" % (
1697*7c568831SAndroid Build Coastguard Worker                                     name, escape(desc)))
1698*7c568831SAndroid Build Coastguard Worker                    else:
1699*7c568831SAndroid Build Coastguard Worker                        output.write("      <arg name='%s'/>\n" % (name))
1700*7c568831SAndroid Build Coastguard Worker            except:
1701*7c568831SAndroid Build Coastguard Worker                pass
1702*7c568831SAndroid Build Coastguard Worker        output.write("    </macro>\n")
1703*7c568831SAndroid Build Coastguard Worker
1704*7c568831SAndroid Build Coastguard Worker    def serialize_typedef(self, output, name):
1705*7c568831SAndroid Build Coastguard Worker        id = self.idx.typedefs[name]
1706*7c568831SAndroid Build Coastguard Worker        if id.info[0:7] == 'struct ':
1707*7c568831SAndroid Build Coastguard Worker            output.write("    <struct name='%s' file='%s' type='%s'" % (
1708*7c568831SAndroid Build Coastguard Worker                     name, self.modulename_file(id.header), id.info))
1709*7c568831SAndroid Build Coastguard Worker            name = id.info[7:]
1710*7c568831SAndroid Build Coastguard Worker            if name in self.idx.structs and ( \
1711*7c568831SAndroid Build Coastguard Worker               type(self.idx.structs[name].info) == type(()) or
1712*7c568831SAndroid Build Coastguard Worker                type(self.idx.structs[name].info) == type([])):
1713*7c568831SAndroid Build Coastguard Worker                output.write(">\n");
1714*7c568831SAndroid Build Coastguard Worker                try:
1715*7c568831SAndroid Build Coastguard Worker                    for field in self.idx.structs[name].info:
1716*7c568831SAndroid Build Coastguard Worker                        output.write("      <field name='%s' type='%s'/>\n" % (field[1] , field[0]))
1717*7c568831SAndroid Build Coastguard Worker                except:
1718*7c568831SAndroid Build Coastguard Worker                    print("Failed to serialize struct %s" % (name))
1719*7c568831SAndroid Build Coastguard Worker                output.write("    </struct>\n")
1720*7c568831SAndroid Build Coastguard Worker            else:
1721*7c568831SAndroid Build Coastguard Worker                output.write("/>\n");
1722*7c568831SAndroid Build Coastguard Worker        else :
1723*7c568831SAndroid Build Coastguard Worker            output.write("    <typedef name='%s' file='%s' type='%s'" % (
1724*7c568831SAndroid Build Coastguard Worker                         name, self.modulename_file(id.header), id.info))
1725*7c568831SAndroid Build Coastguard Worker            try:
1726*7c568831SAndroid Build Coastguard Worker                desc = id.extra
1727*7c568831SAndroid Build Coastguard Worker                if desc != None and desc != "":
1728*7c568831SAndroid Build Coastguard Worker                    output.write(">\n      <info>%s</info>\n" % (escape(desc)))
1729*7c568831SAndroid Build Coastguard Worker                    output.write("    </typedef>\n")
1730*7c568831SAndroid Build Coastguard Worker                else:
1731*7c568831SAndroid Build Coastguard Worker                    output.write("/>\n")
1732*7c568831SAndroid Build Coastguard Worker            except:
1733*7c568831SAndroid Build Coastguard Worker                output.write("/>\n")
1734*7c568831SAndroid Build Coastguard Worker
1735*7c568831SAndroid Build Coastguard Worker    def serialize_variable(self, output, name):
1736*7c568831SAndroid Build Coastguard Worker        id = self.idx.variables[name]
1737*7c568831SAndroid Build Coastguard Worker        if id.info != None:
1738*7c568831SAndroid Build Coastguard Worker            output.write("    <variable name='%s' file='%s' type='%s'" % (
1739*7c568831SAndroid Build Coastguard Worker                    name, self.modulename_file(id.header), id.info))
1740*7c568831SAndroid Build Coastguard Worker        else:
1741*7c568831SAndroid Build Coastguard Worker            output.write("    <variable name='%s' file='%s'" % (
1742*7c568831SAndroid Build Coastguard Worker                    name, self.modulename_file(id.header)))
1743*7c568831SAndroid Build Coastguard Worker        desc = id.extra
1744*7c568831SAndroid Build Coastguard Worker        if desc != None and desc != "":
1745*7c568831SAndroid Build Coastguard Worker            output.write(">\n      <info>%s</info>\n" % (escape(desc)))
1746*7c568831SAndroid Build Coastguard Worker            output.write("    </variable>\n")
1747*7c568831SAndroid Build Coastguard Worker        else:
1748*7c568831SAndroid Build Coastguard Worker            output.write("/>\n")
1749*7c568831SAndroid Build Coastguard Worker
1750*7c568831SAndroid Build Coastguard Worker    def serialize_function(self, output, name):
1751*7c568831SAndroid Build Coastguard Worker        id = self.idx.functions[name]
1752*7c568831SAndroid Build Coastguard Worker        if name == debugsym:
1753*7c568831SAndroid Build Coastguard Worker            print("=>", id)
1754*7c568831SAndroid Build Coastguard Worker
1755*7c568831SAndroid Build Coastguard Worker        output.write("    <%s name='%s' file='%s' module='%s'>\n" % (id.type,
1756*7c568831SAndroid Build Coastguard Worker                     name, self.modulename_file(id.header),
1757*7c568831SAndroid Build Coastguard Worker                     self.modulename_file(id.module)))
1758*7c568831SAndroid Build Coastguard Worker        #
1759*7c568831SAndroid Build Coastguard Worker        # Processing of conditionals modified by Bill 1/1/05
1760*7c568831SAndroid Build Coastguard Worker        #
1761*7c568831SAndroid Build Coastguard Worker        if id.conditionals != None:
1762*7c568831SAndroid Build Coastguard Worker            apstr = ""
1763*7c568831SAndroid Build Coastguard Worker            for cond in id.conditionals:
1764*7c568831SAndroid Build Coastguard Worker                if apstr != "":
1765*7c568831SAndroid Build Coastguard Worker                    apstr = apstr + " &amp;&amp; "
1766*7c568831SAndroid Build Coastguard Worker                apstr = apstr + cond
1767*7c568831SAndroid Build Coastguard Worker            output.write("      <cond>%s</cond>\n"% (apstr));
1768*7c568831SAndroid Build Coastguard Worker        try:
1769*7c568831SAndroid Build Coastguard Worker            (ret, params, desc) = id.info
1770*7c568831SAndroid Build Coastguard Worker            if (desc == None or desc == '') and \
1771*7c568831SAndroid Build Coastguard Worker               name[0:9] != "xmlThrDef" and name != "xmlDllMain" and \
1772*7c568831SAndroid Build Coastguard Worker               ret[1] == '':
1773*7c568831SAndroid Build Coastguard Worker                print("%s %s from %s has no description" % (id.type, name,
1774*7c568831SAndroid Build Coastguard Worker                       self.modulename_file(id.module)))
1775*7c568831SAndroid Build Coastguard Worker
1776*7c568831SAndroid Build Coastguard Worker            output.write("      <info>%s</info>\n" % (escape(desc)))
1777*7c568831SAndroid Build Coastguard Worker            if ret[0] != None:
1778*7c568831SAndroid Build Coastguard Worker                if ret[0] == "void":
1779*7c568831SAndroid Build Coastguard Worker                    output.write("      <return type='void'/>\n")
1780*7c568831SAndroid Build Coastguard Worker                else:
1781*7c568831SAndroid Build Coastguard Worker                    output.write("      <return type='%s' info='%s'/>\n" % (
1782*7c568831SAndroid Build Coastguard Worker                             ret[0], escape(ret[1])))
1783*7c568831SAndroid Build Coastguard Worker            for param in params:
1784*7c568831SAndroid Build Coastguard Worker                if param[0] == 'void':
1785*7c568831SAndroid Build Coastguard Worker                    continue
1786*7c568831SAndroid Build Coastguard Worker                if param[2] == None:
1787*7c568831SAndroid Build Coastguard Worker                    output.write("      <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0]))
1788*7c568831SAndroid Build Coastguard Worker                else:
1789*7c568831SAndroid Build Coastguard Worker                    output.write("      <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2])))
1790*7c568831SAndroid Build Coastguard Worker        except:
1791*7c568831SAndroid Build Coastguard Worker            print("Failed to save function %s info: " % name, repr(id.info))
1792*7c568831SAndroid Build Coastguard Worker        output.write("    </%s>\n" % (id.type))
1793*7c568831SAndroid Build Coastguard Worker
1794*7c568831SAndroid Build Coastguard Worker    def serialize_exports(self, output, file):
1795*7c568831SAndroid Build Coastguard Worker        module = self.modulename_file(file)
1796*7c568831SAndroid Build Coastguard Worker        output.write("    <file name='%s'>\n" % (module))
1797*7c568831SAndroid Build Coastguard Worker        dict = self.headers[file]
1798*7c568831SAndroid Build Coastguard Worker        if dict.info != None:
1799*7c568831SAndroid Build Coastguard Worker            for data in ('Summary', 'Description', 'Author'):
1800*7c568831SAndroid Build Coastguard Worker                try:
1801*7c568831SAndroid Build Coastguard Worker                    output.write("     <%s>%s</%s>\n" % (
1802*7c568831SAndroid Build Coastguard Worker                                 data.lower(),
1803*7c568831SAndroid Build Coastguard Worker                                 escape(dict.info[data]),
1804*7c568831SAndroid Build Coastguard Worker                                 data.lower()))
1805*7c568831SAndroid Build Coastguard Worker                except:
1806*7c568831SAndroid Build Coastguard Worker                    if data != 'Author':
1807*7c568831SAndroid Build Coastguard Worker                        print("Header %s lacks a %s description" % (module, data))
1808*7c568831SAndroid Build Coastguard Worker            if 'Description' in dict.info:
1809*7c568831SAndroid Build Coastguard Worker                desc = dict.info['Description']
1810*7c568831SAndroid Build Coastguard Worker                if desc.find("DEPRECATED") != -1:
1811*7c568831SAndroid Build Coastguard Worker                    output.write("     <deprecated/>\n")
1812*7c568831SAndroid Build Coastguard Worker
1813*7c568831SAndroid Build Coastguard Worker        ids = list(dict.macros.keys())
1814*7c568831SAndroid Build Coastguard Worker        ids.sort()
1815*7c568831SAndroid Build Coastguard Worker        for id in ids:
1816*7c568831SAndroid Build Coastguard Worker            # Macros are sometime used to masquerade other types.
1817*7c568831SAndroid Build Coastguard Worker            if id in dict.functions:
1818*7c568831SAndroid Build Coastguard Worker                continue
1819*7c568831SAndroid Build Coastguard Worker            if id in dict.variables:
1820*7c568831SAndroid Build Coastguard Worker                continue
1821*7c568831SAndroid Build Coastguard Worker            if id in dict.typedefs:
1822*7c568831SAndroid Build Coastguard Worker                continue
1823*7c568831SAndroid Build Coastguard Worker            if id in dict.structs:
1824*7c568831SAndroid Build Coastguard Worker                continue
1825*7c568831SAndroid Build Coastguard Worker            if id in dict.enums:
1826*7c568831SAndroid Build Coastguard Worker                continue
1827*7c568831SAndroid Build Coastguard Worker            output.write("     <exports symbol='%s' type='macro'/>\n" % (id))
1828*7c568831SAndroid Build Coastguard Worker        ids = list(dict.enums.keys())
1829*7c568831SAndroid Build Coastguard Worker        ids.sort()
1830*7c568831SAndroid Build Coastguard Worker        for id in ids:
1831*7c568831SAndroid Build Coastguard Worker            output.write("     <exports symbol='%s' type='enum'/>\n" % (id))
1832*7c568831SAndroid Build Coastguard Worker        ids = list(dict.typedefs.keys())
1833*7c568831SAndroid Build Coastguard Worker        ids.sort()
1834*7c568831SAndroid Build Coastguard Worker        for id in ids:
1835*7c568831SAndroid Build Coastguard Worker            output.write("     <exports symbol='%s' type='typedef'/>\n" % (id))
1836*7c568831SAndroid Build Coastguard Worker        ids = list(dict.structs.keys())
1837*7c568831SAndroid Build Coastguard Worker        ids.sort()
1838*7c568831SAndroid Build Coastguard Worker        for id in ids:
1839*7c568831SAndroid Build Coastguard Worker            output.write("     <exports symbol='%s' type='struct'/>\n" % (id))
1840*7c568831SAndroid Build Coastguard Worker        ids = list(dict.variables.keys())
1841*7c568831SAndroid Build Coastguard Worker        ids.sort()
1842*7c568831SAndroid Build Coastguard Worker        for id in ids:
1843*7c568831SAndroid Build Coastguard Worker            output.write("     <exports symbol='%s' type='variable'/>\n" % (id))
1844*7c568831SAndroid Build Coastguard Worker        ids = list(dict.functions.keys())
1845*7c568831SAndroid Build Coastguard Worker        ids.sort()
1846*7c568831SAndroid Build Coastguard Worker        for id in ids:
1847*7c568831SAndroid Build Coastguard Worker            output.write("     <exports symbol='%s' type='function'/>\n" % (id))
1848*7c568831SAndroid Build Coastguard Worker        output.write("    </file>\n")
1849*7c568831SAndroid Build Coastguard Worker
1850*7c568831SAndroid Build Coastguard Worker    def serialize(self):
1851*7c568831SAndroid Build Coastguard Worker        filename = "%s-api.xml" % self.name
1852*7c568831SAndroid Build Coastguard Worker        print("Saving XML description %s" % (filename))
1853*7c568831SAndroid Build Coastguard Worker        output = open(filename, "w")
1854*7c568831SAndroid Build Coastguard Worker        output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
1855*7c568831SAndroid Build Coastguard Worker        output.write("<api name='%s'>\n" % self.name)
1856*7c568831SAndroid Build Coastguard Worker        output.write("  <files>\n")
1857*7c568831SAndroid Build Coastguard Worker        headers = list(self.headers.keys())
1858*7c568831SAndroid Build Coastguard Worker        headers.sort()
1859*7c568831SAndroid Build Coastguard Worker        for file in headers:
1860*7c568831SAndroid Build Coastguard Worker            self.serialize_exports(output, file)
1861*7c568831SAndroid Build Coastguard Worker        output.write("  </files>\n")
1862*7c568831SAndroid Build Coastguard Worker        output.write("  <symbols>\n")
1863*7c568831SAndroid Build Coastguard Worker        macros = list(self.idx.macros.keys())
1864*7c568831SAndroid Build Coastguard Worker        macros.sort()
1865*7c568831SAndroid Build Coastguard Worker        for macro in macros:
1866*7c568831SAndroid Build Coastguard Worker            self.serialize_macro(output, macro)
1867*7c568831SAndroid Build Coastguard Worker        enums = list(self.idx.enums.keys())
1868*7c568831SAndroid Build Coastguard Worker        enums.sort()
1869*7c568831SAndroid Build Coastguard Worker        for enum in enums:
1870*7c568831SAndroid Build Coastguard Worker            self.serialize_enum(output, enum)
1871*7c568831SAndroid Build Coastguard Worker        typedefs = list(self.idx.typedefs.keys())
1872*7c568831SAndroid Build Coastguard Worker        typedefs.sort()
1873*7c568831SAndroid Build Coastguard Worker        for typedef in typedefs:
1874*7c568831SAndroid Build Coastguard Worker            self.serialize_typedef(output, typedef)
1875*7c568831SAndroid Build Coastguard Worker        variables = list(self.idx.variables.keys())
1876*7c568831SAndroid Build Coastguard Worker        variables.sort()
1877*7c568831SAndroid Build Coastguard Worker        for variable in variables:
1878*7c568831SAndroid Build Coastguard Worker            self.serialize_variable(output, variable)
1879*7c568831SAndroid Build Coastguard Worker        functions = list(self.idx.functions.keys())
1880*7c568831SAndroid Build Coastguard Worker        functions.sort()
1881*7c568831SAndroid Build Coastguard Worker        for function in functions:
1882*7c568831SAndroid Build Coastguard Worker            self.serialize_function(output, function)
1883*7c568831SAndroid Build Coastguard Worker        output.write("  </symbols>\n")
1884*7c568831SAndroid Build Coastguard Worker        output.write("</api>\n")
1885*7c568831SAndroid Build Coastguard Worker        output.close()
1886*7c568831SAndroid Build Coastguard Worker
1887*7c568831SAndroid Build Coastguard Worker
1888*7c568831SAndroid Build Coastguard Workerdef rebuild():
1889*7c568831SAndroid Build Coastguard Worker    builder = None
1890*7c568831SAndroid Build Coastguard Worker    if glob.glob("parser.c") != [] :
1891*7c568831SAndroid Build Coastguard Worker        print("Rebuilding API description for libxml2")
1892*7c568831SAndroid Build Coastguard Worker        builder = docBuilder("libxml2", [".", "."],
1893*7c568831SAndroid Build Coastguard Worker                             ["tst.c"])
1894*7c568831SAndroid Build Coastguard Worker    elif glob.glob("../parser.c") != [] :
1895*7c568831SAndroid Build Coastguard Worker        print("Rebuilding API description for libxml2")
1896*7c568831SAndroid Build Coastguard Worker        builder = docBuilder("libxml2", ["..", "../include/libxml"],
1897*7c568831SAndroid Build Coastguard Worker                             ["tst.c"])
1898*7c568831SAndroid Build Coastguard Worker    elif glob.glob("../libxslt/transform.c") != [] :
1899*7c568831SAndroid Build Coastguard Worker        print("Rebuilding API description for libxslt")
1900*7c568831SAndroid Build Coastguard Worker        builder = docBuilder("libxslt", ["../libxslt"],
1901*7c568831SAndroid Build Coastguard Worker                             ["win32config.h", "libxslt.h", "tst.c"])
1902*7c568831SAndroid Build Coastguard Worker    else:
1903*7c568831SAndroid Build Coastguard Worker        print("rebuild() failed, unable to guess the module")
1904*7c568831SAndroid Build Coastguard Worker        return None
1905*7c568831SAndroid Build Coastguard Worker    builder.scan()
1906*7c568831SAndroid Build Coastguard Worker    builder.analyze()
1907*7c568831SAndroid Build Coastguard Worker    builder.serialize()
1908*7c568831SAndroid Build Coastguard Worker    if glob.glob("../libexslt/exslt.c") != [] :
1909*7c568831SAndroid Build Coastguard Worker        extra = docBuilder("libexslt", ["../libexslt"], ["libexslt.h"])
1910*7c568831SAndroid Build Coastguard Worker        extra.scan()
1911*7c568831SAndroid Build Coastguard Worker        extra.analyze()
1912*7c568831SAndroid Build Coastguard Worker        extra.serialize()
1913*7c568831SAndroid Build Coastguard Worker    return builder
1914*7c568831SAndroid Build Coastguard Worker
1915*7c568831SAndroid Build Coastguard Worker#
1916*7c568831SAndroid Build Coastguard Worker# for debugging the parser
1917*7c568831SAndroid Build Coastguard Worker#
1918*7c568831SAndroid Build Coastguard Workerdef parse(filename):
1919*7c568831SAndroid Build Coastguard Worker    parser = CParser(filename)
1920*7c568831SAndroid Build Coastguard Worker    idx = parser.parse()
1921*7c568831SAndroid Build Coastguard Worker    return idx
1922*7c568831SAndroid Build Coastguard Worker
1923*7c568831SAndroid Build Coastguard Workerif __name__ == "__main__":
1924*7c568831SAndroid Build Coastguard Worker    if len(sys.argv) > 1:
1925*7c568831SAndroid Build Coastguard Worker        debug = 1
1926*7c568831SAndroid Build Coastguard Worker        parse(sys.argv[1])
1927*7c568831SAndroid Build Coastguard Worker    else:
1928*7c568831SAndroid Build Coastguard Worker        rebuild()
1929