Synopsis - Cross-Reference
File: Synopsis/SXRServer.py1# 2# Copyright (C) 2006 Stefan Seefeld 3# All rights reserved. 4# Licensed to the public under the terms of the GNU LGPL (>= 2), 5# see the file COPYING for details. 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] # strip of trailing '.html' 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 # Check for exact match 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 # Search for last part of name in index 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 Tue May 13 02:39:09 2008 by
synopsis (version 0.10)
synopsis (version 0.10)