diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/generate_adaptor.cpp | 1358 | ||||
-rw-r--r-- | tools/generate_proxy.cpp | 1244 | ||||
-rw-r--r-- | tools/generator_utils.cpp | 270 | ||||
-rw-r--r-- | tools/generator_utils.h | 2 | ||||
-rw-r--r-- | tools/introspect.cpp | 62 | ||||
-rw-r--r-- | tools/introspect.h | 6 | ||||
-rw-r--r-- | tools/xml.cpp | 356 | ||||
-rw-r--r-- | tools/xml.h | 82 | ||||
-rw-r--r-- | tools/xml2cpp.cpp | 131 |
9 files changed, 1758 insertions, 1753 deletions
diff --git a/tools/generate_adaptor.cpp b/tools/generate_adaptor.cpp index 940e451..f7972be 100644 --- a/tools/generate_adaptor.cpp +++ b/tools/generate_adaptor.cpp @@ -40,683 +40,683 @@ extern const char *dbus_includes; */ 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 - << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl - << 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(); + 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 + << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl + << 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(); } diff --git a/tools/generate_proxy.cpp b/tools/generate_proxy.cpp index a90d025..bf1094a 100644 --- a/tools/generate_proxy.cpp +++ b/tools/generate_proxy.cpp @@ -40,626 +40,626 @@ extern const char *dbus_includes; */ void generate_proxy(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 + "__PROXY_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 "_proxy" is added to class name to distinguish between proxy and adaptor - ifaceclass += "_proxy"; - - 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::InterfaceProxy" << endl - << "{" << endl - << "public:" << endl - << endl - << tab << ifaceclass << "()" << endl - << tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl - << tab << "{" << endl; - - // generates code to connect all the signal stubs; this is still inside the constructor - for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) - { - Xml::Node &signal = **si; - - string marshname = "_" + signal.get("name") + "_stub"; - - body << tab << tab << "connect_signal(" - << ifaceclass << ", " << signal.get("name") << ", " << stub_name(signal.get("name")) - << ");" << endl; - } - - // the constructor ends here - body << tab << "}" << endl - << endl; - - // write public block header for properties - body << "public:" << endl << endl - << tab << "/* properties exported by this interface */" << endl; - - // this loop generates all properties - for (Xml::Nodes::iterator pi = properties.begin (); - pi != properties.end (); ++pi) - { - Xml::Node & property = **pi; - string prop_name = property.get ("name"); - string property_access = property.get ("access"); - if (property_access == "read" || property_access == "readwrite") - { - body << tab << tab << "const " << signature_to_type (property.get("type")) - << " " << prop_name << "() {" << endl; - body << tab << tab << tab << "::DBus::CallMessage call ;\n "; - body << tab << tab << tab - << "call.member(\"Get\"); call.interface(\"org.freedesktop.DBus.Properties\");" - << endl; - body << tab << tab << tab - << "::DBus::MessageIter wi = call.writer(); " << endl; - body << tab << tab << tab - << "const std::string interface_name = \"" << ifacename << "\";" - << endl; - body << tab << tab << tab - << "const std::string property_name = \"" << prop_name << "\";" - << endl; - body << tab << tab << tab << "wi << interface_name;" << endl; - body << tab << tab << tab << "wi << property_name;" << endl; - body << tab << tab << tab - << "::DBus::Message ret = this->invoke_method (call);" << endl; - // TODO: support invoke_method_NoReply for properties - body << tab << tab << tab - << "::DBus::MessageIter ri = ret.reader ();" << endl; - body << tab << tab << tab << "::DBus::Variant argout; " << endl; - body << tab << tab << tab << "ri >> argout;" << endl; - body << tab << tab << tab << "return argout;" << endl; - body << tab << tab << "};" << endl; - } - - if (property_access == "write" || property_access == "readwrite") - { - body << tab << tab << "void " << prop_name << "( const "<< signature_to_type (property.get("type")) << " & input" << ") {" << endl; - body << tab << tab << tab << "::DBus::CallMessage call ;\n "; - body << tab << tab << tab <<"call.member(\"Set\"); call.interface( \"org.freedesktop.DBus.Properties\");"<< endl; - body << tab << tab << tab <<"::DBus::MessageIter wi = call.writer(); " << endl; - body << tab << tab << tab <<"::DBus::Variant value;" << endl; - body << tab << tab << tab <<"::DBus::MessageIter vi = value.writer ();" << endl; - body << tab << tab << tab <<"vi << input;" << endl; - body << tab << tab << tab <<"const std::string interface_name = \"" << ifacename << "\";" << endl; - body << tab << tab << tab <<"const std::string property_name = \"" << prop_name << "\";"<< endl; - body << tab << tab << tab <<"wi << interface_name;" << endl; - body << tab << tab << tab <<"wi << property_name;" << endl; - body << tab << tab << tab <<"wi << value;" << endl; - body << tab << tab << tab <<"::DBus::Message ret = this->invoke_method (call);" << endl; - // TODO: support invoke_method_noreply for properties - body << tab << tab << "};" << endl; - } - } - - // write public block header for methods - body << "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; - - // this loop generates all methods - 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 method_annotations = method["annotation"]; - Xml::Nodes annotations_noreply = method_annotations.select("name","org.freedesktop.DBus.Method.NoReply"); - Xml::Nodes annotations_object = annotations.select("name","org.freedesktop.DBus.Object"); - string arg_object; - bool annotation_noreply_value = false; - - // parse method level noreply annotations - if (!annotations_noreply.empty()) - { - string annotation_noreply_value_str = annotations_noreply.front()->get("value"); - - if (annotation_noreply_value_str == "true") - { - annotation_noreply_value = true; - } - } - - if (!annotations_object.empty()) - { - arg_object = annotations_object.front()->get("value"); - } - - if (args_out.size() == 0 || args_out.size() > 1) - { - body << tab << "void "; - } - else if (args_out.size() == 1) - { - if (arg_object.length()) - { - body << tab << arg_object << " "; - } - else - { - body << tab << signature_to_type(args_out.front()->get("type")) << " "; - } - } - - body << method.get("name") << "("; - - // generate all 'in' arguments for a method signature - 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_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); - } - - string arg_name = arg.get("name"); - if (arg_name.length()) - body << arg_name; - else - body << "argin" << i; - - if ((i+1 != args_in.size() || args_out.size() > 1)) - body << ", "; - } - - if (args_out.size() > 1) - { - // generate all 'out' arguments for a method signature - unsigned int j = 0; - for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++j) - { - 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 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); - } - - string arg_name = arg.get("name"); - if (arg_name.length()) - body << " " << arg_name; - else - body << " argout" << j; - - if (j+1 != args_out.size()) - body << ", "; - } - } - body << ")" << endl; - - body << tab << "{" << endl - << tab << tab << "::DBus::CallMessage call;" << endl; - - if (!args_in.empty()) - { - body << tab << tab << "::DBus::MessageIter wi = call.writer();" << endl - << endl; - } - - // generate all 'in' arguments for a method body - i = 0; - for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i) - { - Xml::Node &arg = **ai; - string arg_name = arg.get("name"); - 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_name.length()) - { - arg_name = "argin"; - arg_name += toString <uint> (i); - } - - // generate extra code to wrap object - if (arg_object.length()) - { - body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl; - body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl; - - arg_name = string ("_") + arg_name; - } - - body << tab << tab << "wi << " << arg_name << ";" << endl; - } - - body << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl; - - // generate noreply/reply method calls - if (annotation_noreply_value) - { - if (args_out.size ()) - { - cerr << "Function: " << method.get("name") << ":" << endl; - cerr << "Option 'org.freedesktop.DBus.Method.NoReply' not allowed for methods with 'out' variables!" << endl << "-> Option ignored!" << endl; - - body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl; - } - else - { - body << tab << tab << "assert (invoke_method_noreply (call));" << endl; // will only assert in case of no memory - } - } - else - { - body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl; - } - - if (!args_out.empty()) - { - body << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl - << endl; - } - - // generate 'out' values as return if only one existing - if (args_out.size() == 1) - { - Xml::Nodes annotations = args_out["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 << " _argout;" << endl; - } - - body << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout;" << endl; - - body << tab << tab << "ri >> argout;" << endl; - - if (arg_object.length()) - { - body << tab << tab << "_argout << argout;" << endl; - body << tab << tab << "return _argout;" << endl; - } - else - { - body << tab << tab << "return argout;" << endl; - } - } - else if (args_out.size() > 1) - { - // generate multible 'out' value - 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"); - 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_name.length()) - { - arg_name = "argout" + toString <uint> (i); - } - - if (arg_object.length()) - { - body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl; - } - - if (arg_object.length()) - { - body << tab << tab << "ri >> " << "_" << arg_name << ";" << endl; - } - else - { - body << tab << tab << "ri >> " << arg_name << ";" << endl; - } - - if (arg_object.length()) - { - body << tab << tab << arg_name << " << " << "_" << arg_name << ";" << endl; - } - } - } - - body << tab << "}" << endl - << endl; - } - - // write public block header for signals - body << endl - << "public:" << endl - << endl - << tab << "/* signal handlers for this interface" << endl - << tab << " */" << endl; - - // this loop generates all signals - for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) - { - Xml::Node &signal = **si; - Xml::Nodes args = signal["arg"]; - - body << tab << "virtual void " << signal.get("name") << "("; - - // this loop generates all argument for a signal - unsigned int i = 0; - for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i) - { - Xml::Node &arg = **ai; - string arg_name = arg.get("name"); - 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")) << "& "; - } - // ...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; - else - body << "argin" << i; - - if ((ai+1 != args.end())) - body << ", "; - } - body << ") = 0;" << endl; - } - - // write private block header for unmarshalers - body << endl - << "private:" << endl - << endl - << tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl - << tab << " */" << endl; - - // generate all the unmarshalers - for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) - { - Xml::Node &signal = **si; - Xml::Nodes args = signal["arg"]; - - body << tab << "void " << stub_name(signal.get("name")) << "(const ::DBus::SignalMessage &sig)" << endl - << tab << "{" << endl; - - if (!args.empty()) - { - body << 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; - string arg_name = arg.get("name"); - 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"); - } - - body << tab << tab << signature_to_type(arg.get("type")) << " " ; - - // use a default if no arg name given - if (!arg_name.length()) - { - arg_name = "arg" + toString <uint> (i); - } - - body << arg_name << ";" << endl; - body << tab << tab << "ri >> " << arg_name << ";" << endl; - - // if a object type is used create a local variable and insert values with '<<' operation - if (arg_object.length()) - { - body << tab << tab << arg_object << " _" << arg_name << ";" << endl; - body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl; - - // store a object name to later generate header includes - include_vector.push_back (arg_object); - } - } - - body << tab << tab << signal.get("name") << "("; - - // generate all arguments for the call to the virtual function - 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"); - 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_name.length()) - { - arg_name = "arg" + toString <uint> (j); - } - - if (arg_object.length()) - { - body << "_" << arg_name; - } - else - { - body << arg_name; - } - - if (ai+1 != args.end()) - body << ", "; - } - - body << ");" << 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(); + ostringstream body; + ostringstream head; + vector <string> include_vector; + + head << header; + string filestring = filename; + underscorize(filestring); + + string cond_comp = "__dbusxx__" + filestring + "__PROXY_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 "_proxy" is added to class name to distinguish between proxy and adaptor + ifaceclass += "_proxy"; + + 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::InterfaceProxy" << endl + << "{" << endl + << "public:" << endl + << endl + << tab << ifaceclass << "()" << endl + << tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl + << tab << "{" << endl; + + // generates code to connect all the signal stubs; this is still inside the constructor + for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node &signal = **si; + + string marshname = "_" + signal.get("name") + "_stub"; + + body << tab << tab << "connect_signal(" + << ifaceclass << ", " << signal.get("name") << ", " << stub_name(signal.get("name")) + << ");" << endl; + } + + // the constructor ends here + body << tab << "}" << endl + << endl; + + // write public block header for properties + body << "public:" << endl << endl + << tab << "/* properties exported by this interface */" << endl; + + // this loop generates all properties + for (Xml::Nodes::iterator pi = properties.begin(); + pi != properties.end(); ++pi) + { + Xml::Node &property = **pi; + string prop_name = property.get("name"); + string property_access = property.get("access"); + if (property_access == "read" || property_access == "readwrite") + { + body << tab << tab << "const " << signature_to_type(property.get("type")) + << " " << prop_name << "() {" << endl; + body << tab << tab << tab << "::DBus::CallMessage call ;\n "; + body << tab << tab << tab + << "call.member(\"Get\"); call.interface(\"org.freedesktop.DBus.Properties\");" + << endl; + body << tab << tab << tab + << "::DBus::MessageIter wi = call.writer(); " << endl; + body << tab << tab << tab + << "const std::string interface_name = \"" << ifacename << "\";" + << endl; + body << tab << tab << tab + << "const std::string property_name = \"" << prop_name << "\";" + << endl; + body << tab << tab << tab << "wi << interface_name;" << endl; + body << tab << tab << tab << "wi << property_name;" << endl; + body << tab << tab << tab + << "::DBus::Message ret = this->invoke_method (call);" << endl; + // TODO: support invoke_method_NoReply for properties + body << tab << tab << tab + << "::DBus::MessageIter ri = ret.reader ();" << endl; + body << tab << tab << tab << "::DBus::Variant argout; " << endl; + body << tab << tab << tab << "ri >> argout;" << endl; + body << tab << tab << tab << "return argout;" << endl; + body << tab << tab << "};" << endl; + } + + if (property_access == "write" || property_access == "readwrite") + { + body << tab << tab << "void " << prop_name << "( const " << signature_to_type(property.get("type")) << " & input" << ") {" << endl; + body << tab << tab << tab << "::DBus::CallMessage call ;\n "; + body << tab << tab << tab << "call.member(\"Set\"); call.interface( \"org.freedesktop.DBus.Properties\");" << endl; + body << tab << tab << tab << "::DBus::MessageIter wi = call.writer(); " << endl; + body << tab << tab << tab << "::DBus::Variant value;" << endl; + body << tab << tab << tab << "::DBus::MessageIter vi = value.writer ();" << endl; + body << tab << tab << tab << "vi << input;" << endl; + body << tab << tab << tab << "const std::string interface_name = \"" << ifacename << "\";" << endl; + body << tab << tab << tab << "const std::string property_name = \"" << prop_name << "\";" << endl; + body << tab << tab << tab << "wi << interface_name;" << endl; + body << tab << tab << tab << "wi << property_name;" << endl; + body << tab << tab << tab << "wi << value;" << endl; + body << tab << tab << tab << "::DBus::Message ret = this->invoke_method (call);" << endl; + // TODO: support invoke_method_noreply for properties + body << tab << tab << "};" << endl; + } + } + + // write public block header for methods + body << "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; + + // this loop generates all methods + 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 method_annotations = method["annotation"]; + Xml::Nodes annotations_noreply = method_annotations.select("name", "org.freedesktop.DBus.Method.NoReply"); + Xml::Nodes annotations_object = annotations.select("name", "org.freedesktop.DBus.Object"); + string arg_object; + bool annotation_noreply_value = false; + + // parse method level noreply annotations + if (!annotations_noreply.empty()) + { + string annotation_noreply_value_str = annotations_noreply.front()->get("value"); + + if (annotation_noreply_value_str == "true") + { + annotation_noreply_value = true; + } + } + + if (!annotations_object.empty()) + { + arg_object = annotations_object.front()->get("value"); + } + + if (args_out.size() == 0 || args_out.size() > 1) + { + body << tab << "void "; + } + else if (args_out.size() == 1) + { + if (arg_object.length()) + { + body << tab << arg_object << " "; + } + else + { + body << tab << signature_to_type(args_out.front()->get("type")) << " "; + } + } + + body << method.get("name") << "("; + + // generate all 'in' arguments for a method signature + 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_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); + } + + string arg_name = arg.get("name"); + if (arg_name.length()) + body << arg_name; + else + body << "argin" << i; + + if ((i + 1 != args_in.size() || args_out.size() > 1)) + body << ", "; + } + + if (args_out.size() > 1) + { + // generate all 'out' arguments for a method signature + unsigned int j = 0; + for (Xml::Nodes::iterator ao = args_out.begin(); ao != args_out.end(); ++ao, ++j) + { + 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 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); + } + + string arg_name = arg.get("name"); + if (arg_name.length()) + body << " " << arg_name; + else + body << " argout" << j; + + if (j + 1 != args_out.size()) + body << ", "; + } + } + body << ")" << endl; + + body << tab << "{" << endl + << tab << tab << "::DBus::CallMessage call;" << endl; + + if (!args_in.empty()) + { + body << tab << tab << "::DBus::MessageIter wi = call.writer();" << endl + << endl; + } + + // generate all 'in' arguments for a method body + i = 0; + for (Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i) + { + Xml::Node &arg = **ai; + string arg_name = arg.get("name"); + 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_name.length()) + { + arg_name = "argin"; + arg_name += toString <uint> (i); + } + + // generate extra code to wrap object + if (arg_object.length()) + { + body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl; + body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl; + + arg_name = string("_") + arg_name; + } + + body << tab << tab << "wi << " << arg_name << ";" << endl; + } + + body << tab << tab << "call.member(\"" << method.get("name") << "\");" << endl; + + // generate noreply/reply method calls + if (annotation_noreply_value) + { + if (args_out.size()) + { + cerr << "Function: " << method.get("name") << ":" << endl; + cerr << "Option 'org.freedesktop.DBus.Method.NoReply' not allowed for methods with 'out' variables!" << endl << "-> Option ignored!" << endl; + + body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl; + } + else + { + body << tab << tab << "assert (invoke_method_noreply (call));" << endl; // will only assert in case of no memory + } + } + else + { + body << tab << tab << "::DBus::Message ret = invoke_method (call);" << endl; + } + + if (!args_out.empty()) + { + body << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl + << endl; + } + + // generate 'out' values as return if only one existing + if (args_out.size() == 1) + { + Xml::Nodes annotations = args_out["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 << " _argout;" << endl; + } + + body << tab << tab << signature_to_type(args_out.front()->get("type")) << " argout;" << endl; + + body << tab << tab << "ri >> argout;" << endl; + + if (arg_object.length()) + { + body << tab << tab << "_argout << argout;" << endl; + body << tab << tab << "return _argout;" << endl; + } + else + { + body << tab << tab << "return argout;" << endl; + } + } + else if (args_out.size() > 1) + { + // generate multible 'out' value + 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"); + 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_name.length()) + { + arg_name = "argout" + toString <uint> (i); + } + + if (arg_object.length()) + { + body << tab << tab << signature_to_type(arg.get("type")) << "_" << arg_name << ";" << endl; + } + + if (arg_object.length()) + { + body << tab << tab << "ri >> " << "_" << arg_name << ";" << endl; + } + else + { + body << tab << tab << "ri >> " << arg_name << ";" << endl; + } + + if (arg_object.length()) + { + body << tab << tab << arg_name << " << " << "_" << arg_name << ";" << endl; + } + } + } + + body << tab << "}" << endl + << endl; + } + + // write public block header for signals + body << endl + << "public:" << endl + << endl + << tab << "/* signal handlers for this interface" << endl + << tab << " */" << endl; + + // this loop generates all signals + for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node &signal = **si; + Xml::Nodes args = signal["arg"]; + + body << tab << "virtual void " << signal.get("name") << "("; + + // this loop generates all argument for a signal + unsigned int i = 0; + for (Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai, ++i) + { + Xml::Node &arg = **ai; + string arg_name = arg.get("name"); + 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")) << "& "; + } + // ...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; + else + body << "argin" << i; + + if ((ai + 1 != args.end())) + body << ", "; + } + body << ") = 0;" << endl; + } + + // write private block header for unmarshalers + body << endl + << "private:" << endl + << endl + << tab << "/* unmarshalers (to unpack the DBus message before calling the actual signal handler)" << endl + << tab << " */" << endl; + + // generate all the unmarshalers + for (Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) + { + Xml::Node &signal = **si; + Xml::Nodes args = signal["arg"]; + + body << tab << "void " << stub_name(signal.get("name")) << "(const ::DBus::SignalMessage &sig)" << endl + << tab << "{" << endl; + + if (!args.empty()) + { + body << 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; + string arg_name = arg.get("name"); + 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"); + } + + body << tab << tab << signature_to_type(arg.get("type")) << " " ; + + // use a default if no arg name given + if (!arg_name.length()) + { + arg_name = "arg" + toString <uint> (i); + } + + body << arg_name << ";" << endl; + body << tab << tab << "ri >> " << arg_name << ";" << endl; + + // if a object type is used create a local variable and insert values with '<<' operation + if (arg_object.length()) + { + body << tab << tab << arg_object << " _" << arg_name << ";" << endl; + body << tab << tab << "_" << arg_name << " << " << arg_name << ";" << endl; + + // store a object name to later generate header includes + include_vector.push_back(arg_object); + } + } + + body << tab << tab << signal.get("name") << "("; + + // generate all arguments for the call to the virtual function + 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"); + 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_name.length()) + { + arg_name = "arg" + toString <uint> (j); + } + + if (arg_object.length()) + { + body << "_" << arg_name; + } + else + { + body << arg_name; + } + + if (ai + 1 != args.end()) + body << ", "; + } + + body << ");" << 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(); } diff --git a/tools/generator_utils.cpp b/tools/generator_utils.cpp index 0e9ed24..2ccf313 100644 --- a/tools/generator_utils.cpp +++ b/tools/generator_utils.cpp @@ -42,136 +42,140 @@ const char *dbus_includes = "\n\ #include <cassert>\n\ "; -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"; -} - -const char *atomic_type_to_string(char t) -{ - static struct { char type; const char *name; } atos[] = - { - { 'y', "uint8_t" }, - { 'b', "bool" }, - { 'n', "int16_t" }, - { 'q', "uint16_t" }, - { 'i', "int32_t" }, - { 'u', "uint32_t" }, - { 'x', "int64_t" }, - { 't', "uint64_t" }, - { 'd', "double" }, - { 's', "std::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; -} - -static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false) -{ - /*cout << "signature: " << signature << endl; - cout << "type: " << type << endl; - cout << "i: " << i << ", signature[i]: " << signature[i] << endl;*/ - - for (; i < signature.length(); ++i) - { - switch (signature[i]) - { - case 'a': - { - switch (signature[++i]) - { - case '{': - { - type += "std::map< "; - ++i; - _parse_signature(signature, type, i); - type += " >"; - - break; - } - case '(': - { - type += "std::vector< ::DBus::Struct< "; - ++i; - _parse_signature(signature, type, i); - type += " > >"; - - break; - } - default: - { - type += "std::vector< "; - _parse_signature(signature, type, i, true); - - type += " >"; - - break; - } - } - break; - } - case '(': - { - type += "::DBus::Struct< "; - ++i; - - _parse_signature(signature, type, i); - - type += " >"; - break; - } - case ')': - case '}': - { - return; - } - default: - { - const char *atom = atomic_type_to_string(signature[i]); - if (!atom) - { - cerr << "invalid signature" << endl; - exit(-1); - } - type += atom; - - break; - } - } - - if (only_once) - return; - - if (i+1 < signature.length() && signature[i+1] != ')' && signature[i+1] != '}') - { - type += ", "; - } - } -} - -string signature_to_type(const string &signature) -{ - string type; - unsigned int i = 0; - _parse_signature(signature, type, i); - return type; -} + 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"; + } + + const char *atomic_type_to_string(char t) + { + static struct + { + char type; + const char *name; + } atos[] = + { + { 'y', "uint8_t" }, + { 'b', "bool" }, + { 'n', "int16_t" }, + { 'q', "uint16_t" }, + { 'i', "int32_t" }, + { 'u', "uint32_t" }, + { 'x', "int64_t" }, + { 't', "uint64_t" }, + { 'd', "double" }, + { 's', "std::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; + } + + static void _parse_signature(const string &signature, string &type, unsigned int &i, bool only_once = false) + { + /*cout << "signature: " << signature << endl; + cout << "type: " << type << endl; + cout << "i: " << i << ", signature[i]: " << signature[i] << endl;*/ + + for (; i < signature.length(); ++i) + { + switch (signature[i]) + { + case 'a': + { + switch (signature[++i]) + { + case '{': + { + type += "std::map< "; + ++i; + _parse_signature(signature, type, i); + type += " >"; + + break; + } + case '(': + { + type += "std::vector< ::DBus::Struct< "; + ++i; + _parse_signature(signature, type, i); + type += " > >"; + + break; + } + default: + { + type += "std::vector< "; + _parse_signature(signature, type, i, true); + + type += " >"; + + break; + } + } + break; + } + case '(': + { + type += "::DBus::Struct< "; + ++i; + + _parse_signature(signature, type, i); + + type += " >"; + break; + } + case ')': + case '}': + { + return; + } + default: + { + const char *atom = atomic_type_to_string(signature[i]); + if (!atom) + { + cerr << "invalid signature" << endl; + exit(-1); + } + type += atom; + + break; + } + } + + if (only_once) + return; + + if (i + 1 < signature.length() && signature[i + 1] != ')' && signature[i + 1] != '}') + { + type += ", "; + } + } + } + + string signature_to_type(const string &signature) + { + string type; + unsigned int i = 0; + _parse_signature(signature, type, i); + return type; + } diff --git a/tools/generator_utils.h b/tools/generator_utils.h index ea754df..276d228 100644 --- a/tools/generator_utils.h +++ b/tools/generator_utils.h @@ -35,7 +35,7 @@ void underscorize(std::string &str); /// create std::string from any number template <typename T> -std::string toString (const T &thing, int w = 0, int p = 0) +std::string toString(const T &thing, int w = 0, int p = 0) { std::ostringstream os; os << std::setw(w) << std::setprecision(p) << thing; diff --git a/tools/introspect.cpp b/tools/introspect.cpp index 8ce9f3a..a994ae1 100644 --- a/tools/introspect.cpp +++ b/tools/introspect.cpp @@ -34,46 +34,46 @@ static char *service; void niam(int sig) { - DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus(); + DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus(); - IntrospectedObject io(conn, path, service); + IntrospectedObject io(conn, path, service); - std::cout << io.Introspect(); + std::cout << io.Introspect(); - dispatcher.leave(); + dispatcher.leave(); } -int main(int argc, char ** argv) +int main(int argc, char **argv) { - signal(SIGTERM, niam); - signal(SIGINT, niam); - signal(SIGALRM, niam); + signal(SIGTERM, niam); + signal(SIGINT, niam); + signal(SIGALRM, niam); - if (argc == 1) - { - std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl; - } - else - { - if (strcmp(argv[1], "--system")) - { - systembus = false; - path = argv[1]; - service = argc > 2 ? argv[2] : 0; - } - else - { - systembus = true; - path = argv[2]; - service = argc > 3 ? argv[3] : 0; - } + if (argc == 1) + { + std::cerr << std::endl << "Usage: " << argv[0] << " [--system] <object_path> [<destination>]" << std::endl << std::endl; + } + else + { + if (strcmp(argv[1], "--system")) + { + systembus = false; + path = argv[1]; + service = argc > 2 ? argv[2] : 0; + } + else + { + systembus = true; + path = argv[2]; + service = argc > 3 ? argv[3] : 0; + } - DBus::default_dispatcher = &dispatcher; + DBus::default_dispatcher = &dispatcher; - alarm(1); + alarm(1); - dispatcher.enter(); - } + dispatcher.enter(); + } - return 0; + return 0; } diff --git a/tools/introspect.h b/tools/introspect.h index 1c6e326..ee7b1c5 100644 --- a/tools/introspect.h +++ b/tools/introspect.h @@ -36,9 +36,9 @@ class IntrospectedObject : public DBus::IntrospectableProxy, public DBus::Object { public: - IntrospectedObject(DBus::Connection &conn, const char *path, const char *service) - : DBus::ObjectProxy(conn, path, service) - {} + IntrospectedObject(DBus::Connection &conn, const char *path, const char *service) + : DBus::ObjectProxy(conn, path, service) + {} }; #endif//__DBUSXX_TOOLS_INTROSPECT_H diff --git a/tools/xml.cpp b/tools/xml.cpp index c363781..d3cc3ab 100644 --- a/tools/xml.cpp +++ b/tools/xml.cpp @@ -28,16 +28,16 @@ std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc) { - std::stringbuf xmlbuf; - in.get(xmlbuf, '\0'); - doc.from_xml(xmlbuf.str()); + std::stringbuf xmlbuf; + in.get(xmlbuf, '\0'); + doc.from_xml(xmlbuf.str()); - return in; + return in; } std::ostream &operator << (std::ostream &out, const DBus::Xml::Document &doc) { - return out << doc.to_xml(); + return out << doc.to_xml(); } using namespace DBus; @@ -45,209 +45,209 @@ using namespace DBus::Xml; Error::Error(const char *error, int line, int column) { - std::ostringstream estream; + std::ostringstream estream; - estream << "line " << line << ", column " << column << ": " << error; + estream << "line " << line << ", column " << column << ": " << error; - _error = estream.str(); + _error = estream.str(); } -Node::Node(const char *n, const char ** a) -: name(n) +Node::Node(const char *n, const char **a) + : name(n) { - if (a) - for (int i = 0; a[i]; i += 2) - { - _attrs[a[i]] = a[i+1]; + if (a) + for (int i = 0; a[i]; i += 2) + { + _attrs[a[i]] = a[i + 1]; - //debug_log("xml:\t%s = %s", a[i], a[i+1]); - } + //debug_log("xml:\t%s = %s", a[i], a[i+1]); + } } Nodes Nodes::operator[](const std::string &key) { - Nodes result; + Nodes result; - for (iterator i = begin(); i != end(); ++i) - { - Nodes part = (**i)[key]; + for (iterator i = begin(); i != end(); ++i) + { + Nodes part = (**i)[key]; - result.insert(result.end(), part.begin(), part.end()); - } - return result; + result.insert(result.end(), part.begin(), part.end()); + } + return result; } Nodes Nodes::select(const std::string &attr, const std::string &value) { - Nodes result; - - for (iterator i = begin(); i != end(); ++i) - { - if ((*i)->get(attr) == value) - result.insert(result.end(), *i); - } - return result; + Nodes result; + + for (iterator i = begin(); i != end(); ++i) + { + if ((*i)->get(attr) == value) + result.insert(result.end(), *i); + } + return result; } Nodes Node::operator[](const std::string &key) { - Nodes result; + Nodes result; - if (key.length() == 0) return result; + if (key.length() == 0) return result; - for (Children::iterator i = children.begin(); i != children.end(); ++i) - { - if (i->name == key) - result.push_back(&(*i)); - } - return result; + for (Children::iterator i = children.begin(); i != children.end(); ++i) + { + if (i->name == key) + result.push_back(&(*i)); + } + return result; } std::string Node::get(const std::string &attribute) { - if (_attrs.find(attribute) != _attrs.end()) - return _attrs[attribute]; - else - return ""; + if (_attrs.find(attribute) != _attrs.end()) + return _attrs[attribute]; + else + return ""; } void Node::set(const std::string &attribute, std::string value) { - if (value.length()) - _attrs[attribute] = value; - else - _attrs.erase(value); + if (value.length()) + _attrs[attribute] = value; + else + _attrs.erase(value); } std::string Node::to_xml() const { - std::string xml; - int depth = 0; + std::string xml; + int depth = 0; - _raw_xml(xml, depth); + _raw_xml(xml, depth); - return xml; + return xml; } void Node::_raw_xml(std::string &xml, int &depth) const { - xml.append(depth *2, ' '); - xml.append("<"+name); - - for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i) - { - xml.append(" "+i->first+"=\""+i->second+"\""); - } - - if (cdata.length() == 0 && children.size() == 0) - { - xml.append("/>\n"); - } - else - { - xml.append(">"); - - if (cdata.length()) - { - xml.append(cdata); - } - - if (children.size()) - { - xml.append("\n"); - depth++; - - for (Children::const_iterator i = children.begin(); i != children.end(); ++i) - { - i->_raw_xml(xml, depth); - } - - depth--; - xml.append(depth *2, ' '); - } - xml.append("</"+name+">\n"); - } + xml.append(depth * 2, ' '); + xml.append("<" + name); + + for (Attributes::const_iterator i = _attrs.begin(); i != _attrs.end(); ++i) + { + xml.append(" " + i->first + "=\"" + i->second + "\""); + } + + if (cdata.length() == 0 && children.size() == 0) + { + xml.append("/>\n"); + } + else + { + xml.append(">"); + + if (cdata.length()) + { + xml.append(cdata); + } + + if (children.size()) + { + xml.append("\n"); + depth++; + + for (Children::const_iterator i = children.begin(); i != children.end(); ++i) + { + i->_raw_xml(xml, depth); + } + + depth--; + xml.append(depth * 2, ' '); + } + xml.append("</" + name + ">\n"); + } } Document::Document() -: root(0), _depth(0) + : root(0), _depth(0) { } - + Document::Document(const std::string &xml) -: root(0), _depth(0) + : root(0), _depth(0) { - from_xml(xml); + from_xml(xml); } Document::~Document() { - delete root; + delete root; } struct Document::Expat { - static void start_doctype_decl_handler( - void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset - ); - static void end_doctype_decl_handler(void *data); - static void start_element_handler(void *data, const XML_Char *name, const XML_Char **atts); - static void character_data_handler(void *data, const XML_Char *chars, int len); - static void end_element_handler(void *data, const XML_Char *name); + static void start_doctype_decl_handler( + void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset + ); + static void end_doctype_decl_handler(void *data); + static void start_element_handler(void *data, const XML_Char *name, const XML_Char **atts); + static void character_data_handler(void *data, const XML_Char *chars, int len); + static void end_element_handler(void *data, const XML_Char *name); }; void Document::from_xml(const std::string &xml) { - _depth = 0; - delete root; - root = 0; - - XML_Parser parser = XML_ParserCreate("UTF-8"); - - XML_SetUserData(parser, this); - - XML_SetDoctypeDeclHandler( - parser, - Document::Expat::start_doctype_decl_handler, - Document::Expat::end_doctype_decl_handler - ); - - XML_SetElementHandler( - parser, - Document::Expat::start_element_handler, - Document::Expat::end_element_handler - ); - - XML_SetCharacterDataHandler( - parser, - Document::Expat::character_data_handler - ); - - XML_Status status = XML_Parse(parser, xml.c_str(), xml.length(), true); - - if (status == XML_STATUS_ERROR) - { - const char *error = XML_ErrorString(XML_GetErrorCode(parser)); - int line = XML_GetCurrentLineNumber(parser); - int column = XML_GetCurrentColumnNumber(parser); - - XML_ParserFree(parser); - - throw Error(error, line, column); - } - else - { - XML_ParserFree(parser); - } + _depth = 0; + delete root; + root = 0; + + XML_Parser parser = XML_ParserCreate("UTF-8"); + + XML_SetUserData(parser, this); + + XML_SetDoctypeDeclHandler( + parser, + Document::Expat::start_doctype_decl_handler, + Document::Expat::end_doctype_decl_handler + ); + + XML_SetElementHandler( + parser, + Document::Expat::start_element_handler, + Document::Expat::end_element_handler + ); + + XML_SetCharacterDataHandler( + parser, + Document::Expat::character_data_handler + ); + + XML_Status status = XML_Parse(parser, xml.c_str(), xml.length(), true); + + if (status == XML_STATUS_ERROR) + { + const char *error = XML_ErrorString(XML_GetErrorCode(parser)); + int line = XML_GetCurrentLineNumber(parser); + int column = XML_GetCurrentColumnNumber(parser); + + XML_ParserFree(parser); + + throw Error(error, line, column); + } + else + { + XML_ParserFree(parser); + } } std::string Document::to_xml() const { - return root->to_xml(); + return root->to_xml(); } void Document::Expat::start_doctype_decl_handler( - void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset + void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset ) { } @@ -258,56 +258,56 @@ void Document::Expat::end_doctype_decl_handler(void *data) void Document::Expat::start_element_handler(void *data, const XML_Char *name, const XML_Char **atts) { - Document *doc = (Document *)data; - - //debug_log("xml:%d -> %s", doc->_depth, name); - - if (!doc->root) - { - doc->root = new Node(name, atts); - } - else - { - Node::Children *cld = &(doc->root->children); - - for (int i = 1; i < doc->_depth; ++i) - { - cld = &(cld->back().children); - } - cld->push_back(Node(name, atts)); - - //std::cerr << doc->to_xml() << std::endl; - } - doc->_depth++; + Document *doc = (Document *)data; + + //debug_log("xml:%d -> %s", doc->_depth, name); + + if (!doc->root) + { + doc->root = new Node(name, atts); + } + else + { + Node::Children *cld = &(doc->root->children); + + for (int i = 1; i < doc->_depth; ++i) + { + cld = &(cld->back().children); + } + cld->push_back(Node(name, atts)); + + //std::cerr << doc->to_xml() << std::endl; + } + doc->_depth++; } void Document::Expat::character_data_handler(void *data, const XML_Char *chars, int len) { - Document *doc = (Document *)data; + Document *doc = (Document *)data; - Node *nod = doc->root; + Node *nod = doc->root; - for (int i = 1; i < doc->_depth; ++i) - { - nod = &(nod->children.back()); - } - int x, y; + for (int i = 1; i < doc->_depth; ++i) + { + nod = &(nod->children.back()); + } + int x, y; - x = 0; - y = len-1; + x = 0; + y = len - 1; - while (isspace(chars[y]) && y > 0) --y; - while (isspace(chars[x]) && x < y) ++x; + while (isspace(chars[y]) && y > 0) --y; + while (isspace(chars[x]) && x < y) ++x; - nod->cdata = std::string(chars, x, y+1); + nod->cdata = std::string(chars, x, y + 1); } void Document::Expat::end_element_handler(void *data, const XML_Char *name) { - Document *doc = (Document *)data; + Document *doc = (Document *)data; - //debug_log("xml:%d <- %s", doc->_depth, name); + //debug_log("xml:%d <- %s", doc->_depth, name); - doc->_depth--; + doc->_depth--; } diff --git a/tools/xml.h b/tools/xml.h index 6a8e69c..736a0dd 100644 --- a/tools/xml.h +++ b/tools/xml.h @@ -36,27 +36,29 @@ #include <iostream> #include <sstream> -namespace DBus { +namespace DBus +{ -namespace Xml { +namespace Xml +{ class Error : public std::exception { public: - Error(const char *error, int line, int column); + Error(const char *error, int line, int column); - ~Error() throw() - {} + ~Error() throw() + {} - const char *what() const throw() - { - return _error.c_str(); - } + const char *what() const throw() + { + return _error.c_str(); + } private: - std::string _error; + std::string _error; }; class Node; @@ -65,71 +67,71 @@ class Nodes : public std::vector<Node *> { public: - Nodes operator[](const std::string &key); + Nodes operator[](const std::string &key); - Nodes select(const std::string &attr, const std::string &value); + Nodes select(const std::string &attr, const std::string &value); }; class Node { public: - typedef std::map<std::string, std::string> Attributes; + typedef std::map<std::string, std::string> Attributes; - typedef std::vector<Node> Children; + typedef std::vector<Node> Children; - std::string name; - std::string cdata; - Children children; + std::string name; + std::string cdata; + Children children; - Node(std::string &n, Attributes &a) - : name(n), _attrs(a) - {} + Node(std::string &n, Attributes &a) + : name(n), _attrs(a) + {} - Node(const char *n, const char ** a = NULL); + Node(const char *n, const char **a = NULL); - Nodes operator[](const std::string &key); + Nodes operator[](const std::string &key); - std::string get(const std::string &attribute); + std::string get(const std::string &attribute); - void set(const std::string &attribute, std::string value); + void set(const std::string &attribute, std::string value); - std::string to_xml() const; + std::string to_xml() const; - Node &add(Node child) - { - children.push_back(child); - return children.back(); - } + Node &add(Node child) + { + children.push_back(child); + return children.back(); + } private: - void _raw_xml(std::string &xml, int &depth) const; + void _raw_xml(std::string &xml, int &depth) const; - Attributes _attrs; + Attributes _attrs; }; class Document { public: - struct Expat; + struct Expat; - Node *root; + Node *root; - Document(); + Document(); - Document(const std::string &xml); + Document(const std::string &xml); - ~Document(); + ~Document(); - void from_xml(const std::string &xml); + void from_xml(const std::string &xml); - std::string to_xml() const; + std::string to_xml() const; private: - int _depth; + int _depth; }; } /* namespace Xml */ diff --git a/tools/xml2cpp.cpp b/tools/xml2cpp.cpp index 7bfc3ea..ff031f8 100644 --- a/tools/xml2cpp.cpp +++ b/tools/xml2cpp.cpp @@ -40,9 +40,9 @@ using namespace DBus; void usage(const char *argv0) { - cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]" - << endl << endl; - exit(-1); + cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]" + << endl << endl; + exit(-1); } /*int char_to_atomic_type(char t) @@ -61,68 +61,67 @@ void usage(const char *argv0) }*/ -int main(int argc, char ** argv) +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; + 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; } |