Logo Search packages:      
Sourcecode: libffado version File versions  Download package

xml2cpp.cpp

/*
 *
 *  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 "xml2cpp.h"

#include <dbus/dbus.h>

#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstring>

using namespace std;
using namespace DBus;

static const char* tab = "    ";

static const char* header = "\n\
/*\n\
 *    This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT!\n\
 */\n\
\n\
";

static const char* dbus_includes = "\n\
#include <dbus-c++/dbus.h>\n\
\n\
";

typedef map<string,string> TypeCache;

void usage( const char* argv0 )
{
      cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]"
           << endl << endl;
      exit(-1);
}

void underscorize( string& str )
{
      for(unsigned int i = 0; i < str.length(); ++i)
      {
            if(!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_';
      }
}

string stub_name( string name )
{
      underscorize(name);

      return "_" + name + "_stub";
}

int char_to_atomic_type( char t )
{
      if(strchr("ybnqiuxtdsgavre", t))
            return t;

      return DBUS_TYPE_INVALID;
}

const char* atomic_type_to_string( char t )
{
      static struct { const char type; const char *name; } atos[] =
      {
            { 'y', "::DBus::Byte" },
            { 'b', "::DBus::Bool" },
            { 'n', "::DBus::Int16" },
            { 'q', "::DBus::UInt16" },
            { 'i', "::DBus::Int32" },
            { 'u', "::DBus::UInt32" },
            { 'x', "::DBus::Int64" },
            { 't', "::DBus::UInt64" },
            { 'd', "::DBus::Double" },
            { 's', "::DBus::String" },
            { 'o', "::DBus::Path" },
            { 'g', "::DBus::Signature" },
            { 'v', "::DBus::Variant" },
            { '\0', "" }
      };
      int i;

      for(i = 0; atos[i].type; ++i)
      {
            if(atos[i].type == t) break;
      }
      return atos[i].name;
}

bool is_atomic_type( const string& type )
{
      return type.length() == 1 && char_to_atomic_type(type[0]) != DBUS_TYPE_INVALID;
}

void _parse_signature( const string& signature, string& type, unsigned int& i )
{
      for(; i < signature.length(); ++i)
      {
            switch(signature[i])
            {
                  case 'a':
                  {
                        switch(signature[++i])
                        {
                              case '{':
                              {
                                    type += "std::map< ";

                                    const char* atom = atomic_type_to_string(signature[++i]);
                                    if(!atom)
                                    {
                                          cerr << "invalid signature" << endl;
                                          exit(-1);
                                    }
                                    type += atom;
                                    type += ", ";
                                    ++i;
                                    break;
                              }
                              default:
                              {
                                    type += "std::vector< ";
                                    break;
                              }
                        }
                        _parse_signature(signature, type, i);
                        type += " >";
                        continue;
                  }
                  case '(':   
                  {
                        type += "::DBus::Struct< ";
                        ++i;
                        _parse_signature(signature, type, i);
                        type += " >";
                        continue;
                  }
                  case ')':
                  case '}':   
                  {
                        return;
                  }
                  default:
                  {
                        const char* atom = atomic_type_to_string(signature[i]);
                        if(!atom)
                        {
                              cerr << "invalid signature" << endl;
                              exit(-1);
                        }
                        type += atom;

                        if(signature[i+1] != ')' && signature[i+1] != '}' && i+1 < signature.length())
                        {
                              type += ", ";
                        }
                        break;
                  }
            }
      }
}

string signature_to_type( const string& signature )
{
      string type;
      unsigned int i = 0;
      _parse_signature(signature, type, i);
      return type;
}

void generate_proxy( Xml::Document& doc, const char* filename )
{
      cerr << "writing " << filename << endl;

      ofstream file(filename);
      if(file.bad())
      {
            cerr << "unable to write file " << filename << endl;
            exit(-1);
      }

      file << header;
      string filestring = filename;
      underscorize(filestring);

      string cond_comp = "__dbusxx__" + filestring + "__PROXY_MARSHAL_H";

      file << "#ifndef " << cond_comp << endl;
      file << "#define " << cond_comp << endl;

      file << dbus_includes;

      Xml::Node& root = *(doc.root);
      Xml::Nodes interfaces = root["interface"];

      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());

            string ifacename = iface.get("name");
            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;

            while(ss.str().find('.', ss.tellg()) != string::npos)
            {
                  getline(ss, nspace, '.');

                  file << "namespace " << nspace << " {" << endl;

                  ++nspaces;
            }
            file << endl;

            string ifaceclass;

            getline(ss, ifaceclass);

            cerr << "generating code for interface " << ifacename << "..." << endl;

            file << "class " << ifaceclass << endl
                 << " : public ::DBus::InterfaceProxy" << endl
                 << "{" << endl
                 << "public:" << endl
                 << endl
                 << tab << ifaceclass << "()" << endl
                 << tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl
                 << tab << "{" << endl;

            for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
            {
                  Xml::Node& signal = **si;

                  string marshname = "_" + signal.get("name") + "_stub";

                  file << tab << tab << "connect_signal(" 
                       << ifaceclass << ", " << signal.get("name") << ", " << stub_name(signal.get("name"))
                       << ");" << endl;
            }

            file << tab << "}" << endl
                 << endl;

            file << "public:" << endl
                 << endl
                 << tab << "/* methods exported by this interface," << endl
                 << tab << " * this functions will invoke the corresponding methods on the remote objects" << endl
                 << tab << " */" << endl;

            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");

                  if(args_out.size() == 0 || args_out.size() > 1 )
                  {
                        file << tab << "void ";
                  }
                  else if(args_out.size() == 1)
                  {
                        file << tab << signature_to_type(args_out.front()->get("type")) << " ";
                  }

                  file << method.get("name") << "( ";
                  
                  unsigned int i = 0;
                  for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
                  {
                        Xml::Node& arg = **ai;
                        file << "const " << signature_to_type(arg.get("type")) << "& ";

                        string arg_name = arg.get("name");
                        if(arg_name.length())
                              file << arg_name;
                        else
                              file << "argin" << i;

                        if((i+1 != args_in.size() || args_out.size() > 1))
                              file << ", ";
                  }

                  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;
                              file << signature_to_type(arg.get("type")) << "&";

                              string arg_name = arg.get("name");
                              if(arg_name.length())
                                    file << " " << arg_name;
                              else
                                    file << " argout" << i;

                              if(i+1 != args_out.size())
                                    file << ", ";
                        }
                  }
                  file << " )" << endl;

                  file << tab << "{" << endl
                       << tab << tab << "::DBus::CallMessage call;" << endl;

                  if(args_in.size() > 0)
                  {
                        file << tab << tab << "::DBus::MessageIter wi = call.writer();" << endl
                             << endl;
                  }

                  unsigned int j = 0;
                  for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++j)
                  {
                        Xml::Node& arg = **ai;
                        string arg_name = arg.get("name");
                        if(arg_name.length())
                              file << tab << tab << "wi << " << arg_name << ";" << endl;
                        else
                              file << tab << tab << "wi << argin" << j << ";" << endl;
                  }

                  file << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl
                       << tab << tab << "::DBus::Message ret = invoke_method(call);" << endl;


                  if(args_out.size() > 0)
                  {
                        file << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl
                             << endl;
                  }

                  if(args_out.size() == 1)
                  {
                        file << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout;" << endl;
                        file << tab << tab << "ri >> argout;" << endl;
                        file << tab << tab << "return argout;" << endl;
                  }
                  else 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;

                              string arg_name = arg.get("name");
                              if(arg_name.length())
                                    file << tab << tab << "ri >> " << arg.get("name") << ";" << endl;
                              else
                                    file << tab << tab << "ri >> argout" << i << ";" << endl;
                        }
                  }

                  file << tab << "}" << endl
                       << endl;
            }

            file << endl
                 << "public:" << endl
                 << endl
                 << tab << "/* signal handlers for this interface" << endl
                 << tab << " */" << endl;

            for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
            {
                  Xml::Node& signal = **si;
                  Xml::Nodes args = signal["arg"];

                  file << tab << "virtual void " << signal.get("name") << "( ";

                  unsigned int i = 0;
                  for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i)
                  {
                        Xml::Node& arg = **ai;
                        file << "const " << signature_to_type(arg.get("type")) << "& ";

                        string arg_name = arg.get("name");
                        if(arg_name.length())
                              file << arg_name;
                        else
                              file << "argin" << i;

                        if((ai+1 != args.end()))
                              file << ", ";
                  }
                  file << " ) = 0;" << endl;
            }

            file << endl
                 << "private:" << endl
                 << endl
                 << tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl
                 << tab << " */" << endl;

            for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
            {
                  Xml::Node& signal = **si;
                  Xml::Nodes args = signal["arg"];

                  file << tab << "void " << stub_name(signal.get("name")) << "( const ::DBus::SignalMessage& sig )" << endl
                       << tab << "{" << endl;

                  if(args.size() > 0)
                  {
                        file << tab << tab << "::DBus::MessageIter ri = sig.reader();" << endl
                             << endl;
                  }

                  unsigned int i = 0;
                  for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i)
                  {
                        Xml::Node& arg = **ai;
                        file << tab << tab << signature_to_type(arg.get("type")) << " " ;

                        string arg_name = arg.get("name");
                        if(arg_name.length())
                              file << arg_name << ";" << " ri >> " << arg_name << ";" << endl;
                        else
                              file << "arg" << i << ";" << " ri >> " << "arg" << i << ";" << endl;
                  }

                  file << tab << tab << signal.get("name") << "(";

                  unsigned int j = 0;
                  for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++j)
                  {
                        Xml::Node& arg = **ai;

                        string arg_name = arg.get("name");
                        if(arg_name.length())
                              file << arg_name;
                        else
                              file << "arg" << j;

                        if(ai+1 != args.end())
                              file << ", ";
                  }

                  file << ");" << endl;

                  file << tab << "}" << endl;
            }


            file << "};" << endl
                 << endl;

            for(unsigned int i = 0; i < nspaces; ++i)
            {
                  file << "} ";
            }
            file << endl;
      }

      file << "#endif//" << cond_comp << endl;

      file.close();
}

void generate_adaptor( Xml::Document& doc, const char* filename )
{
      cerr << "writing " << filename << endl;

      ofstream file(filename);
      if(file.bad())
      {
            cerr << "unable to write file " << filename << endl;
            exit(-1);
      }

      file << header;
      string filestring = filename;
      underscorize(filestring);

      string cond_comp = "__dbusxx__" + filestring + "__ADAPTOR_MARSHAL_H";

      file << "#ifndef " << cond_comp << endl
           << "#define " << cond_comp << endl;

      file << dbus_includes;

      Xml::Node& root = *(doc.root);
      Xml::Nodes interfaces = root["interface"];

      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());

            string ifacename = iface.get("name");
            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;

            while(ss.str().find('.', ss.tellg()) != string::npos)
            {
                  getline(ss, nspace, '.');

                  file << "namespace " << nspace << " {" << endl;

                  ++nspaces;
            }
            file << endl;

            string ifaceclass;

            getline(ss, ifaceclass);

            cerr << "generating code for interface " << ifacename << "..." << endl;

            file << "class " << ifaceclass << endl
                 << ": public ::DBus::InterfaceAdaptor" << endl
                 << "{" << endl
                 << "public:" << endl
                 << endl
                 << tab << ifaceclass << "()" << endl
                 << tab << ": ::DBus::InterfaceAdaptor(\"" << ifacename << "\")" << endl
                 << tab << "{" << endl;

            for(Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi)
            {
                  Xml::Node& property = **pi;

                  file << 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;
            }

            for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
            {
                  Xml::Node& method = **mi;

                  file << tab << tab << "register_method(" 
                       << ifaceclass << ", " << method.get("name") << ", "<< stub_name(method.get("name")) 
                       << ");" << endl;
            }

            file << tab << "}" << endl
                 << endl;

            file << tab << "::DBus::IntrospectedInterface* const introspect() const " << endl
                 << tab << "{" << endl;

            for(Xml::Nodes::iterator mi = ms.begin(); mi != ms.end(); ++mi)
            {
                  Xml::Node& method = **mi;
                  Xml::Nodes args = method["arg"];

                  file << 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;

                        file << tab << tab << tab << "{ ";

                        if(arg.get("name").length())
                        {
                              file << "\"" << arg.get("name") << "\", ";
                        }
                        else
                        {
                              file << "0, ";
                        }
                        file << "\"" << arg.get("type") << "\", "
                             << ( arg.get("direction") == "in" ? "true" : "false" )
                             << " }," << endl;
                  }
                  file << tab << tab << tab << "{ 0, 0, 0 }" << endl
                       << tab << tab << "};" << endl;
            }

            file << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_methods[] = " << endl
                 << tab << tab << "{" << endl;

            for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi)
            {
                  Xml::Node& method = **mi;
                  
                  file << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
            }

            file << tab << tab << tab << "{ 0, 0 }" << endl
                 << tab << tab << "};" << endl;

            file << 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;
                  
                  file << tab << tab << tab << "{ \"" << method.get("name") << "\", " << method.get("name") << "_args }," << endl;
            }

            file << tab << tab << tab << "{ 0, 0 }" << endl
                 << tab << tab << "};" << endl;

            file << 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;

                  file << 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;
            }


            file << tab << tab << tab << "{ 0, 0, 0, 0 }" << endl
                 << tab << tab << "};" << endl;

            file << 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;

            file << "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;

            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);

                  file << tab << "::DBus::PropertyAdaptor< " << type_name << " > " << name << ";" << endl;
            }

            file << endl;

            file << "public:" << endl
                 << endl
                 << tab << "/* methods exported by this interface," << endl
                 << tab << " * you will have to implement them in your ObjectAdaptor" << endl
                 << tab << " */" << endl;

            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");

                  file << tab << "virtual ";

                  if(args_out.size() == 0 || args_out.size() > 1 )
                  {
                        file << "void ";
                  }
                  else if(args_out.size() == 1)
                  {
                        file << signature_to_type(args_out.front()->get("type")) << " ";
                  }

                  file << method.get("name") << "( ";
                  
                  unsigned int i = 0;
                  for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
                  {
                        Xml::Node& arg = **ai;
                        file << "const " << signature_to_type(arg.get("type")) << "& ";

                        string arg_name = arg.get("name");
                        if(arg_name.length())
                              file << arg_name;

                        if((i+1 != args_in.size() || args_out.size() > 1))
                              file << ", ";
                  }

                  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;
                              file << signature_to_type(arg.get("type")) << "&";

                              string arg_name = arg.get("name");
                              if(arg_name.length())
                                    file << " " << arg_name;

                              if(i+1 != args_out.size())
                                    file << ", ";
                        }           
                  }
                  file << " ) = 0;" << endl;
            }

            file << endl
                 << "public:" << endl
                 << endl
                 << tab << "/* signal emitters for this interface" << endl
                 << tab << " */" << endl;

            for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si)
            {
                  Xml::Node& signal = **si;
                  Xml::Nodes args = signal["arg"];

                  file << tab << "void " << signal.get("name") << "( ";

                  unsigned int i = 0;
                  for(Xml::Nodes::iterator a = args.begin(); a != args.end(); ++a, ++i)
                  {
                        Xml::Node& arg = **a;

                        file << "const " << signature_to_type(arg.get("type")) << "& arg" << i+1;

                        if(i+1 != args.size())
                              file << ", ";
                  }

                  file << " )" << endl
                       << tab << "{" << endl
                       << tab << tab << "::DBus::SignalMessage sig(\"" << signal.get("name") <<"\");" << endl;;


                  if(args.size() > 0)
                  {
                        file << tab << tab << "::DBus::MessageIter wi = sig.writer();" << endl;

                        for(unsigned int i = 0; i < args.size(); ++i)
                        {
                              file << tab << tab << "wi << arg" << i+1 << ";" << endl;
                        }
                  }

                  file << tab << tab << "emit_signal(sig);" << endl
                       << tab << "}" << endl;
            }

            file << endl
                 << "private:" << endl
                 << endl
                 << tab << "/* unmarshalers (to unpack the DBus message before calling the actual interface method)" << endl
                 << tab << " */" << endl;

            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");

                  file << tab << "::DBus::Message " << stub_name(method.get("name")) << "( const ::DBus::CallMessage& call )" << endl
                       << tab << "{" << endl
                       << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl
                       << endl;

                  unsigned int i = 1;
                  for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i)
                  {
                        Xml::Node& arg = **ai;
                        file << tab << tab << signature_to_type(arg.get("type")) << " argin" << i << ";"
                             << " ri >> argin" << i << ";" << endl;
                  }

                  if(args_out.size() == 0)
                  {
                        file << tab << tab;
                  }
                  else if(args_out.size() == 1)
                  {
                        file << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout1 = ";
                  }
                  else
                  {
                        unsigned int i = 1;
                        for(Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++i)
                        {
                              Xml::Node& arg = **ao;
                              file << tab << tab << signature_to_type(arg.get("type")) << " argout" << i << ";" << endl;
                        }           
                        file << tab << tab;
                  }

                  file << method.get("name") << "(";

                  for(unsigned int i = 0; i < args_in.size(); ++i)
                  {
                        file << "argin" << i+1;

                        if((i+1 != args_in.size() || args_out.size() > 1))
                              file << ", ";
                  }

                  if(args_out.size() > 1)
                  for(unsigned int i = 0; i < args_out.size(); ++i)
                  {
                        file << "argout" << i+1;

                        if(i+1 != args_out.size())
                              file << ", ";
                  }

                  file << ");" << endl;

                  file << tab << tab << "::DBus::ReturnMessage reply(call);" << endl;

                  if(args_out.size() > 0)
                  {
                        file << tab << tab << "::DBus::MessageIter wi = reply.writer();" << endl;

                        for(unsigned int i = 0; i < args_out.size(); ++i)
                        {
                              file << tab << tab << "wi << argout" << i+1 << ";" << endl;
                        }
                  }

                  file << tab << tab << "return reply;" << endl;

                  file << tab << "}" << endl;
            }

            file << "};" << endl
                 << endl;

            for(unsigned int i = 0; i < nspaces; ++i)
            {
                  file << "} ";
            }
            file << endl;
      }

      file << "#endif//" << cond_comp << endl;

      file.close();
}

int main( int argc, char** argv )
{
      if(argc < 2)
      {
            usage(argv[0]);
      }

      bool proxy_mode, adaptor_mode;
      char *proxy, *adaptor;

      proxy_mode = false;
      proxy = 0;

      adaptor_mode = false;
      adaptor = 0;
      
      for(int a = 1; a < argc; ++a)
      {
            if(!strncmp(argv[a], "--proxy=", 8))
            {
                  proxy_mode = true;
                  proxy = argv[a] +8;
            }
            else
            if(!strncmp(argv[a], "--adaptor=", 10))
            {
                  adaptor_mode = true;
                  adaptor = argv[a] +10;
            }
      }

      if(!proxy_mode && !adaptor_mode) usage(argv[0]);

      ifstream xmlfile(argv[1]);

      if(xmlfile.bad())
      {
            cerr << "unable to open file " << argv[1] << endl;
            return -1;
      }

      Xml::Document doc;

      try
      {
            xmlfile >> doc;
            //cout << doc.to_xml();
      }
      catch(Xml::Error& e)
      {
            cerr << "error parsing " << argv[1] << ": " << e.what() << endl;
            return -1;
      }

      if(!doc.root)
      {
            cerr << "empty document" << endl;
            return -1;
      }

      if(proxy_mode)   generate_proxy(doc, proxy);
      if(adaptor_mode) generate_adaptor(doc, adaptor);

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index