2013-03-06 01:08:15 -08:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import re
|
|
|
|
import subprocess
|
2013-03-08 08:15:59 -08:00
|
|
|
import argparse
|
2013-03-06 01:08:15 -08:00
|
|
|
|
2013-03-12 01:31:08 -07:00
|
|
|
c_excludes = "elm_app|elm_widget|elm_prefs"
|
|
|
|
py_excludes = "elm_naviframe_item_simple_push|elm_object_item_content|elm_object_item_text|elm_object_content|elm_object_text"
|
2013-03-10 03:56:34 -07:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
def pkg_config(require, min_vers=None):
|
|
|
|
name = require.capitalize()
|
2013-03-06 01:08:15 -08:00
|
|
|
try:
|
|
|
|
sys.stdout.write("Checking for " + name + ": ")
|
|
|
|
ver = subprocess.check_output(["pkg-config", "--modversion", require]).decode("utf-8").strip()
|
|
|
|
if min_vers is not None:
|
|
|
|
assert 0 == subprocess.call(["pkg-config", "--atleast-version", min_vers, require])
|
|
|
|
cflags = subprocess.check_output(["pkg-config", "--cflags", require]).decode("utf-8").split()
|
|
|
|
sys.stdout.write("OK, found " + ver + "\n")
|
2013-03-08 08:15:59 -08:00
|
|
|
return cflags
|
2013-03-06 01:08:15 -08:00
|
|
|
except (OSError, subprocess.CalledProcessError):
|
2013-03-08 08:15:59 -08:00
|
|
|
raise SystemExit("Failed to find" + name + "with 'pkg-config'. Please make sure that it is installed and available on your system path.")
|
2013-03-06 01:08:15 -08:00
|
|
|
except (AssertionError):
|
|
|
|
raise SystemExit("Failed to match version. Found: " + ver + " Needed: " + min_vers)
|
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
def get_capis(inc_path, prefix):
|
|
|
|
capis = []
|
2013-03-06 01:08:15 -08:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
for path, dirs, files in os.walk(inc_path):
|
|
|
|
for f in files:
|
|
|
|
with open(os.path.join(path, f), "r") as header:
|
|
|
|
capi = header.read()
|
2013-03-12 01:31:08 -07:00
|
|
|
matches = re.finditer("^ *EAPI [A-Za-z_ *\n]+ +\**(?!" + c_excludes + ")(" + prefix + "_\w+) *\(", capi, re.S|re.M)
|
2013-03-08 08:15:59 -08:00
|
|
|
for match in matches:
|
|
|
|
func = match.group(1)
|
|
|
|
capis.append(func)
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
return capis
|
2013-03-06 01:08:15 -08:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
def get_pyapis(pxd_path, header_name, prefix):
|
|
|
|
pyapis = []
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
for path, dirs, files in os.walk(pxd_path):
|
|
|
|
for f in files:
|
|
|
|
if f.endswith(".pxd"):
|
|
|
|
with open(os.path.join(path, f), "r") as pxd:
|
|
|
|
pyapi = pxd.read()
|
|
|
|
cdef = re.search('(cdef extern from "' + header_name + '\.h":\n)(.+)', pyapi, re.S)
|
|
|
|
if cdef:
|
2013-03-12 01:31:08 -07:00
|
|
|
matches = re.finditer("^ [a-zA-Z _*]+?(?!" + py_excludes + ")(" + prefix + "_\w+)\(", cdef.group(2), re.M)
|
2013-03-08 08:15:59 -08:00
|
|
|
for match in matches:
|
|
|
|
func = match.group(1)
|
|
|
|
pyapis.append(func)
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
return pyapis
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
2013-03-08 10:35:13 -08:00
|
|
|
parser.add_argument("--python", action="store_true", default=False, help="Show Python API coverage")
|
|
|
|
parser.add_argument("--c", action="store_true", default=False, help="Show C API coverage")
|
2013-04-03 09:34:37 -07:00
|
|
|
parser.add_argument("libs", nargs="+", help="Possible values are eo, evas, ecore, ecore-file, edje, emotion, edbus, elementary and all.")
|
2013-03-08 08:15:59 -08:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
if args.libs is "all":
|
2013-03-12 01:31:08 -07:00
|
|
|
args.libs = ["eo", "evas", "efreet", "ecore", "efile", "edje", "emotion", "edbus", "elementary"]
|
2013-03-08 08:15:59 -08:00
|
|
|
|
|
|
|
params = {
|
|
|
|
"eo": ("include", "Eo", "eo"),
|
|
|
|
"evas": ("include", "Evas", "evas"),
|
|
|
|
"ecore": ("include", "Ecore", "ecore"),
|
2013-03-08 16:13:54 -08:00
|
|
|
"ecore-file": ("include", "Ecore_File", "ecore_file"),
|
2013-03-08 08:15:59 -08:00
|
|
|
"edje": ("include", "Edje", "edje"),
|
|
|
|
"emotion": ("include", "Emotion", "emotion"),
|
|
|
|
"edbus2": ("efl/edbus", "EDBus", "edbus"),
|
|
|
|
"elementary": ("efl/elementary", "Elementary", "elm"),
|
|
|
|
}
|
|
|
|
|
|
|
|
for key in args.libs:
|
|
|
|
inc_path = pkg_config(key, "1.7.99")[0][2:]
|
|
|
|
pxd_path, header_name, prefix = params[key]
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
capis = get_capis(inc_path, prefix)
|
|
|
|
pyapis = get_pyapis(pxd_path, header_name, prefix)
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 08:15:59 -08:00
|
|
|
ecs = set(capis)
|
|
|
|
eps = set(pyapis)
|
2013-03-08 10:35:13 -08:00
|
|
|
differences = ecs.union(eps) - ecs.intersection(eps)
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 10:35:13 -08:00
|
|
|
for d in sorted(differences):
|
|
|
|
if args.python and d in ecs:
|
|
|
|
print("{0} is missing from Python API".format(d))
|
|
|
|
if args.c and d in eps:
|
|
|
|
print("{0} is missing from C API".format(d))
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 10:35:13 -08:00
|
|
|
if args.python or args.c: print("\n---")
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 10:35:13 -08:00
|
|
|
if args.python:
|
|
|
|
print("Number of functions missing from Python API: {0}".format(len(ecs - ecs.intersection(eps))))
|
|
|
|
if args.c:
|
|
|
|
print("Number of functions missing from C API: {0}".format(len(eps - ecs.intersection(eps))))
|
|
|
|
|
|
|
|
if args.python or args.c: print("---")
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 10:35:13 -08:00
|
|
|
if args.python:
|
|
|
|
print("Python API functions: {0}".format(len(eps)))
|
|
|
|
if args.c:
|
|
|
|
print("C API functions: {0}".format(len(ecs)))
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 10:35:13 -08:00
|
|
|
if args.python:
|
|
|
|
percentage = float(len(ecs.intersection(eps))) / float(len(ecs)) * 100.0
|
|
|
|
print("===")
|
|
|
|
print("Bindings coverage {0:.2f}%".format(percentage))
|
2013-03-08 16:13:54 -08:00
|
|
|
|
2013-03-08 10:35:13 -08:00
|
|
|
if args.python or args.c: print("---\n")
|