diff options
-rw-r--r-- | php/src/php7/Communicator.cpp | 89 | ||||
-rw-r--r-- | php/src/php7/Init.cpp | 4 | ||||
-rw-r--r-- | php/src/php7/Properties.cpp | 10 | ||||
-rw-r--r-- | python/modules/IcePy/Communicator.cpp | 11 | ||||
-rw-r--r-- | ruby/src/IceRuby/Communicator.cpp | 97 |
5 files changed, 149 insertions, 62 deletions
diff --git a/php/src/php7/Communicator.cpp b/php/src/php7/Communicator.cpp index 50e124a2615..4c7a9fd5d8b 100644 --- a/php/src/php7/Communicator.cpp +++ b/php/src/php7/Communicator.cpp @@ -1101,52 +1101,82 @@ ZEND_FUNCTION(Ice_initialize) zval* zvinit = 0; // - // Accept the following invocations: + // The argument options are: // - // initialize(array, InitializationData) - // initialize(array) - // initialize(InitializationData) // initialize() + // initialize(args) + // initialize(initData) + // initialize(args, initData) + // initialize(initData, args) // - bool hasArgs = false; - if(ZEND_NUM_ARGS()) + + if(ZEND_NUM_ARGS() > 2) { - if(Z_TYPE(args[0]) == IS_ARRAY) + runtimeError("too many arguments to initialize"); + RETURN_NULL(); + } + + if(ZEND_NUM_ARGS() > 0) + { + zval* arg = &args[0]; + while(Z_TYPE_P(arg) == IS_REFERENCE) + { + arg = Z_REFVAL_P(arg); + } + + if(Z_TYPE_P(arg) == IS_ARRAY) + { + zvargs = arg; + } + else if(Z_TYPE_P(arg) == IS_OBJECT && Z_OBJCE_P(arg) == initClass) { - if(!extractStringArray(&args[0], seq)) + zvinit = arg; + } + else + { + invalidArgument("initialize expects an argument list, an InitializationData object, or both"); + RETURN_NULL(); + } + } + + if(ZEND_NUM_ARGS() > 1) + { + zval* arg = &args[1]; + while(Z_TYPE_P(arg) == IS_REFERENCE) + { + arg = Z_REFVAL_P(arg); + } + + if(Z_TYPE_P(arg) == IS_ARRAY) + { + if(zvargs) { + invalidArgument("unexpected array argument to initialize"); RETURN_NULL(); } - zvargs = &args[0]; - hasArgs = true; - if(ZEND_NUM_ARGS() > 1) - { - if(Z_TYPE(args[1]) != IS_OBJECT || Z_OBJCE(args[1]) != initClass) - { - string s = zendTypeToString(Z_TYPE(args[1])); - invalidArgument("expected InitializationData object but received %s", s.c_str()); - RETURN_NULL(); - } - zvinit = &args[1]; - } + zvargs = arg; } - else if(Z_TYPE(args[0]) == IS_OBJECT && Z_OBJCE(args[0]) == initClass) + else if(Z_TYPE_P(arg) == IS_OBJECT && Z_OBJCE_P(arg) == initClass) { - if(ZEND_NUM_ARGS() > 1) + if(zvinit) { - runtimeError("too many arguments"); + invalidArgument("unexpected InitializationData argument to initialize"); RETURN_NULL(); } - zvinit = &args[0]; + zvinit = arg; } else { - string s = zendTypeToString(Z_TYPE(args[0])); - invalidArgument("unexpected argument type %s", s.c_str()); + invalidArgument("initialize expects an argument list, an InitializationData object, or both"); RETURN_NULL(); } } + if(zvargs && !extractStringArray(zvargs, seq)) + { + RETURN_NULL(); + } + if(zvinit) { zval* data; @@ -1180,13 +1210,16 @@ ZEND_FUNCTION(Ice_initialize) initData.compactIdResolver = new IdResolver(); initData.valueFactoryManager = new ValueFactoryManager; - CommunicatorInfoIPtr info = initializeCommunicator(return_value, seq, hasArgs, initData); + CommunicatorInfoIPtr info = initializeCommunicator(return_value, seq, zvargs != 0, initData); if(!info) { RETURN_NULL(); } - if(zvargs && Z_ISREF_P(zvargs)) + // + // Replace the existing argument array with the filtered set. + // + if(zvargs) { zval_dtor(zvargs); if(!createStringArray(zvargs, seq)) diff --git a/php/src/php7/Init.cpp b/php/src/php7/Init.cpp index 15b19085ad1..5d10252aa0e 100644 --- a/php/src/php7/Init.cpp +++ b/php/src/php7/Init.cpp @@ -23,9 +23,13 @@ using namespace IcePHP; ZEND_DECLARE_MODULE_GLOBALS(ice) ZEND_BEGIN_ARG_INFO_EX(Ice_initialize_arginfo, 1, ZEND_RETURN_VALUE, static_cast<zend_ulong>(-1)) + ZEND_ARG_PASS_INFO(1) + ZEND_ARG_PASS_INFO(1) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(Ice_createProperties_arginfo, 1, ZEND_RETURN_VALUE, static_cast<zend_ulong>(-1)) + ZEND_ARG_PASS_INFO(1) + ZEND_ARG_PASS_INFO(0) ZEND_END_ARG_INFO() #ifdef ICEPHP_USE_NAMESPACES diff --git a/php/src/php7/Properties.cpp b/php/src/php7/Properties.cpp index e394d62c00c..df4ffb4848b 100644 --- a/php/src/php7/Properties.cpp +++ b/php/src/php7/Properties.cpp @@ -524,6 +524,14 @@ ZEND_FUNCTION(Ice_createProperties) RETURN_NULL(); } + if(arglist) + { + while(Z_TYPE_P(arglist) == IS_REFERENCE) + { + arglist = Z_REFVAL_P(arglist); + } + } + Ice::StringSeq seq; if(arglist && !extractStringArray(arglist, seq)) { @@ -553,7 +561,7 @@ ZEND_FUNCTION(Ice_createProperties) RETURN_NULL(); } - if(arglist && Z_ISREF_P(arglist)) + if(arglist) { zval_dtor(arglist); if(!createStringArray(arglist, seq)) diff --git a/python/modules/IcePy/Communicator.cpp b/python/modules/IcePy/Communicator.cpp index 563c02e1d31..ef4472f325f 100644 --- a/python/modules/IcePy/Communicator.cpp +++ b/python/modules/IcePy/Communicator.cpp @@ -250,11 +250,7 @@ communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) // data.valueFactoryManager = new ValueFactoryManager; - if(argList) - { - data.properties = Ice::createProperties(seq, data.properties); - } - else if(!data.properties) + if(!data.properties) { data.properties = Ice::createProperties(); } @@ -263,6 +259,11 @@ communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) { data.properties->load(getString(configFile)); } + + if(argList) + { + data.properties = Ice::createProperties(seq, data.properties); + } } catch(const Ice::Exception& ex) { diff --git a/ruby/src/IceRuby/Communicator.cpp b/ruby/src/IceRuby/Communicator.cpp index 19d39267e44..efa32357b08 100644 --- a/ruby/src/IceRuby/Communicator.cpp +++ b/ruby/src/IceRuby/Communicator.cpp @@ -62,9 +62,26 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self) { ICE_RUBY_TRY { + // + // The argument options are: + // + // Ice::initialize() + // Ice::initialize(args) + // Ice::initialize(initData) + // Ice::initialize(configFile) + // Ice::initialize(args, initData) + // Ice::initialize(args, configFile) + // + + if(argc > 2) + { + throw RubyException(rb_eArgError, "invalid number of arguments to Ice::initialize"); + } + volatile VALUE initDataCls = callRuby(rb_path2class, "Ice::InitializationData"); - volatile VALUE args = Qnil, initData = Qnil; - if(argc == 1) + volatile VALUE args = Qnil, initData = Qnil, configFile = Qnil; + + if(argc >= 1) { if(isArray(argv[0])) { @@ -74,23 +91,54 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self) { initData = argv[0]; } + else if(TYPE(argv[0]) == T_STRING) + { + configFile = argv[0]; + } else { - throw RubyException(rb_eTypeError, "invalid argument to Ice::initialize"); + throw RubyException(rb_eTypeError, + "initialize expects an argument list, InitializationData or a configuration filename"); } } - else if(argc == 2) + + if(argc >= 2) { - if(!isArray(argv[0]) || callRuby(rb_obj_is_instance_of, argv[1], initDataCls) == Qfalse) + if(isArray(argv[1])) + { + if(!NIL_P(args)) + { + throw RubyException(rb_eTypeError, "unexpected array argument to initialize"); + } + args = argv[1]; + } + else if(callRuby(rb_obj_is_instance_of, argv[1], initDataCls) == Qtrue) + { + if(!NIL_P(initData)) + { + throw RubyException(rb_eTypeError, "unexpected InitializationData argument to initialize"); + } + initData = argv[1]; + } + else if(TYPE(argv[1]) == T_STRING) + { + if(!NIL_P(configFile)) + { + throw RubyException(rb_eTypeError, "unexpected string argument to initialize"); + } + configFile = argv[1]; + } + else { - throw RubyException(rb_eTypeError, "invalid argument to Ice::initialize"); + throw RubyException(rb_eTypeError, + "initialize expects an argument list, InitializationData or a configuration filename"); } - args = argv[0]; - initData = argv[1]; } - else if(argc > 0) + + if(!NIL_P(initData) && !NIL_P(configFile)) { - throw RubyException(rb_eArgError, "invalid number of arguments to Ice::initialize"); + throw RubyException(rb_eTypeError, + "initialize accepts either Ice.InitializationData or a configuration filename"); } Ice::StringSeq seq; @@ -99,11 +147,6 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self) throw RubyException(rb_eTypeError, "invalid array argument to Ice::initialize"); } - // - // Use the with-args or the without-args version of initialize()? - // - bool hasArgs = !NIL_P(args); - Ice::InitializationData data; if(!NIL_P(initData)) { @@ -131,22 +174,20 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self) data.compactIdResolver = new IdResolver; data.valueFactoryManager = new ValueFactoryManager; - if(hasArgs) + if(!data.properties) { - data.properties = Ice::createProperties(seq, data.properties); + data.properties = Ice::createProperties(); + } + + if(!NIL_P(configFile)) + { + data.properties->load(getString(configFile)); } - else if(!data.properties) + + if(!NIL_P(args)) { - data.properties = Ice::createProperties(); + data.properties = Ice::createProperties(seq, data.properties); } - // - // Disable collocation optimization, otherwise an invocation on a - // collocated servant results in a CollocationOptimizationException - // (because Ruby uses the blobject API). - // - // TODO: Enable if a server mapping is added. - // - //data.properties->setProperty("Ice.Default.CollocationOptimization", "0"); // // Remaining command line options are passed to the communicator @@ -164,7 +205,7 @@ IceRuby_initialize(int argc, VALUE* argv, VALUE self) Ice::CommunicatorPtr communicator; try { - if(hasArgs) + if(!NIL_P(args)) { communicator = Ice::initialize(ac, av, data); } |