3 # python script to search through doxygen_sqlite3.db
5 # Permission to use, copy, modify, and distribute this software and its
6 # documentation under the terms of the GNU General Public License is hereby
7 # granted. No representations are made about the suitability of this software
8 # for any purpose. It is provided "as is" without express or implied warranty.
9 # See the GNU General Public License for more details.
44 ###############################################################################
46 # case-insensitive sqlite regexp function
47 def re_fn(expr, item):
48 reg = re.compile(expr, re.I)
49 return reg.search(item) is not None
53 dbname = "doxygen_sqlite3.db"
55 if not os.path.isfile(dbname):
56 raise BaseException("No such file %s" % dbname )
58 conn = sqlite3.connect(dbname)
59 conn.execute('PRAGMA temp_store = MEMORY;')
60 conn.row_factory = sqlite3.Row
61 conn.create_function("REGEXP", 2, re_fn)
63 ###############################################################################
65 def __init__(self,cn,name,row_type=str):
68 self.row_type=row_type
71 if self.row_type is int:
74 if g_use_regexp == True:
75 return " REGEXP (?,%s)" %row
79 def fileName(self,id_file):
80 if self.cn.execute("SELECT COUNT(*) FROM files WHERE rowid=?",[id_file]).fetchone()[0] > 1:
81 print >>sys.stderr,"WARNING: non-uniq fileid [%s]. Considering only the first match." % id_file
83 for r in self.cn.execute("SELECT * FROM files WHERE rowid=?",[id_file]).fetchall():
88 def fileId(self,name):
89 if self.cn.execute("SELECT COUNT(*) FROM files WHERE"+self.match("name"),[name]).fetchone()[0] > 1:
90 print >>sys.stderr,"WARNING: non-uniq file name [%s]. Considering only the first match." % name
92 for r in self.cn.execute("SELECT rowid FROM files WHERE"+self.match("name"),[name]).fetchall():
96 ###############################################################################
99 cur = self.cn.cursor()
100 cur.execute("SELECT refid FROM memberdef WHERE"+self.match("name"),[self.name])
101 refids = cur.fetchall()
106 refid = refids[0]['refid']
107 cur = self.cn.cursor()
108 #TODO:SELECT rowid from refids where refid=refid
109 for info in cur.execute("SELECT * FROM xrefs WHERE refid_dst LIKE '%"+refid+"%'"):
111 cur = self.cn.cursor()
112 for i2 in cur.execute("SELECT * FROM memberdef WHERE refid=?",[info['src']]):
113 item['name']=i2['name']
114 item['src']=info['src']
115 item['file']=self.fileName(info['id_file'])
116 item['line']=info['line']
120 ###############################################################################
123 c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Function])
124 for r in c.fetchall():
126 item['name'] = r['name']
127 item['definition'] = r['definition']
128 item['argsstring'] = r['argsstring']
129 item['file'] = self.fileName(r['id_file'])
130 item['line'] = r['line']
131 item['detaileddescription'] = r['detaileddescription']
134 ###############################################################################
137 for r in self.cn.execute("SELECT rowid,* FROM files WHERE"+self.match("name"),[self.name]).fetchall():
139 item['name'] = r['name']
140 item['id'] = r['rowid']
144 ###############################################################################
147 c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Define])
148 for r in c.fetchall():
150 item['name'] = r['name']
152 item['argsstring'] = r['argsstring']
153 item['definition'] = r['initializer']
154 item['file'] = self.fileName(r['id_file'])
155 item['line'] = r['line']
158 ###############################################################################
161 c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Typedef])
162 for r in c.fetchall():
164 item['name'] = r['name']
165 item['definition'] = r['definition']
166 item['file'] = self.fileName(r['id_file'])
167 item['line'] = r['line']
170 ###############################################################################
173 c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Variable])
174 for r in c.fetchall():
176 item['name'] = r['name']
177 item['definition'] = r['definition']
178 item['file'] = self.fileName(r['id_file'])
179 item['line'] = r['line']
182 ###############################################################################
185 c=self.cn.execute('SELECT id FROM memberdef WHERE'+self.match("name"),[self.name])
186 for r in c.fetchall():
187 #a=("SELECT * FROM params where id=(SELECT id_param FROM memberdef_params where id_memberdef=?",[id_memberdef])
192 ###############################################################################
195 c=self.cn.execute('SELECT * FROM compounddef WHERE'+self.match("name"),[self.name])
196 for r in c.fetchall():
198 item['name'] = r['name']
201 ###############################################################################
204 fid = self.fileId(self.name)
205 c=self.cn.execute('SELECT * FROM includes WHERE id_dst=?',[fid])
206 for r in c.fetchall():
208 item['name'] = self.fileName(r['id_src'])
211 ###############################################################################
214 fid = self.fileId(self.name)
215 c=self.cn.execute('SELECT * FROM includes WHERE id_src=?',[fid])
216 for r in c.fetchall():
218 item['name'] = self.fileName(r['id_dst'])
221 ###############################################################################
224 c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("scope"),[self.name])
225 for r in c.fetchall():
227 item['name'] = r['name']
228 item['definition'] = r['definition']
229 item['argsstring'] = r['argsstring']
230 item['file'] = self.fileName(r['id_file'])
231 item['line'] = r['line']
232 #item['documentation'] = r['documentation']
235 ###############################################################################
236 def baseClasses(self):
238 c=self.cn.execute('SELECT base FROM basecompoundref WHERE'+self.match("derived"),[self.name])
239 for r in c.fetchall():
241 item['name'] = r['base']
244 ###############################################################################
245 def subClasses(self):
247 c=self.cn.execute('SELECT derived FROM basecompoundref WHERE'+self.match("base"),[self.name])
248 for r in c.fetchall():
250 item['name'] = r['derived']
253 ###############################################################################
255 request_processors = {
256 MemberType.Function: f.function,
257 MemberType.File: f.file,
258 MemberType.Define: f.macro,
259 MemberType.Variable: f.variable,
260 MemberType.Typedef: f.typedef,
261 RequestType.References: f.references,
262 RequestType.Struct: f.struct,
263 RequestType.Includers: f.includers,
264 RequestType.Includees: f.includees,
265 RequestType.Members: f.members,
266 RequestType.BaseClasses: f.baseClasses,
267 RequestType.SubClasses: f.subClasses
269 return request_processors[kind]()
270 ###############################################################################
271 def processHref(cn,ref):
274 # is it in memberdef ?
276 if ( cn.execute("SELECT count(*) from %s WHERE refid=?"%table,[ref] ).fetchone()[0] > 0 ):
277 for r in cn.execute("SELECT kind,id FROM %s WHERE refid='%s'" % (table,ref) ).fetchall():
278 f=Finder(cn,r['id'],int)
279 j=process(f,str(r['kind']))
281 # is it in compounddef ?
283 if ( cn.execute("SELECT count(*) from %s WHERE refid=?"%table,[ref]).fetchone()[0] > 0 ):
284 for r in cn.execute("SELECT id FROM %s WHERE refid=?"%table,[ref] ).fetchall():
285 f=Finder(cn,r['id'],int)
286 j=process(f,RequestType.Struct)
289 ###############################################################################
293 print 'Content-Type: application/json\n'
295 fieldStorage = cgi.FieldStorage()
296 form = dict((key, fieldStorage.getvalue(key)) for key in fieldStorage.keys())
301 print '{"result": null, "error": "no refid given"}'
304 cn=openDb('doxygen_sqlite3.db')
306 j = processHref(cn,ref)
308 print json.dumps({"result":j,"error":None})
309 ###############################################################################
311 print >>sys.stderr,"""Usage: search.py [Options]
314 -d <D> Use database <D> for queries.
315 -f <F> Search for definition of function <F>.
316 -m <M> Search for definition of macro <M>.
317 -r <F> Search for references to function <F>.
318 -t <T> Search for definition of type <T>.
319 -v <V> Search for definition of variable <V>.
320 -I <I> What files are including <I>.
321 -i <i> What files are included by <i>.
322 -B <C> Get the base classes of class <C>.
323 -M <C> Get all members of class <C>.
324 -S <C> Get the sub classes of class <C>.
325 -R Consider the search <term> to be a regex.
327 ###############################################################################
330 opts, args = getopt.getopt(argv, "hr:RI:i:d:f:m:t:v:H:M:B:S:F:",["help"])
331 except getopt.GetoptError:
341 if a in ('-h', '--help'):
348 kind=RequestType.References
353 kind=RequestType.Includers
355 kind=RequestType.Includees
357 kind=RequestType.Members
359 kind=RequestType.BaseClasses
361 kind=RequestType.SubClasses
363 kind=MemberType.Function
367 kind=MemberType.Define
369 kind=MemberType.Typedef
371 kind=MemberType.Variable
378 j=processHref(cn,ref)
381 print json.dumps(j,indent=4)
385 if 'REQUEST_METHOD' in os.environ:
390 if __name__ == '__main__':