2011-04-08 22:57:31 +02:00
|
|
|
|
# -*- Mode: Python -*-
|
2018-01-15 16:58:10 +01:00
|
|
|
|
# coding=utf-8
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
2011-04-15 14:33:30 +02:00
|
|
|
|
# GDBus - GLib D-Bus Library
|
|
|
|
|
#
|
|
|
|
|
# Copyright (C) 2008-2011 Red Hat, Inc.
|
2018-01-04 14:18:07 +01:00
|
|
|
|
# Copyright (C) 2018 Iñigo Martínez <inigomartinez@gmail.com>
|
2011-04-15 14:33:30 +02:00
|
|
|
|
#
|
|
|
|
|
# This library is free software; you can redistribute it and/or
|
|
|
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
# License as published by the Free Software Foundation; either
|
2017-01-05 14:44:41 +01:00
|
|
|
|
# version 2.1 of the License, or (at your option) any later version.
|
2011-04-15 14:33:30 +02:00
|
|
|
|
#
|
|
|
|
|
# This library is distributed in the hope that it will be useful,
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
# Lesser General Public License for more details.
|
|
|
|
|
#
|
|
|
|
|
# You should have received a copy of the GNU Lesser General
|
2014-01-23 12:58:29 +01:00
|
|
|
|
# Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
2011-04-15 14:33:30 +02:00
|
|
|
|
#
|
|
|
|
|
# Author: David Zeuthen <davidz@redhat.com>
|
|
|
|
|
|
2018-01-02 20:24:56 +01:00
|
|
|
|
import argparse
|
2018-01-04 14:18:07 +01:00
|
|
|
|
import os
|
2011-04-08 22:57:31 +02:00
|
|
|
|
import sys
|
2024-01-28 23:31:37 +01:00
|
|
|
|
from contextlib import contextmanager
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
2011-08-23 17:37:35 +02:00
|
|
|
|
from . import config
|
2011-08-23 07:35:01 +02:00
|
|
|
|
from . import dbustypes
|
|
|
|
|
from . import parser
|
|
|
|
|
from . import codegen
|
|
|
|
|
from . import codegen_docbook
|
2022-12-29 13:42:12 +01:00
|
|
|
|
from . import codegen_md
|
2022-01-19 14:55:29 +01:00
|
|
|
|
from . import codegen_rst
|
2018-01-02 20:24:56 +01:00
|
|
|
|
from .utils import print_error, print_warning
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
2020-11-17 16:07:09 +01:00
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
def find_arg(arg_list, arg_name):
|
|
|
|
|
for a in arg_list:
|
|
|
|
|
if a.name == arg_name:
|
|
|
|
|
return a
|
|
|
|
|
return None
|
|
|
|
|
|
2020-11-17 16:07:09 +01:00
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
def find_method(iface, method):
|
|
|
|
|
for m in iface.methods:
|
|
|
|
|
if m.name == method:
|
|
|
|
|
return m
|
|
|
|
|
return None
|
|
|
|
|
|
2020-11-17 16:07:09 +01:00
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
def find_signal(iface, signal):
|
|
|
|
|
for m in iface.signals:
|
|
|
|
|
if m.name == signal:
|
|
|
|
|
return m
|
|
|
|
|
return None
|
|
|
|
|
|
2020-11-17 16:07:09 +01:00
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
def find_prop(iface, prop):
|
|
|
|
|
for m in iface.properties:
|
|
|
|
|
if m.name == prop:
|
|
|
|
|
return m
|
|
|
|
|
return None
|
|
|
|
|
|
2020-11-17 16:07:09 +01:00
|
|
|
|
|
2024-01-28 23:31:37 +01:00
|
|
|
|
@contextmanager
|
|
|
|
|
def file_or_stdout(filename):
|
2024-02-06 11:54:51 +01:00
|
|
|
|
if filename is None or filename == "-":
|
2024-01-28 23:31:37 +01:00
|
|
|
|
yield sys.stdout
|
|
|
|
|
else:
|
|
|
|
|
with open(filename, "w") as outfile:
|
|
|
|
|
yield outfile
|
|
|
|
|
|
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
def apply_annotation(iface_list, iface, method, signal, prop, arg, key, value):
|
gdbus-codegen: avoid error when wrong interface is provided to --annotate
If the interface given cannot be matched, `iface_obj' was left uninitialized and
the iface_obj == None check would end up crashing:
Traceback (most recent call last):
File "/usr/bin/gdbus-codegen", line 41, in <module>
sys.exit(codegen_main.codegen_main())
File "/usr/lib64/gdbus-2.0/codegen/codegen_main.py", line 175, in codegen_main
apply_annotations(all_ifaces, opts.annotate)
File "/usr/lib64/gdbus-2.0/codegen/codegen_main.py", line 146, in apply_annotations
apply_annotation(iface_list, iface, None, None, None, None, key, value)
File "/usr/lib64/gdbus-2.0/codegen/codegen_main.py", line 64, in apply_annotation
if iface_obj == None:
UnboundLocalError: local variable 'iface_obj' referenced before assignment
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=683088
2012-08-31 11:41:53 +02:00
|
|
|
|
iface_obj = None
|
2011-04-08 22:57:31 +02:00
|
|
|
|
for i in iface_list:
|
|
|
|
|
if i.name == iface:
|
|
|
|
|
iface_obj = i
|
|
|
|
|
break
|
|
|
|
|
|
2018-07-12 23:40:50 +02:00
|
|
|
|
if iface_obj is None:
|
2018-01-12 08:55:36 +01:00
|
|
|
|
print_error('No interface "{}"'.format(iface))
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
|
|
|
|
target_obj = None
|
|
|
|
|
|
|
|
|
|
if method:
|
|
|
|
|
method_obj = find_method(iface_obj, method)
|
2018-07-12 23:40:50 +02:00
|
|
|
|
if method_obj is None:
|
2018-01-12 08:55:36 +01:00
|
|
|
|
print_error('No method "{}" on interface "{}"'.format(method, iface))
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if arg:
|
|
|
|
|
arg_obj = find_arg(method_obj.in_args, arg)
|
2020-11-17 16:07:09 +01:00
|
|
|
|
if arg_obj is None:
|
2011-04-08 22:57:31 +02:00
|
|
|
|
arg_obj = find_arg(method_obj.out_args, arg)
|
2020-11-17 16:07:09 +01:00
|
|
|
|
if arg_obj is None:
|
|
|
|
|
print_error(
|
|
|
|
|
'No arg "{}" on method "{}" on interface "{}"'.format(
|
|
|
|
|
arg, method, iface
|
|
|
|
|
)
|
|
|
|
|
)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
target_obj = arg_obj
|
|
|
|
|
else:
|
|
|
|
|
target_obj = method_obj
|
|
|
|
|
elif signal:
|
|
|
|
|
signal_obj = find_signal(iface_obj, signal)
|
2018-07-12 23:40:50 +02:00
|
|
|
|
if signal_obj is None:
|
2018-01-12 08:55:36 +01:00
|
|
|
|
print_error('No signal "{}" on interface "{}"'.format(signal, iface))
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if arg:
|
|
|
|
|
arg_obj = find_arg(signal_obj.args, arg)
|
2020-11-17 16:07:09 +01:00
|
|
|
|
if arg_obj is None:
|
|
|
|
|
print_error(
|
|
|
|
|
'No arg "{}" on signal "{}" on interface "{}"'.format(
|
|
|
|
|
arg, signal, iface
|
|
|
|
|
)
|
|
|
|
|
)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
target_obj = arg_obj
|
|
|
|
|
else:
|
|
|
|
|
target_obj = signal_obj
|
|
|
|
|
elif prop:
|
|
|
|
|
prop_obj = find_prop(iface_obj, prop)
|
2018-07-12 23:40:50 +02:00
|
|
|
|
if prop_obj is None:
|
2018-01-12 08:55:36 +01:00
|
|
|
|
print_error('No property "{}" on interface "{}"'.format(prop, iface))
|
2011-04-08 22:57:31 +02:00
|
|
|
|
target_obj = prop_obj
|
|
|
|
|
else:
|
|
|
|
|
target_obj = iface_obj
|
|
|
|
|
target_obj.annotations.insert(0, dbustypes.Annotation(key, value))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def apply_annotations(iface_list, annotation_list):
|
|
|
|
|
# apply annotations given on the command line
|
2023-06-30 16:25:31 +02:00
|
|
|
|
for what, key, value in annotation_list:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
pos = what.find("::")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if pos != -1:
|
|
|
|
|
# signal
|
2020-11-17 16:07:09 +01:00
|
|
|
|
iface = what[0:pos]
|
|
|
|
|
signal = what[pos + 2 :]
|
|
|
|
|
pos = signal.find("[")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if pos != -1:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
arg = signal[pos + 1 :]
|
2011-04-08 22:57:31 +02:00
|
|
|
|
signal = signal[0:pos]
|
2020-11-17 16:07:09 +01:00
|
|
|
|
pos = arg.find("]")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
arg = arg[0:pos]
|
|
|
|
|
apply_annotation(iface_list, iface, None, signal, None, arg, key, value)
|
|
|
|
|
else:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
apply_annotation(
|
|
|
|
|
iface_list, iface, None, signal, None, None, key, value
|
|
|
|
|
)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
else:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
pos = what.find(":")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if pos != -1:
|
|
|
|
|
# property
|
2020-11-17 16:07:09 +01:00
|
|
|
|
iface = what[0:pos]
|
|
|
|
|
prop = what[pos + 1 :]
|
2011-04-08 22:57:31 +02:00
|
|
|
|
apply_annotation(iface_list, iface, None, None, prop, None, key, value)
|
|
|
|
|
else:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
pos = what.find("()")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if pos != -1:
|
|
|
|
|
# method
|
|
|
|
|
combined = what[0:pos]
|
2020-11-17 16:07:09 +01:00
|
|
|
|
pos = combined.rfind(".")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
iface = combined[0:pos]
|
2020-11-17 16:07:09 +01:00
|
|
|
|
method = combined[pos + 1 :]
|
|
|
|
|
pos = what.find("[")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if pos != -1:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
arg = what[pos + 1 :]
|
|
|
|
|
pos = arg.find("]")
|
2011-04-08 22:57:31 +02:00
|
|
|
|
arg = arg[0:pos]
|
2020-11-17 16:07:09 +01:00
|
|
|
|
apply_annotation(
|
|
|
|
|
iface_list, iface, method, None, None, arg, key, value
|
|
|
|
|
)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
else:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
apply_annotation(
|
|
|
|
|
iface_list, iface, method, None, None, None, key, value
|
|
|
|
|
)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
else:
|
|
|
|
|
# must be an interface
|
|
|
|
|
iface = what
|
2020-11-17 16:07:09 +01:00
|
|
|
|
apply_annotation(
|
|
|
|
|
iface_list, iface, None, None, None, None, key, value
|
|
|
|
|
)
|
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
|
|
|
|
def codegen_main():
|
2020-11-17 16:07:09 +01:00
|
|
|
|
arg_parser = argparse.ArgumentParser(
|
|
|
|
|
description="D-Bus code and documentation generator"
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"files", metavar="FILE", nargs="+", help="D-Bus introspection XML file"
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--xml-files",
|
|
|
|
|
metavar="FILE",
|
|
|
|
|
action="append",
|
|
|
|
|
default=[],
|
|
|
|
|
help=argparse.SUPPRESS,
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--interface-prefix",
|
|
|
|
|
metavar="PREFIX",
|
|
|
|
|
default="",
|
|
|
|
|
help="String to strip from D-Bus interface names for code and docs",
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--c-namespace",
|
|
|
|
|
metavar="NAMESPACE",
|
|
|
|
|
default="",
|
|
|
|
|
help="The namespace to use for generated C code",
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--c-generate-object-manager",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Generate a GDBusObjectManagerClient subclass when generating C code",
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--c-generate-autocleanup",
|
|
|
|
|
choices=["none", "objects", "all"],
|
|
|
|
|
default="objects",
|
|
|
|
|
help="Generate autocleanup support",
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--generate-docbook",
|
|
|
|
|
metavar="OUTFILES",
|
|
|
|
|
help="Generate Docbook in OUTFILES-org.Project.IFace.xml",
|
|
|
|
|
)
|
2022-12-29 13:42:12 +01:00
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--generate-md",
|
|
|
|
|
metavar="OUTFILES",
|
|
|
|
|
help="Generate Markdown in OUTFILES-org.Project.IFace.md",
|
|
|
|
|
)
|
2022-01-19 14:55:29 +01:00
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--generate-rst",
|
|
|
|
|
metavar="OUTFILES",
|
|
|
|
|
help="Generate reStructuredText in OUTFILES-org.Project.IFace.rst",
|
|
|
|
|
)
|
2020-11-17 16:07:09 +01:00
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--pragma-once",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help='Use "pragma once" as the inclusion guard',
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--annotate",
|
|
|
|
|
nargs=3,
|
|
|
|
|
action="append",
|
|
|
|
|
metavar="WHAT KEY VALUE",
|
|
|
|
|
help="Add annotation (may be used several times)",
|
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--glib-min-required",
|
|
|
|
|
metavar="VERSION",
|
2020-11-17 16:32:10 +01:00
|
|
|
|
help="Minimum version of GLib to be supported by the outputted code "
|
|
|
|
|
"(default: 2.30)",
|
2020-11-17 16:07:09 +01:00
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--glib-max-allowed",
|
|
|
|
|
metavar="VERSION",
|
2020-11-17 16:32:10 +01:00
|
|
|
|
help="Maximum version of GLib to be used by the outputted code "
|
|
|
|
|
"(default: current GLib version)",
|
2020-11-17 16:07:09 +01:00
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--symbol-decorator",
|
2020-11-17 16:32:10 +01:00
|
|
|
|
help="Macro used to decorate a symbol in the outputted header, "
|
|
|
|
|
"possibly to export symbols",
|
2020-11-17 16:07:09 +01:00
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--symbol-decorator-header",
|
2020-11-17 16:32:10 +01:00
|
|
|
|
help="Additional header required for decorator specified by "
|
|
|
|
|
"--symbol-decorator",
|
2020-11-17 16:07:09 +01:00
|
|
|
|
)
|
|
|
|
|
arg_parser.add_argument(
|
|
|
|
|
"--symbol-decorator-define",
|
2020-11-17 16:32:10 +01:00
|
|
|
|
help="Additional define required for decorator specified by "
|
|
|
|
|
"--symbol-decorator",
|
2020-11-17 16:07:09 +01:00
|
|
|
|
)
|
2018-01-04 14:18:07 +01:00
|
|
|
|
|
|
|
|
|
group = arg_parser.add_mutually_exclusive_group()
|
2020-11-17 16:07:09 +01:00
|
|
|
|
group.add_argument(
|
|
|
|
|
"--generate-c-code", metavar="OUTFILES", help="Generate C code in OUTFILES.[ch]"
|
|
|
|
|
)
|
|
|
|
|
group.add_argument("--header", action="store_true", help="Generate C headers")
|
|
|
|
|
group.add_argument("--body", action="store_true", help="Generate C code")
|
|
|
|
|
group.add_argument(
|
|
|
|
|
"--interface-info-header",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Generate GDBusInterfaceInfo C header",
|
|
|
|
|
)
|
|
|
|
|
group.add_argument(
|
|
|
|
|
"--interface-info-body",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Generate GDBusInterfaceInfo C code",
|
|
|
|
|
)
|
2018-01-04 14:18:07 +01:00
|
|
|
|
|
|
|
|
|
group = arg_parser.add_mutually_exclusive_group()
|
2020-11-17 16:07:09 +01:00
|
|
|
|
group.add_argument(
|
|
|
|
|
"--output", metavar="FILE", help="Write output into the specified file"
|
|
|
|
|
)
|
|
|
|
|
group.add_argument(
|
|
|
|
|
"--output-directory",
|
|
|
|
|
metavar="OUTDIR",
|
|
|
|
|
default="",
|
|
|
|
|
help="Location to output generated files",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
args = arg_parser.parse_args()
|
2018-01-02 20:24:56 +01:00
|
|
|
|
|
|
|
|
|
if len(args.xml_files) > 0:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_warning(
|
|
|
|
|
'The "--xml-files" option is deprecated; use positional arguments instead'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (
|
2022-01-19 14:55:29 +01:00
|
|
|
|
args.generate_c_code is not None
|
|
|
|
|
or args.generate_docbook is not None
|
2022-12-29 13:42:12 +01:00
|
|
|
|
or args.generate_md is not None
|
2022-01-19 14:55:29 +01:00
|
|
|
|
or args.generate_rst is not None
|
2020-11-17 16:07:09 +01:00
|
|
|
|
) and args.output is not None:
|
|
|
|
|
print_error(
|
2022-12-29 13:42:12 +01:00
|
|
|
|
"Using --generate-c-code or --generate-{docbook,md,rst} and "
|
2020-11-17 16:07:09 +01:00
|
|
|
|
"--output at the same time is not allowed"
|
|
|
|
|
)
|
2018-01-04 14:18:07 +01:00
|
|
|
|
|
|
|
|
|
if args.generate_c_code:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
header_name = args.generate_c_code + ".h"
|
2018-01-24 16:25:09 +01:00
|
|
|
|
h_file = os.path.join(args.output_directory, header_name)
|
2018-01-04 14:18:07 +01:00
|
|
|
|
args.header = True
|
2020-11-17 16:07:09 +01:00
|
|
|
|
c_file = os.path.join(args.output_directory, args.generate_c_code + ".c")
|
2018-01-04 14:18:07 +01:00
|
|
|
|
args.body = True
|
2018-01-24 16:25:09 +01:00
|
|
|
|
elif args.header:
|
|
|
|
|
if args.output is None:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error("Using --header requires --output")
|
2018-01-24 16:25:09 +01:00
|
|
|
|
|
|
|
|
|
h_file = args.output
|
|
|
|
|
header_name = os.path.basename(h_file)
|
|
|
|
|
elif args.body:
|
2018-01-04 14:18:07 +01:00
|
|
|
|
if args.output is None:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error("Using --body requires --output")
|
2018-01-04 14:18:07 +01:00
|
|
|
|
|
2018-01-24 16:25:09 +01:00
|
|
|
|
c_file = args.output
|
2024-02-06 14:48:45 +01:00
|
|
|
|
|
|
|
|
|
if c_file == "-":
|
|
|
|
|
header_name = ""
|
|
|
|
|
else:
|
|
|
|
|
header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h"
|
2018-04-17 15:10:07 +02:00
|
|
|
|
elif args.interface_info_header:
|
|
|
|
|
if args.output is None:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error("Using --interface-info-header requires --output")
|
2018-04-17 15:10:07 +02:00
|
|
|
|
if args.c_generate_object_manager:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error(
|
|
|
|
|
"--c-generate-object-manager is incompatible with "
|
|
|
|
|
"--interface-info-header"
|
|
|
|
|
)
|
2018-04-17 15:10:07 +02:00
|
|
|
|
|
|
|
|
|
h_file = args.output
|
|
|
|
|
header_name = os.path.basename(h_file)
|
|
|
|
|
elif args.interface_info_body:
|
|
|
|
|
if args.output is None:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error("Using --interface-info-body requires --output")
|
2018-04-17 15:10:07 +02:00
|
|
|
|
if args.c_generate_object_manager:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error(
|
|
|
|
|
"--c-generate-object-manager is incompatible with "
|
|
|
|
|
"--interface-info-body"
|
|
|
|
|
)
|
2018-04-17 15:10:07 +02:00
|
|
|
|
|
|
|
|
|
c_file = args.output
|
2024-02-06 14:48:45 +01:00
|
|
|
|
|
|
|
|
|
if c_file == "-":
|
|
|
|
|
header_name = ""
|
|
|
|
|
else:
|
|
|
|
|
header_name = os.path.splitext(os.path.basename(c_file))[0] + ".h"
|
2018-01-04 14:18:07 +01:00
|
|
|
|
|
2020-01-27 11:11:46 +01:00
|
|
|
|
# Check the minimum GLib version. The minimum --glib-min-required is 2.30,
|
2019-12-02 16:53:14 +01:00
|
|
|
|
# because that’s when gdbus-codegen was introduced. Support 1, 2 or 3
|
|
|
|
|
# component versions, but ignore the micro component if it’s present.
|
2020-01-27 11:11:46 +01:00
|
|
|
|
if args.glib_min_required:
|
2019-12-02 16:53:14 +01:00
|
|
|
|
try:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
parts = args.glib_min_required.split(".", 3)
|
|
|
|
|
glib_min_required = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0))
|
2019-12-02 16:53:14 +01:00
|
|
|
|
# Ignore micro component, but still validate it:
|
2020-12-15 10:43:35 +01:00
|
|
|
|
_ = int(parts[2] if len(parts) > 2 else 0) # noqa: F841
|
2019-12-02 16:53:14 +01:00
|
|
|
|
except (ValueError, IndexError):
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error(
|
|
|
|
|
"Unrecognized --glib-min-required string ‘{}’".format(
|
|
|
|
|
args.glib_min_required
|
|
|
|
|
)
|
|
|
|
|
)
|
2019-12-02 16:53:14 +01:00
|
|
|
|
|
2020-01-31 13:23:22 +01:00
|
|
|
|
if glib_min_required < (2, 30):
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error(
|
|
|
|
|
"Invalid --glib-min-required string ‘{}’: minimum "
|
|
|
|
|
"version is 2.30".format(args.glib_min_required)
|
|
|
|
|
)
|
2019-12-02 16:53:14 +01:00
|
|
|
|
else:
|
2020-01-27 11:11:46 +01:00
|
|
|
|
glib_min_required = (2, 30)
|
2019-12-02 16:53:14 +01:00
|
|
|
|
|
2020-01-27 11:36:03 +01:00
|
|
|
|
# And the maximum GLib version.
|
|
|
|
|
if args.glib_max_allowed:
|
|
|
|
|
try:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
parts = args.glib_max_allowed.split(".", 3)
|
|
|
|
|
glib_max_allowed = (int(parts[0]), int(parts[1] if len(parts) > 1 else 0))
|
2020-01-27 11:36:03 +01:00
|
|
|
|
# Ignore micro component, but still validate it:
|
2020-12-15 10:43:35 +01:00
|
|
|
|
_ = int(parts[2] if len(parts) > 2 else 0) # noqa: F841
|
2020-01-27 11:36:03 +01:00
|
|
|
|
except (ValueError, IndexError):
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error(
|
|
|
|
|
"Unrecognized --glib-max-allowed string ‘{}’".format(
|
|
|
|
|
args.glib_max_allowed
|
|
|
|
|
)
|
|
|
|
|
)
|
2020-01-27 11:36:03 +01:00
|
|
|
|
else:
|
|
|
|
|
glib_max_allowed = (config.MAJOR_VERSION, config.MINOR_VERSION)
|
|
|
|
|
|
2020-11-17 16:32:10 +01:00
|
|
|
|
# Only allow --symbol-decorator-define and --symbol-decorator-header if
|
|
|
|
|
# --symbol-decorator is used
|
2020-04-17 12:01:54 +02:00
|
|
|
|
if args.symbol_decorator is None:
|
|
|
|
|
if args.symbol_decorator_header or args.symbol_decorator_define:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error(
|
2020-11-17 16:32:10 +01:00
|
|
|
|
"--symbol-decorator-define and --symbol-decorator-header must "
|
|
|
|
|
"be used with --symbol-decorator"
|
2020-11-17 16:07:09 +01:00
|
|
|
|
)
|
2020-04-17 12:01:54 +02:00
|
|
|
|
|
2020-01-27 11:36:03 +01:00
|
|
|
|
# Round --glib-max-allowed up to the next stable release.
|
2020-11-17 16:07:09 +01:00
|
|
|
|
glib_max_allowed = (
|
|
|
|
|
glib_max_allowed[0],
|
|
|
|
|
glib_max_allowed[1] + (glib_max_allowed[1] % 2),
|
|
|
|
|
)
|
2020-01-27 11:36:03 +01:00
|
|
|
|
|
|
|
|
|
if glib_max_allowed < glib_min_required:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
print_error(
|
|
|
|
|
"Invalid versions: --glib-min-required ({}) must be "
|
|
|
|
|
"less than or equal to --glib-max-allowed ({})".format(
|
|
|
|
|
glib_min_required, glib_max_allowed
|
|
|
|
|
)
|
|
|
|
|
)
|
2020-01-27 11:36:03 +01:00
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
all_ifaces = []
|
2018-04-23 16:54:08 +02:00
|
|
|
|
input_files_basenames = []
|
2018-12-10 14:40:11 +01:00
|
|
|
|
for fname in sorted(args.files + args.xml_files):
|
2020-11-17 16:07:09 +01:00
|
|
|
|
with open(fname, "rb") as f:
|
2018-01-02 20:24:56 +01:00
|
|
|
|
xml_data = f.read()
|
2020-11-17 16:07:09 +01:00
|
|
|
|
parsed_ifaces = parser.parse_dbus_xml(
|
|
|
|
|
xml_data, h_type_implies_unix_fd=(glib_min_required >= (2, 64))
|
|
|
|
|
)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
all_ifaces.extend(parsed_ifaces)
|
2018-04-23 16:54:08 +02:00
|
|
|
|
input_files_basenames.append(os.path.basename(fname))
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
2018-04-17 15:13:05 +02:00
|
|
|
|
if args.annotate is not None:
|
2018-01-02 20:24:56 +01:00
|
|
|
|
apply_annotations(all_ifaces, args.annotate)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
2011-09-01 20:28:57 +02:00
|
|
|
|
for i in all_ifaces:
|
2018-01-02 20:24:56 +01:00
|
|
|
|
i.post_process(args.interface_prefix, args.c_namespace)
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
2018-01-02 20:24:56 +01:00
|
|
|
|
docbook = args.generate_docbook
|
2020-11-17 16:07:09 +01:00
|
|
|
|
docbook_gen = codegen_docbook.DocbookCodeGenerator(all_ifaces)
|
2011-04-18 20:23:19 +02:00
|
|
|
|
if docbook:
|
2020-11-17 16:32:10 +01:00
|
|
|
|
docbook_gen.generate(docbook, args.output_directory)
|
2011-04-18 20:23:19 +02:00
|
|
|
|
|
2022-12-29 13:42:12 +01:00
|
|
|
|
md = args.generate_md
|
|
|
|
|
md_gen = codegen_md.MdCodeGenerator(all_ifaces)
|
|
|
|
|
if md:
|
|
|
|
|
md_gen.generate(md, args.output_directory)
|
|
|
|
|
|
2022-01-19 14:55:29 +01:00
|
|
|
|
rst = args.generate_rst
|
|
|
|
|
rst_gen = codegen_rst.RstCodeGenerator(all_ifaces)
|
|
|
|
|
if rst:
|
|
|
|
|
rst_gen.generate(rst, args.output_directory)
|
|
|
|
|
|
2018-01-04 14:18:07 +01:00
|
|
|
|
if args.header:
|
2024-01-28 23:31:37 +01:00
|
|
|
|
with file_or_stdout(h_file) as outfile:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
gen = codegen.HeaderCodeGenerator(
|
|
|
|
|
all_ifaces,
|
|
|
|
|
args.c_namespace,
|
|
|
|
|
args.c_generate_object_manager,
|
|
|
|
|
args.c_generate_autocleanup,
|
|
|
|
|
header_name,
|
|
|
|
|
input_files_basenames,
|
|
|
|
|
args.pragma_once,
|
|
|
|
|
glib_min_required,
|
|
|
|
|
args.symbol_decorator,
|
|
|
|
|
args.symbol_decorator_header,
|
|
|
|
|
outfile,
|
|
|
|
|
)
|
2018-01-04 09:56:59 +01:00
|
|
|
|
gen.generate()
|
|
|
|
|
|
2018-01-04 14:18:07 +01:00
|
|
|
|
if args.body:
|
2024-01-28 23:31:37 +01:00
|
|
|
|
with file_or_stdout(c_file) as outfile:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
gen = codegen.CodeGenerator(
|
|
|
|
|
all_ifaces,
|
|
|
|
|
args.c_namespace,
|
|
|
|
|
args.c_generate_object_manager,
|
|
|
|
|
header_name,
|
|
|
|
|
input_files_basenames,
|
|
|
|
|
docbook_gen,
|
|
|
|
|
glib_min_required,
|
|
|
|
|
args.symbol_decorator_define,
|
|
|
|
|
outfile,
|
|
|
|
|
)
|
2018-01-04 09:56:59 +01:00
|
|
|
|
gen.generate()
|
2011-04-08 22:57:31 +02:00
|
|
|
|
|
2018-04-17 15:10:07 +02:00
|
|
|
|
if args.interface_info_header:
|
2024-01-28 23:31:37 +01:00
|
|
|
|
with file_or_stdout(h_file) as outfile:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
gen = codegen.InterfaceInfoHeaderCodeGenerator(
|
|
|
|
|
all_ifaces,
|
|
|
|
|
args.c_namespace,
|
|
|
|
|
header_name,
|
|
|
|
|
input_files_basenames,
|
|
|
|
|
args.pragma_once,
|
|
|
|
|
glib_min_required,
|
|
|
|
|
args.symbol_decorator,
|
|
|
|
|
args.symbol_decorator_header,
|
|
|
|
|
outfile,
|
|
|
|
|
)
|
2018-04-17 15:10:07 +02:00
|
|
|
|
gen.generate()
|
|
|
|
|
|
|
|
|
|
if args.interface_info_body:
|
2024-01-28 23:31:37 +01:00
|
|
|
|
with file_or_stdout(c_file) as outfile:
|
2020-11-17 16:07:09 +01:00
|
|
|
|
gen = codegen.InterfaceInfoBodyCodeGenerator(
|
|
|
|
|
all_ifaces,
|
|
|
|
|
args.c_namespace,
|
|
|
|
|
header_name,
|
|
|
|
|
input_files_basenames,
|
|
|
|
|
glib_min_required,
|
|
|
|
|
args.symbol_decorator_define,
|
|
|
|
|
outfile,
|
|
|
|
|
)
|
2018-04-17 15:10:07 +02:00
|
|
|
|
gen.generate()
|
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
2020-11-17 16:07:09 +01:00
|
|
|
|
|
2011-04-08 22:57:31 +02:00
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
codegen_main()
|