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:
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)
192
192
def __init__(self, name = "noname"):
194
194
self.identifiers = {}
195
195
self.functions = {}
205
205
def add_ref(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None):
206
206
if name[0:2] == '__':
210
d = self.identifiers[name]
211
d.update(header, module, type, lineno, info, extra, conditionals)
213
d = identifier(name, header, module, type, lineno, info, extra, conditionals)
214
self.identifiers[name] = d
216
if d != None and static == 1:
219
if d != None and name != None and type != None:
220
self.references[name] = d
223
print "New ref: %s" % (d)
210
d = self.identifiers[name]
211
d.update(header, module, type, lineno, info, extra, conditionals)
213
d = identifier(name, header, module, type, lineno, info, extra, conditionals)
214
self.identifiers[name] = d
216
if d != None and static == 1:
219
if d != None and name != None and type != None:
220
self.references[name] = d
223
print("New ref: %s" % (d))
227
227
def add(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None):
228
228
if name[0:2] == '__':
232
d = self.identifiers[name]
233
d.update(header, module, type, lineno, info, extra, conditionals)
235
d = identifier(name, header, module, type, lineno, info, extra, conditionals)
236
self.identifiers[name] = d
238
if d != None and static == 1:
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
254
elif type == "typedef":
255
self.typedefs[name] = d
256
elif type == "macro":
257
self.macros[name] = d
259
print "Unable to register type ", type
262
print "New symbol: %s" % (d)
232
d = self.identifiers[name]
233
d.update(header, module, type, lineno, info, extra, conditionals)
235
d = identifier(name, header, module, type, lineno, info, extra, conditionals)
236
self.identifiers[name] = d
238
if d != None and static == 1:
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
254
elif type == "typedef":
255
self.typedefs[name] = d
256
elif type == "macro":
257
self.macros[name] = d
259
print("Unable to register type ", type)
262
print("New symbol: %s" % (d))
266
266
def merge(self, idx):
267
for id in idx.functions.keys():
269
# macro might be used to override functions or variables
272
if self.macros.has_key(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)
278
self.functions[id] = idx.functions[id]
279
self.identifiers[id] = idx.functions[id]
280
for id in idx.variables.keys():
282
# macro might be used to override functions or variables
285
if self.macros.has_key(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)
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)
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)
305
self.typedefs[id] = idx.typedefs[id]
306
self.identifiers[id] = idx.typedefs[id]
307
for id in idx.macros.keys():
309
# macro might be used to override functions or variables
312
if self.variables.has_key(id):
314
if self.functions.has_key(id):
316
if self.enums.has_key(id):
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)
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)
329
self.enums[id] = idx.enums[id]
330
self.identifiers[id] = idx.enums[id]
267
for id in list(idx.functions.keys()):
269
# macro might be used to override functions or variables
272
if id in self.macros:
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))
278
self.functions[id] = idx.functions[id]
279
self.identifiers[id] = idx.functions[id]
280
for id in list(idx.variables.keys()):
282
# macro might be used to override functions or variables
285
if id in self.macros:
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))
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))
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))
305
self.typedefs[id] = idx.typedefs[id]
306
self.identifiers[id] = idx.typedefs[id]
307
for id in list(idx.macros.keys()):
309
# macro might be used to override functions or variables
312
if id in self.variables:
314
if id in self.functions:
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))
322
self.macros[id] = idx.macros[id]
323
self.identifiers[id] = idx.macros[id]
324
for id in list(idx.enums.keys()):
326
print("enum %s from %s redeclared in %s" % (
327
id, self.enums[id].header, idx.enums[id].header))
329
self.enums[id] = idx.enums[id]
330
self.identifiers[id] = idx.enums[id]
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:" \
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)
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:" \
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)
345
# print "Function %s from %s is not declared in headers" % (
346
# id, idx.functions[id].module)
347
# TODO: do the same for variables.
349
349
def analyze_dict(self, type, dict):
352
for name in dict.keys():
352
for name in list(dict.keys()):
357
357
if count != public:
358
print " %d %s , %d public" % (count, type, public)
360
print " %d public %s" % (count, type)
358
print(" %d %s , %d public" % (count, type, public))
360
print(" %d public %s" % (count, type))
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)
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
379
379
def getline(self):
382
line = self.input.readline()
385
self.lineno = self.lineno + 1
386
line = string.lstrip(line)
387
line = string.rstrip(line)
390
while line[-1] == '\\':
392
n = self.input.readline()
393
self.lineno = self.lineno + 1
382
line = self.input.readline()
385
self.lineno = self.lineno + 1
390
while line[-1] == '\\':
392
n = self.input.readline()
393
self.lineno = self.lineno + 1
402
402
def getlineno(self):
406
406
self.tokens.insert(0, token);
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)
414
414
while self.tokens == []:
416
line = self.getline()
424
self.tokens = map((lambda x: ('preproc', x)),
428
if line[0] == '"' or line[0] == "'":
438
self.line = line[i+1:]
448
line = self.getline()
451
self.last = ('string', tok)
454
if l >= 2 and line[0] == '/' and line[1] == '*':
462
if line[i] == '*' and i+1 < l and line[i+1] == '/':
463
self.line = line[i+2:]
473
line = self.getline()
476
self.last = ('comment', tok)
478
if l >= 2 and line[0] == '/' and line[1] == '/':
480
self.last = ('comment', line)
484
if line[i] == '/' and i+1 < l and line[i+1] == '/':
488
if line[i] == '/' and i+1 < l and line[i+1] == '*':
492
if line[i] == '"' or line[i] == "'":
500
if line[i] == ' ' or line[i] == '\t':
504
if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
505
(o >= 48 and o <= 57):
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:
515
self.tokens.append(('name', line[s:i]))
517
if string.find("(){}:;,[]", line[i]) != -1:
416
line = self.getline()
424
self.tokens = list(map((lambda x: ('preproc', x)),
428
if line[0] == '"' or line[0] == "'":
438
self.line = line[i+1:]
448
line = self.getline()
451
self.last = ('string', tok)
454
if l >= 2 and line[0] == '/' and line[1] == '*':
462
if line[i] == '*' and i+1 < l and line[i+1] == '/':
463
self.line = line[i+2:]
473
line = self.getline()
476
self.last = ('comment', tok)
478
if l >= 2 and line[0] == '/' and line[1] == '/':
480
self.last = ('comment', line)
484
if line[i] == '/' and i+1 < l and line[i+1] == '/':
488
if line[i] == '/' and i+1 < l and line[i+1] == '*':
492
if line[i] == '"' or line[i] == "'":
500
if line[i] == ' ' or line[i] == '\t':
504
if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
505
(o >= 48 and o <= 57):
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:
515
self.tokens.append(('name', line[s:i]))
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]))
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]))
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', '...'))
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]))
545
self.tokens.append(('op', 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
569
self.tokens.append(('name', line[s:i]))
572
self.tokens = self.tokens[1:]
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', '...'))
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]))
545
self.tokens.append(('op', 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
569
self.tokens.append(('name', line[s:i]))
572
self.tokens = self.tokens[1:]
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':
580
if len(filename) > 2 and filename[-2:] == '.h':
584
584
self.input = open(filename)
585
self.lexer = CLexer(self.input)
590
self.top_comment = ""
591
self.last_comment = ""
595
self.conditionals = []
585
self.lexer = CLexer(self.input)
590
self.top_comment = ""
591
self.last_comment = ""
595
self.conditionals = []
598
598
def collect_references(self):
599
599
self.collect_ref = 1
608
608
return self.lexer.getlineno()
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)
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)
615
self.index.add(name, None, module, static, type, self.lineno(),
616
info, extra, self.conditionals)
618
618
def index_add_ref(self, name, module, static, type, info=None,
620
if self.is_header == 1:
621
self.index.add_ref(name, module, module, static, type,
622
self.lineno(), info, extra, self.conditionals)
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)
624
self.index.add_ref(name, None, module, static, type, self.lineno(),
625
info, extra, self.conditionals)
627
627
def warning(self, msg):
628
628
if self.no_error:
632
632
def error(self, msg, token=-1):
633
633
if self.no_error:
636
print "Parse Error: " + msg
638
print "Got token ", token
636
print("Parse Error: " + msg)
638
print("Got token ", token)
642
642
def debug(self, msg, token=-1):
643
print "Debug: " + msg
645
print "Got token ", token
643
print("Debug: " + msg)
645
print("Got token ", token)
648
648
def parseTopComment(self, comment):
650
lines = string.split(comment, "\n")
653
while line != "" and (line[0] == ' ' or line[0] == '\t'):
655
while line != "" and line[0] == '*':
657
while line != "" and (line[0] == ' ' or line[0] == '\t'):
660
(it, line) = string.split(line, ":", 1)
662
while line != "" and (line[0] == ' ' or line[0] == '\t'):
664
if res.has_key(item):
665
res[item] = res[item] + " " + line
670
if res.has_key(item):
671
res[item] = res[item] + " " + line
674
self.index.info = res
650
lines = comment.split("\n")
653
while line != "" and (line[0] == ' ' or line[0] == '\t'):
655
while line != "" and line[0] == '*':
657
while line != "" and (line[0] == ' ' or line[0] == '\t'):
660
(it, line) = line.split(":", 1)
662
while line != "" and (line[0] == ' ' or line[0] == '\t'):
665
res[item] = res[item] + " " + line
671
res[item] = res[item] + " " + line
674
self.index.info = res
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];
682
self.comment = self.comment + token[1]
683
token = self.lexer.token()
685
if string.find(self.comment, "DOC_DISABLE") != -1:
688
if string.find(self.comment, "DOC_ENABLE") != -1:
678
self.top_comment = token[1]
679
if self.comment == None or token[1][0] == '*':
680
self.comment = token[1];
682
self.comment = self.comment + token[1]
683
token = self.lexer.token()
685
if self.comment.find("DOC_DISABLE") != -1:
688
if self.comment.find("DOC_ENABLE") != -1:
694
694
# Parse a comment block associate to a typedef
696
696
def parseTypeComment(self, name, quiet = 0):
697
697
if name[0:2] == '__':
703
703
if self.comment == None:
705
self.warning("Missing comment for type %s" % (name))
705
self.warning("Missing comment for type %s" % (name))
707
707
if self.comment[0] != '*':
709
self.warning("Missing * in type comment for %s" % (name))
711
lines = string.split(self.comment, '\n')
714
if lines[0] != "* %s:" % (name):
716
self.warning("Misformatted type comment for %s" % (name))
717
self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0]))
720
while len(lines) > 0 and lines[0] == '*':
723
while len(lines) > 0:
725
while len(l) > 0 and l[0] == '*':
728
desc = desc + " " + l
731
desc = string.strip(desc)
735
self.warning("Type comment for %s lack description of the macro" % (name))
709
self.warning("Missing * in type comment for %s" % (name))
711
lines = self.comment.split('\n')
714
if lines[0] != "* %s:" % (name):
716
self.warning("Misformatted type comment for %s" % (name))
717
self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0]))
720
while len(lines) > 0 and lines[0] == '*':
723
while len(lines) > 0:
725
while len(l) > 0 and l[0] == '*':
728
desc = desc + " " + l
735
self.warning("Type comment for %s lack description of the macro" % (name))
739
739
# Parse a comment block associate to a macro
741
741
def parseMacroComment(self, name, quiet = 0):
742
742
if name[0:2] == '__':
748
748
if self.comment == None:
750
self.warning("Missing comment for macro %s" % (name))
750
self.warning("Missing comment for macro %s" % (name))
752
752
if self.comment[0] != '*':
754
self.warning("Missing * in macro comment for %s" % (name))
756
lines = string.split(self.comment, '\n')
759
if lines[0] != "* %s:" % (name):
761
self.warning("Misformatted macro comment for %s" % (name))
762
self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0]))
765
while lines[0] == '*':
767
while len(lines) > 0 and lines[0][0:3] == '* @':
770
(arg, desc) = string.split(l, ':', 1)
771
desc=string.strip(desc)
772
arg=string.strip(arg)
754
self.warning("Missing * in macro comment for %s" % (name))
756
lines = self.comment.split('\n')
759
if lines[0] != "* %s:" % (name):
761
self.warning("Misformatted macro comment for %s" % (name))
762
self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0]))
765
while lines[0] == '*':
767
while len(lines) > 0 and lines[0][0:3] == '* @':
770
(arg, desc) = l.split(':', 1)
775
self.warning("Misformatted macro comment for %s" % (name))
776
self.warning(" problem with '%s'" % (lines[0]))
780
l = string.strip(lines[0])
781
while len(l) > 2 and l[0:3] != '* @':
784
desc = desc + ' ' + string.strip(l)
775
self.warning("Misformatted macro comment for %s" % (name))
776
self.warning(" problem with '%s'" % (lines[0]))
781
while len(l) > 2 and l[0:3] != '* @':
784
desc = desc + ' ' + l.strip()
789
789
args.append((arg, desc))
790
while len(lines) > 0 and lines[0] == '*':
793
while len(lines) > 0:
795
while len(l) > 0 and l[0] == '*':
798
desc = desc + " " + l
801
desc = string.strip(desc)
805
self.warning("Macro comment for %s lack description of the macro" % (name))
790
while len(lines) > 0 and lines[0] == '*':
793
while len(lines) > 0:
795
while len(l) > 0 and l[0] == '*':
798
desc = desc + " " + l
805
self.warning("Macro comment for %s lack description of the macro" % (name))
810
810
# Parse a comment block and merge the informations found in the
814
814
def mergeFunctionComment(self, name, description, quiet = 0):
815
815
if name == 'main':
817
817
if name[0:2] == '__':
820
(ret, args) = description
820
(ret, args) = description
824
824
if self.comment == None:
826
self.warning("Missing comment for function %s" % (name))
827
return(((ret[0], retdesc), args, desc))
826
self.warning("Missing comment for function %s" % (name))
827
return(((ret[0], retdesc), args, desc))
828
828
if self.comment[0] != '*':
830
self.warning("Missing * in function comment for %s" % (name))
831
return(((ret[0], retdesc), args, desc))
832
lines = string.split(self.comment, '\n')
835
if lines[0] != "* %s:" % (name):
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))
841
while lines[0] == '*':
844
while len(lines) > 0 and lines[0][0:3] == '* @':
847
(arg, desc) = string.split(l, ':', 1)
848
desc=string.strip(desc)
849
arg=string.strip(arg)
830
self.warning("Missing * in function comment for %s" % (name))
831
return(((ret[0], retdesc), args, desc))
832
lines = self.comment.split('\n')
835
if lines[0] != "* %s:" % (name):
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))
841
while lines[0] == '*':
844
while len(lines) > 0 and lines[0][0:3] == '* @':
847
(arg, desc) = l.split(':', 1)
852
self.warning("Misformatted function comment for %s" % (name))
853
self.warning(" problem with '%s'" % (lines[0]))
857
l = string.strip(lines[0])
858
while len(l) > 2 and l[0:3] != '* @':
861
desc = desc + ' ' + string.strip(l)
868
if args[i][1] == arg:
869
args[i] = (args[i][0], arg, desc)
874
self.warning("Unable to find arg %s from function comment for %s" % (
876
while len(lines) > 0 and lines[0] == '*':
879
while len(lines) > 0:
881
while len(l) > 0 and l[0] == '*':
884
if len(l) >= 6 and l[0:6] == "return" or l[0:6] == "Return":
886
l = string.split(l, ' ', 1)[1]
889
retdesc = string.strip(l)
891
while len(lines) > 0:
893
while len(l) > 0 and l[0] == '*':
896
retdesc = retdesc + " " + l
899
desc = desc + " " + l
902
retdesc = string.strip(retdesc)
903
desc = string.strip(desc)
907
# report missing comments
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]))
915
if retdesc == "" and ret[0] != "void":
916
self.warning("Function comment for %s lacks description of return value" % (name))
918
self.warning("Function comment for %s lacks description of the function" % (name))
920
return(((ret[0], retdesc), args, desc))
852
self.warning("Misformatted function comment for %s" % (name))
853
self.warning(" problem with '%s'" % (lines[0]))
858
while len(l) > 2 and l[0:3] != '* @':
861
desc = desc + ' ' + l.strip()
868
if args[i][1] == arg:
869
args[i] = (args[i][0], arg, desc)
874
self.warning("Unable to find arg %s from function comment for %s" % (
876
while len(lines) > 0 and lines[0] == '*':
879
while len(lines) > 0:
881
while len(l) > 0 and l[0] == '*':
884
if len(l) >= 6 and l[0:6] == "return" or l[0:6] == "Return":
886
l = l.split(' ', 1)[1]
891
while len(lines) > 0:
893
while len(l) > 0 and l[0] == '*':
896
retdesc = retdesc + " " + l
899
desc = desc + " " + l
902
retdesc = retdesc.strip()
907
# report missing comments
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]))
915
if retdesc == "" and ret[0] != "void":
916
self.warning("Function comment for %s lacks description of return value" % (name))
918
self.warning("Function comment for %s lacks description of the function" % (name))
920
return(((ret[0], retdesc), args, desc))
922
922
def parsePreproc(self, token):
924
print "=> preproc ", token, self.lexer.tokens
924
print("=> preproc ", token, self.lexer.tokens)
926
if name == "#include":
927
token = self.lexer.token()
930
if token[0] == 'preproc':
931
self.index_add(token[1], self.filename, not self.is_header,
933
return self.lexer.token()
935
if name == "#define":
936
token = self.lexer.token()
939
if token[0] == 'preproc':
940
# TODO macros with arguments
943
token = self.lexer.token()
944
while token != None and token[0] == 'preproc' and \
947
token = self.lexer.token()
926
if name == "#include":
927
token = self.lexer.token()
930
if token[0] == 'preproc':
931
self.index_add(token[1], self.filename, not self.is_header,
933
return self.lexer.token()
935
if name == "#define":
936
token = self.lexer.token()
939
if token[0] == 'preproc':
940
# TODO macros with arguments
943
token = self.lexer.token()
944
while token != None and token[0] == 'preproc' and \
947
token = self.lexer.token()
949
name = string.split(name, '(') [0]
949
name = name.split('(') [0]
952
952
info = self.parseMacroComment(name, not self.is_header)
953
self.index_add(name, self.filename, not self.is_header,
953
self.index_add(name, self.filename, not self.is_header,
958
# Processing of conditionals modified by Bill 1/1/05
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.
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'
975
apstr = self.lexer.tokens[0][1]
977
self.defines.append(apstr)
978
if string.find(apstr, 'ENABLED') != -1:
979
self.conditionals.append("defined(%s)" % apstr)
982
elif name == "#ifndef":
983
apstr = self.lexer.tokens[0][1]
985
self.defines.append(apstr)
986
if string.find(apstr, 'ENABLED') != -1:
987
self.conditionals.append("!defined(%s)" % apstr)
992
for tok in self.lexer.tokens:
995
apstr = apstr + tok[1]
997
self.defines.append(apstr)
998
if string.find(apstr, 'ENABLED') != -1:
999
self.conditionals.append(apstr)
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 \
1014
token = self.lexer.token()
958
# Processing of conditionals modified by Bill 1/1/05
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.
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'
975
apstr = self.lexer.tokens[0][1]
977
self.defines.append(apstr)
978
if apstr.find('ENABLED') != -1:
979
self.conditionals.append("defined(%s)" % apstr)
982
elif name == "#ifndef":
983
apstr = self.lexer.tokens[0][1]
985
self.defines.append(apstr)
986
if apstr.find('ENABLED') != -1:
987
self.conditionals.append("!defined(%s)" % apstr)
992
for tok in self.lexer.tokens:
995
apstr = apstr + tok[1]
997
self.defines.append(apstr)
998
if apstr.find('ENABLED') != -1:
999
self.conditionals.append(apstr)
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 \
1014
token = self.lexer.token()
1018
1018
# token acquisition on top of the lexer, it handle internally
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] == "}":
1121
token = self.token()
1124
if self.collect_ref == 1:
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,
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,
1138
elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_":
1139
self.index_add_ref(oldtok[1], self.filename,
1141
elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_":
1142
self.index_add_ref(oldtok[1], self.filename,
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] == "}":
1121
token = self.token()
1124
if self.collect_ref == 1:
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,
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,
1138
elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_":
1139
self.index_add_ref(oldtok[1], self.filename,
1141
elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_":
1142
self.index_add_ref(oldtok[1], self.filename,
1146
token = self.token()
1146
token = self.token()
1150
1150
# Parse a C struct definition till the balancing }
1152
1152
def parseStruct(self, token):
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)
1163
token = self.token()
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":
1172
token = self.token()
1173
if token[0] == "sep" and token[1] == ";":
1175
token = self.token()
1176
fields.append((self.type, fname, self.comment))
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()
1188
self.error("parseStruct: expecting ;", token)
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)
1163
token = self.token()
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":
1172
token = self.token()
1173
if token[0] == "sep" and token[1] == ";":
1175
token = self.token()
1176
fields.append((self.type, fname, self.comment))
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()
1188
self.error("parseStruct: expecting ;", token)
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)
1194
#self.debug("end parseStruct", token)
1199
1199
# Parse a C enum block, parse till the balancing }
1201
1201
def parseEnumBlock(self, token):
1202
1202
self.enums = []
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] == "}":
1213
if self.comment != None:
1214
comment = self.comment
1216
self.enums.append((name, value, comment))
1217
token = self.token()
1219
elif token[0] == "name":
1221
if self.comment != None:
1222
comment = string.strip(self.comment)
1224
self.enums.append((name, value, comment))
1227
token = self.token()
1228
if token[0] == "op" and token[1][0] == "=":
1230
if len(token[1]) > 1:
1231
value = token[1][1:]
1232
token = self.token()
1233
while token[0] != "sep" or (token[1] != ',' and
1235
value = value + token[1]
1236
token = self.token()
1239
value = "%d" % (int(value) + 1)
1241
self.warning("Failed to compute value of enum %s" % (name))
1243
if token[0] == "sep" and token[1] == ",":
1244
token = self.token()
1246
token = self.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] == "}":
1213
if self.comment != None:
1214
comment = self.comment
1216
self.enums.append((name, value, comment))
1217
token = self.token()
1219
elif token[0] == "name":
1221
if self.comment != None:
1222
comment = self.comment.strip()
1224
self.enums.append((name, value, comment))
1227
token = self.token()
1228
if token[0] == "op" and token[1][0] == "=":
1230
if len(token[1]) > 1:
1231
value = token[1][1:]
1232
token = self.token()
1233
while token[0] != "sep" or (token[1] != ',' and
1235
value = value + token[1]
1236
token = self.token()
1239
value = "%d" % (int(value) + 1)
1241
self.warning("Failed to compute value of enum %s" % (name))
1243
if token[0] == "sep" and token[1] == ",":
1244
token = self.token()
1246
token = self.token()
1250
1250
# Parse a C definition block, used for structs it parse till
1270
1270
def parseType(self, token):
1272
self.struct_fields = []
1272
self.struct_fields = []
1273
1273
self.signature = None
1277
while token[0] == "name" and (
1278
token[1] == "const" or \
1279
token[1] == "unsigned" or \
1280
token[1] == "signed"):
1282
self.type = token[1]
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"):
1282
self.type = token[1]
1284
self.type = self.type + " " + token[1]
1285
token = self.token()
1287
1287
if token[0] == "name" and (token[1] == "long" or token[1] == "short"):
1289
self.type = token[1]
1291
self.type = self.type + " " + token[1]
1292
if token[0] == "name" and token[1] == "int":
1296
self.type = self.type + " " + tmp[1]
1289
self.type = token[1]
1291
self.type = self.type + " " + token[1]
1292
if token[0] == "name" and token[1] == "int":
1296
self.type = self.type + " " + tmp[1]
1298
1298
elif token[0] == "name" and token[1] == "struct":
1300
self.type = token[1]
1302
self.type = self.type + " " + token[1]
1303
token = self.token()
1305
if token[0] == "name":
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":
1319
token = self.token()
1321
self.error("struct : expecting name", token)
1323
elif token != None and token[0] == "name" and nametok != None:
1324
self.type = self.type + " " + nametok[1]
1300
self.type = token[1]
1302
self.type = self.type + " " + token[1]
1303
token = self.token()
1305
if token[0] == "name":
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":
1319
token = self.token()
1321
self.error("struct : expecting name", token)
1323
elif token != None and token[0] == "name" and nametok != None:
1324
self.type = self.type + " " + nametok[1]
1328
self.lexer.push(token)
1328
self.lexer.push(token)
1332
1332
elif token[0] == "name" and token[1] == "enum":
1334
self.type = token[1]
1336
self.type = self.type + " " + token[1]
1338
token = self.token()
1339
if token != None and token[0] == "sep" and token[1] == "{":
1340
token = self.token()
1341
token = self.parseEnumBlock(token)
1343
self.error("parsing enum: expecting '{'", token)
1345
if token != None and token[0] != "name":
1346
self.lexer.push(token)
1347
token = ("name", "enum")
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))
1334
self.type = token[1]
1336
self.type = self.type + " " + token[1]
1338
token = self.token()
1339
if token != None and token[0] == "sep" and token[1] == "{":
1340
token = self.token()
1341
token = self.parseEnumBlock(token)
1343
self.error("parsing enum: expecting '{'", token)
1345
if token != None and token[0] != "name":
1346
self.lexer.push(token)
1347
token = ("name", "enum")
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))
1356
elif token[0] == "name":
1358
self.type = token[1]
1360
self.type = self.type + " " + token[1]
1362
self.error("parsing type %s: expecting a name" % (self.type),
1365
token = self.token()
1356
elif token[0] == "name":
1358
self.type = token[1]
1360
self.type = self.type + " " + token[1]
1362
self.error("parsing type %s: expecting a name" % (self.type),
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()
1372
# if there is a parenthesis here, this means a function type
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);
1383
self.type = self.type + token[1]
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()
1392
token = self.parseSignature(token);
1395
self.error("parsing function type, '(' expected", token);
1398
self.error("parsing function type, ')' expected", token);
1400
self.lexer.push(token)
1405
# do some lookahead for arrays
1407
if token != None and token[0] == "name":
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()
1423
self.error("parsing array type, ']' expected", 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)
1367
token[0] == "name" and token[1] == "const"):
1368
self.type = self.type + " " + token[1]
1369
token = self.token()
1372
# if there is a parenthesis here, this means a function type
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);
1383
self.type = self.type + token[1]
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()
1392
token = self.parseSignature(token);
1395
self.error("parsing function type, '(' expected", token);
1398
self.error("parsing function type, ')' expected", token);
1400
self.lexer.push(token)
1405
# do some lookahead for arrays
1407
if token != None and token[0] == "name":
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()
1423
self.error("parsing array type, ']' expected", 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)
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):
1439
if token != None and token[0] == "sep" and token[1] == ')':
1441
token = self.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()
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))
1456
signature.append((self.type, None, None))
1457
if token != None and token[0] == "sep":
1459
token = self.token()
1461
elif token[1] == ')':
1462
token = self.token()
1464
self.signature = signature
1439
if token != None and token[0] == "sep" and token[1] == ')':
1441
token = self.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()
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))
1456
signature.append((self.type, None, None))
1457
if token != None and token[0] == "sep":
1459
token = self.token()
1461
elif token[1] == ')':
1462
token = self.token()
1464
self.signature = signature
1468
1468
# Parse a global definition, be it a type, variable or function
1471
1471
def parseGlobal(self, token):
1473
1473
if token[1] == 'extern':
1474
token = self.token()
1477
if token[0] == 'string':
1479
token = self.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
1487
if token[0] == 'name':
1488
token = self.parseGlobal(token)
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()
1499
elif token[1] == 'static':
1501
token = self.token()
1502
if token == None or token[0] != 'name':
1505
if token[1] == 'typedef':
1506
token = self.token()
1507
return self.parseTypedef(token)
1509
token = self.parseType(token)
1510
type_orig = self.type
1511
if token == None or token[0] != "name":
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":
1519
type = type + token[1]
1520
token = self.token()
1521
while token != None and (token[0] != "sep" or \
1523
type = type + token[1]
1524
token = self.token()
1526
if token != None and token[0] == "op" and token[1] == "=":
1528
# Skip the initialization of the variable
1530
token = self.token()
1531
if token[0] == 'sep' and token[1] == '{':
1532
token = self.token()
1533
token = self.parseBlock(token)
1536
while token != None and (token[0] != "sep" or \
1537
(token[1] != ';' and token[1] != ',')):
1538
token = self.token()
1540
if token == None or token[0] != "sep" or (token[1] != ';' and
1542
self.error("missing ';' or ',' after value")
1544
if token != None and token[0] == "sep":
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)
1552
self.index_add(self.name, self.filename,
1553
not self.is_header, "variable", type)
1555
elif token[1] == "(":
1556
token = self.token()
1557
token = self.parseSignature(token)
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,
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,
1571
token = self.token()
1572
token = self.parseBlock(token);
1573
elif token[1] == ',':
1575
self.index_add(self.name, self.filename, static,
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()
1474
token = self.token()
1477
if token[0] == 'string':
1479
token = self.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
1487
if token[0] == 'name':
1488
token = self.parseGlobal(token)
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()
1499
elif token[1] == 'static':
1501
token = self.token()
1502
if token == None or token[0] != 'name':
1505
if token[1] == 'typedef':
1506
token = self.token()
1507
return self.parseTypedef(token)
1509
token = self.parseType(token)
1510
type_orig = self.type
1511
if token == None or token[0] != "name":
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":
1519
type = type + token[1]
1520
token = self.token()
1521
while token != None and (token[0] != "sep" or \
1523
type = type + token[1]
1524
token = self.token()
1526
if token != None and token[0] == "op" and token[1] == "=":
1528
# Skip the initialization of the variable
1530
token = self.token()
1531
if token[0] == 'sep' and token[1] == '{':
1532
token = self.token()
1533
token = self.parseBlock(token)
1536
while token != None and (token[0] != "sep" or \
1537
(token[1] != ';' and token[1] != ',')):
1538
token = self.token()
1540
if token == None or token[0] != "sep" or (token[1] != ';' and
1542
self.error("missing ';' or ',' after value")
1544
if token != None and token[0] == "sep":
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)
1552
self.index_add(self.name, self.filename,
1553
not self.is_header, "variable", type)
1555
elif token[1] == "(":
1556
token = self.token()
1557
token = self.parseSignature(token)
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,
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,
1571
token = self.token()
1572
token = self.parseBlock(token);
1573
elif token[1] == ',':
1575
self.index_add(self.name, self.filename, static,
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()
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)
1597
self.error("token %s %s unexpected at the top level" % (
1598
token[0], token[1]))
1599
token = self.parseGlobal(token)
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)
1601
self.parseTopComment(self.top_comment)
1602
1602
return self.index
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()
1610
self.excludes = excludes + list(ignored_files.keys())
1616
if name == 'libxml2':
1617
self.basename = 'libxml'
1619
self.basename = name
1616
if name == 'libxml2':
1617
self.basename = 'libxml'
1619
self.basename = name
1621
1621
def indexString(self, id, str):
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:
1643
if string.find(string.letters, c) < 0:
1645
elif len(token) < 3:
1648
lower = string.lower(token)
1649
# TODO: generalize this a bit
1650
if lower == 'and' or lower == 'the':
1652
elif self.xref.has_key(token):
1653
self.xref[token].append(id)
1655
self.xref[token] = [id]
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:
1643
if string.ascii_letters.find(c) < 0:
1645
elif len(token) < 3:
1648
lower = token.lower()
1649
# TODO: generalize this a bit
1650
if lower == 'and' or lower == 'the':
1652
elif token in self.xref:
1653
self.xref[token].append(id)
1655
self.xref[token] = [id]
1659
1659
def analyze(self):
1660
print "Project %s : %d headers, %d modules" % (self.name, len(self.headers.keys()), len(self.modules.keys()))
1660
print("Project %s : %d headers, %d modules" % (self.name, len(list(self.headers.keys())), len(list(self.modules.keys()))))
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;
1664
for header in list(self.headers.keys()):
1665
parser = CParser(header)
1666
idx = parser.parse()
1667
self.headers[header] = idx;
1670
1670
def scanModules(self):
1671
for module in self.modules.keys():
1672
parser = CParser(module)
1673
idx = parser.parse()
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()
1675
self.modules[module] = idx
1676
self.idx.merge_public(idx)
1678
1678
def scan(self):
1679
1679
for directory in self.directories:
1680
files = glob.glob(directory + "/*.c")
1683
for excl in self.excludes:
1684
if string.find(file, excl) != -1:
1685
print "Skipping %s" % file
1689
self.modules[file] = None;
1690
files = glob.glob(directory + "/*.h")
1693
for excl in self.excludes:
1694
if string.find(file, excl) != -1:
1695
print "Skipping %s" % file
1699
self.headers[file] = None;
1680
files = glob.glob(directory + "/*.c")
1683
for excl in self.excludes:
1684
if file.find(excl) != -1:
1685
print("Skipping %s" % file)
1689
self.modules[file] = None;
1690
files = glob.glob(directory + "/*.h")
1693
for excl in self.excludes:
1694
if file.find(excl) != -1:
1695
print("Skipping %s" % file)
1699
self.headers[file] = None;
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]
1705
if module[-2:] == '.h':
1706
module = module[:-2]
1707
elif module[-2:] == '.c':
1708
module = module[:-2]
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)))
1717
if info[0] != None and 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)))
1717
if info[0] != None and 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")
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)))
1732
self.modulename_file(id.header)))
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)
1741
if desc != None and desc != "":
1742
output.write(" <arg name='%s' info='%s'/>\n" % (
1743
name, escape(desc)))
1744
self.indexString(name, desc)
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)
1741
if desc != None and desc != "":
1742
output.write(" <arg name='%s' info='%s'/>\n" % (
1743
name, escape(desc)))
1744
self.indexString(name, desc)
1746
output.write(" <arg name='%s'/>\n" % (name))
1749
1749
output.write(" </macro>\n")
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))
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");
1762
for field in self.idx.structs[name].info:
1764
self.indexString(name, desc)
1769
output.write(" <field name='%s' type='%s' info='%s'/>\n" % (field[1] , field[0], desc))
1771
print "Failed to serialize struct %s" % (name)
1772
output.write(" </struct>\n")
1774
output.write("/>\n");
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))
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");
1762
for field in self.idx.structs[name].info:
1764
self.indexString(name, desc)
1769
output.write(" <field name='%s' type='%s' info='%s'/>\n" % (field[1] , field[0], desc))
1771
print("Failed to serialize struct %s" % (name))
1772
output.write(" </struct>\n")
1774
output.write("/>\n");
1776
output.write(" <typedef name='%s' file='%s' type='%s'" % (
1777
name, self.modulename_file(id.header), id.info))
1780
if desc != None and desc != "":
1781
output.write(">\n <info>%s</info>\n" % (escape(desc)))
1782
output.write(" </typedef>\n")
1784
output.write("/>\n")
1786
output.write("/>\n")
1780
if desc != None and desc != "":
1781
output.write(">\n <info>%s</info>\n" % (escape(desc)))
1782
output.write(" </typedef>\n")
1784
output.write("/>\n")
1786
output.write("/>\n")
1788
1788
def serialize_variable(self, output, name):
1789
1789
id = self.idx.variables[name]
1791
output.write(" <variable name='%s' file='%s' type='%s'/>\n" % (
1792
name, self.modulename_file(id.header), id.info))
1794
output.write(" <variable name='%s' file='%s'/>\n" % (
1795
name, self.modulename_file(id.header)))
1791
output.write(" <variable name='%s' file='%s' type='%s'/>\n" % (
1792
name, self.modulename_file(id.header), id.info))
1794
output.write(" <variable name='%s' file='%s'/>\n" % (
1795
name, self.modulename_file(id.header)))
1797
1797
def serialize_function(self, output, name):
1798
1798
id = self.idx.functions[name]
1799
if name == debugsym:
1799
if name == debugsym:
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)))
1806
# Processing of conditionals modified by Bill 1/1/05
1808
if id.conditionals != None:
1810
for cond in id.conditionals:
1812
apstr = apstr + " && "
1813
apstr = apstr + cond
1814
output.write(" <cond>%s</cond>\n"% (apstr));
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)))
1806
# Processing of conditionals modified by Bill 1/1/05
1808
if id.conditionals != None:
1810
for cond in id.conditionals:
1812
apstr = apstr + " && "
1813
apstr = apstr + cond
1814
output.write(" <cond>%s</cond>\n"% (apstr));
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)))
1822
output.write(" <info>%s</info>\n" % (escape(desc)))
1823
self.indexString(name, desc)
1825
if ret[0] == "void":
1826
output.write(" <return type='void'/>\n")
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':
1834
if param[2] == None:
1835
output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0]))
1837
output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2])))
1838
self.indexString(name, param[2])
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)
1825
if ret[0] == "void":
1826
output.write(" <return type='void'/>\n")
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':
1834
if param[2] == None:
1835
output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0]))
1837
output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2])))
1838
self.indexString(name, param[2])
1840
print("Failed to save function %s info: " % name, repr(id.info))
1841
1841
output.write(" </%s>\n" % (id.type))
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'):
1850
output.write(" <%s>%s</%s>\n" % (
1852
escape(dict.info[data]),
1853
string.lower(data)))
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'):
1850
output.write(" <%s>%s</%s>\n" % (
1852
escape(dict.info[data]),
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")
1861
ids = dict.macros.keys()
1863
for id in uniq(ids):
1864
# Macros are sometime used to masquerade other types.
1865
if dict.functions.has_key(id):
1867
if dict.variables.has_key(id):
1869
if dict.typedefs.has_key(id):
1871
if dict.structs.has_key(id):
1873
if dict.enums.has_key(id):
1875
output.write(" <exports symbol='%s' type='macro'/>\n" % (id))
1876
ids = dict.enums.keys()
1878
for id in uniq(ids):
1879
output.write(" <exports symbol='%s' type='enum'/>\n" % (id))
1880
ids = dict.typedefs.keys()
1882
for id in uniq(ids):
1883
output.write(" <exports symbol='%s' type='typedef'/>\n" % (id))
1884
ids = dict.structs.keys()
1886
for id in uniq(ids):
1887
output.write(" <exports symbol='%s' type='struct'/>\n" % (id))
1888
ids = dict.variables.keys()
1890
for id in uniq(ids):
1891
output.write(" <exports symbol='%s' type='variable'/>\n" % (id))
1892
ids = dict.functions.keys()
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())
1863
for id in uniq(ids):
1864
# Macros are sometime used to masquerade other types.
1865
if id in dict.functions:
1867
if id in dict.variables:
1869
if id in dict.typedefs:
1871
if id in dict.structs:
1873
if id in dict.enums:
1875
output.write(" <exports symbol='%s' type='macro'/>\n" % (id))
1876
ids = list(dict.enums.keys())
1878
for id in uniq(ids):
1879
output.write(" <exports symbol='%s' type='enum'/>\n" % (id))
1880
ids = list(dict.typedefs.keys())
1882
for id in uniq(ids):
1883
output.write(" <exports symbol='%s' type='typedef'/>\n" % (id))
1884
ids = list(dict.structs.keys())
1886
for id in uniq(ids):
1887
output.write(" <exports symbol='%s' type='struct'/>\n" % (id))
1888
ids = list(dict.variables.keys())
1890
for id in uniq(ids):
1891
output.write(" <exports symbol='%s' type='variable'/>\n" % (id))
1892
ids = list(dict.functions.keys())
1894
for id in uniq(ids):
1895
output.write(" <exports symbol='%s' type='function'/>\n" % (id))
1896
output.write(" </file>\n")
1898
1898
def serialize_xrefs_files(self, output):
1899
headers = self.headers.keys()
1899
headers = list(self.headers.keys())
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())
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()))
1910
output.write(" <ref name='%s'/>\n" % (id))
1911
output.write(" </file>\n")
1914
1914
def serialize_xrefs_functions(self, output):
1916
for name in self.idx.functions.keys():
1917
id = self.idx.functions[name]
1919
(ret, params, desc) = id.info
1920
for param in params:
1921
if param[0] == 'void':
1923
if funcs.has_key(param[0]):
1924
funcs[param[0]].append(name)
1926
funcs[param[0]] = [name]
1932
if type == '' or type == 'void' or type == "int" or \
1933
type == "char *" or type == "const char *" :
1935
output.write(" <type name='%s'>\n" % (type))
1938
pid = '' # not sure why we have dups, but get rid of them!
1941
output.write(" <ref name='%s'/>\n" % (id))
1943
output.write(" </type>\n")
1916
for name in list(self.idx.functions.keys()):
1917
id = self.idx.functions[name]
1919
(ret, params, desc) = id.info
1920
for param in params:
1921
if param[0] == 'void':
1923
if param[0] in funcs:
1924
funcs[param[0]].append(name)
1926
funcs[param[0]] = [name]
1929
typ = list(funcs.keys())
1932
if type == '' or type == 'void' or type == "int" or \
1933
type == "char *" or type == "const char *" :
1935
output.write(" <type name='%s'>\n" % (type))
1938
pid = '' # not sure why we have dups, but get rid of them!
1941
output.write(" <ref name='%s'/>\n" % (id))
1943
output.write(" </type>\n")
1945
1945
def serialize_xrefs_constructors(self, output):
1947
for name in self.idx.functions.keys():
1948
id = self.idx.functions[name]
1950
(ret, params, desc) = id.info
1951
if ret[0] == "void":
1953
if funcs.has_key(ret[0]):
1954
funcs[ret[0]].append(name)
1956
funcs[ret[0]] = [name]
1962
if type == '' or type == 'void' or type == "int" or \
1963
type == "char *" or type == "const char *" :
1965
output.write(" <type name='%s'>\n" % (type))
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]
1950
(ret, params, desc) = id.info
1951
if ret[0] == "void":
1954
funcs[ret[0]].append(name)
1956
funcs[ret[0]] = [name]
1959
typ = list(funcs.keys())
1962
if type == '' or type == 'void' or type == "int" or \
1963
type == "char *" or type == "const char *" :
1965
output.write(" <type name='%s'>\n" % (type))
1969
output.write(" <ref name='%s'/>\n" % (id))
1970
output.write(" </type>\n")
1972
1972
def serialize_xrefs_alpha(self, output):
1974
ids = self.idx.identifiers.keys()
1979
output.write(" </letter>\n")
1981
output.write(" <letter name='%s'>\n" % (letter))
1982
output.write(" <ref name='%s'/>\n" % (id))
1984
output.write(" </letter>\n")
1974
ids = list(self.idx.identifiers.keys())
1979
output.write(" </letter>\n")
1981
output.write(" <letter name='%s'>\n" % (letter))
1982
output.write(" <ref name='%s'/>\n" % (id))
1984
output.write(" </letter>\n")
1986
1986
def serialize_xrefs_references(self, output):
1987
typ = self.idx.identifiers.keys()
1990
idf = self.idx.identifiers[id]
1992
output.write(" <reference name='%s' href='%s'/>\n" % (id,
1993
'html/' + self.basename + '-' +
1994
self.modulename_file(module) + '.html#' +
1987
typ = list(self.idx.identifiers.keys())
1990
idf = self.idx.identifiers[id]
1992
output.write(" <reference name='%s' href='%s'/>\n" % (id,
1993
'html/' + self.basename + '-' +
1994
self.modulename_file(module) + '.html#' +
1997
1997
def serialize_xrefs_index(self, output):
1998
1998
index = self.xref
2006
if len(index[id]) > 30:
2009
if letter == None or count > 200:
2011
output.write(" </letter>\n")
2012
output.write(" </chunk>\n")
2014
chunks.append(["chunk%s" % (chunk -1), first_letter, letter])
2015
output.write(" <chunk name='chunk%s'>\n" % (chunk))
2016
first_letter = id[0]
2018
elif letter != None:
2019
output.write(" </letter>\n")
2021
output.write(" <letter name='%s'>\n" % (letter))
2022
output.write(" <word name='%s'>\n" % (id))
2026
for token in tokens:
2030
output.write(" <ref name='%s'/>\n" % (token))
2032
output.write(" </word>\n")
2034
output.write(" </letter>\n")
2035
output.write(" </chunk>\n")
2037
chunks.append(["chunk%s" % (chunk -1), first_letter, letter])
2038
output.write(" <chunks>\n")
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())
2006
if len(index[id]) > 30:
2009
if letter == None or count > 200:
2011
output.write(" </letter>\n")
2012
output.write(" </chunk>\n")
2014
chunks.append(["chunk%s" % (chunk -1), first_letter, letter])
2015
output.write(" <chunk name='chunk%s'>\n" % (chunk))
2016
first_letter = id[0]
2018
elif letter != None:
2019
output.write(" </letter>\n")
2021
output.write(" <letter name='%s'>\n" % (letter))
2022
output.write(" <word name='%s'>\n" % (id))
2026
for token in tokens:
2030
output.write(" <ref name='%s'/>\n" % (token))
2032
output.write(" </word>\n")
2034
output.write(" </letter>\n")
2035
output.write(" </chunk>\n")
2037
chunks.append(["chunk%s" % (chunk -1), first_letter, letter])
2038
output.write(" <chunks>\n")
2040
output.write(" <chunk name='%s' start='%s' end='%s'/>\n" % (
2041
ch[0], ch[1], ch[2]))
2042
output.write(" </chunks>\n")
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")
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())
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())
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())
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)