idlpython.cc
来自「编译工具」· CC 代码 · 共 1,666 行 · 第 1/3 页
CC
1,666 行
// -*- c++ -*-// Package : omniidl// idlpython.cc Created on: 1999/10/27// Author : Duncan Grisby (dpg1)//// Copyright (C) 1999 AT&T Laboratories Cambridge//// This file is part of omniidl.//// omniidl is free software; you can redistribute it and/or modify it// under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA.//// Description:// // Python interface to front-end// $Id: idlpython.cc,v 1.17.2.16 2004/10/17 20:14:34 dgrisby Exp $// $Log: idlpython.cc,v $// Revision 1.17.2.16 2004/10/17 20:14:34 dgrisby// Updated support for OpenVMS. Many thanks to Bruce Visscher.//// Revision 1.17.2.15 2003/01/16 11:08:27 dgrisby// Patches to support Digital Mars C++. Thanks Christof Meerwald.//// Revision 1.17.2.14 2002/10/28 11:56:50 dgrisby// Work around VC++ 7 problem with FILE* change.//// Revision 1.17.2.13 2002/09/21 21:07:48 dgrisby// Support ValueBase in omniidl. (No use to omniORB yet...)//// Revision 1.17.2.12 2001/11/14 17:13:43 dpg1// Long double support.//// Revision 1.17.2.11 2001/10/17 16:48:33 dpg1// Minor error message tweaks//// Revision 1.17.2.10 2001/08/29 11:55:23 dpg1// Enumerator nodes record their value.//// Revision 1.17.2.9 2001/08/15 10:31:23 dpg1// Minor tweaks and fixes.//// Revision 1.17.2.8 2001/03/13 10:32:12 dpg1// Fixed point support.//// Revision 1.17.2.7 2001/01/08 12:35:26 dpg1// Incorrect exception handling when omniidl is an executable.//// Revision 1.17.2.6 2000/12/05 17:45:19 dpg1// omniidl case sensitivity updates from omni3_develop.//// Revision 1.17.2.5 2000/11/01 15:57:03 dpg1// More updates for 2.4.//// Revision 1.17.2.4 2000/11/01 12:45:56 dpg1// Update to CORBA 2.4 specification.//// Revision 1.17.2.3 2000/10/27 16:31:09 dpg1// Clean up of omniidl dependencies and types, from omni3_develop.//// Revision 1.17.2.2 2000/10/10 10:18:51 dpg1// Update omniidl front-end from omni3_develop.//// Revision 1.15.2.15 2000/09/06 11:20:50 dpg1// Support for Python 1.6 and 2.0b1.//// Revision 1.15.2.14 2000/08/30 18:12:46 dpg1// Register operation declarations so they can be found with findDecl().//// Revision 1.15.2.13 2000/08/29 15:20:28 dpg1// New relativeScope() function. New -i flag to enter interactive loop// after parsing//// Revision 1.15.2.12 2000/08/29 10:20:26 dpg1// Operations and attributes now have repository ids.//// Revision 1.15.2.11 2000/08/14 16:07:52 dpg1// Error message now says "Could not open..." rather than "Could not// find..." when Python imports fail.//// Revision 1.15.2.10 2000/08/07 15:34:36 dpg1// Partial back-port of long long from omni3_1_develop.//// Revision 1.15.2.9 2000/06/27 16:23:25 sll// Merged OpenVMS port.//// Revision 1.15.2.8 2000/06/20 13:55:58 dpg1// omniidl now keeps the C++ tree until after the back-ends have run.// This means that back-ends can be C++ extension modules.//// Revision 1.15.2.7 2000/06/08 14:36:19 dpg1// Comments and pragmas are now objects rather than plain strings, so// they can have file,line associated with them.//// Revision 1.15.2.6 2000/06/06 15:21:47 dpg1// Comments and pragmas attached to attribute declarators are now// attached to the Python Attribute object.//// Revision 1.15.2.5 2000/06/05 18:13:27 dpg1// Comments can be attached to subsequent declarations (with -K). Better// idea of most recent decl in operation declarations//// Revision 1.15.2.4 2000/03/10 10:04:40 dpg1// Windows file/directory names are case insensitive.//// Revision 1.15.2.3 2000/03/06 15:03:48 dpg1// Minor bug fixes to omniidl. New -nf and -k flags.//// Revision 1.15.2.2 2000/02/17 10:00:38 dpg1// More robust path discovery.//// Revision 1.15.2.1 2000/02/16 16:23:52 dpg1// Support things for Python neophytes.//// Revision 1.15 2000/02/04 12:17:08 dpg1// Support for VMS.//// Revision 1.14 2000/01/18 17:15:05 dpg1// Changes for "small" distribution.//// Revision 1.13 1999/12/15 12:17:18 dpg1// Changes to compile with SunPro CC 5.0.//// Revision 1.12 1999/12/01 11:35:22 dpg1// Include path for Python.h changed to be consistent with omnipy module.//// Revision 1.11 1999/11/17 14:34:42 dpg1// More multi-platform support (NT and AIX).//// Revision 1.10 1999/11/11 15:55:19 dpg1// Python back-end interface now supports valuetype declarations.// Back-ends still don't support them, though.//// Revision 1.9 1999/11/08 11:43:34 dpg1// Changes for NT support.//// Revision 1.8 1999/11/04 17:16:55 dpg1// Changes for NT.//// Revision 1.7 1999/11/04 11:46:19 dpg1// Now uses our own version of the GNU C preprocessor.//// Revision 1.6 1999/11/02 17:07:26 dpg1// Changes to compile on Solaris.//// Revision 1.5 1999/11/02 10:01:47 dpg1// Minor fixes.//// Revision 1.4 1999/11/01 20:19:56 dpg1// Support for union switch types declared inside the switch statement.//// Revision 1.3 1999/11/01 10:05:27 dpg1// New file attribute to AST.// Fix stupid bug in module initialisation.//// Revision 1.2 1999/10/29 18:19:19 dpg1// Added dump() function//// Revision 1.1 1999/10/29 15:44:45 dpg1// First revision.//#if defined(__VMS)# include <Python.h>#else# include PYTHON_INCLUDE#endif#include <idlsysdep.h>#include <idlast.h>#include <idltype.h>#include <idlscope.h>#include <idlvisitor.h>#include <idldump.h>#include <idlerr.h>#include <idlconfig.h>// PyLongFromLongLong is broken in Python 1.5.2. Workaround here:#ifdef HAS_LongLong# if !defined(PY_VERSION_HEX) || (PY_VERSION_HEX < 0x01050200)# error "omniidl requires Python 1.5.2 or higher"# elif (PY_VERSION_HEX < 0x02000000)// Don't know when it was fixed -- certainly in 2.0.0static inline PyObject* MyPyLong_FromLongLong(IDL_LongLong ll){ if (ll >= 0) // Positive numbers work OK return PyLong_FromLongLong(ll); else { IDL_ULongLong ull = (~ll) + 1; // Hope integers are 2's complement... PyObject* p = PyLong_FromUnsignedLongLong(ull); PyObject* n = PyNumber_Negative(p); Py_DECREF(p); return n; }}# else# define MyPyLong_FromLongLong(ll) PyLong_FromLongLong(ll)# endif#endif#define ASSERT_RESULT if (!result_) PyErr_Print(); assert(result_)#define ASSERT_PYOBJ(pyo) if (!pyo) PyErr_Print(); assert(pyo)class PythonVisitor : public AstVisitor, public TypeVisitor {public: PythonVisitor(); virtual ~PythonVisitor(); void visitAST (AST*); void visitModule (Module*); void visitInterface (Interface*); void visitForward (Forward*); void visitConst (Const*); void visitDeclarator (Declarator*); void visitTypedef (Typedef*); void visitMember (Member*); void visitStruct (Struct*); void visitStructForward (StructForward*); void visitException (Exception*); void visitCaseLabel (CaseLabel*); void visitUnionCase (UnionCase*); void visitUnion (Union*); void visitUnionForward (UnionForward*); void visitEnumerator (Enumerator*); void visitEnum (Enum*); void visitAttribute (Attribute*); void visitParameter (Parameter*); void visitOperation (Operation*); void visitNative (Native*); void visitStateMember (StateMember*); void visitFactory (Factory*); void visitValueForward (ValueForward*); void visitValueBox (ValueBox*); void visitValueAbs (ValueAbs*); void visitValue (Value*); void visitBaseType (BaseType*); void visitStringType (StringType*); void visitWStringType (WStringType*); void visitSequenceType(SequenceType*); void visitFixedType (FixedType*); void visitDeclaredType(DeclaredType*); PyObject* result() { return result_; } static PyObject* scopedNameToList(const ScopedName* sn); static PyObject* wstringToList(const IDL_WChar* ws);private: PyObject* pragmasToList(const Pragma* ps); PyObject* commentsToList(const Comment* cs); void registerPyDecl(const ScopedName* sn, PyObject* pydecl); PyObject* findPyDecl(const ScopedName* sn); PyObject* idlast_; PyObject* idltype_; PyObject* result_; // Current working value};PythonVisitor::PythonVisitor(){ idlast_ = PyImport_ImportModule((char*)"omniidl.idlast"); idltype_ = PyImport_ImportModule((char*)"omniidl.idltype"); ASSERT_PYOBJ(idlast_); ASSERT_PYOBJ(idltype_);}PythonVisitor::~PythonVisitor(){ Py_DECREF(idlast_); Py_DECREF(idltype_);}PyObject*PythonVisitor::scopedNameToList(const ScopedName* sn){ ScopedName::Fragment* f; int i; for (i=0, f = sn->scopeList(); f; f = f->next(), ++i); PyObject* pylist = PyList_New(i); for (i=0, f = sn->scopeList(); f; f = f->next(), ++i) PyList_SetItem(pylist, i, PyString_FromString(f->identifier())); return pylist;}PyObject*PythonVisitor::pragmasToList(const Pragma* ps){ const Pragma* p; int i; for (i=0, p = ps; p; p = p->next(), ++i); PyObject* pylist = PyList_New(i); PyObject* pypragma; for (i=0, p = ps; p; p = p->next(), ++i) { pypragma = PyObject_CallMethod(idlast_, (char*)"Pragma", (char*)"ssi", p->pragmaText(), p->file(), p->line()); ASSERT_PYOBJ(pypragma); PyList_SetItem(pylist, i, pypragma); } return pylist;}PyObject*PythonVisitor::commentsToList(const Comment* cs){ const Comment* c; int i; for (i=0, c = cs; c; c = c->next(), ++i); PyObject* pylist = PyList_New(i); PyObject* pycomment; for (i=0, c = cs; c; c = c->next(), ++i) { pycomment = PyObject_CallMethod(idlast_, (char*)"Comment", (char*)"ssi", c->commentText(), c->file(), c->line()); ASSERT_PYOBJ(pycomment); PyList_SetItem(pylist, i, pycomment); } return pylist;}voidPythonVisitor::registerPyDecl(const ScopedName* sn, PyObject* pydecl){ PyObject* pysn = scopedNameToList(sn); PyObject* r = PyObject_CallMethod(idlast_, (char*)"registerDecl", (char*)"NO", pysn, pydecl); ASSERT_PYOBJ(r); Py_DECREF(r);}PyObject*PythonVisitor::findPyDecl(const ScopedName* sn){ PyObject* pysn = scopedNameToList(sn); PyObject* pydecl = PyObject_CallMethod(idlast_, (char*)"findDecl", (char*)"N", pysn); ASSERT_PYOBJ(pydecl); return pydecl;}PyObject*PythonVisitor::wstringToList(const IDL_WChar* ws){ int i; const IDL_WChar* wc; for (i=0, wc=ws; *wc; ++wc, ++i); PyObject* pyl = PyList_New(i); for (i=0, wc=ws; *wc; ++wc, ++i) PyList_SetItem(pyl, i, PyInt_FromLong(*wc)); return pyl;}//// AST visit functions//voidPythonVisitor::visitAST(AST* a){ Decl* d; int i; for (i=0, d = a->declarations(); d; d = d->next(), ++i); PyObject* pydecls = PyList_New(i); for (i=0, d = a->declarations(); d; d = d->next(), ++i) { d->accept(*this); PyList_SetItem(pydecls, i, result_); } result_ = PyObject_CallMethod(idlast_, (char*)"AST", (char*)"sNNN", a->file(), pydecls, pragmasToList(a->pragmas()), commentsToList(a->comments())); ASSERT_RESULT;}voidPythonVisitor::visitModule(Module* m){ Decl* d; int i; for (i=0, d = m->definitions(); d; d = d->next(), ++i); PyObject* pydecls = PyList_New(i); for (i=0, d = m->definitions(); d; d = d->next(), ++i) { d->accept(*this); PyList_SetItem(pydecls, i, result_); } result_ = PyObject_CallMethod(idlast_, (char*)"Module", (char*)"siiNNsNsN", m->file(), m->line(), (int)m->mainFile(), pragmasToList(m->pragmas()), commentsToList(m->comments()), m->identifier(), scopedNameToList(m->scopedName()), m->repoId(), pydecls); ASSERT_RESULT; registerPyDecl(m->scopedName(), result_);}voidPythonVisitor::visitInterface(Interface* i){ int l; PyObject* pyobj; Decl* d; // Inherited interfaces InheritSpec* inh; for (l=0, inh = i->inherits(); inh; inh = inh->next(), ++l); PyObject* pyinherits = PyList_New(l); for (l=0, inh = i->inherits(); inh; inh = inh->next(), ++l) { d = inh->decl(); if (d->kind() == Decl::D_INTERFACE) pyobj = findPyDecl(((Interface*)d)->scopedName()); else if (d->kind() == Decl::D_DECLARATOR) pyobj = findPyDecl(((Declarator*)d)->scopedName()); else assert(0); PyList_SetItem(pyinherits, l, pyobj); } PyObject* pyintf = PyObject_CallMethod(idlast_, (char*)"Interface", (char*)"siiNNsNsiiN", i->file(), i->line(), (int)i->mainFile(), pragmasToList(i->pragmas()), commentsToList(i->comments()), i->identifier(), scopedNameToList(i->scopedName()), i->repoId(), (int)i->abstract(), (int)i->local(), pyinherits); ASSERT_PYOBJ(pyintf); registerPyDecl(i->scopedName(), pyintf); // Contents for (l=0, d = i->contents(); d; d = d->next(), ++l); PyObject* pycontents = PyList_New(l); for (l=0, d = i->contents(); d; d = d->next(), ++l) { d->accept(*this); PyList_SetItem(pycontents, l, result_); } PyObject* r = PyObject_CallMethod(pyintf, (char*)"_setContents", (char*)"N", pycontents); ASSERT_PYOBJ(r); Py_DECREF(r); result_ = pyintf;}voidPythonVisitor::visitForward(Forward* f){ result_ = PyObject_CallMethod(idlast_, (char*)"Forward", (char*)"siiNNsNsii", f->file(), f->line(), (int)f->mainFile(), pragmasToList(f->pragmas()), commentsToList(f->comments()), f->identifier(), scopedNameToList(f->scopedName()), f->repoId(), (int)f->abstract(), (int)f->local()); ASSERT_RESULT; registerPyDecl(f->scopedName(), result_);}voidPythonVisitor::visitConst(Const* c){ c->constType()->accept(*this); PyObject* pytype = result_; PyObject* pyv; switch(c->constKind()) { case IdlType::tk_short: pyv = PyInt_FromLong(c->constAsShort()); break; case IdlType::tk_long: pyv = PyInt_FromLong(c->constAsLong()); break; case IdlType::tk_ushort: pyv = PyInt_FromLong(c->constAsUShort()); break; case IdlType::tk_ulong: pyv = PyLong_FromUnsignedLong(c->constAsULong()); break; case IdlType::tk_float: pyv = PyFloat_FromDouble(c->constAsFloat()); break; case IdlType::tk_double: pyv = PyFloat_FromDouble(c->constAsDouble()); break; case IdlType::tk_boolean: pyv = PyInt_FromLong(c->constAsBoolean()); break; case IdlType::tk_char: pyv = Py_BuildValue((char*)"c", c->constAsChar()); break; case IdlType::tk_octet: pyv = PyInt_FromLong(c->constAsOctet()); break; case IdlType::tk_string: pyv = PyString_FromString(c->constAsString()); break;#ifdef HAS_LongLong case IdlType::tk_longlong: pyv = MyPyLong_FromLongLong(c->constAsLongLong()); break; case IdlType::tk_ulonglong: pyv = PyLong_FromUnsignedLongLong(c->constAsULongLong()); break;#endif#ifdef HAS_LongDouble case IdlType::tk_longdouble: pyv = PyFloat_FromDouble(c->constAsLongDouble()); IdlWarning(c->file(), c->line(), "long double constant truncated to double. Sorry."); break;#endif case IdlType::tk_wchar: pyv = PyInt_FromLong(c->constAsWChar()); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?