From c99422b0c7919e953811a3a06e18c7cacbacd7c6 Mon Sep 17 00:00:00 2001 From: Adrian Negreanu Date: Sat, 8 Feb 2014 23:45:12 +0200 Subject: sqlite3: add new searches to search.py + -I Get the includers of + -i Get the includees of + -M Get all members of class + -B Get the base classes of class + -S Get the sub classes of class Signed-off-by: Adrian Negreanu --- addon/doxypysql/search.py | 329 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 267 insertions(+), 62 deletions(-) diff --git a/addon/doxypysql/search.py b/addon/doxypysql/search.py index 353eb56..d0c88c0 100755 --- a/addon/doxypysql/search.py +++ b/addon/doxypysql/search.py @@ -12,8 +12,8 @@ import sqlite3 import sys import os -import re import getopt +import json class MemberType: Define="0" @@ -29,82 +29,210 @@ class MemberType: Property="10" Event="11" +class RequestType: + References="9901" + Struct="9902" + Includers="9903" + Includees="9904" + Members="9905" + BaseClasses="9906" + SubClasses="9907" + +g_conn=None ############################################################################### def escapeLike(val): return 'LIKE "%' + val.replace("\\", "\\\\").replace("_", "\\_") \ .replace("%", "\\%") + '%" ESCAPE "\\"' +def matchName(name): + if type(name) is str: + return "name "+escapeLike(name) + else: + return 'id=%d' %name + +def fileName(id_file): + if g_conn.execute("SELECT COUNT(*) FROM files WHERE id=?",[id_file]).fetchone()[0] > 1: + print "non-uniq fileid" + + for r in g_conn.execute("SELECT * FROM files WHERE id=?",[id_file]).fetchall(): + return r['name'] + + return "" + +def fileId(name): + if g_conn.execute("SELECT COUNT(*) FROM files WHERE name=?",[name]).fetchone()[0] > 1: + print "non-uniq file name" -def getLine(id_file,line,column): - rv="" - for r in g_conn.execute('SELECT * FROM files WHERE id=%d;' % id_file).fetchall(): - rv += "found in file %s:%d:%d" % (r['name'],line,column) - return rv + for r in g_conn.execute("SELECT * FROM files WHERE name=?",[name]).fetchall(): + return r['id'] + + return -1 ############################################################################### -def processCallers(caller, path=None, fid=None): +def findReferences(name): + o=[] + + cur = g_conn.cursor() + cur.execute("SELECT refid FROM memberdef WHERE name=?",[name]) + refids = cur.fetchall() + + if len(refids) == 0: + return o + + refid = refids[0]['refid'] cur = g_conn.cursor() - if fid is None: - cur.execute("SELECT refid FROM memberdef WHERE name='%s'" % caller) - refids = cur.fetchall() - if len(refids) == 0: - print 'No results found' - return - refid = refids[0]['refid'] - print "%s" % refid + for info in cur.execute("SELECT * FROM xrefs WHERE dst LIKE '%"+refid+"%'"): + item={} cur = g_conn.cursor() - for info in cur.execute("SELECT * FROM xrefs WHERE dst LIKE '%"+refid+"%'"): - cur = g_conn.cursor() - for i2 in cur.execute("SELECT * FROM memberdef WHERE refid='%s'" % info['src']): - print "caller:%s" % i2['name'] - for i2 in cur.execute("SELECT * FROM files WHERE id='%s'" % info['id_file']): - print "file : %s:%d" % (i2['name'],info['line']) + for i2 in cur.execute("SELECT * FROM memberdef WHERE refid=?",[info['src']]): + item['name']=i2['name'] + item['src']=info['src'] + item['file']=fileName(info['id_file']) + item['line']=info['line'] + o.append(item) + return o -def processFunction(name): - for r in g_conn.execute('SELECT * FROM memberdef WHERE name LIKE "%' - +name+'%" AND kind='+MemberType.Function+';').fetchall(): - print '==> %s %s %s' % (r['type'],r['name'],r['argsstring']) - print getLine(r['id_file'],r['line'],r['column']) +def findFunction(name): + o=[] + for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Function]).fetchall(): + item={} + item['name'] = r['name'] + item['definition'] = r['definition'] + item['argsstring'] = r['argsstring'] + item['file'] = fileName(r['id_file']) + item['line'] = r['line'] + item['detaileddescription'] = r['detaileddescription'] + o.append(item) + return o -def processMacro(name): - for r in g_conn.execute('SELECT * FROM memberdef WHERE name LIKE "%' - +name+'%" AND kind='+MemberType.Define+';').fetchall(): - mname = r['name'] + +def findMacro(name): + o=[] + for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Define]).fetchall(): + item={} + item['name'] = r['name'] if r['argsstring']: - mname += r['argsstring'] - print '%s' % (mname) - print getLine(r['id_file'],r['line'],r['column']) + item['argsstring'] = r['argsstring'] + item['definition'] = r['initializer'] + item['file'] = fileName(r['id_file']) + item['line'] = r['line'] + o.append(item) + return o + + +def findTypedef(name): + o=[] + for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Typedef]).fetchall(): + item={} + item['name'] = r['name'] + item['definition'] = r['definition'] + item['file'] = fileName(r['id_file']) + item['line'] = r['line'] + o.append(item) + return o + + +def findVariable(name): + o=[] + for r in g_conn.execute('SELECT * FROM memberdef WHERE '+matchName(name)+' AND kind=?',[MemberType.Variable]).fetchall(): + item={} + item['name'] = r['name'] + item['definition'] = r['definition'] + item['file'] = fileName(r['id_file']) + item['line'] = r['line'] + o.append(item) + return o + +def findParams(name): + o=[] + for r in g_conn.execute('SELECT id FROM memberdef WHERE '+matchName(name)).fetchall(): + #a=("SELECT * FROM params where id=(SELECT id_param FROM memberdef_params where id_memberdef=?",[id_memberdef]) + item={} + item['id'] = r['id'] + o.append(item) + return o + + +def findStruct(name): + o=[] + for r in g_conn.execute('SELECT * FROM compounddef WHERE '+matchName(name)).fetchall(): + item={} + item['name'] = r['name'] + o.append(item) + return o + +def findIncluders(name): + o=[] + fid = fileId(name) + for r in g_conn.execute('SELECT * FROM includes WHERE id_dst=?',[fid]).fetchall(): + item={} + item['name'] = fileName(r['id_src']) + o.append(item) + return o + +def findIncludees(name): + o=[] + fid = fileId(name) + for r in g_conn.execute('SELECT * FROM includes WHERE id_src=?',[fid]).fetchall(): + item={} + item['name'] = r['dst'] + o.append(item) + return o -def processType(name, path=None): - for r in g_conn.execute('SELECT * FROM memberdef WHERE name LIKE "%' - +name+'%" AND kind='+MemberType.Typedef+';').fetchall(): - print '%s' % (r['name']) - print getLine(r['id_file'],r['line'],r['column']) +def findMembers(name): + o=[] + for r in g_conn.execute('SELECT * FROM memberdef WHERE scope LIKE "%'+name+'%";').fetchall(): + item={} + item['name'] = r['name'] + item['definition'] = r['definition'] + item['argsstring'] = r['argsstring'] + item['file'] = fileName(r['id_file']) + item['line'] = r['line'] + item['documentation'] = r['documentation'] + o.append(item) + return o -def processVariable(name): - for r in g_conn.execute('SELECT * FROM memberdef WHERE name LIKE "%'+ - name + '%" AND kind='+MemberType.Variable+';').fetchall(): - print '> %s' % (r['name']) - print getLine(r['id_file'],r['line'],r['column']) +def findBaseClasses(name): + o=[] + for r in g_conn.execute('SELECT base FROM basecompoundref WHERE derived=?',[name]).fetchall(): + item={} + item['name'] = r['base'] + o.append(item) + return o + + +def findSubClasses(name): + o=[] + for r in g_conn.execute('SELECT derived FROM basecompoundref WHERE base=?',[name]).fetchall(): + item={} + item['name'] = r['derived'] + o.append(item) + return o + ############################################################################### def usage(): - print """Usage: search.py [options] + print """Usage: search.py [Options] Options: -h, --help -d Use database for queries - -c Search for callers of - -f Search for function - -m Search for macro - -t Search for type - -v Search for variable + -r Search for references to + -f Search for definition of function + -m Search for definition of macro + -t Search for definition of type + -v Search for definition of variable + -I Get the includers of + -i Get the includees of + -M Get all members of class + -B Get the base classes of class + -S Get the sub classes of class """ def openDb(dbname): @@ -121,17 +249,72 @@ def openDb(dbname): g_conn.row_factory = sqlite3.Row ############################################################################### +def process(kind,o): + request_processors = { + MemberType.Function: findFunction, + MemberType.Define: findMacro, + MemberType.Variable: findVariable, + MemberType.Typedef: findTypedef, + RequestType.References: findReferences, + RequestType.Struct: findStruct, + RequestType.Includers: findIncluders, + RequestType.Includees: findIncludees, + RequestType.Members: findMembers, + RequestType.BaseClasses: findBaseClasses, + RequestType.SubClasses: findSubClasses + } + return request_processors[kind](o) -def main(argv): +def processHref(ref): + j={} + + # is it in memberdef ? + table="memberdef" + if ( g_conn.execute("SELECT count(*) from %s WHERE refid='%s'" % (table,ref) ).fetchone()[0] > 0 ): + for r in g_conn.execute("SELECT kind,id FROM %s WHERE refid='%s'" % (table,ref) ).fetchall(): + j=process(str(r['kind']),int(r['id'])) + + # is it in compounddef ? + table="compounddef" + if ( g_conn.execute("SELECT count(*) from %s WHERE refid='%s'" % (table,ref)).fetchone()[0] > 0 ): + for r in g_conn.execute("SELECT id FROM %s WHERE refid='%s'" % (table,ref) ).fetchall(): + j=process(RequestType.Struct,int(r['id'])) + + return j + + +def serveCgi(): + import cgi + + print 'Content-Type: application/json\n' + fieldStorage = cgi.FieldStorage() + form = dict((key, fieldStorage.getvalue(key)) for key in fieldStorage.keys()) + + if 'href' in form: + ref = form['href'] + else: + print '{"result": null, "error": "no refid given"}' + sys.exit(0) + + openDb('doxygen_sqlite3.db') + + j = processHref(ref) + + print json.dumps({"result":j,"error":None}) + + +def serveCli(argv): try: - opts, args = getopt.getopt(argv, "hc:d:f:m:t:v:",["help"]) + opts, args = getopt.getopt(argv, "hr:I:i:d:f:m:t:v:H:M:B:S:",["help"]) except getopt.GetoptError: usage() sys.exit(1) + ref=None dbname=None + j={} for a, o in opts: if a in ('-h', '--help'): @@ -139,21 +322,43 @@ def main(argv): sys.exit(0) elif a in ('-d'): dbname=o - elif a in ('-c'): - openDb(dbname) - processCallers(o) + continue + elif a in ('-r'): + kind=RequestType.References + elif a in ('-I'): + kind=RequestType.Includers + elif a in ('-i'): + kind=RequestType.Includees + elif a in ('-M'): + kind=RequestType.Members + elif a in ('-B'): + kind=RequestType.BaseClasses + elif a in ('-S'): + kind=RequestType.SubClasses elif a in ('-f'): - openDb(dbname) - processFunction(o) + kind=MemberType.Function elif a in ('-m'): - openDb(dbname) - processMacro(o) + kind=MemberType.Define elif a in ('-t'): - openDb(dbname) - processType(o) + kind=MemberType.Typedef elif a in ('-v'): - openDb(dbname) - processVariable(o) + kind=MemberType.Variable + elif a in ('-H'): + ref = o + + openDb(dbname) + if ref != None: + j=processHref(ref) + else: + j=process(kind,o) + print json.dumps(j) + + +def main(argv): + if 'REQUEST_METHOD' in os.environ: + serveCgi() + else: + serveCli(argv) if __name__ == '__main__': main(sys.argv[1:]) -- cgit v0.12