
This patch modifies the dbusxx-xml2cpp's generate_adaptor function so that it prevents generation of the MessageIter ri in cases where an interface method has no input arguments. By making this element conditional based on the presence of input arguments we avoid "unused-but-set-variable" warning in code that uses the DBus-C++ adaptor glue headers. Change-Id: I0f04439bf7b2b3cecb9d639e61c2b6dedc148e51 Type: Code Improvement
725 lines
22 KiB
C++
725 lines
22 KiB
C++
/*
|
|
*
|
|
* D-Bus++ - C++ bindings for D-Bus
|
|
*
|
|
* Copyright (C) 2005-2007 Paolo Durante <shackan@gmail.com>
|
|
*
|
|
*
|
|
* 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
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* 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 Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <cstdlib>
|
|
#include <algorithm>
|
|
|
|
#include "generator_utils.h"
|
|
#include "generate_adaptor.h"
|
|
|
|
using namespace std;
|
|
using namespace DBus;
|
|
|
|
extern const char *tab;
|
|
extern const char *header;
|
|
extern const char *dbus_includes;
|
|
|
|
/*! Generate adaptor code for a XML introspection
|
|
*/
|
|
void generate_adaptor(Xml::Document &doc, const char *filename)
|
|
{
|
|
ostringstream body;
|
|
ostringstream head;
|
|
vector <string> include_vector;
|
|
|
|
head << header;
|
|
string filestring = filename;
|
|
underscorize(filestring);
|
|
|
|
string cond_comp = "__dbusxx__" + filestring + "__ADAPTOR_MARSHAL_H";
|
|
|
|
head << "#ifndef " << cond_comp << endl
|
|
<< "#define " << cond_comp << endl;
|
|
|
|
head << dbus_includes;
|
|
|
|
Xml::Node &root = *(doc.root);
|
|
Xml::Nodes interfaces = root["interface"];
|
|
|
|
// iterate over all interface definitions
|
|
for (Xml::Nodes::iterator i = interfaces.begin(); i != interfaces.end(); ++i)
|
|
{
|
|
Xml::Node &iface = **i;
|
|
Xml::Nodes methods = iface["method"];
|
|
Xml::Nodes signals = iface["signal"];
|
|
Xml::Nodes properties = iface["property"];
|
|
Xml::Nodes ms;
|
|
ms.insert(ms.end(), methods.begin(), methods.end());
|
|
ms.insert(ms.end(), signals.begin(), signals.end());
|
|
|
|
// gets the name of a interface: <interface name="XYZ">
|
|
string ifacename = iface.get("name");
|
|
|
|
// these interface names are skipped.
|
|
if (ifacename == "org.freedesktop.DBus.Introspectable"
|
|
|| ifacename == "org.freedesktop.DBus.Properties")
|
|
{
|
|
cerr << "skipping interface " << ifacename << endl;
|
|
continue;
|
|
}
|
|
|
|
istringstream ss(ifacename);
|
|
string nspace;
|
|
unsigned int nspaces = 0;
|
|
|
|
// prints all the namespaces defined with <interface name="X.Y.Z">
|
|
while (ss.str().find('.', ss.tellg()) != string::npos)
|
|
{
|
|
getline(ss, nspace, '.');
|
|
|
|
body << "namespace " << nspace << " {" << endl;
|
|
|
|
++nspaces;
|
|
}
|
|
body << endl;
|
|
|
|
string ifaceclass;
|
|
|
|
getline(ss, ifaceclass);
|
|
|
|
// a "_adaptor" is added to class name to distinguish between proxy and adaptor
|
|
ifaceclass += "_adaptor";
|
|
|
|
cerr << "generating code for interface " << ifacename << "..." << endl;
|
|
|
|
// the code from class definiton up to opening of the constructor is generated...
|
|
body << "class " << ifaceclass << endl
|
|
<< ": public ::DBus::InterfaceAdaptor" << endl
|
|
<< "{" << endl
|
|
<< "public:" << endl
|
|
<< endl
|
|
<< tab << ifaceclass << "()" << endl
|
|
<< tab << ": ::DBus::InterfaceAdaptor(\"" << ifacename << "\")" << endl
|
|
<< tab << "{" << endl;
|
|
|
|
// generates code to bind the properties
|
|
for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
|
|
{
|
|
Xml::Node &property = **pi;
|
|
|
|
body << tab << tab << "bind_property("
|
|
<< property.get("name") << ", "
|
|
<< "\"" << property.get("type") << "\", "
|
|
<< (property.get("access").find("read") != string::npos
|
|
? "true"
|
|
: "false")
|
|
<< ", "
|
|
<< (property.get("access").find("write") != string::npos
|
|
? "true"
|
|
: "false")
|
|
<< ");" << endl;
|
|
}
|
|
|
|
// generate code to register all methods
|
|
for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
|
|
{
|
|
Xml::Node &method = **mi;
|
|
|
|
body << tab << tab << "register_method("
|
|
<< ifaceclass << ", " << method.get("name") << ", " << stub_name(method.get("name"))
|
|
<< ");" << endl;
|
|
}
|
|
|
|
body << tab << "}" << endl
|
|
<< endl;
|
|
|
|
body << tab << "::DBus::IntrospectedInterface *introspect() const " << endl
|
|
<< tab << "{" << endl;
|
|
|
|
// generate the introspect arguments
|
|
for (Xml::Nodes::iterator mi = ms.begin(); mi != ms.end(); ++mi)
|
|
{
|
|
Xml::Node &method = **mi;
|
|
Xml::Nodes args = method["arg"];
|
|
|
|
body << tab << tab << "static ::DBus::IntrospectedArgument " << method.get("name") << "_args[] = " << endl
|
|
<< tab << tab << "{" << endl;
|
|
|
|
for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai)
|
|
{
|
|
Xml::Node &arg = **ai;
|
|
|
|
body << tab << tab << tab << "{ ";
|
|
|
|
if (arg.get("name").length())
|
|
{
|
|
body << "\"" << arg.get("name") << "\", ";
|
|
}
|
|
else
|
|
{
|
|
body << "0, ";
|
|
}
|
|
body << "\"" << arg.get("type") << "\", "
|
|
<< (arg.get("direction") == "in" ? "true" : "false")
|
|
<< " }," << endl;
|
|
}
|
|
body << tab << tab << tab << "{ 0, 0, 0 }" << endl
|
|
<< tab << tab << "};" << endl;
|
|
}
|
|
|
|
body << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_methods[] = " << endl
|
|
<< tab << tab << "{" << endl;
|
|
|
|
// generate the introspect methods
|
|
for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
|
|
{
|
|
Xml::Node &method = **mi;
|
|
|
|
body << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
|
|
}
|
|
|
|
body << tab << tab << tab << "{ 0, 0 }" << endl
|
|
<< tab << tab << "};" << endl;
|
|
|
|
body << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_signals[] = " << endl
|
|
<< tab << tab << "{" << endl;
|
|
|
|
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
|
|
{
|
|
Xml::Node &method = **si;
|
|
|
|
body << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
|
|
}
|
|
|
|
body << tab << tab << tab << "{ 0, 0 }" << endl
|
|
<< tab << tab << "};" << endl;
|
|
|
|
body << tab << tab << "static ::DBus::IntrospectedProperty " << ifaceclass << "_properties[] = " << endl
|
|
<< tab << tab << "{" << endl;
|
|
|
|
for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
|
|
{
|
|
Xml::Node &property = **pi;
|
|
|
|
body << tab << tab << tab << "{ "
|
|
<< "\"" << property.get("name") << "\", "
|
|
<< "\"" << property.get("type") << "\", "
|
|
<< (property.get("access").find("read") != string::npos
|
|
? "true"
|
|
: "false")
|
|
<< ", "
|
|
<< (property.get("access").find("write") != string::npos
|
|
? "true"
|
|
: "false")
|
|
<< " }," << endl;
|
|
}
|
|
|
|
|
|
body << tab << tab << tab << "{ 0, 0, 0, 0 }" << endl
|
|
<< tab << tab << "};" << endl;
|
|
|
|
// generate the Introspected interface
|
|
body << tab << tab << "static ::DBus::IntrospectedInterface " << ifaceclass << "_interface = " << endl
|
|
<< tab << tab << "{" << endl
|
|
<< tab << tab << tab << "\"" << ifacename << "\"," << endl
|
|
<< tab << tab << tab << ifaceclass << "_methods," << endl
|
|
<< tab << tab << tab << ifaceclass << "_signals," << endl
|
|
<< tab << tab << tab << ifaceclass << "_properties" << endl
|
|
<< tab << tab << "};" << endl
|
|
<< tab << tab << "return &" << ifaceclass << "_interface;" << endl
|
|
<< tab << "}" << endl
|
|
<< endl;
|
|
|
|
body << "public:" << endl
|
|
<< endl
|
|
<< tab << "/* properties exposed by this interface, use" << endl
|
|
<< tab << " * property() and property(value) to get and set a particular property" << endl
|
|
<< tab << " */" << endl;
|
|
|
|
// generate the properties code
|
|
for (Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
|
|
{
|
|
Xml::Node &property = **pi;
|
|
string name = property.get("name");
|
|
string type = property.get("type");
|
|
string type_name = signature_to_type(type);
|
|
|
|
body << tab << "::DBus::PropertyAdaptor< " << type_name << " > " << name << ";" << endl;
|
|
}
|
|
|
|
body << endl;
|
|
|
|
body << "public:" << endl
|
|
<< endl
|
|
<< tab << "/* methods exported by this interface," << endl
|
|
<< tab << " * you will have to implement them in your ObjectAdaptor" << endl
|
|
<< tab << " */" << endl;
|
|
|
|
// generate the methods code
|
|
for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
|
|
{
|
|
Xml::Node &method = **mi;
|
|
Xml::Nodes args = method["arg"];
|
|
Xml::Nodes args_in = args.select("direction", "in");
|
|
Xml::Nodes args_out = args.select("direction", "out");
|
|
Xml::Nodes annotations = args["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
body << tab << "virtual ";
|
|
|
|
// return type is 'void' if none or multible return values
|
|
if (args_out.size() == 0 || args_out.size() > 1)
|
|
{
|
|
body << "void ";
|
|
}
|
|
else if (args_out.size() == 1)
|
|
{
|
|
// generate basic or object return type
|
|
if (arg_object.length())
|
|
{
|
|
body << arg_object << " ";
|
|
}
|
|
else
|
|
{
|
|
body << signature_to_type(args_out.front()->get("type")) << " ";
|
|
}
|
|
}
|
|
|
|
// generate the method name
|
|
body << method.get("name") << "(";
|
|
|
|
// generate the methods 'in' variables
|
|
unsigned int i = 0;
|
|
for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
|
|
{
|
|
Xml::Node &arg = **ai;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_name = arg.get("name");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
// generate basic signature only if no object name available...
|
|
if (!arg_object.length())
|
|
{
|
|
body << "const " << signature_to_type(arg.get("type")) << "& ";
|
|
}
|
|
// ...or generate object style if available
|
|
else
|
|
{
|
|
body << "const " << arg_object << "& ";
|
|
|
|
// store a object name to later generate header includes
|
|
include_vector.push_back(arg_object);
|
|
}
|
|
|
|
if (arg_name.length())
|
|
body << arg_name;
|
|
|
|
if ((i + 1 != args_in.size() || args_out.size() > 1))
|
|
body << ", ";
|
|
}
|
|
|
|
// generate the method 'out' variables if multibe 'out' values exist
|
|
if (args_out.size() > 1)
|
|
{
|
|
unsigned int i = 0;
|
|
for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
|
|
{
|
|
Xml::Node &arg = **ao;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_name = arg.get("name");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
// generate basic signature only if no object name available...
|
|
if (!arg_object.length())
|
|
{
|
|
body << signature_to_type(arg.get("type")) << "& ";
|
|
}
|
|
// ...or generate object style if available
|
|
else
|
|
{
|
|
body << arg_object << "& ";
|
|
|
|
// store a object name to later generate header includes
|
|
include_vector.push_back(arg_object);
|
|
}
|
|
|
|
if (arg_name.length())
|
|
body << arg_name;
|
|
|
|
if (i + 1 != args_out.size())
|
|
body << ", ";
|
|
}
|
|
}
|
|
body << ") = 0;" << endl;
|
|
}
|
|
|
|
body << endl
|
|
<< "public:" << endl
|
|
<< endl
|
|
<< tab << "/* signal emitters for this interface" << endl
|
|
<< tab << " */" << endl;
|
|
|
|
// generate the signals code
|
|
for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
|
|
{
|
|
Xml::Node &signal = **si;
|
|
Xml::Nodes args = signal["arg"];
|
|
|
|
body << tab << "void " << signal.get("name") << "(";
|
|
|
|
// generate the signal arguments
|
|
unsigned int i = 0;
|
|
for (Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i)
|
|
{
|
|
Xml::Node &arg = **a;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
// generate basic signature only if no object name available...
|
|
if (!arg_object.length())
|
|
{
|
|
body << "const " << signature_to_type(arg.get("type")) << "& arg" << i + 1;
|
|
}
|
|
// ...or generate object style if available
|
|
else
|
|
{
|
|
body << "const " << arg_object << "& arg" << i + 1;
|
|
|
|
// store a object name to later generate header includes
|
|
include_vector.push_back(arg_object);
|
|
}
|
|
|
|
if (i + 1 != args.size())
|
|
body << ", ";
|
|
}
|
|
|
|
body << ")" << endl
|
|
<< tab << "{" << endl
|
|
<< tab << tab << "::DBus::SignalMessage sig(\"" << signal.get("name") << "\");" << endl;
|
|
|
|
// generate the signal body
|
|
if (!args.empty())
|
|
{
|
|
body << tab << tab << "::DBus::MessageIter wi = sig.writer();" << endl;
|
|
|
|
unsigned int i = 0;
|
|
for (Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i)
|
|
{
|
|
Xml::Node &arg = **a;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
if (arg_object.length())
|
|
{
|
|
body << tab << tab << signature_to_type(arg.get("type")) << " _arg" << i + 1 << ";" << endl;
|
|
body << tab << tab << "_arg" << i + 1 << " << " << "arg" << i + 1 << ";" << endl;
|
|
|
|
body << tab << tab << "wi << _arg" << i + 1 << ";" << endl;
|
|
}
|
|
else
|
|
{
|
|
body << tab << tab << "wi << arg" << i + 1 << ";" << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// emit the signal in method body
|
|
body << tab << tab << "emit_signal(sig);" << endl
|
|
<< tab << "}" << endl;
|
|
}
|
|
|
|
body << endl
|
|
<< "private:" << endl
|
|
<< endl
|
|
<< tab << "/* unmarshalers (to unpack the DBus message before calling the actual interface method)" << endl
|
|
<< tab << " */" << endl;
|
|
|
|
// generate the unmarshalers
|
|
for (Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
|
|
{
|
|
Xml::Node &method = **mi;
|
|
Xml::Nodes args = method["arg"];
|
|
Xml::Nodes args_in = args.select("direction", "in");
|
|
Xml::Nodes args_out = args.select("direction", "out");
|
|
|
|
body << tab << "::DBus::Message " << stub_name(method.get("name")) << "(const ::DBus::CallMessage &call)" << endl
|
|
<< tab << "{" << endl;
|
|
if(!args_in.empty())
|
|
{
|
|
body << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl;
|
|
body << endl;
|
|
}
|
|
|
|
// generate the 'in' variables
|
|
unsigned int i = 1;
|
|
for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
|
|
{
|
|
Xml::Node &arg = **ai;
|
|
|
|
body << tab << tab << signature_to_type(arg.get("type")) << " argin" << i << ";" << " ";
|
|
body << "ri >> argin" << i << ";" << endl;
|
|
}
|
|
|
|
// generate the 'in' object variables
|
|
i = 1;
|
|
for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
|
|
{
|
|
Xml::Node &arg = **ai;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
if (arg_object.length())
|
|
{
|
|
body << tab << tab << arg_object << " _argin" << i << ";";
|
|
body << " " << "_argin" << i << " << " << "argin" << i << ";" << endl;
|
|
}
|
|
}
|
|
|
|
// generate 'out' variables
|
|
if (!args_out.empty())
|
|
{
|
|
unsigned int i = 1;
|
|
for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
|
|
{
|
|
Xml::Node &arg = **ao;
|
|
|
|
body << tab << tab << signature_to_type(arg.get("type")) << " argout" << i;
|
|
|
|
if (args_out.size() == 1) // a single 'out' parameter will be assigned
|
|
{
|
|
body << " = ";
|
|
}
|
|
else // multible 'out' parameters will be handled as parameters below
|
|
{
|
|
body << ";" << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// generate 'out' object variables
|
|
if (!args_out.empty())
|
|
{
|
|
unsigned int i = 1;
|
|
for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
|
|
{
|
|
Xml::Node &arg = **ao;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
// generate object types
|
|
if (arg_object.length())
|
|
{
|
|
body << tab << tab << arg_object << " _argout" << i << ";" << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// generate in '<<' operation
|
|
i = 0;
|
|
for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
|
|
{
|
|
Xml::Node &arg = **ai;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
}
|
|
|
|
// do correct indent
|
|
if (args_out.size() != 1)
|
|
{
|
|
body << tab << tab;
|
|
}
|
|
|
|
body << method.get("name") << "(";
|
|
|
|
// generate call stub parameters
|
|
i = 0;
|
|
for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
|
|
{
|
|
Xml::Node &arg = **ai;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
if (arg_object.length())
|
|
{
|
|
body << "_argin" << i + 1;
|
|
}
|
|
else
|
|
{
|
|
body << "argin" << i + 1;
|
|
}
|
|
|
|
if ((i + 1 != args_in.size() || args_out.size() > 1))
|
|
body << ", ";
|
|
}
|
|
|
|
if (args_out.size() > 1)
|
|
{
|
|
i = 0;
|
|
for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
|
|
{
|
|
Xml::Node &arg = **ao;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
if (arg_object.length())
|
|
{
|
|
body << "_argout" << i + 1;
|
|
}
|
|
else
|
|
{
|
|
body << "argout" << i + 1;
|
|
}
|
|
|
|
if (i + 1 != args_out.size())
|
|
body << ", ";
|
|
}
|
|
}
|
|
|
|
body << ");" << endl;
|
|
|
|
body << tab << tab << "::DBus::ReturnMessage reply(call);" << endl;
|
|
|
|
if (!args_out.empty())
|
|
{
|
|
body << tab << tab << "::DBus::MessageIter wi = reply.writer();" << endl;
|
|
|
|
// generate out '<<' operation
|
|
i = 0;
|
|
for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
|
|
{
|
|
Xml::Node &arg = **ao;
|
|
Xml::Nodes annotations = arg["annotation"];
|
|
Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object");
|
|
string arg_object;
|
|
|
|
if (!annotations_object.empty())
|
|
{
|
|
arg_object = annotations_object.front()->get("value");
|
|
}
|
|
|
|
if (arg_object.length())
|
|
{
|
|
body << tab << tab << "argout" << i + 1 << " << " << "_argout" << i + 1 << ";" << endl;
|
|
}
|
|
}
|
|
|
|
for (unsigned int i = 0; i < args_out.size(); ++i)
|
|
{
|
|
body << tab << tab << "wi << argout" << i + 1 << ";" << endl;
|
|
}
|
|
}
|
|
|
|
body << tab << tab << "return reply;" << endl;
|
|
|
|
body << tab << "}" << endl;
|
|
}
|
|
|
|
body << "};" << endl
|
|
<< endl;
|
|
|
|
for (unsigned int i = 0; i < nspaces; ++i)
|
|
{
|
|
body << "} ";
|
|
}
|
|
body << endl;
|
|
}
|
|
|
|
body << "#endif //" << cond_comp << endl;
|
|
|
|
// remove all duplicates in the header include vector
|
|
vector<string>::const_iterator vec_end_it = unique(include_vector.begin(), include_vector.end());
|
|
|
|
for (vector<string>::const_iterator vec_it = include_vector.begin();
|
|
vec_it != vec_end_it;
|
|
++vec_it)
|
|
{
|
|
const string &include = *vec_it;
|
|
|
|
head << "#include " << "\"" << include << ".h" << "\"" << endl;
|
|
}
|
|
head << endl;
|
|
|
|
ofstream file(filename);
|
|
if (file.bad())
|
|
{
|
|
cerr << "unable to write file " << filename << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
file << head.str();
|
|
file << body.str();
|
|
|
|
file.close();
|
|
}
|