Exemple #1
0
    void test_OK ()
    {
        testcase ("OK");
        {
            auto s = codeString (Status ());
            expect (s.empty(), "String for OK status");
        }

        {
            auto s = codeString (Status::OK);
            expect (s.empty(), "String for OK status");
        }

        {
            auto s = codeString (0);
            expect (s.empty(), "String for 0 status");
        }

        {
            auto s = codeString (tesSUCCESS);
            expect (s.empty(), "String for tesSUCCESS");
        }

        {
            auto s = codeString (rpcSUCCESS);
            expect (s.empty(), "String for rpcSUCCESS");
        }
    }
Exemple #2
0
 std::string Status::toString() const {
     std::ostringstream ss;
     ss << codeString();
     if ( !isOK() )
         ss << " " << reason();
     if ( location() != 0 )
         ss << " @ " << location();
     return ss.str();
 }
Exemple #3
0
    void test_error ()
    {
        testcase ("error");
        {
            auto s = codeString (23);
            expect (s == "23", s);
        }

        {
            auto s = codeString (temBAD_AMOUNT);
            expect (s == "temBAD_AMOUNT: Can only send positive amounts.", s);
        }

        {
            auto s = codeString (rpcBAD_SYNTAX);
            expect (s == "badSyntax: Syntax error.", s);
        }
    }
Exemple #4
0
void Lingo::codeArgStore() {
	while (true) {
		if (_argstack.empty()) {
			break;
		}

		Common::String *arg = _argstack.back();
		_argstack.pop_back();

		code1(c_varpush);
		codeString(arg->c_str());
		code1(c_assign);
		code1(c_xpop);

		delete arg;
	}
}
Exemple #5
0
/**
 * Compile the code
 */
PyObject *PythonScript::compileToByteCode(bool for_eval)
{
    // Support for the convenient col() and cell() functions.
    // This can't be done anywhere else, because we need access to the local
    // variables self, i and j.
    if( context() )
    {
        if( context()->inherits("Table") )
        {
            // A bit of a hack, but we need either IndexError or len() from __builtins__.
            PyDict_SetItemString(localDict, "__builtins__",
                                 PyDict_GetItemString(pythonEnv()->globalDict(), "__builtins__"));
            PyObject *ret = PyRun_String(
                                "def col(c,*arg):\n"
                                "\ttry: return self.cell(c,arg[0])\n"
                                "\texcept(IndexError): return self.cell(c,i)\n"
                                "def cell(c,r):\n"
                                "\treturn self.cell(c,r)\n"
                                "def tablecol(t,c):\n"
                                "\treturn self.folder().rootFolder().table(t,True).cell(c,i)\n"
                                "def _meth_table_col_(t,c):\n"
                                "\treturn t.cell(c,i)\n"
                                "self.__class__.col = _meth_table_col_",
                                Py_file_input, localDict, localDict);
            if (ret)
                Py_DECREF(ret);
            else
                PyErr_Print();
        }
        else if(context()->inherits("Matrix"))
        {
            // A bit of a hack, but we need either IndexError or len() from __builtins__.
            PyDict_SetItemString(localDict, "__builtins__",
                                 PyDict_GetItemString(pythonEnv()->globalDict(), "__builtins__"));
            PyObject *ret = PyRun_String(
                                "def cell(*arg):\n"
                                "\ttry: return self.cell(arg[0],arg[1])\n"
                                "\texcept(IndexError): return self.cell(i,j)\n",
                                Py_file_input, localDict, localDict);
            if (ret)
                Py_DECREF(ret);
            else
                PyErr_Print();
        }
    }
    bool success(false);
    // Simplest case: Code is a single expression
    PyObject *compiledCode = Py_CompileString(codeString().c_str(), identifier().c_str(), Py_file_input);

    if( compiledCode )
    {
        success = true;
    }
    else if (for_eval)
    {
        // Code contains statements (or errors) and we want to get a return
        // value from it.
        // So we wrap the code into a function definition,
        // execute that (as Py_file_input) and store the function object in PyCode.
        // See http://mail.python.org/pipermail/python-list/2001-June/046940.html
        // for why there isn't an easier way to do this in Python.
        PyErr_Clear(); // silently ignore errors
        PyObject *key(NULL), *value(NULL);
        Py_ssize_t i(0);
        QString signature = "";
        while(PyDict_Next(localDict, &i, &key, &value))
        {
            signature.append(PyString_AsString(key)).append(",");
        }
        signature.truncate(signature.length()-1);
        std::string fdef = "def __doit__("+signature.toStdString()+"):\n";
        fdef += codeString();
        compiledCode = Py_CompileString(fdef.c_str(), identifier().c_str(), Py_file_input);
        if( compiledCode )
        {
            PyObject *tmp = PyDict_New();
            Py_XDECREF(PyEval_EvalCode((PyCodeObject*)compiledCode, localDict, tmp));
            Py_DECREF(compiledCode);
            compiledCode = PyDict_GetItemString(tmp,"__doit__");
            Py_XINCREF(compiledCode);
            Py_DECREF(tmp);
        }
        success = (compiledCode != NULL);
    }
    else
    {
    }

    if(success)
    {
        m_CodeFileObject = ((PyCodeObject*)(compiledCode))->co_filename;
    }
    else
    {
        compiledCode = NULL;
        m_CodeFileObject = NULL;
    }
    return compiledCode;
}
/*
 * This routine needs to emulate load_source_module in import.c in
 * python, but with DataSectionPtr using FILE*
 * However, we can't get an mTime (there's no interface for it in DataSection)
 * Need to resolve this before we can commit
 */
PyObject* PyResMgrImportLoader::load_source_module( const std::string& name, BinaryPtr py_data, DataSectionPtr pDirectory )
{
    std::string compiledExtension = "pyc";
    if ( Py_OptimizeFlag )
        compiledExtension = "pyo";
    std::string moduleName = name;
    std::string::size_type dotPos = name.rfind( "." );
    if ( dotPos != std::string::npos )
    {
        moduleName = name.substr( dotPos + 1 );
    }

    // Find source (.py) and object (.pyc/.pyo) files to
    // process for this source module or package.
    std::string modulePath;
    bool isPackage = false;
    std::string objectModuleName;
    if ( modules_[ name ].first == PKG_DIRECTORY )
    {
        isPackage = true;
        modulePath = path_ + "/" + moduleName + "/__init__.py";
        objectModuleName = "__init__." + compiledExtension;
    } else {
        modulePath = path_ + "/" + moduleName + ".py";
        objectModuleName = moduleName + "." +  compiledExtension;
    }
    // Remove this from the cache. We have it now, and will feed it to Python.
    // This ensures that a reload() call will work correctly.
    modules_.erase( name );

    // Fetch mtime of py file
    time_t pyModTime = static_cast< time_t >( -1 );
    IFileSystem::FileInfo fInfo;
    IFileSystem::FileType fType =
        BWResource::instance().fileSystem()->getFileType( modulePath, &fInfo );
    if ( fType != IFileSystem::FT_NOT_FOUND )
    {
        pyModTime = fInfo.modified;
    }
    // If possible, palm this off to load_compiled_module
    DataSectionPtr pycSection = pDirectory->openSection( objectModuleName );
    if ( pycSection && check_compiled_module( name, pycSection->asBinary() ))
    {
        if ( check_compiled_module_mtime( name, pycSection->asBinary(), pyModTime ) )
        {
            // We know the module was valid and up-to-date, so trust the loader
            // to either load it or fail noisily
            return load_compiled_module( name, pycSection->asBinary(), true );
        }
    }
    if ( pycSection )
    {
        // Get rid of our reference to the old compiled python file.
        // TODO: Purge this section from the DataSection cache, we're about
        // to replace it on disk
        pycSection = NULL;
    }

    // We got here, the object file for this source either doesn't exist, isn't
    // valid, or isn't as recent as the source.
    // Emulate parse_source_module
    // The code string needs to have (\n) as a line seperator, and needs an EOF
    // (-1) or null termination, and has to end in a newline.
    // Also, need to ensure there's no embedded nulls.
    // So have to make a copy of the string.
    // We shouldn't ever do this in release anyway.
    std::string codeString( py_data->cdata(), py_data->len() );
    if ( codeString.find( '\0' ) != std::string::npos )
    {
        PyErr_Format( PyExc_ImportError,
                      "%s contains an embedded null character",
                      modulePath.c_str()
                    );
        return NULL;
    }
    std::string::size_type winNLpos;
    // Convert any Windows newlines into UNIX newlines
    if ( ( winNLpos = codeString.find( "\r\n", 0 ) ) != std::string::npos )
    {
        do
        {
            codeString.replace( winNLpos, 2, "\n" );
            winNLpos = codeString.find( "\r\n", winNLpos );
        } while ( winNLpos != std::string::npos );
    }
    // Ensure we're newline-terminated
    codeString.append( "\n" );
    PyObject* codeObject = Py_CompileString( codeString.c_str(),
                           const_cast< char* >( modulePath.c_str() ),
                           Py_file_input );
    if ( codeObject == NULL )
        // Compiler didn't like it. Propagate the error up
        return NULL;

    // OK, we have a module, now we just execute it into the correct space.
    // Always call it a .py, even though we've created a .pyc
    PyObject* module = PyImport_ExecCodeModuleEx(
                           const_cast< char* >( name.c_str() ), codeObject,
                           const_cast< char* >( modulePath.c_str() )
                       );

    if ( module == NULL )
    {
        Py_DECREF( codeObject );
        return NULL;
    }

    // It executed OK, so write out an object file for later use, if possible
    // Emulates write_compiled_module( co, cpathname, mtime )
    do {
        PyObject* codeString = PyMarshal_WriteObjectToString( codeObject, Py_MARSHAL_VERSION );
        // XXX: Maybe we should care if _this_ fails, or at least report it?
        if ( codeString == NULL || !PyString_Check( codeString ) )
        {
            PyErr_Clear();
            break;
        }
        char* dataBlock = new char[ PyString_Size( codeString ) + 8 ];
        // XXX: On-disk format is little-endian, we're not checking that here
        reinterpret_cast< uint32* >(dataBlock)[ 0 ] = PyImport_GetMagicNumber();
        reinterpret_cast< int32* >(dataBlock)[ 1 ] = static_cast< int32 >( pyModTime );
        memcpy( dataBlock + 8, PyString_AsString( codeString ), PyString_Size( codeString ) );

        // The following is a little nasty, we end up copying the data a couple of times
        // Wrap dataBlock in a BinaryBlock (which takes a copy of it)
        BinaryPtr pycData = new BinaryBlock( dataBlock,
                                             PyString_Size( codeString ) + 8,
                                             "PyResMgrImportLoader::load_source_module" );
        delete[] dataBlock;
        if ( !pycData )
            break;
        // Save out our new pyc file
        pycSection = pDirectory->openSection( objectModuleName, true, BinSection::creator() );
        if ( !pycSection )
            break;
        pycSection->setBinary( pycData );
        pycSection->save();
    } while( false );

    Py_DECREF( codeObject );

    PyObject *moduleDict = PyModule_GetDict( module );
    if ( moduleDict != NULL )
    {
        int err = PyDict_SetItemString( moduleDict, "__loader__", this );
        if ( err != 0 )
        {
            Py_DECREF( module );
            return NULL;
        }
    }

//	TRACE_MSG( "PyResMgrImportLoader(%s)::load_source_module: loaded %s\n", path_.c_str(),
//		name.c_str() );
    return module;
}