def post(self): parser = reqparse.RequestParser() parser.add_argument('verbose', type=bool) parser.add_argument('tag') parser.add_argument('ignorecase', type=bool) parser.add_argument('rex') args = parser.parse_args() db = g_ctx.obj['db'] if args['tag']: db.set_tag(args['tag']) if args['verbose']: keys = ('cls', 'tag', 'src', 'use') flg = re.MULTILINE if args['ignorecase']: flg |= re.IGNORECASE rex = args['rex'] Q = (where('id').matches(rex, flags=flg)) Q |= (where('val').matches(rex, flags=flg)) L = [] for l in db.search(Q): d = {'id': l['id'], 'val': l['val']} if args['verbose']: for k in keys: d[k] = l[k] L.append(d) return L
def search(ctx, ignorecase, rex): """Search for documents in the remote database (or the local database if no remote is found) with either name or definition matching the provided regular expression. """ db = ctx.obj['db'] flg = re.MULTILINE if ignorecase: flg |= re.IGNORECASE try: cx = re.compile(rex, flags=flg) except re.error as err: click.secho(f'bad regular expression: {err=}', fg='red') return None look = (lambda v: cx.search(str(v))) Q = (where('id').matches(rex, flags=flg)) if db.rdb: Q |= (where('val').matches(rex, flags=flg)) else: Q |= (where('val').test(look)) L = db.search(Q) for l in L: click.echo('found ', nl=False) click.secho('%s ' % l['cls'], nl=False, fg='cyan') click.echo('identifer ', nl=False) click.secho('"%s"' % l['id'], nl=False, fg='magenta') if look(l['val']): click.echo(' with matching value', nl=False) click.echo('') return L
def post(self): parser = reqparse.RequestParser() parser.add_argument("verbose", type=bool) parser.add_argument("tag") parser.add_argument("ignorecase", type=bool) parser.add_argument("rex") args = parser.parse_args() db = g_ctx.obj["db"] if args["tag"]: db.set_tag(args["tag"]) if args["verbose"]: keys = ("cls", "tag", "src", "use") flg = re.MULTILINE if args["ignorecase"]: flg |= re.IGNORECASE rex = args["rex"] Q = where("id").matches(rex, flags=flg) Q |= where("val").matches(rex, flags=flg) L = [] for l in db.search(Q): d = {"id": l["id"], "val": l["val"]} if args["verbose"]: for k in keys: d[k] = l[k] L.append(d) return L
def select(ctx, ands, ors): """Get document(s) from the remote database (or the local database if no remote is found) matching multiple constraints. """ Q = Query().noop() try: for x in ands: k, v = x.split('=') Q &= (where(k).search(v)) for x in ors: k, v = x.split('=') Q |= (where(k).search(v)) except Exception: click.secho('invalid options (ignored)', fg='yellow', err=True) ctx.obj['select'] = Q if ctx.invoked_subcommand is None: db = ctx.obj['db'] L = db.search(Q) for l in L: click.echo('found ', nl=False) click.secho('%s ' % l['cls'], nl=False, fg='cyan') click.echo('identifer ', nl=False) click.secho('"%s"' % l['id'], fg='magenta') else: if conf.DEBUG: click.echo('FIND_COMMAND: %s' % ctx.invoked_subcommand)
class Select_Prototype(Resource): def get(self): return { "verbose": False, "tag": "", "key": "", "match": "", "format": "C", "proto": "", } def post(self): parser = reqparse.RequestParser() parser.add_argument("verbose", type=bool) parser.add_argument("tag") parser.add_argument("key") parser.add_argument("match") parser.add_argument("proto") parser.add_argument("format") args = parser.parse_args() db = g_ctx.obj["db"] if args["tag"]: db.set_tag(args["tag"]) if verbose := args["verbose"]: keys = ("src", "tag") if args["key"] and args["match"]: Q = where(args["key"]).matches(args["match"]) else: Q = Query().noop() proto = args["proto"].split(";") fmt = args.get("format", "C") reqs = {} try: for p in proto: pos, t = p.split(":") pos = int(pos) reqs[pos] = c_type(t).show() except Exception: return abort(400, reason="bad prototype request") L = [] for l in db.search(Q & (where("cls") == "cFunc")): x = ccore.from_db(l) P = [c_type(t).show() for t in x.argtypes()] P.insert(0, c_type(x.restype()).show()) if max(reqs) >= len(P): continue if not all(((t == P[i]) for (i, t) in reqs.items())): continue d = {"id": l["id"], "val": x.show(db, form=fmt)} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
class Select_Prototype(Resource): def get(self): return { 'verbose': False, 'tag': '', 'key': '', 'match': '', 'format': 'C', 'proto': '' } def post(self): parser = reqparse.RequestParser() parser.add_argument('verbose', type=bool) parser.add_argument('tag') parser.add_argument('key') parser.add_argument('match') parser.add_argument('proto') parser.add_argument('format') args = parser.parse_args() db = g_ctx.obj['db'] if args['tag']: db.set_tag(args['tag']) if verbose := args['verbose']: keys = ('src', 'tag') if args['key'] and args['match']: Q = where(args['key']).matches(args['match']) else: Q = Query() proto = args['proto'].split(';') fmt = args.get('format', 'C') reqs = {} try: for p in proto: pos, t = p.split(':') pos = int(pos) reqs[pos] = c_type(t).show() except Exception: return abort(400, reason="bad prototype request") L = [] for l in db.search(Q & (where('cls') == 'cFunc')): x = ccore.from_db(l) P = [c_type(t).show() for t in x.argtypes()] P.insert(0, c_type(x.restype()).show()) if max(reqs) >= len(P): continue if not all(((t == P[i]) for (i, t) in reqs.items())): continue d = {'id': l['id'], 'val': x.show(db, form=fmt)} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
def stats(ctx): """Show some statistics about the remote (or local if remote is not found) database. """ db = ctx.obj['db'] click.echo('database: ') click.echo(' .local : %s' % str(db.ldb)) click.echo(' .url : %s' % str(db.rdb)) click.echo('documents:') F = db.search(where('cls') == 'cFunc') click.echo(' .cFunc : %d' % len(F)) C = db.search(where('cls') == 'cClass') click.echo(' .cClass : %d' % len(C)) S = db.search(where('cls') == 'cStruct') click.echo(' .cStruct : %d' % len(S)) U = db.search(where('cls') == 'cUnion') click.echo(' .cUnion : %d' % len(U)) E = db.search(where('cls') == 'cEnum') click.echo(' .cEnum : %d' % len(E)) T = db.search(where('cls') == 'cTypedef') click.echo(' .cTypedef : %d' % len(T)) M = db.search(where('cls') == 'cMacro') click.echo(' .cMacro : %d' % len(M)) P = db.search(where('cls') == 'cTemplate') click.echo(' .cTemplate : %d' % len(P)) click.echo('structures:') l, s = max(((len(s['val']), s['id']) for s in S)) click.echo(" max fields: %d (in '%s')" % (l, s))
class Select(Resource): def get(self): return {"verbose": False, "tag": "", "key": "", "match": ""} def post(self): parser = reqparse.RequestParser() parser.add_argument("verbose", type=bool) parser.add_argument("tag") parser.add_argument("key") parser.add_argument("match") args = parser.parse_args() db = g_ctx.obj["db"] if args["tag"]: db.set_tag(args["tag"]) if verbose := args["verbose"]: keys = ("cls", "tag", "src", "use") key = args["key"] rex = args["match"] or ".*" Q = where(key).matches(rex) L = [] for l in db.search(Q): d = {"id": l["id"], key: l[key]} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
def get(self): db = g_ctx.obj['db'] D = {'database': str(db.rdb)} for x in ('cFunc', 'cClass', 'cStruct', 'cUnion', 'cEnum', 'cTypedef', 'cMacro', 'cTemplate'): D[x] = len(db.search(where('cls') == x)) return D
class Select(Resource): def get(self): return {'verbose': False, 'tag': '', 'key': '', 'match': ''} def post(self): parser = reqparse.RequestParser() parser.add_argument('verbose', type=bool) parser.add_argument('tag') parser.add_argument('key') parser.add_argument('match') args = parser.parse_args() db = g_ctx.obj['db'] if args['tag']: db.set_tag(args['tag']) if verbose := args['verbose']: keys = ('cls', 'tag', 'src', 'use') key = args['key'] rex = args['match'] or '.*' Q = where(key).matches(rex) L = [] for l in db.search(Q): d = {'id': l['id'], key: l[key]} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
def add_subtype(self, db, elt, limit=None): x = ccore._cache_.get(elt, None) if x is None: data = db.get(where("id") == elt) if data: x = ccore.from_db(data) ccore._cache_[elt] = x else: self.subtypes[elt] = None return self.subtypes[elt] = x.unfold(db, limit)
def constant(ctx, mask, symbol, val): """Get constant definitions (macros or enums) from the remote database (or the local database if no remote is found) matching constraints on value (possibly representing a mask of several symbols) and symbol prefix. """ value = int(val, 0) db = ctx.obj['db'] Q = ctx.obj.get('select', Query().noop()) Q &= ((where('cls') == 'cMacro') | (where('cls') == 'cEnum')) L = db.search(Q) R = [] with click.progressbar(L) as pL: for l in pL: x = ccore.from_db(l) if x._is_macro: if not (symbol in x.identifier): continue try: v = int(x, 0) except Exception: continue else: if v == value: R.append(x.identifier + '\n') elif mask and (symbol in x.identifier): if v < value and v & value: R.append(x.identifier + ' | ') else: for k, v in x.items(): if v == value and (symbol in k): R.append(k + '\n') break elif mask and (symbol in k): if v < value and v & value: R.append(k + ' | ') if R: s = ''.join(R) click.echo(s.strip(' |\n'))
def get(self): db = g_ctx.obj["db"] D = {"database": str(db.rdb)} for x in ( "cFunc", "cClass", "cStruct", "cUnion", "cEnum", "cTypedef", "cMacro", "cTemplate", ): D[x] = len(db.search(where("cls") == x)) return D
def show(ctx, form, recursive, identifier): """Print a definition from the remote database (or the local database if no remote is found) in C/C++ (default) format or other supported format (ctypes, amoco, raw). If the recursive option is used, the printed definitions include all other types required by the topmost definition. """ db = ctx.obj['db'] if recursive is True: recursive = set() Q = where('id') == identifier if db.contains(Q): for l in db.search(Q): x = ccore.from_db(l) click.echo(x.show(db, recursive, form=form)) else: click.secho("identifier '%s' not found" % identifier, fg='red', err=True)
class Show(Resource): def get(self): return { 'verbose': False, 'tag': '', 'recursive': False, 'fmt': 'C', 'identifier': '' } def post(self): parser = reqparse.RequestParser() parser.add_argument('verbose', type=bool) parser.add_argument('recursive', type=bool) parser.add_argument('tag') parser.add_argument('fmt') parser.add_argument('identifier') args = parser.parse_args() db = g_ctx.obj['db'] if args['tag']: db.set_tag(args['tag']) if verbose := args['verbose']: keys = ('cls', 'tag', 'src', 'use') fmt = args['fmt'] or 'C' recursive = args['recursive'] identifier = args['identifier'] Q = where('id') == identifier L = [] for l in db.search(Q): x = ccore.from_db(l) d = {'id': l['id'], 'val': x.show(db, recursive, form=fmt)} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
def info(ctx, identifier): """Get database internal informations about a definition. """ db = ctx.obj['db'] Q = where('id') == identifier if db.contains(Q): for l in db.search(Q): x = ccore.from_db(l) click.echo("identifier: {}".format(identifier)) click.secho("class : {}".format(l['cls']), fg='cyan') click.echo("source : {}".format(l['src'])) click.secho("tag : {}".format(l['tag']), fg='magenta') if x._is_struct or x._is_union or x._is_class: try: t = x.build(db) except (TypeError, KeyError) as e: what = e.args[0] click.secho("can't build %s:\nmissing type: '%s'" % (x.identifier, what), fg='red', err=True) click.echo('', err=True) continue F = [] for i, f in enumerate(t._fields_): field = getattr(t, f[0]) F.append((field.offset, field.size)) xsize = F[-1][0] + F[-1][1] click.secho("size : {}".format(xsize), fg='yellow') click.secho("offsets : {}".format([(f[0], f[1]) for f in F]), fg='yellow') else: click.secho("identifier '%s' not found" % identifier, fg='red', err=True)
class Show(Resource): def get(self): return { "verbose": False, "tag": "", "recursive": False, "fmt": "C", "identifier": "", } def post(self): parser = reqparse.RequestParser() parser.add_argument("verbose", type=bool) parser.add_argument("recursive", type=bool) parser.add_argument("tag") parser.add_argument("fmt") parser.add_argument("identifier") args = parser.parse_args() db = g_ctx.obj["db"] if args["tag"]: db.set_tag(args["tag"]) if verbose := args["verbose"]: keys = ("cls", "tag", "src", "use") fmt = args["fmt"] or "C" recursive = args["recursive"] identifier = args["identifier"] Q = where("id") == identifier L = [] for l in db.search(Q): x = ccore.from_db(l) d = {"id": l["id"], "val": x.show(db, recursive, form=fmt)} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
class Select_Struct(Resource): def get(self): return { 'verbose': False, 'tag': '', 'key': '', 'match': '', 'def': False, 'format': 'C', 'conds': '' } def post(self): parser = reqparse.RequestParser() parser.add_argument('verbose', type=bool) parser.add_argument('tag') parser.add_argument('key') parser.add_argument('match') parser.add_argument('def', type=bool) parser.add_argument('format') parser.add_argument('conds') args = parser.parse_args() db = g_ctx.obj['db'] if args['tag']: db.set_tag(args['tag']) if verbose := args['verbose']: keys = ('src', 'tag') if args['key'] and args['match']: Q = where(args['key']).matches(args['match']) else: Q = Query() fmt = args['format'] or 'C' conds = args['conds'].split(';') pdef = args['def'] reqs = {} try: for p in conds: off, t = p.split(':') if off == '*': sz = int(t) reqs[off] = sz else: off = int(off) if t[0] == '+': reqs[off] = int(t) elif t[0] == '?': reqs[off] = t else: reqs[off] = c_type(t) except Exception: abort(400, reason="invalid constraints") L = [] for l in db.search(Q & ( (where('cls') == 'cStruct') | (where('cls') == 'cClass'))): x = ccore.from_db(l) out = '' ctcls = c_type try: if x._is_class: x = x.as_cStruct(db) t = x.build(db) except: continue F = [] for i, f in enumerate(t._fields_): field = getattr(t, f[0]) F.append((field.offset, field.size, ctcls(x[i][0]))) if F: xsize = F[-1][0] + F[-1][1] if '*' in reqs and reqs['*'] != xsize: continue F = dict(((f[0], f[1:3]) for f in F)) ok = [] for o, s in reqs.items(): if o == '*': continue cond = (o in F) ok.append(cond) if not cond: break if s == '?': continue if s == '*': cond = (F[o][1].is_ptr) elif isinstance(s, c_type): cond = (F[o][1].show() == s.show()) else: cond = (F[o][0] == s) ok.append(cond) if not cond: break if all(ok): if not pdef: out = x.identifier else: out = x.show(db, form=fmt) if out: d = {'val': out} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
def struct(ctx, pdef, conds): """Get structured definitions (struct, union or class) from the remote database (or the local database if no remote is found) matching constraints on total size or specific type name or size at given offset within the structure. """ reqs = {} try: for p in conds: off, t = p.split(':') if off == '*': sz = int(t) reqs[off] = sz else: off = int(off) if t[0] == '+': reqs[off] = int(t) elif t[0] == '?': reqs[off] = t else: reqs[off] = c_type(t) except Exception: click.secho('invalid arguments', fg='red', err=True) return db = ctx.obj['db'] Q = ctx.obj.get('select', Query().noop()) L = db.search(Q & ((where('cls') == 'cStruct') | (where('cls') == 'cClass'))) R = [] fails = [] with click.progressbar(L) as pL: for l in pL: x = ccore.from_db(l) ctcls = c_type try: if x._is_class: x = x.as_cStruct(db) t = x.build(db) except Exception: fails.append("can't build %s" % x.identifier) continue F = [] for i, f in enumerate(t._fields_): field = getattr(t, f[0]) F.append((field.offset, field.size, ctcls(x[i][0]))) if F: xsize = F[-1][0] + F[-1][1] if '*' in reqs and reqs['*'] != xsize: continue F = dict(((f[0], f[1:3]) for f in F)) ok = [] for o, s in reqs.items(): if o == '*': continue cond = (o in F) ok.append(cond) if not cond: break if s == '?': continue if s == '*': cond = (F[o][1].is_ptr) elif isinstance(s, c_type): cond = (F[o][1].show() == s.show()) else: cond = (F[o][0] == s) ok.append(cond) if not cond: break if all(ok): if not pdef: res = x.identifier else: res = x.show(db, form='C') R.append(res) if conf.VERBOSE: click.secho(u'\n'.join(fails), fg='red', err=True) if R: click.echo('\n'.join(R))
class Select_Struct(Resource): def get(self): return { "verbose": False, "tag": "", "key": "", "match": "", "def": False, "format": "C", "conds": "", } def post(self): parser = reqparse.RequestParser() parser.add_argument("verbose", type=bool) parser.add_argument("tag") parser.add_argument("key") parser.add_argument("match") parser.add_argument("def", type=bool) parser.add_argument("format") parser.add_argument("conds") args = parser.parse_args() db = g_ctx.obj["db"] if args["tag"]: db.set_tag(args["tag"]) if verbose := args["verbose"]: keys = ("src", "tag") if args["key"] and args["match"]: Q = where(args["key"]).matches(args["match"]) else: Q = Query().noop() fmt = args["format"] or "C" conds = args["conds"].split(";") pdef = args["def"] reqs = {} try: for p in conds: off, t = p.split(":") if off == "*": sz = int(t) reqs[off] = sz else: off = int(off) if t[0] == "+": reqs[off] = int(t) elif t[0] == "?": reqs[off] = t else: reqs[off] = c_type(t) except Exception: abort(400, reason="invalid constraints") L = [] for l in db.search(Q & ( (where("cls") == "cStruct") | (where("cls") == "cClass"))): x = ccore.from_db(l) out = "" ctcls = c_type try: if x._is_class: x = x.as_cStruct(db) t = x.build(db) except Exception: continue F = [] for i, f in enumerate(t._fields_): field = getattr(t, f[0]) F.append((field.offset, field.size, ctcls(x[i][0]))) if F: xsize = F[-1][0] + F[-1][1] if "*" in reqs and reqs["*"] != xsize: continue F = dict(((f[0], f[1:3]) for f in F)) ok = [] for o, s in reqs.items(): if o == "*": continue cond = o in F ok.append(cond) if not cond: break if s == "?": continue if s == "*": cond = F[o][1].is_ptr elif isinstance(s, c_type): cond = F[o][1].show() == s.show() else: cond = F[o][0] == s ok.append(cond) if not cond: break if all(ok): if not pdef: out = x.identifier else: out = x.show(db, form=fmt) if out: d = {"val": out} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
class Select_Constant(Resource): def get(self): return { 'verbose': False, 'tag': '', 'key': '', 'match': '', 'mask': False, 'prefix': '', 'val': '' } def post(self): parser = reqparse.RequestParser() parser.add_argument('verbose', type=bool) parser.add_argument('tag') parser.add_argument('key') parser.add_argument('match') parser.add_argument('mask', type=bool) parser.add_argument('prefix') parser.add_argument('val') args = parser.parse_args() db = g_ctx.obj['db'] if args['tag']: db.set_tag(args['tag']) if verbose := args['verbose']: keys = ('src', 'tag') if args['key'] and args['match']: Q = where(args['key']).matches(args['match']) else: Q = Query() try: value = int(args['val'], 0) except (ValueError, TypeError): abort(400, reason="invalid value") mask = args['mask'] pfx = args['prefix'] or '' Q &= (where('cls') == 'cMacro') | (where('cls') == 'cEnum') L = [] for l in db.search(Q): x = ccore.from_db(l) out = '' if x._is_macro: if (pfx not in x.identifier): continue try: v = int(x, 0) except Exception: continue else: if v == value: out = x.identifier elif mask and (pfx in x.identifier): if v < value and v & value: out = x.identifier + ' | ' else: for k, v in x.items(): if v == value and (pfx in k): out = k break elif mask and (pfx in k): if v < value and v & value: out = k + ' | ' if out: d = {'val': out} if verbose: for k in keys: d[k] = l[k] L.append(d) return L
class Select_Constant(Resource): def get(self): return { "verbose": False, "tag": "", "key": "", "match": "", "mask": False, "prefix": "", "val": "", } def post(self): parser = reqparse.RequestParser() parser.add_argument("verbose", type=bool) parser.add_argument("tag") parser.add_argument("key") parser.add_argument("match") parser.add_argument("mask", type=bool) parser.add_argument("prefix") parser.add_argument("val") args = parser.parse_args() db = g_ctx.obj["db"] if args["tag"]: db.set_tag(args["tag"]) if verbose := args["verbose"]: keys = ("src", "tag") if args["key"] and args["match"]: Q = where(args["key"]).matches(args["match"]) else: Q = Query().noop() try: value = int(args["val"], 0) except (ValueError, TypeError): abort(400, reason="invalid value") mask = args["mask"] pfx = args["prefix"] or "" Q &= (where("cls") == "cMacro") | (where("cls") == "cEnum") L = [] for l in db.search(Q): x = ccore.from_db(l) out = "" if x._is_macro: if pfx not in x.identifier: continue try: v = int(x, 0) except Exception: continue else: if v == value: out = x.identifier elif mask and (pfx in x.identifier): if v < value and v & value: out = x.identifier + " | " else: for k, v in x.items(): if v == value and (pfx in k): out = k break elif mask and (pfx in k): if v < value and v & value: out = k + " | " if out: d = {"val": out} if verbose: for k in keys: d[k] = l[k] L.append(d) return L