~ubuntu-branches/ubuntu/wily/libxml2/wily-proposed

« back to all changes in this revision

Viewing changes to doc/apibuild.py

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-07-11 09:31:50 UTC
  • mfrom: (43.2.4 sid)
  • Revision ID: package-import@ubuntu.com-20130711093150-t3vcnrpfqepqt0mp
Tags: 2.9.1+dfsg1-2ubuntu1
* Merged from Debian unstable. Remaining changes:
  - Fix python multi-arch includes issues. 
  - Allow the package to cross-build.
  - Set PYTHON_LIBS for cross builds.
  - Remove explicit build dependency on binutils.
  - Configure the udeb --without-python.
* Dropped patches:
  - CVE-2013-0338.patch: upstream
  - CVE-2013-1969.patch: upstream

Show diffs side-by-side

added added

removed removed

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