File: Synopsis/SXRServer.py 1
2
3
4
5
6
7
8from Synopsis import IR
9import os, fnmatch
10
11def escape(text):
12 """escape special characters ('&', '\"', '<', '>')"""
13
14 text = text.replace('&', '&')
15 text = text.replace('"', '"')
16 text = text.replace('<', '<')
17 text = text.replace('>', '>')
18 return text
19
20default_template = """
21<html>
22 <head><title>Synopsis Cross-Reference</title></head>
23 <body>
24 <h1>Synopsis Cross-Reference</h1>
25 @CONTENT@
26 </body>
27</html>
28"""
29
30file_search_form = """
31<table class=\"form\">
32 <tr>
33 <td>Enter a file name to search:</td>
34 <td>
35 <form method=\"get\" action=\"%(script)s/file\">
36 <input type="text" name="string" value="" size="15"/>
37 <input type="submit" value="Find"/>
38 </form>
39 </td>
40 </tr>
41</table>
42"""
43
44ident_search_form = """
45<table class=\"form\">
46 <tr>
47 <td>Enter a variable, type, or function name to search:</td>
48 <td>
49 <form method=\"get\" action=\"%(script)s/ident\">
50 <input type="text" name="string" value="" size="15"/>
51 <input type="submit" value="Find"/>
52 </form>
53 </td>
54 </tr>
55</table>
56"""
57
58class SXRServer:
59
60 def __init__(self, root, cgi_url, src_url,
61 template_file = None,
62 sxr_prefix='/sxr'):
63
64 self.cgi_url = cgi_url
65 self.src_url = src_url
66 self.src_dir = os.path.join(root, 'Source')
67 ir = IR.load(os.path.join(root, 'sxr.syn'))
68 self.data = ir.sxr
69 self.index = ir.sxr.index()
70
71 if template_file:
72 template = open(template_file).read()
73 else:
74 template = default_template
75 self.template = template.split("@CONTENT@")
76
77
78 def ident_ref(self, file, line, scope):
79
80 if len(scope):
81 text = '::'.join(scope)
82 else:
83 text = '<global scope>'
84 return '<a href=\"%s/Source/%s.html#%s\">%s:%s: %s</a>'%(self.src_url, file, line, file, line, escape(text))
85
86
87 def file_ref(self, file, name = None):
88
89 if not name: name = file
90 name = name[:-5]
91 return "<a href=\"%s/Source/%s\">%s</a>"%(self.src_url, file, name)
92
93
94 def list_refs(self, data, name):
95
96 html = ''
97 if not data.has_key(name): return '\n'
98 html += '<h3>%s</h3>\n'%escape('::'.join(name))
99 entry = data[name]
100 if entry.definitions:
101 html += '<li>Defined at:<br/>\n'
102 html += '<ul>\n'
103 for file, line, scope in entry.definitions:
104 html += '<li>%s</li>\n'%(self.ident_ref(file, line, scope))
105 html += '</ul></li>\n'
106 if entry.calls:
107 html += '<li>Called from:<br/>\n'
108 html += '<ul>\n'
109 for file, line, scope in entry.calls:
110 html += '<li>%s</li>\n'%(self.ident_ref(file, line, scope))
111 html += '</ul></li>\n'
112 if entry.references:
113 html += '<li>Referenced from:<br/>\n'
114 html += '<ul>\n'
115 for file, line, scope in entry.references:
116 html += '<li>%s</li>\n'%(self.ident_ref(file, line, scope))
117 html += '</ul></li>\n'
118 return html
119
120
121 def search_file(self, pattern):
122 """Generate a file search listing."""
123
124 html = self.template[0]
125 html += file_search_form%{'script': self.cgi_url}
126
127 base_path_len = len(self.src_dir)
128 def find(result, base, files):
129
130 result.extend([os.path.join(base[base_path_len + 1:], file)
131 for file in files
132 if os.path.isfile(os.path.join(base, file)) and
133 fnmatch.fnmatch(os.path.splitext(file)[0], pattern)])
134
135 result = []
136 os.path.walk(self.src_dir, find, result)
137 if result:
138 html += '<ul>\n'
139 for f in result:
140 html += '<li>%s</li>\n'%(self.file_ref(f.strip()))
141 html += '</ul>\n'
142 html += self.template[1]
143
144 return html
145
146
147 def search_ident(self, name, qualified = False):
148 """Generate an identifier listing."""
149
150 html = self.template[0]
151 html += ident_search_form%{'script' : self.cgi_url}
152
153 if qualified:
154 if '::' in name:
155 name = tuple(name.split('::'))
156 else:
157 name = tuple(name.split('.'))
158 found = False
159
160 if self.data.has_key(name):
161 html += 'Found exact match:<br/>\n'
162 html += self.list_refs(self.data, name)
163 found = True
164
165 if self.index.has_key(name[-1]):
166 matches = self.index[name[-1]]
167 html += 'Found (%d) possible matches:<br/>\n'%(len(matches))
168 html += '<ul>\n'
169 for name in matches:
170 html += self.list_refs(self.data, name)
171 html += '</ul>\n'
172 found = True
173 if not found:
174 html += "No matches found<br/>\n"
175
176 elif self.index.has_key(name):
177 matches = self.index[name]
178 html += 'Found (%d) possible matches:<br/>\n'%(len(matches))
179 html += '<ul>\n'
180 for name in matches:
181 html += self.list_refs(self.data, name)
182 html += '</ul>\n'
183 else:
184 html += 'No matches found<br/>\n'
185 html += self.template[1]
186
187 return html
188
Generated on Thu Apr 16 16:27:12 2009 by
synopsis (version devel)