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 + -
显示快捷键?