github/workflows/pycopy-test: Upgrade Pycopy to 3.6.1.
[ScratchABlock.git] / funcdb_query.py
blob428ac18eb7f4f34debfe5b6d5bb0a1419b47aff5
1 #!/usr/bin/env python3
2 import sys
3 import os
4 import argparse
6 import yaml
8 import yamlutils
11 argp = argparse.ArgumentParser(description="Query a function database")
12 argp.add_argument("file_or_dir", help="function database file (YAML) or project directory")
13 argp.add_argument("--select", help="fields to select")
14 argp.add_argument("--where", help="condition of rows to select")
15 argp.add_argument("--sort", action="store_true", help="sort resultset")
16 argp.add_argument("--html", action="store_true", help="output HTML")
17 args = argp.parse_args()
19 if not args.select and not args.where:
20 argp.error("At least one of --select or --where should be given")
22 if os.path.isdir(args.file_or_dir):
23 args.file_or_dir += "/funcdb.yaml"
25 with open(args.file_or_dir) as f:
26 FUNC_DB = yaml.load(f)
29 def where(props):
30 #print("where", props)
31 if args.where is None:
32 return True
33 try:
34 res = eval(args.where, None, props)
35 except NameError:
36 return False
37 return res
39 def select(props):
40 #print("select", props)
41 if args.select == "*":
42 return props
43 res = eval("(" + args.select + ",)", None, props)
44 return res
46 res = []
47 for addr, props in FUNC_DB.items():
48 props = props.copy()
49 props["addr"] = addr
50 if "calls_indir" not in props:
51 props["calls_indir"] = []
52 if where(props):
53 res.append(select(props))
55 if args.sort:
56 res.sort()
58 if args.html:
59 print("<html><body><table border='1' cellspacing='0'>")
61 for row in res:
62 if isinstance(row, dict):
63 if args.html:
64 print("<tr><td>" + row + "</td></tr>")
65 else:
66 print(row)
67 else:
68 row = [str(x) for x in row]
69 if args.html:
70 print("<tr><td>" + "</td><td>".join(row) + "</td></tr>")
71 else:
72 print(": ".join(row))
74 if args.html:
75 print("</table></body></html>")