index.py revision d8cf90610c63a695d948245cc4e22890e2c063be
1#!/usr/bin/python -u
2#
3# Indexes the examples and build doc and web pages.
4#
5import string
6import sys
7try:
8    import libxml2
9except:
10    sys.exit(1)
11sys.path.append("..")
12from apibuild import CParser, escape
13
14symbols = {}
15api_dict = None
16api_doc = None
17
18def load_api():
19    global api_dict
20    global api_doc
21
22    if api_dict != None:
23        return
24    api_dict = {}
25    try:
26        print "loading ../libxml2-api.xml"
27        api_doc = libxml2.parseFile("../libxml2-api.xml")
28    except:
29        print "failed to parse ../libxml2-api.xml"
30	sys.exit(1)
31
32def find_symbol(name):
33    global api_dict
34    global api_doc
35
36    if api_doc == None:
37        load_api()
38
39    if name == None:
40        return
41    if api_dict.has_key(name):
42        return api_dict[name]
43    ctxt = api_doc.xpathNewContext()
44    res = ctxt.xpathEval("/api/symbols/*[@name = '%s']" % (name))
45    if type(res) == type([]) and len(res) >= 1:
46        if len(res) > 1:
47	    print "Found %d references to %s in the API" % (len(res), name)
48	node = res[0]
49	typ = node.name
50	file = node.xpathEval("string(@file)")
51	info = node.xpathEval("string(info)")
52    else:
53        print "Reference %s not found in the API" % (name)
54	return None
55    ret = (typ, file, info)
56    api_dict[name] = ret
57    return ret
58
59def parse_top_comment(filename, comment):
60    res = {}
61    lines = string.split(comment, "\n")
62    item = None
63    for line in lines:
64        while line != "" and line[0] == ' ':
65	    line = line[1:]
66        while line != "" and line[0] == '*':
67	    line = line[1:]
68        while line != "" and line[0] == ' ':
69	    line = line[1:]
70	try:
71	    (it, line) = string.split(line, ":", 1)
72	    item = it
73	    while line != "" and line[0] == ' ':
74		line = line[1:]
75	    if res.has_key(item):
76	        res[item] = res[item] + " " + line
77	    else:
78		res[item] = line
79	except:
80	    if item != None:
81	        if res.has_key(item):
82		    res[item] = res[item] + " " + line
83		else:
84		    res[item] = line
85    return res
86
87def parse(filename, output):
88    global symbols
89
90    parser = CParser(filename)
91    parser.collect_references()
92    idx = parser.parse()
93    info = parse_top_comment(filename, parser.top_comment)
94    output.write("  <example filename='%s'>\n" % filename)
95    try:
96        purpose = info['purpose']
97	output.write("    <purpose>%s</purpose>\n" % purpose);
98    except:
99        print "Example %s lacks a purpose description" % (filename)
100    try:
101        usage = info['usage']
102	output.write("    <usage>%s</usage>\n" % usage);
103    except:
104        print "Example %s lacks an usage description" % (filename)
105    try:
106        author = info['author']
107	output.write("    <author>%s</author>\n" % author);
108    except:
109        print "Example %s lacks an author description" % (filename)
110    try:
111        copy = info['copy']
112	output.write("    <copy>%s</copy>\n" % copy);
113    except:
114        print "Example %s lacks a copyright description" % (filename)
115    for topic in info.keys():
116        if topic != "purpose" and topic != "usage" and \
117	   topic != "author" and topic != "copy":
118	    str = info[topic]
119	    output.write("    <extra topic='%s'>%s</extra>\n" % str)
120#    print idx.functions
121    output.write("    <uses>\n")
122    for include in idx.includes.keys():
123        if include.find("libxml") != -1:
124	    output.write("      <include>%s</include>\n" % (escape(include)))
125    for ref in idx.references.keys():
126        id = idx.references[ref]
127	name = id.get_name()
128	line = id.get_lineno()
129	if symbols.has_key(name):
130	    sinfo = symbols[name]
131	    refs = sinfo[0]
132	    # gather at most 5 references per symbols
133	    if refs > 5:
134	        continue
135	    sinfo[refs] = filename
136	    sinfo[0] = refs + 1
137	else:
138	    symbols[name] = [1, filename]
139	info = find_symbol(name)
140	if info != None:
141	    type = info[0]
142	    file = info[1]
143	    output.write("      <%s line='%d' file='%s'>%s</%s>\n" % (type,
144	                 line, file, name, type))
145	else:
146	    type = id.get_type()
147	    output.write("      <%s line='%d'>%s</%s>\n" % (type,
148	                 line, name, type))
149
150    output.write("    </uses>\n")
151    output.write("  </example>\n")
152
153    return idx
154
155def dump_symbols(output):
156    global symbols
157
158    output.write("  <symbols>\n")
159    keys = symbols.keys()
160    keys.sort()
161    for symbol in keys:
162        output.write("    <symbol name='%s'>\n" % (symbol))
163	info = symbols[symbol]
164	i = 1
165	while i < len(info):
166	    output.write("      <ref filename='%s'/>\n" % (info[i]))
167	    i = i + 1
168        output.write("    </symbol>\n")
169    output.write("  </symbols>\n")
170
171if __name__ == "__main__":
172    load_api()
173    output = open("examples.xml", "w")
174    output.write("<examples>\n")
175
176    parse("example1.c", output)
177
178    dump_symbols(output)
179    output.write("</examples>\n")
180    output.close()
181
182