blob: 9bccabd01636ca593113f755138e5578a22e460c [file] [log] [blame]
Daniel Veillard61006472002-01-21 17:31:47 +00001#!/usr/bin/python -u
2#
3# tries to parse the output of gtk-doc declaration files and make
4# an XML reusable description from them
5#
6# TODO: try to extracts comments from the DocBook output of
7
8import sys
9import string
10
Daniel Veillard2d1464f2002-01-21 23:16:56 +000011macros = {}
12variables = {}
13structs = {}
14typedefs = {}
Daniel Veillard61006472002-01-21 17:31:47 +000015enums = {}
16functions = {}
Daniel Veillard2d1464f2002-01-21 23:16:56 +000017user_functions = {}
Daniel Veillard61006472002-01-21 17:31:47 +000018ret_types = {}
19types = {}
20
21sections = []
22files = {}
23identifiers_file = {}
24identifiers_type = {}
25
Daniel Veillard2d1464f2002-01-21 23:16:56 +000026##################################################################
27#
28# Parsing: libxml-decl.txt
29#
30##################################################################
Daniel Veillard61006472002-01-21 17:31:47 +000031def mormalizeTypeSpaces(raw, function):
32 global types
33
34 tokens = string.split(raw)
35 type = ''
36 for token in tokens:
37 if type != '':
38 type = type + ' ' + token
39 else:
40 type = token
41 if types.has_key(type):
42 types[type].append(function)
43 else:
44 types[type] = [function]
45 return type
46
47def removeComments(raw):
48 while string.find(raw, '/*') > 0:
49 e = string.find(raw, '/*')
50 tmp = raw[0:e]
51 raw = raw[e:]
52 e = string.find(raw, '*/')
53 if e > 0:
54 raw = tmp + raw[e + 2:]
55 else:
56 raw = tmp
57 return raw
58
59def extractArgs(raw, function):
60 raw = removeComments(raw)
Daniel Veillard9d06d302002-01-22 18:15:52 +000061 raw = string.replace(raw, '\n', ' ')
62 raw = string.replace(raw, '\r', ' ')
Daniel Veillard61006472002-01-21 17:31:47 +000063 list = string.split(raw, ",")
64 ret = []
65 for arg in list:
66 i = len(arg)
67 if i == 0:
68 continue
69 i = i - 1
70 c = arg[i]
71 while string.find(string.letters, c) >= 0 or \
Daniel Veillard9d06d302002-01-22 18:15:52 +000072 string.find(string.digits, c) >= 0 or c == '_':
Daniel Veillard61006472002-01-21 17:31:47 +000073 i = i - 1
74 if i < 0:
75 break
76 c = arg[i]
77 name = arg[i+1:]
78 while string.find(string.whitespace, c) >= 0:
79 i = i - 1
80 if i < 0:
81 break
82 c = arg[i]
83 type = mormalizeTypeSpaces(arg[0:i+1], function)
Daniel Veillard9d06d302002-01-22 18:15:52 +000084 if name == 'void' and type == '':
85 pass
86 else:
87 ret.append([type, name, ''])
88
Daniel Veillard61006472002-01-21 17:31:47 +000089 return ret
90
91def extractTypes(raw, function):
92 global ret_types
93
94 tokens = string.split(raw)
95 type = ''
96 for token in tokens:
97 if type != '':
98 type = type + ' ' + token
99 else:
100 type = token
101 if ret_types.has_key(type):
102 ret_types[type].append(function)
103 else:
104 ret_types[type] = [function]
Daniel Veillard9d06d302002-01-22 18:15:52 +0000105
Daniel Veillard61006472002-01-21 17:31:47 +0000106 return type
107
108def parseMacro():
109 global input
110 global macros
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000111 global variables
Daniel Veillard61006472002-01-21 17:31:47 +0000112
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000113 var = 1
Daniel Veillard61006472002-01-21 17:31:47 +0000114 line = input.readline()[:-1]
115 while line != "</MACRO>":
116 if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
117 name = line[6:-7]
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000118 elif string.find(line, "#define") >= 0:
119 var = 0
Daniel Veillard61006472002-01-21 17:31:47 +0000120 line = input.readline()[:-1]
121
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000122 if var == 1:
Daniel Veillard9d06d302002-01-22 18:15:52 +0000123 variables[name] = ['', ''] # type, info
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000124 identifiers_type[name] = "variable"
125 else:
Daniel Veillard9d06d302002-01-22 18:15:52 +0000126 macros[name] = [[], ''] # args, info
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000127 identifiers_type[name] = "macro"
Daniel Veillard61006472002-01-21 17:31:47 +0000128
129def parseStruct():
130 global input
131 global structs
132
133 line = input.readline()[:-1]
134 while line != "</STRUCT>":
135 if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
136 name = line[6:-7]
137 line = input.readline()[:-1]
138
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000139 structs[name] = ''
Daniel Veillard61006472002-01-21 17:31:47 +0000140 identifiers_type[name] = "struct"
141
142def parseTypedef():
143 global input
144 global typedefs
145
146 line = input.readline()[:-1]
147 while line != "</TYPEDEF>":
148 if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
149 name = line[6:-7]
150 line = input.readline()[:-1]
151
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000152 typedefs[name] = ''
Daniel Veillard61006472002-01-21 17:31:47 +0000153 identifiers_type[name] = "typedef"
154
155def parseEnum():
156 global input
157 global enums
158
159 line = input.readline()[:-1]
160 consts = []
161 while line != "</ENUM>":
162 if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
163 name = line[6:-7]
164 elif string.find(line, 'enum') >= 0:
165 pass
166 elif string.find(line, '{') >= 0:
167 pass
168 elif string.find(line, '}') >= 0:
169 pass
170 elif string.find(line, ';') >= 0:
171 pass
172 else:
173 comment = string.find(line, '/*')
174 if comment >= 0:
175 line = line[0:comment]
176 decls = string.split(line, ",")
177 for decl in decls:
178 val = string.split(decl, "=")[0]
179 tokens = string.split(val)
180 if len(tokens) >= 1:
181 token = tokens[0]
182 if string.find(string.letters, token[0]) >= 0:
183 consts.append(token)
184 identifiers_type[token] = "const"
185 line = input.readline()[:-1]
186
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000187 enums[name] = [consts, '']
Daniel Veillard61006472002-01-21 17:31:47 +0000188 identifiers_type[name] = "enum"
189
190def parseStaticFunction():
191 global input
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000192 global user_functions
Daniel Veillard61006472002-01-21 17:31:47 +0000193
194 line = input.readline()[:-1]
195 type = None
Daniel Veillard9d06d302002-01-22 18:15:52 +0000196 signature = ""
Daniel Veillard61006472002-01-21 17:31:47 +0000197 while line != "</USER_FUNCTION>":
198 if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
199 name = line[6:-7]
200 elif line[0:9] == "<RETURNS>" and line[-10:] == "</RETURNS>":
201 type = extractTypes(line[9:-10], name)
202 else:
Daniel Veillard9d06d302002-01-22 18:15:52 +0000203 signature = signature + line
Daniel Veillard61006472002-01-21 17:31:47 +0000204 line = input.readline()[:-1]
205
206 args = extractArgs(signature, name)
Daniel Veillard9d06d302002-01-22 18:15:52 +0000207 user_functions[name] = [[type, ''] , args, '']
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000208 identifiers_type[name] = "functype"
Daniel Veillard61006472002-01-21 17:31:47 +0000209
210def parseFunction():
211 global input
212 global functions
213
214 line = input.readline()[:-1]
215 type = None
Daniel Veillard9d06d302002-01-22 18:15:52 +0000216 signature = ""
Daniel Veillard61006472002-01-21 17:31:47 +0000217 while line != "</FUNCTION>":
218 if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
219 name = line[6:-7]
220 elif line[0:9] == "<RETURNS>" and line[-10:] == "</RETURNS>":
221 type = extractTypes(line[9:-10], name)
222 else:
Daniel Veillard9d06d302002-01-22 18:15:52 +0000223 signature = signature + line
Daniel Veillard61006472002-01-21 17:31:47 +0000224 line = input.readline()[:-1]
225
226 args = extractArgs(signature, name)
Daniel Veillard9d06d302002-01-22 18:15:52 +0000227 functions[name] = [[type, ''] , args, '']
Daniel Veillard61006472002-01-21 17:31:47 +0000228 identifiers_type[name] = "function"
229
Daniel Veillard61006472002-01-21 17:31:47 +0000230print "Parsing: libxml-decl.txt"
231input = open('libxml-decl.txt')
232while 1:
233 line = input.readline()
234 if not line:
235 break
236 line = line[:-1]
237 if line == "<MACRO>":
238 parseMacro()
239 elif line == "<ENUM>":
240 parseEnum()
241 elif line == "<FUNCTION>":
242 parseFunction()
243 elif line == "<STRUCT>":
244 parseStruct()
245 elif line == "<TYPEDEF>":
246 parseTypedef()
247 elif line == "<USER_FUNCTION>":
248 parseStaticFunction()
249 elif len(line) >= 1 and line[0] == "<":
250 print "unhandled %s" % (line)
251
252print "Parsed: %d macros. %d structs, %d typedefs, %d enums" % (
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000253 len(macros.keys()), len(structs.keys()), len(typedefs.keys()),
254 len(enums))
Daniel Veillard61006472002-01-21 17:31:47 +0000255c = 0
256for enum in enums.keys():
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000257 consts = enums[enum][0]
Daniel Veillard61006472002-01-21 17:31:47 +0000258 c = c + len(consts)
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000259print " %d variables, %d constants, %d functions and %d functypes" % (
260 len(variables.keys()), c, len(functions.keys()),
261 len(user_functions.keys()))
Daniel Veillard61006472002-01-21 17:31:47 +0000262print "The functions manipulates %d different types" % (len(types.keys()))
263print "The functions returns %d different types" % (len(ret_types.keys()))
264
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000265##################################################################
266#
267# Parsing: libxml-decl-list.txt
268#
269##################################################################
270def parseSection():
271 global input
272 global sections
273 global files
274 global identifiers_file
275
276 tokens = []
277 line = input.readline()[:-1]
278 while line != "</SECTION>":
279 if line[0:6] == "<FILE>" and line[-7:] == "</FILE>":
280 name = line[6:-7]
281 elif len(line) > 0:
282 tokens.append(line)
283 line = input.readline()[:-1]
284
285 sections.append(name)
286 files[name] = tokens
287 for token in tokens:
288 identifiers_file[token] = name
289 #
290 # Small transitivity for enum values
291 #
292 if enums.has_key(token):
293 for const in enums[token][0]:
294 identifiers_file[const] = name
295
Daniel Veillard61006472002-01-21 17:31:47 +0000296print "Parsing: libxml-decl-list.txt"
297input = open('libxml-decl-list.txt')
298while 1:
299 line = input.readline()
300 if not line:
301 break
302 line = line[:-1]
303 if line == "<SECTION>":
304 parseSection()
305 elif len(line) >= 1 and line[0] == "<":
306 print "unhandled %s" % (line)
307
308print "Parsed: %d files %d identifiers" % (len(files), len(identifiers_file.keys()))
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000309##################################################################
310#
311# Parsing: xml/*.xml
312# To enrich the existing info with extracted comments
313#
314##################################################################
315
316nbcomments = 0
317
Daniel Veillard9d06d302002-01-22 18:15:52 +0000318def insertParameterComment(id, name, value, is_param):
319 global nbcomments
320
321 if functions.has_key(id):
322 if is_param == 1:
323 args = functions[id][1]
324 found = 0
325 for arg in args:
326 if arg[1] == name:
327 arg[2] = value
328 found = 1
329 break
330 if found == 0 and name != '...':
331 print "Arg %s not found on function %s description" % (name, id)
332 return
333 else:
334 ret = functions[id][0]
335 ret[1] = value
336 elif user_functions.has_key(id):
337 if is_param == 1:
338 args = user_functions[id][1]
339 found = 0
340 for arg in args:
341 if arg[1] == name:
342 arg[2] = value
343 found = 1
344 break
345 if found == 0 and name != '...':
346 print "Arg %s not found on functype %s description" % (name, id)
347 print args
348 return
349 else:
350 ret = user_functions[id][0]
351 ret[1] = value
352 elif macros.has_key(id):
353 if is_param == 1:
354 args = macros[id][0]
355 found = 0
356 for arg in args:
357 if arg[0] == name:
358 arg[1] = value
359 found = 1
360 break
361 if found == 0:
362 args.append([name, value])
363 else:
364 print "Return info for macro %s: %s" % (id, value)
365# ret = macros[id][0]
366# ret[1] = value
367 else:
368 print "lost specific comment %s: %s: %s" % (id, name, value)
369 return
370 nbcomments = nbcomments + 1
371
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000372def insertComment(name, title, value):
373 global nbcomments
374
375 if functions.has_key(name):
376 functions[name][2] = value
Daniel Veillard9d06d302002-01-22 18:15:52 +0000377 return "function"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000378 elif typedefs.has_key(name):
379 typedefs[name] = value
Daniel Veillard9d06d302002-01-22 18:15:52 +0000380 return "typedef"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000381 elif macros.has_key(name):
Daniel Veillard9d06d302002-01-22 18:15:52 +0000382 macros[name][1] = value
383 return "macro"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000384 elif variables.has_key(name):
Daniel Veillard9d06d302002-01-22 18:15:52 +0000385 variables[name][1] = value
386 return "variable"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000387 elif structs.has_key(name):
388 structs[name] = value
Daniel Veillard9d06d302002-01-22 18:15:52 +0000389 return "struct"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000390 elif enums.has_key(name):
391 enums[name][1] = value
Daniel Veillard9d06d302002-01-22 18:15:52 +0000392 return "enum"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000393 elif user_functions.has_key(name):
Daniel Veillard9d06d302002-01-22 18:15:52 +0000394 user_functions[name][2] = value
395 return "user_function"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000396 else:
397 print "lost comment %s: %s" % (name, value)
Daniel Veillard9d06d302002-01-22 18:15:52 +0000398 return "unknown"
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000399 nbcomments = nbcomments + 1
400
401import os
402import xmllib
403try:
404 import sgmlop
405except ImportError:
406 sgmlop = None # accelerator not available
407
408debug = 0
409
410if sgmlop:
411 class FastParser:
412 """sgmlop based XML parser. this is typically 15x faster
413 than SlowParser..."""
414
415 def __init__(self, target):
416
417 # setup callbacks
418 self.finish_starttag = target.start
419 self.finish_endtag = target.end
420 self.handle_data = target.data
421
422 # activate parser
423 self.parser = sgmlop.XMLParser()
424 self.parser.register(self)
425 self.feed = self.parser.feed
426 self.entity = {
427 "amp": "&", "gt": ">", "lt": "<",
428 "apos": "'", "quot": '"'
429 }
430
431 def close(self):
432 try:
433 self.parser.close()
434 finally:
435 self.parser = self.feed = None # nuke circular reference
436
437 def handle_entityref(self, entity):
438 # <string> entity
439 try:
440 self.handle_data(self.entity[entity])
441 except KeyError:
442 self.handle_data("&%s;" % entity)
443
444else:
445 FastParser = None
446
447
448class SlowParser(xmllib.XMLParser):
449 """slow but safe standard parser, based on the XML parser in
450 Python's standard library."""
451
452 def __init__(self, target):
453 self.unknown_starttag = target.start
454 self.handle_data = target.data
455 self.unknown_endtag = target.end
456 xmllib.XMLParser.__init__(self)
457
458def getparser(target = None):
459 # get the fastest available parser, and attach it to an
460 # unmarshalling object. return both objects.
461 if target == None:
462 target = docParser()
463 if FastParser:
464 return FastParser(target), target
465 return SlowParser(target), target
466
467class docParser:
468 def __init__(self):
469 self._methodname = None
470 self._data = []
471 self.id = None
472 self.title = None
473 self.descr = None
474 self.string = None
475
476 def close(self):
477 if debug:
478 print "close"
479
480 def getmethodname(self):
481 return self._methodname
482
483 def data(self, text):
484 if debug:
485 print "data %s" % text
486 self._data.append(text)
487
488 def start(self, tag, attrs):
489 if debug:
490 print "start %s, %s" % (tag, attrs)
491 if tag == 'refsect2':
492 self.id = None
493 self.title = None
494 self.descr = None
495 self.string = None
Daniel Veillard9d06d302002-01-22 18:15:52 +0000496 self.type = None
497 self.in_parameter = 0
498 self.is_parameter = 0
499 self.parameter = None
500 self.parameter_info = None
501 self.entry = 0
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000502 elif tag == 'para':
503 self._data = []
504 elif tag == 'title':
505 self._data = []
Daniel Veillard9d06d302002-01-22 18:15:52 +0000506 elif tag == 'tgroup':
507 self.in_parameter = 1
508 elif tag == 'row':
509 self._data = []
510 self.entry = 0
511 elif tag == 'entry':
512 self.entry = self.entry + 1
513 elif tag == 'parameter' and self.in_parameter == 1:
514 self._data = []
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000515 elif tag == 'anchor' and self.id == None:
516 if attrs.has_key('id'):
517 self.id = attrs['id']
518 self.id = string.replace(self.id, '-CAPS', '')
519 self.id = string.replace(self.id, '-', '_')
520
521 def end(self, tag):
522 if debug:
523 print "end %s" % tag
524 if tag == 'refsect2':
Daniel Veillard9d06d302002-01-22 18:15:52 +0000525 self.type = insertComment(self.id, self.title, self.string)
526 self.string = None
527 elif tag == 'row':
528 if self.parameter_info != None and self.parameter_info != '':
529 insertParameterComment(self.id, self.parameter,
530 self.parameter_info, self.is_parameter)
531 self.parameter_info = None
532 self.parameter = 0
533 self.is_parameter = 0
534 elif tag == 'parameter' and self.in_parameter == 1 and self.entry == 1:
535 str = ''
536 for c in self._data:
537 str = str + c
538 str = string.replace(str, '\n', ' ')
539 str = string.replace(str, '\r', ' ')
540 str = string.replace(str, ' ', ' ')
541 str = string.replace(str, ' ', ' ')
542 str = string.replace(str, ' ', ' ')
543 while len(str) >= 1 and str[0] == ' ':
544 str=str[1:]
545 self.parameter = str
546 self.is_parameter = 1
547 self._data = []
548 elif tag == 'para' or tag == 'entry':
549 str = ''
550 for c in self._data:
551 str = str + c
552 str = string.replace(str, '\n', ' ')
553 str = string.replace(str, '\r', ' ')
554 str = string.replace(str, ' ', ' ')
555 str = string.replace(str, ' ', ' ')
556 str = string.replace(str, ' ', ' ')
557 while len(str) >= 1 and str[0] == ' ':
558 str=str[1:]
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000559 if self.string == None:
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000560 self.string = str
Daniel Veillard9d06d302002-01-22 18:15:52 +0000561 elif self.in_parameter == 1:
562 self.parameter_info = str
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000563 self._data = []
564 elif tag == 'title':
565 str = ''
566 for c in self._data:
567 str = str + c
568 str = string.replace(str, '\n', ' ')
569 str = string.replace(str, '\r', ' ')
570 str = string.replace(str, ' ', ' ')
571 str = string.replace(str, ' ', ' ')
572 str = string.replace(str, ' ', ' ')
573 while len(str) >= 1 and str[0] == ' ':
574 str=str[1:]
575 self.title = str
576
577xmlfiles = 0
578filenames = os.listdir("xml")
579for filename in filenames:
580 try:
581 f = open("xml/" + filename, 'r')
582 except IOError, msg:
583 print file, ":", msg
584 continue
585 data = f.read()
586 (parser, target) = getparser()
587 parser.feed(data)
588 parser.close()
589 xmlfiles = xmlfiles + 1
590
591print "Parsed: %d XML files collexting %d comments" % (xmlfiles, nbcomments)
592
593##################################################################
594#
595# Saving: libxml2-api.xml
596#
597##################################################################
598
599def escape(raw):
Daniel Veillard9d06d302002-01-22 18:15:52 +0000600 raw = string.replace(raw, '&', '&amp;')
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000601 raw = string.replace(raw, '<', '&lt;')
602 raw = string.replace(raw, '>', '&gt;')
Daniel Veillard9d06d302002-01-22 18:15:52 +0000603 raw = string.replace(raw, "'", '&apos;')
604 raw = string.replace(raw, '"', '&quot;')
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000605 return raw
Daniel Veillard61006472002-01-21 17:31:47 +0000606
607print "Saving XML description libxml2-api.xml"
608output = open("libxml2-api.xml", "w")
609output.write("<api name='libxml2'>\n")
610output.write(" <files>\n")
611for file in files.keys():
612 output.write(" <file name='%s'>\n" % file)
613 for symbol in files[file]:
614 output.write(" <exports symbol='%s'/>\n" % (symbol))
615 output.write(" </file>\n")
616output.write(" </files>\n")
617
618output.write(" <symbols>\n")
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000619symbols=macros.keys()
620for i in structs.keys(): symbols.append(i)
621for i in variables.keys(): variables.append(i)
622for i in typedefs.keys(): symbols.append(i)
Daniel Veillard61006472002-01-21 17:31:47 +0000623for i in enums.keys():
624 symbols.append(i)
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000625 for j in enums[i][0]:
Daniel Veillard61006472002-01-21 17:31:47 +0000626 symbols.append(j)
627for i in functions.keys(): symbols.append(i)
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000628for i in user_functions.keys(): symbols.append(i)
Daniel Veillard61006472002-01-21 17:31:47 +0000629symbols.sort()
630prev = None
631for i in symbols:
632 if i == prev:
633# print "Symbol %s redefined" % (i)
634 continue
635 else:
636 prev = i
637 if identifiers_type.has_key(i):
638 type = identifiers_type[i]
639
640 if identifiers_file.has_key(i):
641 file = identifiers_file[i]
642 else:
643 file = None
644
645 output.write(" <%s name='%s'" % (type, i))
646 if file != None:
647 output.write(" file='%s'" % (file))
648 if type == "function":
649 output.write(">\n");
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000650 (ret, args, doc) = functions[i]
651 if doc != None and doc != '':
652 output.write(" <info>%s</info>\n" % (escape(doc)))
Daniel Veillard9d06d302002-01-22 18:15:52 +0000653 if ret[1] != None and ret[1] != '':
654 output.write(" <return type='%s' info='%s'/>\n" % (
655 ret[0], escape(ret[1])))
656 else:
657 if ret[0] != 'void' and\
658 ret[0][0:4] != 'void': # This one is actually a bug in GTK Doc
659 print "Description for return on %s is missing" % (i)
660 output.write(" <return type='%s'/>\n" % (ret[0]))
Daniel Veillard61006472002-01-21 17:31:47 +0000661 for arg in args:
Daniel Veillard9d06d302002-01-22 18:15:52 +0000662 if arg[2] != None and arg[2] != '':
663 output.write(" <arg name='%s' type='%s' info='%s'/>\n" %
664 (arg[1], arg[0], escape(arg[2])))
665 else:
666 if arg[0] != '...':
667 print "Description for %s on %s is missing" % (arg[1], i)
668 output.write(" <arg name='%s' type='%s'/>\n" % (
669 arg[1], arg[0]))
670 output.write(" </%s>\n" % (type));
671 elif type == 'functype':
672 output.write(">\n");
673 (ret, args, doc) = user_functions[i]
674 if doc != None and doc != '':
675 output.write(" <info>%s</info>\n" % (escape(doc)))
676 if ret[1] != None and ret[1] != '':
677 output.write(" <return type='%s' info='%s'/>\n" % (
678 ret[0], escape(ret[1])))
679 else:
680 if ret[0] != 'void' and\
681 ret[0][0:4] != 'void': # This one is actually a bug in GTK Doc
682 print "Description for return on %s is missing" % (i)
683 output.write(" <return type='%s'/>\n" % (ret[0]))
684 for arg in args:
685 if arg[2] != None and arg[2] != '':
686 output.write(" <arg name='%s' type='%s' info='%s'/>\n" %
687 (arg[1], arg[0], escape(arg[2])))
688 else:
689 if arg[0] != '...':
690 print "Description for %s on %s is missing" % (arg[1], i)
691 output.write(" <arg name='%s' type='%s'/>\n" % (
692 arg[1], arg[0]))
Daniel Veillard61006472002-01-21 17:31:47 +0000693 output.write(" </%s>\n" % (type));
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000694 elif type == 'macro':
Daniel Veillard9d06d302002-01-22 18:15:52 +0000695 output.write(">\n");
696 if macros[i][1] != None and macros[i][1] != '':
697 output.write(" <info>%s</info>\n" % (escape(macros[i][1])))
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000698 else:
Daniel Veillard9d06d302002-01-22 18:15:52 +0000699 print "Description for %s is missing" % (i)
700 args = macros[i][0]
701 for arg in args:
702 if arg[1] != None and arg[1] != '':
703 output.write(" <arg name='%s' info='%s'/>\n" %
704 (arg[0], escape(arg[1])))
705 else:
706 print "Description for %s on %s is missing" % (arg[1], i)
707 output.write(" <arg name='%s'/>\n" % (arg[0]))
708 output.write(" </%s>\n" % (type));
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000709 elif type == 'struct':
710 if structs[i] != None and structs[i] != '':
711 output.write(" info='%s'/>\n" % (escape(structs[i])))
712 else:
713 output.write("/>\n");
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000714 elif type == 'variable':
Daniel Veillard9d06d302002-01-22 18:15:52 +0000715 if variables[i][1] != None and variables[i][1] != '':
Daniel Veillard2d1464f2002-01-21 23:16:56 +0000716 output.write(" info='%s'/>\n" % (escape(variables[i])))
717 else:
718 output.write("/>\n");
719 elif type == 'typedef':
720 if typedefs[i] != None and typedefs[i] != '':
721 output.write(" info='%s'/>\n" % (escape(typedefs[i])))
722 else:
723 output.write("/>\n");
Daniel Veillard61006472002-01-21 17:31:47 +0000724 else:
725 output.write("/>\n");
726 else:
727 print "Symbol %s not found in identifiers list" % (i)
728output.write(" </symbols>\n")
729output.write("</api>\n")
730print "generated XML for %d symbols" % (len(symbols))