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"); } }
std::string Status::toString() const { std::ostringstream ss; ss << codeString(); if ( !isOK() ) ss << " " << reason(); if ( location() != 0 ) ss << " @ " << location(); return ss.str(); }
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); } }
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; } }
/** * 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; }