///---------------------------------------------------------------------------------
///
///---------------------------------------------------------------------------------
bool RunConsoleCommandFromLine( const std::string& line )
{
    std::string lineLC = ConvertToLowerCase( line );

    std::vector< std::string> args;
    Tokenize( lineLC, args, "( ,;)" );

    DeveloperConsoleArguments argsObj( args, 1 );
    DeveloperConsole::WriteLine( line, INFO_TEXT_COLOR );
    return RunConsoleCommand( args[0], &argsObj );
}
Ejemplo n.º 2
0
Pothos::Proxy PythonProxyHandle::call(const std::string &name, const Pothos::Proxy *args, const size_t numArgs)
{
    PyGilStateLock lock;
    if (this->obj == nullptr) throw Pothos::ProxyHandleCallError(
        "PythonProxyHandle::call("+name+")", "cant call on a null object");

    /*******************************************************************
     * Step 0) handle field accessors and mutators
     ******************************************************************/
    const auto colon = name.find(":");
    if (colon != std::string::npos)
    {
        PyObjectRef result(Py_None, REF_BORROWED);

        if (name.substr(0, colon) == "set" and numArgs == 1)
        {
            PyObject_SetAttrString(this->obj, name.substr(colon+1).c_str(), env->getHandle(args[0])->obj);
        }
        else if (name.substr(0, colon) == "get" and numArgs == 0)
        {
            result = PyObjectRef(PyObject_GetAttrString(this->obj, name.substr(colon+1).c_str()), REF_NEW);
        }
        else throw Pothos::ProxyHandleCallError(
            "PythonProxyHandle::call("+name+")", "unknown operation");

        auto errorMsg = getErrorString();
        if (not errorMsg.empty())
        {
            throw Pothos::ProxyExceptionMessage(errorMsg);
        }
        return env->makeHandle(result);
    }

    /*******************************************************************
     * Step 1) locate the callable object
     ******************************************************************/
    PyObjectRef attrObj;

    if (name.empty() or name == "()") attrObj = PyObjectRef(ref);
    else attrObj = PyObjectRef(PyObject_GetAttrString(this->obj, name.c_str()), REF_NEW);

    if (attrObj.obj == nullptr)
    {
        throw Pothos::ProxyHandleCallError(
            "PythonProxyHandle::call("+name+")",
            Poco::format("no attribute on %s", this->toString()));
    }

    if (not PyCallable_Check(attrObj.obj))
    {
        if (numArgs == 0) return env->makeHandle(attrObj); //access a field
        else throw Pothos::ProxyHandleCallError(
            "PythonProxyHandle::call("+name+")",
            Poco::format("cant call on %s", this->toString()));
    }

    /*******************************************************************
     * Step 2) create tuple of arguments
     ******************************************************************/
    PyObjectRef argsObj(PyTuple_New(numArgs), REF_NEW);
    std::vector<std::shared_ptr<PythonProxyHandle>> argHandles(numArgs);
    for (size_t i = 0; i < numArgs; i++)
    {
        argHandles[i] = env->getHandle(args[i]);
        PyTuple_SetItem(argsObj.obj, i, argHandles[i]->ref.newRef());
    }

    /*******************************************************************
     * Step 4) call into the callable object
     ******************************************************************/
    PyObjectRef result(PyObject_CallObject(attrObj.obj, argsObj.obj), REF_NEW);

    /*******************************************************************
     * Step 5) exception handling and reporting
     ******************************************************************/
    auto errorMsg = getErrorString();
    if (not errorMsg.empty())
    {
        throw Pothos::ProxyExceptionMessage(errorMsg);
    }

    auto x = env->makeHandle(result);
    if (x.getClassName() == "PothosProxy") return x.convert<Pothos::Proxy>();
    return x;
}