sbus_codegen revision 73b68aa708e1ffa0e0ab5b021fa93ff3a0f484b1
3853N/A# Stef Walter <stefw@redhat.com> 3853N/A# Copyright (C) 2014 Red Hat 3853N/A# This program is free software; you can redistribute it and/or modify 3853N/A# it under the terms of the GNU General Public License as published by 3853N/A# the Free Software Foundation; either version 3 of the License, or 3853N/A# (at your option) any later version. 3853N/A# This program is distributed in the hope that it will be useful, 3853N/A# but WITHOUT ANY WARRANTY; without even the implied warranty of 3853N/A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3853N/A# GNU General Public License for more details. 3853N/A# You should have received a copy of the GNU General Public License 3853N/A# Some parser code from GLib 3853N/A# Copyright (C) 2008-2011 Red Hat, Inc. 3853N/A# This library is free software; you can redistribute it and/or 3853N/A# modify it under the terms of the GNU Lesser General Public 3853N/A# License as published by the Free Software Foundation; either 3853N/A# version 2 of the License, or (at your option) any later version. 3853N/A# This library is distributed in the hope that it will be useful, 3853N/A# but WITHOUT ANY WARRANTY; without even the implied warranty of 3853N/A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3853N/A# Lesser General Public License for more details. 3853N/A# You should have received a copy of the GNU Lesser General 3853N/A# Public License along with this library; if not, write to the 3853N/A# Free Software Foundation, Inc., 59 Temple Place, Suite 330, 3853N/A# Boston, MA 02111-1307, USA. 3853N/A# Portions by: David Zeuthen <davidz@redhat.com> 3853N/A# DBus interfaces are defined here: 3853N/A# The introspection data format has become the standard way to represent a 3853N/A# A word about annotations. These are extra flags or values that can be 3853N/A# assigned to anything. So far, the codegen supports this annotation: 3853N/A# - An annotation specified in the specification that tells us what C symbol 3853N/A# to generate for a given interface or method. By default the codegen will 3853N/A# build up a symbol name from the DBus name. 3853N/A# ----------------------------------------------------------------------------- 3853N/A # Lets us print problems like a compiler would 3853N/A# The basic types that we support marshalling right now. These 3853N/A# are the ones we can pass as basic arguments to libdbus directly. 3853N/A# If the dbus and sssd types are identical we pass things directly. 3853N/A# otherwise some copying is necessary. 3853N/A 'y': ( "DBUS_TYPE_BYTE", "uint8_t", "uint8_t" ), 3853N/A 'b': ( "DBUS_TYPE_BOOLEAN", "dbus_bool_t", "bool" ), 3853N/A 'n': ( "DBUS_TYPE_INT16", "int16_t", "int16_t" ), 3853N/A 'q': ( "DBUS_TYPE_UINT16", "uint16_t", "uint16_t" ), 3853N/A 'i': ( "DBUS_TYPE_INT32", "int32_t", "int32_t" ), 3853N/A 'u': ( "DBUS_TYPE_UINT32", "uint32_t", "uint32_t" ), 3853N/A 'x': ( "DBUS_TYPE_INT64", "int64_t", "int64_t" ), 3853N/A 't': ( "DBUS_TYPE_UINT64", "uint64_t", "uint64_t" ), 3853N/A 'd': ( "DBUS_TYPE_DOUBLE", "double", "double" ), 3853N/A 's': ( "DBUS_TYPE_STRING", "const char *", "const char *" ), 3853N/A 'o': ( "DBUS_TYPE_OBJECT_PATH", "const char *", "const char *" ), 3853N/A # If types are not identical, we can't do array (yet) 3853N/A# ----------------------------------------------------------------------------- 3853N/A # NOTE: Would like to use the following syntax for this function 3853N/A # but need to wait until python3 until it is supported: 3853N/A # def out(format, *args, new_line=True) 3853N/A return "int (*%s)(struct sbus_request *%s, void *%s%s)" % \ 3853N/A out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr);", signature) 3853N/A out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr)", signature) 3853N/A out(" if (!sbus_request_parse_or_finish(dbus_req,") 3853N/A out(" DBUS_TYPE_ARRAY, %s, &arg_%d, &len_%d,", out(" return EOK; /* request handled */") out(" return (handler)(dbus_req, dbus_req->intf->instance_data", new_line=False) out("static int %s(struct sbus_request *dbus_req, void *function_ptr)", out(" (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val", new_line=False) out(" out_val = prop_val == NULL ? \"\" : prop_val;") out(" out_val = prop_val == NULL ? \"/\" : prop_val;") out(" out_val = prop_val;") out("static int invoke_%s_get_all(struct sbus_request *dbus_req, void *function_ptr)", out(" DBusMessage *reply;") out(" dbus_bool_t dbret;") out(" DBusMessageIter iter;") out(" DBusMessageIter iter_dict;") out(" struct sbus_interface *intf = dbus_req->intf;") out(" const struct sbus_property_meta *property;") out(" reply = dbus_message_new_method_return(dbus_req->message);") out(" if (!reply) return ENOMEM;") out(" dbus_message_iter_init_append(reply, &iter);") out(" dbret = dbus_message_iter_open_container(") out(" &iter, DBUS_TYPE_ARRAY,") out(" DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING") out(" DBUS_TYPE_STRING_AS_STRING") out(" DBUS_TYPE_VARIANT_AS_STRING") out(" DBUS_DICT_ENTRY_END_CHAR_AS_STRING,") out(" if (!dbret) return ENOMEM;") out(" property = sbus_meta_find_property(intf->vtable->meta, \"%s\");", prop.c_name()) out(" if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {") out(" %s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);", prop.type) out(" %s_out_val = %s_prop_val == NULL ? \"\" : %s_prop_val;", out(" %s_out_val = %s_prop_val == NULL ? \"/\" : %s_prop_val;", out(" ret = sbus_add_array_as_variant_to_dict(&iter_dict, \"%s\", %s, (uint8_t*)%s_out_val, %s_prop_len, sizeof(%s));", prop.c_name(), prop.dbus_constant, prop.type, prop.type, prop.sssd_type) out(" if (ret != EOK) return ret;") out(" dbret = dbus_message_iter_close_container(&iter, &iter_dict);") out(" if (!dbret) return ENOMEM;") out(" return sbus_request_finish(dbus_req, reply);") out("static int %s(struct sbus_request *dbus_req, void *function_ptr);", out("int %s_finish(struct sbus_request *req%s)", out(" return sbus_request_return_and_finish(req,") out("DBUS_TYPE_ARRAY, %s, &arg_%s, len_%s,", out(" DBUS_TYPE_INVALID);") out(" NULL, /* no in_args */") out(" NULL, /* no out_args */") out(" NULL, /* no invoker */") out(" NULL, /* no args */") out("const struct sbus_property_meta %s__properties[] = {", iface.c_name()) out(" SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE,") out(" SBUS_PROPERTY_READABLE,") out(" SBUS_PROPERTY_WRITABLE,") out(" 0, /* not readable */") out(" NULL, /* no invoker */") out(" 0, /* not writable */") out(" NULL, /* no invoker */") out(" NULL, /* no methods */") out(" NULL, /* no signals */") out(" NULL, /* no properties */") out("/* The following definitions are auto-generated from %s */", basename) # always generate getall, for interfaces without properties # let's return an empty array # The sbus_interface structure out("int %s_finish(struct sbus_request *req%s);", out(" struct sbus_vtable vtable; /* derive from sbus_vtable */") out("/* The following declarations are auto-generated from %s */", basename) out("/* ------------------------------------------------------------------------") out(" * Various constants of interface and method names mostly for use by clients") out("/* ------------------------------------------------------------------------") out(" * These structures are filled in by implementors of the different") out(" * dbus interfaces to handle method calls.") out(" * Handler functions of type sbus_msg_handler_fn accept raw messages,") out(" * other handlers are typed appropriately. If a handler that is") out(" * set to NULL is invoked it will result in a") out(" * Handlers have a matching xxx_finish() function (unless the method has") out(" * accepts raw messages). These finish functions the") out(" * sbus_request_return_and_finish() with the appropriate arguments to") out(" * construct a valid reply. Once a finish function has been called, the") out(" * @dbus_req it was called with is freed and no longer valid.") out("/* ------------------------------------------------------------------------") out(" * DBus Interface Metadata") out(" * These structure definitions are filled in with the information about") out(" * the interfaces, methods, properties and so on.") out(" * The actual definitions are found in the accompanying C file next") out(" * to this header.") # ----------------------------------------------------------------------------- from standard XML Introspect data.") help="'header' or 'source' (default: header)", help="Set output file name (default: stdout)", help="name of a header to #include", print >> sys.stderr, "sbus_codegen: no input file specified" print >> sys.stderr, "sbus_codegen: specify --mode=header or --mode=source" # Write output at end to be nice to 'make'