Blame addon/doxypysql/search.py

Packit 1c1d7e
#!/usr/bin/python
Packit 1c1d7e
Packit 1c1d7e
# python script to search through doxygen_sqlite3.db
Packit 1c1d7e
#
Packit 1c1d7e
# Permission to use, copy, modify, and distribute this software and its
Packit 1c1d7e
# documentation under the terms of the GNU General Public License is hereby
Packit 1c1d7e
# granted. No representations are made about the suitability of this software
Packit 1c1d7e
# for any purpose. It is provided "as is" without express or implied warranty.
Packit 1c1d7e
# See the GNU General Public License for more details.
Packit 1c1d7e
#
Packit 1c1d7e
Packit 1c1d7e
import sqlite3
Packit 1c1d7e
import sys
Packit 1c1d7e
import os
Packit 1c1d7e
import getopt
Packit 1c1d7e
import json
Packit 1c1d7e
import re
Packit 1c1d7e
Packit 1c1d7e
class MemberType:
Packit 1c1d7e
  Define="0"
Packit 1c1d7e
  Function="1"
Packit 1c1d7e
  Variable="2"
Packit 1c1d7e
  Typedef="3"
Packit 1c1d7e
  Enumeration="4"
Packit 1c1d7e
  EnumValue="5"
Packit 1c1d7e
  Signal="6"
Packit 1c1d7e
  Slot="7"
Packit 1c1d7e
  Friend="8"
Packit 1c1d7e
  DCOP="9"
Packit 1c1d7e
  Property="10"
Packit 1c1d7e
  Event="11"
Packit 1c1d7e
  File="12"
Packit 1c1d7e
Packit 1c1d7e
class RequestType:
Packit 1c1d7e
  References="9901"
Packit 1c1d7e
  Struct="9902"
Packit 1c1d7e
  Includers="9903"
Packit 1c1d7e
  Includees="9904"
Packit 1c1d7e
  Members="9905"
Packit 1c1d7e
  BaseClasses="9906"
Packit 1c1d7e
  SubClasses="9907"
Packit 1c1d7e
Packit 1c1d7e
g_use_regexp=False
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
Packit 1c1d7e
# case-insensitive sqlite regexp function
Packit 1c1d7e
def re_fn(expr, item):
Packit 1c1d7e
    reg = re.compile(expr, re.I)
Packit 1c1d7e
    return reg.search(item) is not None
Packit 1c1d7e
Packit 1c1d7e
def openDb(dbname):
Packit 1c1d7e
    if dbname == None:
Packit 1c1d7e
        dbname = "doxygen_sqlite3.db"
Packit 1c1d7e
Packit 1c1d7e
    if not os.path.isfile(dbname):
Packit 1c1d7e
        raise BaseException("No such file %s" % dbname )
Packit 1c1d7e
Packit 1c1d7e
    conn = sqlite3.connect(dbname)
Packit 1c1d7e
    conn.execute('PRAGMA temp_store = MEMORY;')
Packit 1c1d7e
    conn.row_factory = sqlite3.Row
Packit 1c1d7e
    conn.create_function("REGEXP", 2, re_fn)
Packit 1c1d7e
    return conn
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
class Finder:
Packit 1c1d7e
    def __init__(self,cn,name,row_type=str):
Packit 1c1d7e
        self.cn=cn
Packit 1c1d7e
        self.name=name
Packit 1c1d7e
        self.row_type=row_type
Packit 1c1d7e
Packit 1c1d7e
    def match(self,row):
Packit 1c1d7e
        if self.row_type is int:
Packit 1c1d7e
            return " id=?"
Packit 1c1d7e
        else:
Packit 1c1d7e
            if g_use_regexp == True:
Packit 1c1d7e
                return " REGEXP (?,%s)" %row
Packit 1c1d7e
            else:
Packit 1c1d7e
                return " %s=?" %row
Packit 1c1d7e
Packit 1c1d7e
    def fileName(self,id_file):
Packit 1c1d7e
        if self.cn.execute("SELECT COUNT(*) FROM files WHERE rowid=?",[id_file]).fetchone()[0] > 1:
Packit 1c1d7e
            print >>sys.stderr,"WARNING: non-uniq fileid [%s]. Considering only the first match." % id_file
Packit 1c1d7e
Packit 1c1d7e
        for r in self.cn.execute("SELECT * FROM files WHERE rowid=?",[id_file]).fetchall():
Packit 1c1d7e
                return r['name']
Packit 1c1d7e
Packit 1c1d7e
        return ""
Packit 1c1d7e
Packit 1c1d7e
    def fileId(self,name):
Packit 1c1d7e
        if self.cn.execute("SELECT COUNT(*) FROM files WHERE"+self.match("name"),[name]).fetchone()[0] > 1:
Packit 1c1d7e
            print >>sys.stderr,"WARNING: non-uniq file name [%s]. Considering only the first match." % name
Packit 1c1d7e
Packit 1c1d7e
        for r in self.cn.execute("SELECT rowid FROM files WHERE"+self.match("name"),[name]).fetchall():
Packit 1c1d7e
                return r[0]
Packit 1c1d7e
Packit 1c1d7e
        return -1
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def references(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        cur = self.cn.cursor()
Packit 1c1d7e
        cur.execute("SELECT refid FROM memberdef WHERE"+self.match("name"),[self.name])
Packit 1c1d7e
        refids = cur.fetchall()
Packit 1c1d7e
Packit 1c1d7e
        if len(refids) == 0:
Packit 1c1d7e
            return o
Packit 1c1d7e
Packit 1c1d7e
        refid = refids[0]['refid']
Packit 1c1d7e
        cur = self.cn.cursor()
Packit 1c1d7e
        #TODO:SELECT rowid from refids where refid=refid
Packit 1c1d7e
        for info in cur.execute("SELECT * FROM xrefs WHERE refid_dst LIKE '%"+refid+"%'"):
Packit 1c1d7e
            item={}
Packit 1c1d7e
            cur = self.cn.cursor()
Packit 1c1d7e
            for i2 in cur.execute("SELECT * FROM memberdef WHERE refid=?",[info['src']]):
Packit 1c1d7e
                item['name']=i2['name']
Packit 1c1d7e
                item['src']=info['src']
Packit 1c1d7e
                item['file']=self.fileName(info['id_file'])
Packit 1c1d7e
                item['line']=info['line']
Packit 1c1d7e
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def function(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Function])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['name']
Packit 1c1d7e
            item['definition'] = r['definition']
Packit 1c1d7e
            item['argsstring'] = r['argsstring']
Packit 1c1d7e
            item['file'] = self.fileName(r['id_file'])
Packit 1c1d7e
            item['line'] = r['line']
Packit 1c1d7e
            item['detaileddescription'] = r['detaileddescription']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def file(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        for r in self.cn.execute("SELECT rowid,* FROM files WHERE"+self.match("name"),[self.name]).fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['name']
Packit 1c1d7e
            item['id'] =   r['rowid']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def macro(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Define])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['name']
Packit 1c1d7e
            if r['argsstring']:
Packit 1c1d7e
                item['argsstring'] = r['argsstring']
Packit 1c1d7e
            item['definition'] = r['initializer']
Packit 1c1d7e
            item['file'] = self.fileName(r['id_file'])
Packit 1c1d7e
            item['line'] = r['line']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def typedef(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Typedef])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['name']
Packit 1c1d7e
            item['definition'] = r['definition']
Packit 1c1d7e
            item['file'] = self.fileName(r['id_file'])
Packit 1c1d7e
            item['line'] = r['line']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def variable(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("name")+' AND kind=?',[self.name,MemberType.Variable])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['name']
Packit 1c1d7e
            item['definition'] = r['definition']
Packit 1c1d7e
            item['file'] = self.fileName(r['id_file'])
Packit 1c1d7e
            item['line'] = r['line']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def params(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT id FROM memberdef WHERE'+self.match("name"),[self.name])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            #a=("SELECT * FROM params where id=(SELECT id_param FROM memberdef_params where id_memberdef=?",[id_memberdef])
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['id'] = r['id']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def struct(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM compounddef WHERE'+self.match("name"),[self.name])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['name']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def includers(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        fid = self.fileId(self.name)
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM includes WHERE id_dst=?',[fid])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = self.fileName(r['id_src'])
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def includees(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        fid = self.fileId(self.name)
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM includes WHERE id_src=?',[fid])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = self.fileName(r['id_dst'])
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def members(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT * FROM memberdef WHERE'+self.match("scope"),[self.name])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['name']
Packit 1c1d7e
            item['definition'] = r['definition']
Packit 1c1d7e
            item['argsstring'] = r['argsstring']
Packit 1c1d7e
            item['file'] = self.fileName(r['id_file'])
Packit 1c1d7e
            item['line'] = r['line']
Packit 1c1d7e
            #item['documentation'] = r['documentation']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def baseClasses(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT base FROM basecompoundref WHERE'+self.match("derived"),[self.name])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['base']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
    def subClasses(self):
Packit 1c1d7e
        o=[]
Packit 1c1d7e
        c=self.cn.execute('SELECT derived FROM basecompoundref WHERE'+self.match("base"),[self.name])
Packit 1c1d7e
        for r in c.fetchall():
Packit 1c1d7e
            item={}
Packit 1c1d7e
            item['name'] = r['derived']
Packit 1c1d7e
            o.append(item)
Packit 1c1d7e
        return o
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
def process(f,kind):
Packit 1c1d7e
    request_processors = {
Packit 1c1d7e
        MemberType.Function: f.function,
Packit 1c1d7e
        MemberType.File: f.file,
Packit 1c1d7e
        MemberType.Define:   f.macro,
Packit 1c1d7e
        MemberType.Variable: f.variable,
Packit 1c1d7e
        MemberType.Typedef:  f.typedef,
Packit 1c1d7e
        RequestType.References: f.references,
Packit 1c1d7e
        RequestType.Struct: f.struct,
Packit 1c1d7e
        RequestType.Includers: f.includers,
Packit 1c1d7e
        RequestType.Includees: f.includees,
Packit 1c1d7e
        RequestType.Members: f.members,
Packit 1c1d7e
        RequestType.BaseClasses: f.baseClasses,
Packit 1c1d7e
        RequestType.SubClasses: f.subClasses
Packit 1c1d7e
    }
Packit 1c1d7e
    return request_processors[kind]()
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
def processHref(cn,ref):
Packit 1c1d7e
    j={}
Packit 1c1d7e
Packit 1c1d7e
    # is it in memberdef ?
Packit 1c1d7e
    table="memberdef"
Packit 1c1d7e
    if ( cn.execute("SELECT count(*) from %s WHERE refid=?"%table,[ref] ).fetchone()[0] > 0 ):
Packit 1c1d7e
        for r in cn.execute("SELECT kind,id FROM %s WHERE refid='%s'" % (table,ref) ).fetchall():
Packit 1c1d7e
            f=Finder(cn,r['id'],int)
Packit 1c1d7e
            j=process(f,str(r['kind']))
Packit 1c1d7e
Packit 1c1d7e
    # is it in compounddef ?
Packit 1c1d7e
    table="compounddef"
Packit 1c1d7e
    if ( cn.execute("SELECT count(*) from %s WHERE refid=?"%table,[ref]).fetchone()[0] > 0 ):
Packit 1c1d7e
        for r in cn.execute("SELECT id FROM %s WHERE refid=?"%table,[ref] ).fetchall():
Packit 1c1d7e
            f=Finder(cn,r['id'],int)
Packit 1c1d7e
            j=process(f,RequestType.Struct)
Packit 1c1d7e
Packit 1c1d7e
    return j
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
def serveCgi():
Packit 1c1d7e
    import cgi
Packit 1c1d7e
Packit 1c1d7e
    print 'Content-Type: application/json\n'
Packit 1c1d7e
Packit 1c1d7e
    fieldStorage = cgi.FieldStorage()
Packit 1c1d7e
    form = dict((key, fieldStorage.getvalue(key)) for key in fieldStorage.keys())
Packit 1c1d7e
Packit 1c1d7e
    if 'href' in form:
Packit 1c1d7e
        ref = form['href']
Packit 1c1d7e
    else:
Packit 1c1d7e
        print '{"result": null, "error": "no refid given"}'
Packit 1c1d7e
        sys.exit(0)
Packit 1c1d7e
Packit 1c1d7e
    cn=openDb('doxygen_sqlite3.db')
Packit 1c1d7e
Packit 1c1d7e
    j = processHref(cn,ref)
Packit 1c1d7e
Packit 1c1d7e
    print json.dumps({"result":j,"error":None})
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
def usage():
Packit 1c1d7e
  print >>sys.stderr,"""Usage: search.py [Options]
Packit 1c1d7e
Options:
Packit 1c1d7e
    -h, --help
Packit 1c1d7e
    -d <D>    Use database <D> for queries.
Packit 1c1d7e
    -f <F>    Search for definition of function <F>.
Packit 1c1d7e
    -m <M>    Search for definition of macro <M>.
Packit 1c1d7e
    -r <F>    Search for references to function <F>.
Packit 1c1d7e
    -t <T>    Search for definition of type <T>.
Packit 1c1d7e
    -v <V>    Search for definition of variable <V>.
Packit 1c1d7e
    -I     What files are including .
Packit 1c1d7e
    -i     What files are included by .
Packit 1c1d7e
    -B <C>    Get the base classes of class <C>.
Packit 1c1d7e
    -M <C>    Get all members of class <C>.
Packit 1c1d7e
    -S <C>    Get the sub classes of class <C>.
Packit 1c1d7e
    -R        Consider the search <term> to be a regex.
Packit 1c1d7e
"""
Packit 1c1d7e
###############################################################################
Packit 1c1d7e
def serveCli(argv):
Packit 1c1d7e
    try:
Packit 1c1d7e
        opts, args = getopt.getopt(argv, "hr:RI:i:d:f:m:t:v:H:M:B:S:F:",["help"])
Packit 1c1d7e
    except getopt.GetoptError:
Packit 1c1d7e
        usage()
Packit 1c1d7e
        sys.exit(1)
Packit 1c1d7e
Packit 1c1d7e
    ref=None
Packit 1c1d7e
    dbname=None
Packit 1c1d7e
    j={}
Packit 1c1d7e
    global g_use_regexp
Packit 1c1d7e
Packit 1c1d7e
    for a, o in opts:
Packit 1c1d7e
        if a in ('-h', '--help'):
Packit 1c1d7e
            usage()
Packit 1c1d7e
            sys.exit(0)
Packit 1c1d7e
        elif a in ('-d'):
Packit 1c1d7e
            dbname=o
Packit 1c1d7e
            continue
Packit 1c1d7e
        elif a in ('-r'):
Packit 1c1d7e
            kind=RequestType.References
Packit 1c1d7e
        elif a in ('-R'):
Packit 1c1d7e
            g_use_regexp=True
Packit 1c1d7e
            continue
Packit 1c1d7e
        elif a in ('-I'):
Packit 1c1d7e
            kind=RequestType.Includers
Packit 1c1d7e
        elif a in ('-i'):
Packit 1c1d7e
            kind=RequestType.Includees
Packit 1c1d7e
        elif a in ('-M'):
Packit 1c1d7e
            kind=RequestType.Members
Packit 1c1d7e
        elif a in ('-B'):
Packit 1c1d7e
            kind=RequestType.BaseClasses
Packit 1c1d7e
        elif a in ('-S'):
Packit 1c1d7e
            kind=RequestType.SubClasses
Packit 1c1d7e
        elif a in ('-f'):
Packit 1c1d7e
            kind=MemberType.Function
Packit 1c1d7e
        elif a in ('-F'):
Packit 1c1d7e
            kind=MemberType.File
Packit 1c1d7e
        elif a in ('-m'):
Packit 1c1d7e
            kind=MemberType.Define
Packit 1c1d7e
        elif a in ('-t'):
Packit 1c1d7e
            kind=MemberType.Typedef
Packit 1c1d7e
        elif a in ('-v'):
Packit 1c1d7e
            kind=MemberType.Variable
Packit 1c1d7e
        elif a in ('-H'):
Packit 1c1d7e
            ref = o
Packit 1c1d7e
Packit 1c1d7e
        cn=openDb(dbname)
Packit 1c1d7e
        f=Finder(cn,o)
Packit 1c1d7e
        if ref != None:
Packit 1c1d7e
          j=processHref(cn,ref)
Packit 1c1d7e
        else:
Packit 1c1d7e
          j=process(f,kind)
Packit 1c1d7e
        print json.dumps(j,indent=4)
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
def main(argv):
Packit 1c1d7e
    if 'REQUEST_METHOD' in os.environ:
Packit 1c1d7e
        serveCgi()
Packit 1c1d7e
    else:
Packit 1c1d7e
        serveCli(argv)
Packit 1c1d7e
Packit 1c1d7e
if __name__ == '__main__':
Packit 1c1d7e
    main(sys.argv[1:])