// ********************************************************************** // // Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #include using namespace std; IcePy::PyObjectHandle::PyObjectHandle(PyObject* p) : _p(p) { } IcePy::PyObjectHandle::PyObjectHandle(const PyObjectHandle& p) : _p(p._p) { Py_XINCREF(_p); } IcePy::PyObjectHandle::~PyObjectHandle() { if(_p) { Py_DECREF(_p); } } void IcePy::PyObjectHandle::operator=(PyObject* p) { if(_p) { Py_DECREF(_p); } _p = p; } void IcePy::PyObjectHandle::operator=(const PyObjectHandle& p) { Py_XDECREF(_p); _p = p._p; Py_XINCREF(_p); } PyObject* IcePy::PyObjectHandle::get() { return _p; } PyObject* IcePy::PyObjectHandle::release() { PyObject* result = _p; _p = NULL; return result; } IcePy::AllowThreads::AllowThreads() { _state = PyEval_SaveThread(); } IcePy::AllowThreads::~AllowThreads() { PyEval_RestoreThread(_state); } IcePy::AdoptThread::AdoptThread() { _state = PyGILState_Ensure(); } IcePy::AdoptThread::~AdoptThread() { PyGILState_Release(_state); } bool IcePy::listToStringSeq(PyObject* list, Ice::StringSeq& seq) { assert(PyList_Check(list)); int sz = PyList_Size(list); for(int i = 0; i < sz; ++i) { PyObject* item = PyList_GetItem(list, i); if(item == NULL) { return false; } char* str = PyString_AsString(item); if(str == NULL) { return false; } seq.push_back(str); } return true; } bool IcePy::stringSeqToList(const Ice::StringSeq& seq, PyObject* list) { assert(PyList_Check(list)); for(Ice::StringSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) { PyObject* str = Py_BuildValue("s", p->c_str()); if(str == NULL) { Py_DECREF(list); return false; } int status = PyList_Append(list, str); Py_DECREF(str); // Give ownership to the list. if(status < 0) { Py_DECREF(list); return false; } } return true; } bool IcePy::dictionaryToContext(PyObject* dict, Ice::Context& context) { assert(PyDict_Check(dict)); int pos = 0; PyObject* key; PyObject* value; while(PyDict_Next(dict, &pos, &key, &value)) { char* keystr = PyString_AsString(key); if(keystr == NULL) { PyErr_Format(PyExc_ValueError, "context key must be a string"); return false; } char* valuestr = PyString_AsString(value); if(valuestr == NULL) { PyErr_Format(PyExc_ValueError, "context value must be a string"); return false; } context.insert(Ice::Context::value_type(keystr, valuestr)); } return true; } bool IcePy::contextToDictionary(const Ice::Context& ctx, PyObject* dict) { assert(PyDict_Check(dict)); for(Ice::Context::const_iterator p = ctx.begin(); p != ctx.end(); ++p) { PyObjectHandle key = PyString_FromString(const_cast(p->first.c_str())); PyObjectHandle value = PyString_FromString(const_cast(p->second.c_str())); if(key.get() == NULL || value.get() == NULL) { return false; } if(PyDict_SetItem(dict, key.get(), value.get()) < 0) { return false; } } return true; } bool IcePy::splitString(const string& str, Ice::StringSeq& args) { string delim = " \t\n\r"; string::size_type beg; string::size_type end = 0; while(true) { beg = str.find_first_not_of(delim, end); if(beg == string::npos) { break; } // // Check for quoted argument. // char ch = str[beg]; if(ch == '"' || ch == '\'') { beg++; end = str.find(ch, beg); if(end == string::npos) { PyErr_Format(PyExc_RuntimeError, "unterminated quote in `%s'", str.c_str()); return false; } args.push_back(str.substr(beg, end - beg)); end++; // Skip end quote. } else { end = str.find_first_of(delim + "'\"", beg); if(end == string::npos) { end = str.length(); } args.push_back(str.substr(beg, end - beg)); } } return true; } string IcePy::scopedToName(const string& scoped) { string result = fixIdent(scoped); if(result.find("::") == 0) { result.erase(0, 2); } string::size_type pos; while((pos = result.find("::")) != string::npos) { result.replace(pos, 2, "."); } return result; } static string lookupKwd(const string& name) { // // Keyword list. *Must* be kept in alphabetical order. // static const string keywordList[] = { "and", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", "exec", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "not", "or", "pass", "print", "raise", "return", "try", "while", "yield" }; bool found = binary_search(&keywordList[0], &keywordList[sizeof(keywordList) / sizeof(*keywordList)], name); return found ? "_" + name : name; } // // Split a scoped name into its components and return the components as a list of (unscoped) identifiers. // static Ice::StringSeq splitScopedName(const string& scoped) { assert(scoped[0] == ':'); Ice::StringSeq ids; string::size_type next = 0; string::size_type pos; while((pos = scoped.find("::", next)) != string::npos) { pos += 2; if(pos != scoped.size()) { string::size_type endpos = scoped.find("::", pos); if(endpos != string::npos) { ids.push_back(scoped.substr(pos, endpos - pos)); } } next = pos; } if(next != scoped.size()) { ids.push_back(scoped.substr(next)); } else { ids.push_back(""); } return ids; } string IcePy::fixIdent(const string& ident) { if(ident[0] != ':') { return lookupKwd(ident); } Ice::StringSeq ids = splitScopedName(ident); transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd)); stringstream result; for(Ice::StringSeq::const_iterator i = ids.begin(); i != ids.end(); ++i) { result << "::" + *i; } return result.str(); } PyObject* IcePy::lookupType(const string& typeName) { string::size_type dot = typeName.rfind('.'); string moduleName; string name; if(dot == string::npos) { moduleName = "__main__"; name = typeName; } else { moduleName = typeName.substr(0, dot); name = typeName.substr(dot + 1); } PyObjectHandle module = PyImport_ImportModule(const_cast(moduleName.c_str())); if(module.get() == NULL) { return NULL; } PyObject* dict = PyModule_GetDict(module.get()); assert(dict); return PyDict_GetItemString(dict, const_cast(name.c_str())); }