mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 09:36:46 +00:00
merged new xmlrpc-c revision 1472 from https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/trunk
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8545 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
#include "DataType.hpp"
|
||||
@@ -15,50 +17,66 @@ using namespace std;
|
||||
// Instances of DataType know how generate code fragments for manipulating
|
||||
// a specific XML-RPC data type.
|
||||
|
||||
string DataType::defaultParameterBaseName (int position) const {
|
||||
ostringstream name_stream;
|
||||
name_stream << typeName() << position << ends;
|
||||
string name(name_stream.str());
|
||||
return name;
|
||||
string
|
||||
DataType::defaultParameterBaseName(unsigned int const position) const {
|
||||
|
||||
ostringstream nameStream;
|
||||
|
||||
nameStream << typeName() << position;
|
||||
|
||||
return nameStream.str();
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class RawDataType
|
||||
//=========================================================================
|
||||
// We want to manipulate some XML-RPC data types as XmlRpcValue objects.
|
||||
|
||||
class RawDataType : public DataType {
|
||||
public:
|
||||
RawDataType (const string& type_name) : DataType(type_name) {}
|
||||
RawDataType(string const& typeName) : DataType(typeName) {}
|
||||
|
||||
virtual string parameterFragment (const string& base_name) const;
|
||||
virtual string inputConversionFragment (const string& base_name) const;
|
||||
virtual string returnTypeFragment () const;
|
||||
virtual string outputConversionFragment (const string& var_name) const;
|
||||
virtual string
|
||||
parameterFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
inputConversionFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
returnTypeFragment() const;
|
||||
|
||||
virtual string
|
||||
outputConversionFragment(string const& varName) const;
|
||||
};
|
||||
|
||||
string RawDataType::parameterFragment (const string& base_name) const {
|
||||
return "XmlRpcValue /*" + typeName() + "*/ " + base_name;
|
||||
|
||||
|
||||
string
|
||||
RawDataType::parameterFragment(string const& baseName) const {
|
||||
return "XmlRpcValue /*" + typeName() + "*/ " + baseName;
|
||||
}
|
||||
|
||||
string RawDataType::inputConversionFragment (const string& base_name) const {
|
||||
return base_name;
|
||||
|
||||
|
||||
string
|
||||
RawDataType::inputConversionFragment(string const& baseName) const {
|
||||
|
||||
return baseName;
|
||||
}
|
||||
|
||||
string RawDataType::returnTypeFragment () const {
|
||||
|
||||
|
||||
string
|
||||
RawDataType::returnTypeFragment() const {
|
||||
return "XmlRpcValue /*" + typeName() + "*/";
|
||||
}
|
||||
|
||||
string RawDataType::outputConversionFragment (const string& var_name) const {
|
||||
return var_name;
|
||||
|
||||
|
||||
string
|
||||
RawDataType::outputConversionFragment(string const& varName) const {
|
||||
|
||||
return varName;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class SimpleDataType
|
||||
//=========================================================================
|
||||
// Other types can be easily converted to and from a single native type.
|
||||
|
||||
class SimpleDataType : public DataType {
|
||||
string mNativeType;
|
||||
@@ -66,130 +84,185 @@ class SimpleDataType : public DataType {
|
||||
string mGetterFunc;
|
||||
|
||||
public:
|
||||
SimpleDataType (const string& type_name,
|
||||
const string& native_type,
|
||||
const string& maker_func,
|
||||
const string& getter_func);
|
||||
SimpleDataType(string const& typeName,
|
||||
string const& nativeType,
|
||||
string const& makerFunc,
|
||||
string const& getterFunc);
|
||||
|
||||
virtual string parameterFragment (const string& base_name) const;
|
||||
virtual string inputConversionFragment (const string& base_name) const;
|
||||
virtual string returnTypeFragment () const;
|
||||
virtual string outputConversionFragment (const string& var_name) const;
|
||||
virtual string
|
||||
parameterFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
inputConversionFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
returnTypeFragment() const;
|
||||
|
||||
virtual string
|
||||
outputConversionFragment(string const& varName) const;
|
||||
};
|
||||
|
||||
SimpleDataType::SimpleDataType (const string& type_name,
|
||||
const string& native_type,
|
||||
const string& maker_func,
|
||||
const string& getter_func)
|
||||
: DataType(type_name),
|
||||
mNativeType(native_type),
|
||||
mMakerFunc(maker_func),
|
||||
mGetterFunc(getter_func)
|
||||
{
|
||||
|
||||
|
||||
SimpleDataType::SimpleDataType(string const& typeName,
|
||||
string const& nativeType,
|
||||
string const& makerFunc,
|
||||
string const& getterFunc)
|
||||
: DataType(typeName),
|
||||
mNativeType(nativeType),
|
||||
mMakerFunc(makerFunc),
|
||||
mGetterFunc(getterFunc) {
|
||||
}
|
||||
|
||||
string SimpleDataType::parameterFragment (const string& base_name) const {
|
||||
return mNativeType + " " + base_name;
|
||||
|
||||
|
||||
string
|
||||
SimpleDataType::parameterFragment(string const& baseName) const {
|
||||
|
||||
return mNativeType + " const " + baseName;
|
||||
}
|
||||
|
||||
string SimpleDataType::inputConversionFragment (const string& base_name) const
|
||||
{
|
||||
return mMakerFunc + "(" + base_name + ")";
|
||||
|
||||
|
||||
string
|
||||
SimpleDataType::inputConversionFragment(string const& baseName) const {
|
||||
|
||||
return mMakerFunc + "(" + baseName + ")";
|
||||
}
|
||||
|
||||
string SimpleDataType::returnTypeFragment () const {
|
||||
|
||||
|
||||
string
|
||||
SimpleDataType::returnTypeFragment() const {
|
||||
|
||||
return mNativeType;
|
||||
}
|
||||
|
||||
string SimpleDataType::outputConversionFragment (const string& var_name) const
|
||||
{
|
||||
return var_name + "." + mGetterFunc + "()";
|
||||
|
||||
|
||||
string
|
||||
SimpleDataType::outputConversionFragment(string const& varName) const {
|
||||
return varName + "." + mGetterFunc + "()";
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class VoidDataType
|
||||
//=========================================================================
|
||||
// Some XML-RPC servers declare functions as void. Such functions have
|
||||
// an arbitrary return value which we should ignore.
|
||||
|
||||
class VoidDataType : public DataType {
|
||||
public:
|
||||
VoidDataType () : DataType("void") {}
|
||||
VoidDataType() : DataType("void") {}
|
||||
|
||||
virtual string parameterFragment (const string& base_name) const;
|
||||
virtual string inputConversionFragment (const string& base_name) const;
|
||||
virtual string returnTypeFragment () const;
|
||||
virtual string outputConversionFragment (const string& var_name) const;
|
||||
virtual string
|
||||
parameterFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
inputConversionFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
returnTypeFragment() const;
|
||||
|
||||
virtual string
|
||||
outputConversionFragment(string const& varName) const;
|
||||
};
|
||||
|
||||
string VoidDataType::parameterFragment (const string&) const {
|
||||
throw domain_error("Can't handle functions with 'void' arguments'");
|
||||
|
||||
}
|
||||
|
||||
string VoidDataType::inputConversionFragment (const string&) const {
|
||||
|
||||
string
|
||||
VoidDataType::parameterFragment(string const&) const {
|
||||
|
||||
throw domain_error("Can't handle functions with 'void' arguments'");
|
||||
}
|
||||
|
||||
string VoidDataType::returnTypeFragment () const {
|
||||
|
||||
|
||||
string
|
||||
VoidDataType::inputConversionFragment(string const&) const {
|
||||
|
||||
throw domain_error("Can't handle functions with 'void' arguments'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
VoidDataType::returnTypeFragment () const {
|
||||
|
||||
return "void";
|
||||
}
|
||||
|
||||
string VoidDataType::outputConversionFragment (const string&) const {
|
||||
|
||||
|
||||
string
|
||||
VoidDataType::outputConversionFragment(string const&) const {
|
||||
return "/* Return value ignored. */";
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function findDataType
|
||||
//=========================================================================
|
||||
// Given the name of an XML-RPC data type, try to find a corresponding
|
||||
// DataType object.
|
||||
|
||||
SimpleDataType intType ("int", "XmlRpcValue::int32",
|
||||
"XmlRpcValue::makeInt",
|
||||
"getInt");
|
||||
SimpleDataType boolType ("bool", "bool",
|
||||
"XmlRpcValue::makeBool",
|
||||
"getBool");
|
||||
SimpleDataType doubleType ("double", "double",
|
||||
"XmlRpcValue::makeDouble",
|
||||
"getDouble");
|
||||
SimpleDataType stringType ("string", "string",
|
||||
"XmlRpcValue::makeString",
|
||||
"getString");
|
||||
static SimpleDataType const intType ("int", "XmlRpcValue::int32",
|
||||
"XmlRpcValue::makeInt",
|
||||
"getInt");
|
||||
static SimpleDataType const boolType ("bool", "bool",
|
||||
"XmlRpcValue::makeBool",
|
||||
"getBool");
|
||||
static SimpleDataType const doubleType ("double", "double",
|
||||
"XmlRpcValue::makeDouble",
|
||||
"getDouble");
|
||||
static SimpleDataType const stringType ("string", "std::string",
|
||||
"XmlRpcValue::makeString",
|
||||
"getString");
|
||||
|
||||
RawDataType dateTimeType ("dateTime");
|
||||
RawDataType base64Type ("base64");
|
||||
RawDataType structType ("struct");
|
||||
RawDataType arrayType ("array");
|
||||
static RawDataType const dateTimeType ("dateTime");
|
||||
static RawDataType const base64Type ("base64");
|
||||
static RawDataType const structType ("struct");
|
||||
static RawDataType const arrayType ("array");
|
||||
|
||||
VoidDataType voidType;
|
||||
static VoidDataType const voidType;
|
||||
|
||||
const DataType& findDataType (const string& name) {
|
||||
|
||||
|
||||
const DataType&
|
||||
findDataType(string const& name) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Given the name of an XML-RPC data type, try to find a corresponding
|
||||
DataType object.
|
||||
-----------------------------------------------------------------------------*/
|
||||
if (name == "int" || name == "i4")
|
||||
return intType;
|
||||
return intType;
|
||||
else if (name == "boolean")
|
||||
return boolType;
|
||||
return boolType;
|
||||
else if (name == "double")
|
||||
return doubleType;
|
||||
return doubleType;
|
||||
else if (name == "string")
|
||||
return stringType;
|
||||
return stringType;
|
||||
else if (name == "dateTime.iso8601")
|
||||
return dateTimeType;
|
||||
return dateTimeType;
|
||||
else if (name == "base64")
|
||||
return base64Type;
|
||||
return base64Type;
|
||||
else if (name == "struct")
|
||||
return structType;
|
||||
return structType;
|
||||
else if (name == "array")
|
||||
return arrayType;
|
||||
return arrayType;
|
||||
else if (name == "void")
|
||||
return voidType;
|
||||
return voidType;
|
||||
else if (name == "INT")
|
||||
return intType;
|
||||
else if (name == "BOOLEAN")
|
||||
return boolType;
|
||||
else if (name == "DOUBLE")
|
||||
return doubleType;
|
||||
else if (name == "STRING")
|
||||
return stringType;
|
||||
else if (name == "DATETIME.ISO8601")
|
||||
return dateTimeType;
|
||||
else if (name == "BASE64")
|
||||
return base64Type;
|
||||
else if (name == "STRUCT")
|
||||
return structType;
|
||||
else if (name == "ARRAY")
|
||||
return arrayType;
|
||||
else if (name == "VOID")
|
||||
return voidType;
|
||||
else if (name == "NIL")
|
||||
return voidType;
|
||||
else
|
||||
throw domain_error("Unknown XML-RPC type " + name);
|
||||
|
||||
// This code should never be executed.
|
||||
XMLRPC_ASSERT(0);
|
||||
return intType;
|
||||
throw domain_error("Unknown XML-RPC type name '" + name + "'");
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ public:
|
||||
// Given a parameter position, calculate a unique base name for all
|
||||
// parameter-related variables.
|
||||
virtual std::string
|
||||
defaultParameterBaseName(int position) const;
|
||||
defaultParameterBaseName(unsigned int const position) const;
|
||||
|
||||
// Virtual functions for processing parameters.
|
||||
virtual std::string
|
||||
|
@@ -1,21 +1,32 @@
|
||||
ifeq ($(SRCDIR)x,x)
|
||||
SRCDIR = $(CURDIR)/../..
|
||||
BUILDDIR= $(SRCDIR)
|
||||
ifeq ($(SRCDIR),)
|
||||
updir = $(shell echo $(dir $(1)) | sed 's/.$$//')
|
||||
TOOLSDIR := $(call updir,$(CURDIR))
|
||||
SRCDIR := $(call updir,$(TOOLSDIR))
|
||||
BLDDIR := $(SRCDIR)
|
||||
endif
|
||||
SUBDIR := tools/xml-rpc-api2cpp
|
||||
|
||||
default: all
|
||||
|
||||
include $(BUILDDIR)/Makefile.config
|
||||
include $(BLDDIR)/config.mk
|
||||
|
||||
include ../Makefile.common
|
||||
include $(SRCDIR)/tools/common.mk
|
||||
|
||||
INCLUDES = -I$(SRCDIR) -I$(SRCDIR)/include
|
||||
INCLUDES = -I$(BLDDIR) -I$(BLDDIR)/include -I$(SRCDIR)/include
|
||||
|
||||
CXXFLAGS = $(INCLUDES) $(CXXFLAGS_COMMON) $(CFLAGS_PERSONAL) $(CADD)
|
||||
|
||||
LDFLAGS = $(CLIENT_LDFLAGS) $(LADD)
|
||||
LDFLAGS = $(LADD)
|
||||
|
||||
all: xml-rpc-api2cpp
|
||||
LDLIBS = -L$(BLDDIR)/src/cpp -lxmlrpc_cpp -lxmlrpc_server $(CLIENT_LDLIBS)
|
||||
|
||||
PROGS :=
|
||||
|
||||
ifeq ($(MUST_BUILD_CLIENT),yes)
|
||||
PROGS += xml-rpc-api2cpp
|
||||
endif
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
OBJECTS = \
|
||||
xml-rpc-api2cpp.o \
|
||||
@@ -30,17 +41,23 @@ xml-rpc-api2cpp: \
|
||||
$(LIBXMLRPC_CLIENT) \
|
||||
$(LIBXMLRPC_SERVER) \
|
||||
$(LIBXMLRPC) \
|
||||
$(LIBXML)
|
||||
$(LIBTOOL) --mode=link $(CXXLD) -o $@ $(LDFLAGS) $^
|
||||
$(LIBXMLRPC_XML) \
|
||||
$(LIBXMLRPC_UTIL)
|
||||
$(CXXLD) -o $@ $(LDFLAGS) $(OBJECTS) $(LDLIBS)
|
||||
|
||||
%.o:%.cpp
|
||||
$(LIBTOOL) --mode=compile $(CXX) -c $(CXXFLAGS) $<
|
||||
$(CXX) -c $(CXXFLAGS) $<
|
||||
|
||||
# This common.mk dependency makes sure the symlinks get built before
|
||||
# this make file is used for anything.
|
||||
|
||||
$(SRCDIR)/common.mk: srcdir blddir
|
||||
|
||||
include Makefile.depend
|
||||
|
||||
.PHONY: clean
|
||||
clean: clean-common
|
||||
rm -f xml-rpc-api2cpp
|
||||
rm -f $(PROGS)
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean distclean-common
|
||||
|
@@ -11,68 +11,74 @@ using namespace std;
|
||||
#include "XmlRpcClass.hpp"
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// XmlRpcClass
|
||||
//=========================================================================
|
||||
// This class stores information about a proxy class, and knows how to
|
||||
// generate code.
|
||||
XmlRpcClass::XmlRpcClass(string const& className) :
|
||||
mClassName(className) {}
|
||||
|
||||
XmlRpcClass::XmlRpcClass (string class_name)
|
||||
: mClassName(class_name)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcClass::XmlRpcClass (const XmlRpcClass& c)
|
||||
: mClassName(c.mClassName),
|
||||
mFunctions(c.mFunctions)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcClass& XmlRpcClass::operator= (const XmlRpcClass& c)
|
||||
{
|
||||
if (this == &c)
|
||||
return *this;
|
||||
mClassName = c.mClassName;
|
||||
mFunctions = c.mFunctions;
|
||||
XmlRpcClass::XmlRpcClass(XmlRpcClass const& c) :
|
||||
mClassName(c.mClassName),
|
||||
mFunctions(c.mFunctions) {}
|
||||
|
||||
|
||||
|
||||
XmlRpcClass&
|
||||
XmlRpcClass::operator= (XmlRpcClass const& c) {
|
||||
|
||||
if (this != &c) {
|
||||
this->mClassName = c.mClassName;
|
||||
this->mFunctions = c.mFunctions;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void XmlRpcClass::addFunction (const XmlRpcFunction& function)
|
||||
{
|
||||
|
||||
|
||||
void
|
||||
XmlRpcClass::addFunction(XmlRpcFunction const& function) {
|
||||
|
||||
mFunctions.push_back(function);
|
||||
}
|
||||
|
||||
void XmlRpcClass::printDeclaration (ostream&)
|
||||
{
|
||||
cout << "class " << mClassName << " {" << endl;
|
||||
cout << " XmlRpcClient mClient;" << endl;
|
||||
cout << endl;
|
||||
cout << "public:" << endl;
|
||||
cout << " " << mClassName << " (const XmlRpcClient& client)" << endl;
|
||||
cout << " : mClient(client) {}" << endl;
|
||||
cout << " " << mClassName << " (const string& server_url)" << endl;
|
||||
cout << " : mClient(XmlRpcClient(server_url)) {}" << endl;
|
||||
cout << " " << mClassName << " (const " << mClassName << "& o)" << endl;
|
||||
cout << " : mClient(o.mClient) {}" << endl;
|
||||
cout << endl;
|
||||
cout << " " << mClassName << "& operator= (const "
|
||||
<< mClassName << "& o) {" << endl;
|
||||
cout << " if (this != &o) mClient = o.mClient;" << endl;
|
||||
cout << " return *this;" << endl;
|
||||
cout << " }" << endl;
|
||||
|
||||
vector<XmlRpcFunction>::iterator f;
|
||||
|
||||
void
|
||||
XmlRpcClass::printDeclaration(ostream & out) const {
|
||||
|
||||
out << "class " << mClassName << " {" << endl;
|
||||
out << " XmlRpcClient mClient;" << endl;
|
||||
out << endl;
|
||||
out << "public:" << endl;
|
||||
out << " " << mClassName << " (const XmlRpcClient& client)" << endl;
|
||||
out << " : mClient(client) {}" << endl;
|
||||
out << " " << mClassName << " (const std::string& server_url)" << endl;
|
||||
out << " : mClient(XmlRpcClient(server_url)) {}" << endl;
|
||||
out << " " << mClassName << " (const " << mClassName << "& o)" << endl;
|
||||
out << " : mClient(o.mClient) {}" << endl;
|
||||
out << endl;
|
||||
out << " " << mClassName << "& operator= (const "
|
||||
<< mClassName << "& o) {" << endl;
|
||||
out << " if (this != &o) mClient = o.mClient;" << endl;
|
||||
out << " return *this;" << endl;
|
||||
out << " }" << endl;
|
||||
|
||||
vector<XmlRpcFunction>::const_iterator f;
|
||||
for (f = mFunctions.begin(); f < mFunctions.end(); ++f) {
|
||||
f->printDeclarations(cout);
|
||||
f->printDeclarations(out);
|
||||
}
|
||||
|
||||
cout << "};" << endl;
|
||||
out << "};" << endl;
|
||||
}
|
||||
|
||||
void XmlRpcClass::printDefinition (ostream&)
|
||||
{
|
||||
vector<XmlRpcFunction>::iterator f;
|
||||
|
||||
|
||||
void
|
||||
XmlRpcClass::printDefinition(ostream & out) const {
|
||||
|
||||
vector<XmlRpcFunction>::const_iterator f;
|
||||
|
||||
for (f = mFunctions.begin(); f < mFunctions.end(); ++f) {
|
||||
f->printDefinitions(cout, mClassName);
|
||||
f->printDefinitions(out, mClassName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,19 +1,22 @@
|
||||
#include <vector>
|
||||
|
||||
class XmlRpcClass {
|
||||
// An object of this class contains information about a proxy
|
||||
// class, and knows how to generate code.
|
||||
|
||||
std::string mClassName;
|
||||
std::vector<XmlRpcFunction> mFunctions;
|
||||
|
||||
|
||||
public:
|
||||
XmlRpcClass (std::string class_name);
|
||||
XmlRpcClass (const XmlRpcClass&);
|
||||
XmlRpcClass& operator= (const XmlRpcClass&);
|
||||
XmlRpcClass (std::string const& className);
|
||||
XmlRpcClass(XmlRpcClass const&);
|
||||
XmlRpcClass& operator= (XmlRpcClass const&);
|
||||
|
||||
std::string className () const { return mClassName; }
|
||||
|
||||
void addFunction (const XmlRpcFunction& function);
|
||||
|
||||
void printDeclaration (ostream& out);
|
||||
void printDefinition (ostream& out);
|
||||
void printDeclaration (ostream& out) const;
|
||||
void printDefinition (ostream& out) const;
|
||||
};
|
||||
|
@@ -1,137 +1,216 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
#include "DataType.hpp"
|
||||
#include "XmlRpcFunction.hpp"
|
||||
|
||||
using std::domain_error;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class XmlRpcFunction
|
||||
//=========================================================================
|
||||
// Contains everything we know about a given server function, and knows
|
||||
// how to print local bindings.
|
||||
XmlRpcFunction::XmlRpcFunction(string const& functionName,
|
||||
string const& methodName,
|
||||
string const& help,
|
||||
XmlRpcValue const signatureList) :
|
||||
mFunctionName(functionName),
|
||||
mMethodName(methodName),
|
||||
mHelp(help),
|
||||
mSynopsis(signatureList) {}
|
||||
|
||||
XmlRpcFunction::XmlRpcFunction(const string& function_name,
|
||||
const string& method_name,
|
||||
const string& help,
|
||||
XmlRpcValue synopsis)
|
||||
: mFunctionName(function_name), mMethodName(method_name),
|
||||
mHelp(help), mSynopsis(synopsis)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcFunction::XmlRpcFunction (const XmlRpcFunction& f)
|
||||
: mFunctionName(f.mFunctionName), mMethodName(f.mMethodName),
|
||||
mHelp(f.mHelp), mSynopsis(f.mSynopsis)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcFunction& XmlRpcFunction::operator= (const XmlRpcFunction& f) {
|
||||
if (this == &f)
|
||||
return *this;
|
||||
mFunctionName = f.mFunctionName;
|
||||
mMethodName = f.mMethodName;
|
||||
mHelp = f.mHelp;
|
||||
mSynopsis = f.mSynopsis;
|
||||
XmlRpcFunction::XmlRpcFunction(XmlRpcFunction const& f) :
|
||||
mFunctionName(f.mFunctionName),
|
||||
mMethodName(f.mMethodName),
|
||||
mHelp(f.mHelp),
|
||||
mSynopsis(f.mSynopsis) {}
|
||||
|
||||
|
||||
|
||||
XmlRpcFunction&
|
||||
XmlRpcFunction::operator= (XmlRpcFunction const& f) {
|
||||
|
||||
if (this != &f) {
|
||||
this->mFunctionName = f.mFunctionName;
|
||||
this->mMethodName = f.mMethodName;
|
||||
this->mHelp = f.mHelp;
|
||||
this->mSynopsis = f.mSynopsis;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void XmlRpcFunction::printDeclarations (ostream& out) {
|
||||
|
||||
// XXX - Do a sloppy job of printing documentation.
|
||||
out << endl << " /* " << mHelp << " */" << endl;
|
||||
|
||||
// Print each declaration.
|
||||
size_t end = mSynopsis.arraySize();
|
||||
for (size_t i = 0; i < end; i++)
|
||||
printDeclaration(out, i);
|
||||
}
|
||||
void
|
||||
XmlRpcFunction::printDeclarations(ostream & out) const {
|
||||
|
||||
void XmlRpcFunction::printDefinitions (ostream& out, const string& className) {
|
||||
size_t end = mSynopsis.arraySize();
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
out << endl;
|
||||
printDefinition(out, className, i);
|
||||
try {
|
||||
// Print the method help as a comment
|
||||
|
||||
out << endl << " /* " << mHelp << " */" << endl;
|
||||
|
||||
size_t end;
|
||||
|
||||
try {
|
||||
end = mSynopsis.arraySize();
|
||||
} catch (XmlRpcFault const& fault) {
|
||||
throw(logic_error("Failed to get size of signature array for "
|
||||
"method " + this->mFunctionName + ". " +
|
||||
fault.getFaultString()));
|
||||
}
|
||||
// Print the declarations for all the signatures of this
|
||||
// XML-RPC method.
|
||||
|
||||
for (size_t i = 0; i < end; ++i)
|
||||
printDeclaration(out, i);
|
||||
|
||||
} catch (exception const& e) {
|
||||
throw(logic_error("Failed to generate declarations for method " +
|
||||
this->mFunctionName + ". " + e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Print the parameter declarations.
|
||||
void XmlRpcFunction::printParameters (ostream& out, size_t synopsis_index) {
|
||||
size_t end = parameterCount(synopsis_index);
|
||||
bool first = true;
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out << ", ";
|
||||
|
||||
const DataType& ptype (parameterType(synopsis_index, i));
|
||||
string basename = ptype.defaultParameterBaseName(i + 1);
|
||||
out << ptype.parameterFragment(basename);
|
||||
|
||||
void
|
||||
XmlRpcFunction::printDefinitions(ostream & out,
|
||||
string const& className) const {
|
||||
|
||||
try {
|
||||
size_t const end(mSynopsis.arraySize());
|
||||
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
out << endl;
|
||||
printDefinition(out, className, i);
|
||||
}
|
||||
} catch (XmlRpcFault const& fault) {
|
||||
throw(logic_error("Failed to generate definitions for class " +
|
||||
this->mFunctionName + ". " +
|
||||
fault.getFaultString()));
|
||||
}
|
||||
}
|
||||
|
||||
void XmlRpcFunction::printDeclaration (ostream& out, size_t synopsis_index) {
|
||||
const DataType& rtype (returnType(synopsis_index));
|
||||
out << " " << rtype.returnTypeFragment() << " "
|
||||
<< mFunctionName << " (";
|
||||
printParameters(out, synopsis_index);
|
||||
out << ");" << endl;
|
||||
|
||||
|
||||
void
|
||||
XmlRpcFunction::printParameters(ostream & out,
|
||||
size_t const synopsisIndex) const {
|
||||
/*----------------------------------------------------------------------------
|
||||
Print the parameter declarations.
|
||||
-----------------------------------------------------------------------------*/
|
||||
size_t const end(parameterCount(synopsisIndex));
|
||||
|
||||
bool first;
|
||||
|
||||
first = true;
|
||||
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
if (!first)
|
||||
out << ", ";
|
||||
|
||||
DataType const& ptype(parameterType(synopsisIndex, i));
|
||||
string const basename(ptype.defaultParameterBaseName(i + 1));
|
||||
out << ptype.parameterFragment(basename);
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlRpcFunction::printDefinition (ostream& out,
|
||||
const string& className,
|
||||
size_t synopsis_index)
|
||||
{
|
||||
const DataType& rtype (returnType(synopsis_index));
|
||||
|
||||
|
||||
void
|
||||
XmlRpcFunction::printDeclaration(ostream & out,
|
||||
size_t const synopsisIndex) const {
|
||||
|
||||
try {
|
||||
DataType const& rtype(returnType(synopsisIndex));
|
||||
|
||||
out << " " << rtype.returnTypeFragment() << " "
|
||||
<< mFunctionName << " (";
|
||||
|
||||
printParameters(out, synopsisIndex);
|
||||
|
||||
out << ");" << endl;
|
||||
} catch (XmlRpcFault const& fault) {
|
||||
ostringstream msg;
|
||||
|
||||
msg << "Failed to generate header for signature "
|
||||
<< synopsisIndex
|
||||
<< " . "
|
||||
<< fault.getFaultString();
|
||||
|
||||
throw(logic_error(msg.str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
XmlRpcFunction::printDefinition(ostream & out,
|
||||
string const& className,
|
||||
size_t const synopsisIndex) const {
|
||||
|
||||
DataType const& rtype(returnType(synopsisIndex));
|
||||
|
||||
out << rtype.returnTypeFragment() << " "
|
||||
<< className << "::" << mFunctionName << " (";
|
||||
printParameters(out, synopsis_index);
|
||||
<< className << "::" << mFunctionName << " (";
|
||||
|
||||
printParameters(out, synopsisIndex);
|
||||
|
||||
out << ") {" << endl;
|
||||
out << " XmlRpcValue params = XmlRpcValue::makeArray();" << endl;
|
||||
out << " XmlRpcValue params(XmlRpcValue::makeArray());" << endl;
|
||||
|
||||
/* Emit code to convert the parameters into an array of XML-RPC objects. */
|
||||
size_t end = parameterCount(synopsis_index);
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
const DataType& ptype (parameterType(synopsis_index, i));
|
||||
string basename = ptype.defaultParameterBaseName(i + 1);
|
||||
out << " params.arrayAppendItem("
|
||||
<< ptype.inputConversionFragment(basename) << ");" << endl;
|
||||
size_t const end(parameterCount(synopsisIndex));
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
DataType const& ptype(parameterType(synopsisIndex, i));
|
||||
string const basename(ptype.defaultParameterBaseName(i + 1));
|
||||
out << " params.arrayAppendItem("
|
||||
<< ptype.inputConversionFragment(basename) << ");" << endl;
|
||||
}
|
||||
|
||||
/* Emit the function call.*/
|
||||
out << " XmlRpcValue result = this->mClient.call(\""
|
||||
<< mMethodName << "\", params);" << endl;
|
||||
out << " XmlRpcValue result(this->mClient.call(\""
|
||||
<< mMethodName << "\", params));" << endl;
|
||||
|
||||
/* Emit the return statement. */
|
||||
out << " return " << rtype.outputConversionFragment("result")
|
||||
<< ";" << endl;
|
||||
<< ";" << endl;
|
||||
out << "}" << endl;
|
||||
}
|
||||
|
||||
const DataType& XmlRpcFunction::returnType (size_t synopsis_index) {
|
||||
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||||
return findDataType(func_synop.arrayGetItem(0).getString());
|
||||
|
||||
|
||||
const DataType&
|
||||
XmlRpcFunction::returnType(size_t const synopsisIndex) const {
|
||||
|
||||
XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
|
||||
|
||||
return findDataType(funcSynop.arrayGetItem(0).getString());
|
||||
}
|
||||
|
||||
size_t XmlRpcFunction::parameterCount (size_t synopsis_index) {
|
||||
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||||
size_t size = func_synop.arraySize();
|
||||
|
||||
|
||||
size_t
|
||||
XmlRpcFunction::parameterCount(size_t const synopsisIndex) const {
|
||||
|
||||
XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
|
||||
size_t const size(funcSynop.arraySize());
|
||||
|
||||
if (size < 1)
|
||||
throw domain_error("Synopsis contained no items");
|
||||
throw domain_error("Synopsis contained no items");
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
const DataType& XmlRpcFunction::parameterType (size_t synopsis_index,
|
||||
size_t parameter_index)
|
||||
{
|
||||
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||||
XmlRpcValue param = func_synop.arrayGetItem(parameter_index + 1);
|
||||
|
||||
|
||||
DataType const&
|
||||
XmlRpcFunction::parameterType(size_t const synopsisIndex,
|
||||
size_t const parameterIndex) const {
|
||||
|
||||
XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
|
||||
XmlRpcValue const param(funcSynop.arrayGetItem(parameterIndex + 1));
|
||||
|
||||
return findDataType(param.getString());
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
@@ -6,6 +5,9 @@ using std::string;
|
||||
using std::ostream;
|
||||
|
||||
class XmlRpcFunction {
|
||||
// An object of this class contains everything we know about a
|
||||
// given XML-RPC method, and knows how to print local bindings.
|
||||
|
||||
string mFunctionName;
|
||||
string mMethodName;
|
||||
string mHelp;
|
||||
@@ -13,25 +15,25 @@ class XmlRpcFunction {
|
||||
|
||||
public:
|
||||
XmlRpcFunction(const string& function_name,
|
||||
const string& method_name,
|
||||
const string& help,
|
||||
XmlRpcValue synopsis);
|
||||
const string& method_name,
|
||||
const string& help,
|
||||
XmlRpcValue synopsis);
|
||||
|
||||
XmlRpcFunction (const XmlRpcFunction&);
|
||||
XmlRpcFunction& operator= (const XmlRpcFunction&);
|
||||
|
||||
void printDeclarations (ostream& out);
|
||||
void printDefinitions (ostream& out, const string& className);
|
||||
void printDeclarations (ostream& out) const;
|
||||
void printDefinitions (ostream& out, const string& className) const;
|
||||
|
||||
private:
|
||||
void printParameters (ostream& out, size_t synopsis_index);
|
||||
void printDeclaration (ostream& out, size_t synopsis_index);
|
||||
void printParameters (ostream& out, size_t synopsis_index) const;
|
||||
void printDeclaration (ostream& out, size_t synopsis_index) const;
|
||||
void printDefinition (ostream& out,
|
||||
const string& className,
|
||||
size_t synopsis_index);
|
||||
const string& className,
|
||||
size_t synopsis_index) const;
|
||||
|
||||
const DataType& returnType (size_t synopsis_index);
|
||||
size_t parameterCount (size_t synopsis_index);
|
||||
const DataType& returnType (size_t synopsis_index) const;
|
||||
size_t parameterCount (size_t synopsis_index) const;
|
||||
const DataType& parameterType (size_t synopsis_index,
|
||||
size_t parameter_index);
|
||||
size_t parameter_index) const;
|
||||
};
|
||||
|
@@ -14,144 +14,199 @@ using namespace std;
|
||||
#define VERSION "0.1"
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function get_class_info
|
||||
//=========================================================================
|
||||
// Connect to a remote server and extract the information we'll need to
|
||||
// build a proxy class.
|
||||
/*----------------------------------------------------------------------------
|
||||
Command line
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
XmlRpcClass get_class_info (string server_url,
|
||||
string class_prefix,
|
||||
string class_name)
|
||||
{
|
||||
// Create a place to store our data.
|
||||
XmlRpcClass info(class_name);
|
||||
class cmdlineInfo {
|
||||
public:
|
||||
string serverUrl;
|
||||
string methodPrefix;
|
||||
string localClass;
|
||||
|
||||
// Create a proxy class.
|
||||
SystemProxy system(server_url);
|
||||
cmdlineInfo(int const argc,
|
||||
const char ** const argv);
|
||||
|
||||
// Fetch the full list of methods, and process the ones we want.
|
||||
XmlRpcValue methods = system.listMethods();
|
||||
size_t end = methods.arraySize();
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
private:
|
||||
cmdlineInfo();
|
||||
};
|
||||
|
||||
// Break the method name into two pieces.
|
||||
string method_prefix;
|
||||
string function_name;
|
||||
string method_name = methods.arrayGetItem(i).getString();
|
||||
size_t last_dot = method_name.rfind('.');
|
||||
if (last_dot == string::npos) {
|
||||
function_name = method_name;
|
||||
} else {
|
||||
method_prefix = string(method_name, 0, last_dot);
|
||||
function_name = string(method_name, last_dot + 1);
|
||||
}
|
||||
|
||||
// Decide whether we care about this function.
|
||||
if (method_prefix == class_prefix) {
|
||||
|
||||
// Fetch some information about the function.
|
||||
string help = system.methodHelp(method_name);
|
||||
XmlRpcValue signature = system.methodSignature(method_name);
|
||||
cmdlineInfo::cmdlineInfo(int const argc,
|
||||
const char ** const argv) {
|
||||
|
||||
// Add this function to our class information.
|
||||
XmlRpcFunction func(function_name, method_name, help, signature);
|
||||
info.addFunction(func);
|
||||
}
|
||||
if (argc-1 != 3) {
|
||||
cerr << argv[0] << ": Usage:" << endl
|
||||
<< " xml-rpc-api2cpp <server_url> <method_prefix> <local_class>"
|
||||
<< endl << endl
|
||||
<< "Sample arguments:" << endl
|
||||
<< " server_url = http://localhost/RPC2" << endl
|
||||
<< " method_prefix = system" << endl
|
||||
<< " local_class = SystemProxy" << endl;
|
||||
exit(1);
|
||||
}
|
||||
this->serverUrl = string(argv[1]);
|
||||
this->methodPrefix = string(argv[2]);
|
||||
this->localClass = string(argv[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static XmlRpcClass
|
||||
getClassInfo(string const& serverUrl,
|
||||
string const& classPrefix,
|
||||
string const& className) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Connect to a remote server and extract the information we'll need to
|
||||
build a proxy class.
|
||||
-----------------------------------------------------------------------------*/
|
||||
XmlRpcClass info(className);
|
||||
|
||||
SystemProxy system(serverUrl);
|
||||
|
||||
XmlRpcValue const methods(system.listMethods());
|
||||
|
||||
size_t const end = methods.arraySize();
|
||||
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
|
||||
// Break the method name into two pieces.
|
||||
string const methodName(methods.arrayGetItem(i).getString());
|
||||
size_t const lastDot(methodName.rfind('.'));
|
||||
|
||||
string methodPrefix;
|
||||
string functionName;
|
||||
|
||||
if (lastDot == string::npos) {
|
||||
methodPrefix = "";
|
||||
functionName = methodName;
|
||||
} else {
|
||||
methodPrefix = string(methodName, 0, lastDot);
|
||||
functionName = string(methodName, lastDot + 1);
|
||||
}
|
||||
|
||||
if (methodPrefix == classPrefix) {
|
||||
// It's a method User cares about
|
||||
|
||||
string const help(system.methodHelp(methodName));
|
||||
XmlRpcValue const signatureList(
|
||||
system.methodSignature(methodName));
|
||||
|
||||
if (signatureList.getType() != XMLRPC_TYPE_ARRAY) {
|
||||
// It must be the string "undef", meaning the server
|
||||
// won't tell us any signatures.
|
||||
cerr << "Skipping method " << methodName << " "
|
||||
<< "because server does not report any signatures "
|
||||
<< "for it (via system.methodSignature method)"
|
||||
<< endl;
|
||||
} else {
|
||||
// Add this function to our class information.
|
||||
XmlRpcFunction const method(functionName,
|
||||
methodName,
|
||||
help,
|
||||
signatureList);
|
||||
info.addFunction(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function print_header
|
||||
//=========================================================================
|
||||
// Print a complete header for the specified class.
|
||||
|
||||
void print_header (ostream& out, XmlRpcClass& class_info) {
|
||||
string class_name = class_info.className();
|
||||
out << "// " << class_name << ".h - xmlrpc-c C++ proxy class" << endl;
|
||||
out << "// Auto-generated by xml-rpc-api2cpp." << endl;
|
||||
out << endl;
|
||||
static void
|
||||
printHeader(ostream & out,
|
||||
XmlRpcClass const& classInfo) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Print a complete header for the specified class.
|
||||
-----------------------------------------------------------------------------*/
|
||||
string const className(classInfo.className());
|
||||
|
||||
string header_symbol = "_" + class_name + "_H_";
|
||||
out << "#ifndef " << header_symbol << endl;
|
||||
out << "#define " << header_symbol << " 1" << endl;
|
||||
out << endl;
|
||||
out << "#include <XmlRpcCpp.h>" << endl;
|
||||
out << endl;
|
||||
try {
|
||||
out << "// " << className << ".h - xmlrpc-c C++ proxy class" << endl;
|
||||
out << "// Auto-generated by xml-rpc-api2cpp." << endl;
|
||||
out << endl;
|
||||
|
||||
class_info.printDeclaration(cout);
|
||||
string const headerSymbol("_" + className + "_H_");
|
||||
|
||||
out << endl;
|
||||
out << "#endif /* " << header_symbol << " */" << endl;
|
||||
}
|
||||
out << "#ifndef " << headerSymbol << endl;
|
||||
out << "#define " << headerSymbol << " 1" << endl;
|
||||
out << endl;
|
||||
out << "#include <xmlrpc-c/oldcppwrapper.hpp>" << endl;
|
||||
out << endl;
|
||||
|
||||
classInfo.printDeclaration(cout);
|
||||
|
||||
//=========================================================================
|
||||
// function print_cc_file
|
||||
//=========================================================================
|
||||
// Print a complete header for the specified class.
|
||||
|
||||
void print_cc_file (ostream& out, XmlRpcClass& class_info) {
|
||||
string class_name = class_info.className();
|
||||
out << "// " << class_name << ".cc - xmlrpc-c C++ proxy class" << endl;
|
||||
out << "// Auto-generated by xml-rpc-api2cpp." << endl;
|
||||
out << endl;
|
||||
|
||||
out << "#include <XmlRpcCpp.h>" << endl;
|
||||
out << "#include \"" << class_name << ".h\"" << endl;
|
||||
|
||||
class_info.printDefinition(cout);
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function main
|
||||
//=========================================================================
|
||||
// For now, just a test harness.
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
/* Parse our command-line arguments. */
|
||||
if (argc != 4) {
|
||||
cerr << argv[0] << ": Usage:" << endl
|
||||
<< " xml-rpc-api2cpp <server_url> <method_prefix> <local_class>"
|
||||
<< endl << endl
|
||||
<< "Sample arguments:" << endl
|
||||
<< " server_url = http://localhost/RPC2" << endl
|
||||
<< " method_prefix = system" << endl
|
||||
<< " local_class = SystemProxy" << endl;
|
||||
exit(1);
|
||||
out << endl;
|
||||
out << "#endif /* " << headerSymbol << " */" << endl;
|
||||
} catch (exception const& e) {
|
||||
throw(logic_error("Failed to generate header for class " +
|
||||
className + ". " + e.what()));
|
||||
}
|
||||
string server_url = argv[1];
|
||||
string method_prefix = argv[2];
|
||||
string local_class = argv[3];
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
printCppFile(ostream & out,
|
||||
XmlRpcClass const& classInfo) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Print a complete definition for the specified class.
|
||||
-----------------------------------------------------------------------------*/
|
||||
string const className(classInfo.className());
|
||||
|
||||
try {
|
||||
out << "// " << className << ".cc - xmlrpc-c C++ proxy class" << endl;
|
||||
out << "// Auto-generated by xml-rpc-api2cpp." << endl;
|
||||
out << endl;
|
||||
|
||||
out << "#include <xmlrpc-c/oldcppwrapper.hpp>" << endl;
|
||||
out << "#include \"" << className << ".h\"" << endl;
|
||||
|
||||
classInfo.printDefinition(cout);
|
||||
} catch (XmlRpcFault const& fault) {
|
||||
throw(logic_error("Failed to generate definition for class " +
|
||||
className + ". " + fault.getFaultString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(int const argc,
|
||||
const char ** const argv) {
|
||||
|
||||
string const progName(argv[0]);
|
||||
|
||||
cmdlineInfo const cmdline(argc, argv);
|
||||
|
||||
int retval;
|
||||
|
||||
int status = 0;
|
||||
XmlRpcClient::Initialize(NAME, VERSION);
|
||||
|
||||
try {
|
||||
XmlRpcClass system = get_class_info(server_url,
|
||||
method_prefix,
|
||||
local_class);
|
||||
print_header(cout, system);
|
||||
cout << endl;
|
||||
print_cc_file(cout, system);
|
||||
XmlRpcClass system = getClassInfo(cmdline.serverUrl,
|
||||
cmdline.methodPrefix,
|
||||
cmdline.localClass);
|
||||
printHeader(cout, system);
|
||||
cout << endl;
|
||||
printCppFile(cout, system);
|
||||
retval = 0;
|
||||
} catch (XmlRpcFault& fault) {
|
||||
cerr << argv[0] << ": XML-RPC fault #" << fault.getFaultCode()
|
||||
<< ": " << fault.getFaultString() << endl;
|
||||
status = 1;
|
||||
cerr << progName << ": XML-RPC fault #" << fault.getFaultCode()
|
||||
<< ": " << fault.getFaultString() << endl;
|
||||
retval = 1;
|
||||
} catch (logic_error& err) {
|
||||
cerr << argv[0] << ": " << err.what() << endl;
|
||||
status = 1;
|
||||
cerr << progName << ": " << err.what() << endl;
|
||||
retval = 1;
|
||||
} catch (...) {
|
||||
cerr << argv[0] << ": Unknown exception" << endl;
|
||||
status = 1;
|
||||
cerr << progName << ": Unknown exception" << endl;
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
XmlRpcClient::Terminate();
|
||||
|
||||
return status;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user