[libvirt PATCH] scripts: include function versions in API definition
Victor Toso
victortoso at redhat.com
Thu Sep 23 14:07:17 UTC 2021
Hi,
On Thu, Sep 23, 2021 at 11:47:58AM +0100, Daniel P. Berrangé wrote:
> In order to auto-generate more of the language binding code, it is
> desirable to know what libvirt version an API was introduced in.
> We can extract this information from the .syms files and expose
> it in the API description
>
> eg instead of
>
> <function name='virNodeNumOfDevices' file='libvirt-nodedev'
> module='libvirt-nodedev'>
>
> we now have
>
> <function name='virNodeNumOfDevices' file='libvirt-nodedev'
> module='libvirt-nodedev' version='0.5.0'>
>
> This will benefit this proposal:
>
> https://gitlab.com/libvirt/libvirt-go-module/-/merge_requests/7
>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
Tested-by: Victor Toso <victortoso at redhat.com>
Thanks, this definitely helps.
Do you think it would make sense to add version metadata to other
types such as structs and enums too?
> ---
> scripts/apibuild.py | 68 +++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 62 insertions(+), 6 deletions(-)
>
> diff --git a/scripts/apibuild.py b/scripts/apibuild.py
> index 9b29466e1d..bdd3077c48 100755
> --- a/scripts/apibuild.py
> +++ b/scripts/apibuild.py
> @@ -2030,8 +2030,9 @@ class CParser:
>
> class docBuilder:
> """A documentation builder"""
> - def __init__(self, name, path='.', directories=['.'], includes=[]):
> + def __init__(self, name, syms, path='.', directories=['.'], includes=[]):
> self.name = name
> + self.syms = syms
> self.path = path
> self.directories = directories
> if name == "libvirt":
> @@ -2044,6 +2045,7 @@ class docBuilder:
> self.includes = includes + list(admin_included_files.keys())
> self.modules = {}
> self.headers = {}
> + self.versions = {}
> self.idx = index()
> self.xref = {}
> self.index = {}
> @@ -2114,6 +2116,44 @@ class docBuilder:
> self.modules[module] = idx
> self.idx.merge_public(idx)
>
> + def scanVersions(self):
> + prefix = self.name.upper().replace("-", "_") + "_"
> +
> + version = None
> + prevversion = None
> + with open(self.syms, "r") as syms:
> + while True:
> + line = syms.readline()
> + if not line:
> + break
> + line = line.strip()
> + if line.startswith("#"):
> + continue
> + if line == "":
> + continue
> +
> + if line.startswith(prefix) and line.endswith(" {"):
> + version = line[len(prefix):-2]
> + elif line == "global:":
> + continue
> + elif line == "local:":
> + continue
> + elif line.startswith("}"):
> + if prevversion is None:
> + if line != "};":
> + raise Exception("Unexpected closing version")
> + else:
> + if line != ("} %s%s;" % (prefix, prevversion)):
> + raise Exception("Unexpected end of version '%s': %s'" % (line, "} " + prefix + version))
> +
> + prevversion = version
> + version = None
> + elif line.endswith(";") and version is not None:
> + func = line[:-1]
> + self.versions[func] = version
> + else:
> + raise Exception("Unexpected line in syms file: %s" % line)
> +
> def scan(self):
> for directory in self.directories:
> files = glob.glob(directory + "/*.c")
> @@ -2136,6 +2176,7 @@ class docBuilder:
> self.headers[file] = None
> self.scanHeaders()
> self.scanModules()
> + self.scanVersions()
>
> def modulename_file(self, file):
> module = os.path.basename(file)
> @@ -2275,9 +2316,17 @@ class docBuilder:
> print("=>", id)
>
> # NB: this is consumed by a regex in 'getAPIFilenames' in hvsupport.pl
> - output.write(" <%s name='%s' file='%s' module='%s'>\n" % (id.type,
> - name, self.modulename_file(id.header),
> - self.modulename_file(id.module)))
> + if id.type == "function":
> + ver = self.versions[name]
> + if ver is None:
> + raise Exception("Missing version for '%s'" % name)
> + output.write(" <function name='%s' file='%s' module='%s' version='%s'>\n" % (
> + name, self.modulename_file(id.header),
> + self.modulename_file(id.module), self.versions[name]))
> + else:
> + output.write(" <functype name='%s' file='%s' module='%s'>\n" % (
> + name, self.modulename_file(id.header),
> + self.modulename_file(id.module)))
> #
> # Processing of conditionals modified by Bill 1/1/05
> #
> @@ -2406,9 +2455,16 @@ class app:
> print(msg)
>
> def rebuild(self, name, srcdir, builddir):
> - if name not in ["libvirt", "libvirt-qemu", "libvirt-lxc", "libvirt-admin"]:
> + syms = {
> + "libvirt": srcdir + "/../src/libvirt_public.syms",
> + "libvirt-qemu": srcdir + "/../src/libvirt_qemu.syms",
> + "libvirt-lxc": srcdir + "/../src/libvirt_lxc.syms",
> + "libvirt-admin": srcdir + "/../src/admin/libvirt_admin_public.syms",
> + }
> + if name not in syms:
> self.warning("rebuild() failed, unknown module %s" % name)
> return None
> +
> builder = None
> if glob.glob(srcdir + "/../src/libvirt.c") != []:
> if not quiet:
> @@ -2418,7 +2474,7 @@ class app:
> srcdir + "/../src/util",
> srcdir + "/../include/libvirt",
> builddir + "/../include/libvirt"]
> - builder = docBuilder(name, builddir, dirs, [])
> + builder = docBuilder(name, syms[name], builddir, dirs, [])
> else:
> self.warning("rebuild() failed, unable to guess the module")
> return None
> --
> 2.31.1
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20210923/dd968647/attachment-0001.sig>
More information about the libvir-list
mailing list