added an XML description of the API, moved the script generating it here.

* Makefile.am doc/Makefile.am doc/libxml2-api.xml doc/parsedecl.py:
  added an XML description of the API, moved the script generating
  it here. Added a "make api" target
Daniel
diff --git a/doc/parsedecl.py b/doc/parsedecl.py
new file mode 100755
index 0000000..0243347
--- /dev/null
+++ b/doc/parsedecl.py
@@ -0,0 +1,336 @@
+#!/usr/bin/python -u
+#
+# tries to parse the output of gtk-doc declaration files and make
+# an XML reusable description from them
+#
+# TODO: try to extracts comments from the DocBook output of
+
+import sys
+import string
+
+macros = []
+structs = []
+typedefs = []
+enums = {}
+functions = {}
+private_functions = {}
+ret_types = {}
+types = {}
+
+sections = []
+files = {}
+identifiers_file = {}
+identifiers_type = {}
+
+def mormalizeTypeSpaces(raw, function):
+    global types
+
+    tokens = string.split(raw)
+    type = ''
+    for token in tokens:
+	if type != '':
+	    type = type + ' ' + token
+	else:
+	    type = token
+    if types.has_key(type):
+        types[type].append(function)
+    else:
+        types[type] = [function]
+    return type
+
+def removeComments(raw):
+    while string.find(raw, '/*') > 0:
+        e = string.find(raw, '/*')
+	tmp = raw[0:e]
+	raw = raw[e:]
+	e = string.find(raw, '*/')
+	if e > 0:
+	    raw = tmp + raw[e + 2:]
+	else:
+	    raw = tmp
+    return raw
+
+def extractArgs(raw, function):
+    raw = removeComments(raw)
+    list = string.split(raw, ",")
+    ret = []
+    for arg in list:
+        i = len(arg)
+	if i == 0:
+	    continue
+	i = i - 1
+	c = arg[i]
+	while string.find(string.letters, c) >= 0 or \
+	      string.find(string.digits, c) >= 0:
+	    i = i - 1
+	    if i < 0:
+	        break
+	    c = arg[i]
+	name = arg[i+1:]
+        while string.find(string.whitespace, c) >= 0:
+	    i = i - 1
+	    if i < 0:
+	        break
+	    c = arg[i]
+	type = mormalizeTypeSpaces(arg[0:i+1], function)
+#	print "list: %s -> %s, %s" % (list, type, name)
+	ret.append((type, name))
+    return ret
+
+def extractTypes(raw, function):
+    global ret_types
+
+    tokens = string.split(raw)
+    type = ''
+    for token in tokens:
+	if type != '':
+	    type = type + ' ' + token
+	else:
+	    type = token
+    if ret_types.has_key(type):
+        ret_types[type].append(function)
+    else:
+        ret_types[type] = [function]
+    return type
+
+def parseMacro():
+    global input
+    global macros
+
+    line = input.readline()[:-1]
+    while line != "</MACRO>":
+        if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
+	    name = line[6:-7]
+	line = input.readline()[:-1]
+
+    macros.append(name)
+    identifiers_type[name] = "macro"
+
+def parseStruct():
+    global input
+    global structs
+
+    line = input.readline()[:-1]
+    while line != "</STRUCT>":
+        if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
+	    name = line[6:-7]
+	line = input.readline()[:-1]
+
+    structs.append(name)
+    identifiers_type[name] = "struct"
+
+def parseTypedef():
+    global input
+    global typedefs
+
+    line = input.readline()[:-1]
+    while line != "</TYPEDEF>":
+        if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
+	    name = line[6:-7]
+	line = input.readline()[:-1]
+
+    typedefs.append(name)
+    identifiers_type[name] = "typedef"
+
+def parseEnum():
+    global input
+    global enums
+
+    line = input.readline()[:-1]
+    consts = []
+    while line != "</ENUM>":
+        if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
+	    name = line[6:-7]
+	elif string.find(line, 'enum') >= 0:
+	    pass
+	elif string.find(line, '{') >= 0:
+	    pass
+	elif string.find(line, '}') >= 0:
+	    pass
+	elif string.find(line, ';') >= 0:
+	    pass
+	else:
+	    comment = string.find(line, '/*')
+	    if comment >= 0:
+	        line = line[0:comment]
+	    decls = string.split(line, ",")
+	    for decl in decls:
+		val = string.split(decl, "=")[0]
+		tokens = string.split(val)
+		if len(tokens) >= 1:
+		    token = tokens[0]
+		    if string.find(string.letters, token[0]) >= 0:
+			consts.append(token)
+			identifiers_type[token] = "const"
+	line = input.readline()[:-1]
+        
+    enums[name] = consts
+    identifiers_type[name] = "enum"
+
+def parseStaticFunction():
+    global input
+    global private_functions
+
+    line = input.readline()[:-1]
+    type = None
+    signature = None
+    while line != "</USER_FUNCTION>":
+        if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
+	    name = line[6:-7]
+        elif line[0:9] == "<RETURNS>" and line[-10:] == "</RETURNS>":
+	    type = extractTypes(line[9:-10], name)
+	else:
+	    signature = line
+	line = input.readline()[:-1]
+
+    args = extractArgs(signature, name)
+    private_functions[name] = (type , args)
+    identifiers_type[name] = "private_func"
+
+def parseFunction():
+    global input
+    global functions
+
+    line = input.readline()[:-1]
+    type = None
+    signature = None
+    while line != "</FUNCTION>":
+        if line[0:6] == "<NAME>" and line[-7:] == "</NAME>":
+	    name = line[6:-7]
+        elif line[0:9] == "<RETURNS>" and line[-10:] == "</RETURNS>":
+	    type = extractTypes(line[9:-10], name)
+	else:
+	    signature = line
+	line = input.readline()[:-1]
+
+    args = extractArgs(signature, name)
+    functions[name] = (type , args)
+    identifiers_type[name] = "function"
+
+def parseSection():
+    global input
+    global sections
+    global files
+    global identifiers_file
+
+    tokens = []
+    line = input.readline()[:-1]
+    while line != "</SECTION>":
+        if line[0:6] == "<FILE>" and line[-7:] == "</FILE>":
+	    name = line[6:-7]
+	elif len(line) > 0:
+	    tokens.append(line)
+	line = input.readline()[:-1]
+
+    sections.append(name)
+    files[name] = tokens
+    for token in tokens:
+        identifiers_file[token] = name
+	#
+	# Small transitivity for enum values
+	#
+	if enums.has_key(token):
+	    for const in enums[token]:
+	        identifiers_file[const] = name
+
+print "Parsing: libxml-decl.txt"
+input = open('libxml-decl.txt')
+while 1:
+    line = input.readline()
+    if not line:
+        break
+    line = line[:-1]
+    if line == "<MACRO>":
+        parseMacro()
+    elif line == "<ENUM>":
+        parseEnum()
+    elif line == "<FUNCTION>":
+        parseFunction()
+    elif line == "<STRUCT>":
+        parseStruct()
+    elif line == "<TYPEDEF>":
+        parseTypedef()
+    elif line == "<USER_FUNCTION>":
+        parseStaticFunction()
+    elif len(line) >= 1 and line[0] == "<":
+        print "unhandled %s" % (line)
+
+print "Parsed: %d macros. %d structs, %d typedefs, %d enums" % (
+          len(macros), len(structs), len(typedefs), len(enums))
+c = 0
+for enum in enums.keys():
+    consts = enums[enum]
+    c = c + len(consts)
+print "        %d constants, %d functions and %d private functions" % (
+          c, len(functions.keys()), len(private_functions.keys()))
+print "The functions manipulates %d different types" % (len(types.keys()))
+print "The functions returns %d different types" % (len(ret_types.keys()))
+
+print "Parsing: libxml-decl-list.txt"
+input = open('libxml-decl-list.txt')
+while 1:
+    line = input.readline()
+    if not line:
+        break
+    line = line[:-1]
+    if line == "<SECTION>":
+        parseSection()
+    elif len(line) >= 1 and line[0] == "<":
+        print "unhandled %s" % (line)
+
+print "Parsed: %d files %d identifiers" % (len(files), len(identifiers_file.keys()))
+
+print "Saving XML description libxml2-api.xml"
+output = open("libxml2-api.xml", "w")
+output.write("<api name='libxml2'>\n")
+output.write("  <files>\n")
+for file in files.keys():
+    output.write("    <file name='%s'>\n" % file)
+    for symbol in files[file]:
+        output.write("     <exports symbol='%s'/>\n" % (symbol))
+    output.write("    </file>\n")
+output.write("  </files>\n")
+
+output.write("  <symbols>\n")
+symbols=macros
+for i in structs: symbols.append(i)
+for i in typedefs: symbols.append(i)
+for i in enums.keys():
+    symbols.append(i)
+    for j in enums[i]:
+        symbols.append(j)
+for i in functions.keys(): symbols.append(i)
+symbols.sort()
+prev = None
+for i in symbols:
+    if i == prev:
+#        print "Symbol %s redefined" % (i)
+	continue
+    else:
+        prev = i
+    if identifiers_type.has_key(i):
+        type = identifiers_type[i]
+	
+        if identifiers_file.has_key(i):
+	    file = identifiers_file[i]
+	else:
+	    file = None
+
+	output.write("    <%s name='%s'" % (type, i))
+	if file != None:
+	    output.write(" file='%s'" % (file))
+	if type == "function":
+	   output.write(">\n");
+	   (ret, args) = functions[i]
+	   output.write("      <return type='%s'/>\n" % (ret))
+	   for arg in args:
+	       output.write("      <arg name='%s' type='%s'/>\n" % (
+	                    arg[1], arg[0]))
+	   output.write("    </%s>\n" % (type));
+	else:
+	   output.write("/>\n");
+    else:
+        print "Symbol %s not found in identifiers list" % (i)
+output.write("  </symbols>\n")
+output.write("</api>\n")
+print "generated XML for %d symbols" % (len(symbols))