Synopsis - Cross-Reference

File: /Synopsis/Parsers/IDL/idlpython.cc
   1// -*- c++ -*-
   2//                          Package   : omniidl
   3// idlpython.cc             Created on: 1999/10/27
   4//			    Author    : Duncan Grisby (dpg1)
   5//
   6//    Copyright (C) 1999 AT&T Laboratories Cambridge
   7//
   8//  This file is part of omniidl.
   9//
  10//  omniidl is free software; you can redistribute it and/or modify it
  11//  under the terms of the GNU General Public License as published by
  12//  the Free Software Foundation; either version 2 of the License, or
  13//  (at your option) any later version.
  14//
  15//  This program is distributed in the hope that it will be useful,
  16//  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18//  General Public License for more details.
  19//
  20//  You should have received a copy of the GNU General Public License
  21//  along with this program; if not, write to the Free Software
  22//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  23//  02111-1307, USA.
  24//
  25// Description:
  26//   
  27//   Python interface to front-end
  28
  29// $Id: idlpython.cc,v 1.22.2.3 2005/01/06 23:11:14 dgrisby Exp $
  30// $Log: idlpython.cc,v $
  31// Revision 1.22.2.3  2005/01/06 23:11:14  dgrisby
  32// Big merge from omni4_0_develop.
  33//
  34// Revision 1.22.2.2  2003/09/04 14:00:29  dgrisby
  35// ValueType IDL updates.
  36//
  37// Revision 1.22.2.1  2003/03/23 21:01:45  dgrisby
  38// Start of omniORB 4.1.x development branch.
  39//
  40// Revision 1.17.2.15  2003/01/16 11:08:27  dgrisby
  41// Patches to support Digital Mars C++. Thanks Christof Meerwald.
  42//
  43// Revision 1.17.2.14  2002/10/28 11:56:50  dgrisby
  44// Work around VC++ 7 problem with FILE* change.
  45//
  46// Revision 1.17.2.13  2002/09/21 21:07:48  dgrisby
  47// Support ValueBase in omniidl. (No use to omniORB yet...)
  48//
  49// Revision 1.17.2.12  2001/11/14 17:13:43  dpg1
  50// Long double support.
  51//
  52// Revision 1.17.2.11  2001/10/17 16:48:33  dpg1
  53// Minor error message tweaks
  54//
  55// Revision 1.17.2.10  2001/08/29 11:55:23  dpg1
  56// Enumerator nodes record their value.
  57//
  58// Revision 1.17.2.9  2001/08/15 10:31:23  dpg1
  59// Minor tweaks and fixes.
  60//
  61// Revision 1.17.2.8  2001/03/13 10:32:12  dpg1
  62// Fixed point support.
  63//
  64// Revision 1.17.2.7  2001/01/08 12:35:26  dpg1
  65// Incorrect exception handling when omniidl is an executable.
  66//
  67// Revision 1.17.2.6  2000/12/05 17:45:19  dpg1
  68// omniidl case sensitivity updates from omni3_develop.
  69//
  70// Revision 1.17.2.5  2000/11/01 15:57:03  dpg1
  71// More updates for 2.4.
  72//
  73// Revision 1.17.2.4  2000/11/01 12:45:56  dpg1
  74// Update to CORBA 2.4 specification.
  75//
  76// Revision 1.17.2.3  2000/10/27 16:31:09  dpg1
  77// Clean up of omniidl dependencies and types, from omni3_develop.
  78//
  79// Revision 1.17.2.2  2000/10/10 10:18:51  dpg1
  80// Update omniidl front-end from omni3_develop.
  81//
  82// Revision 1.15.2.15  2000/09/06 11:20:50  dpg1
  83// Support for Python 1.6 and 2.0b1.
  84//
  85// Revision 1.15.2.14  2000/08/30 18:12:46  dpg1
  86// Register operation declarations so they can be found with findDecl().
  87//
  88// Revision 1.15.2.13  2000/08/29 15:20:28  dpg1
  89// New relativeScope() function. New -i flag to enter interactive loop
  90// after parsing
  91//
  92// Revision 1.15.2.12  2000/08/29 10:20:26  dpg1
  93// Operations and attributes now have repository ids.
  94//
  95// Revision 1.15.2.11  2000/08/14 16:07:52  dpg1
  96// Error message now says "Could not open..." rather than "Could not
  97// find..." when Python imports fail.
  98//
  99// Revision 1.15.2.10  2000/08/07 15:34:36  dpg1
 100// Partial back-port of long long from omni3_1_develop.
 101//
 102// Revision 1.15.2.9  2000/06/27 16:23:25  sll
 103// Merged OpenVMS port.
 104//
 105// Revision 1.15.2.8  2000/06/20 13:55:58  dpg1
 106// omniidl now keeps the C++ tree until after the back-ends have run.
 107// This means that back-ends can be C++ extension modules.
 108//
 109// Revision 1.15.2.7  2000/06/08 14:36:19  dpg1
 110// Comments and pragmas are now objects rather than plain strings, so
 111// they can have file,line associated with them.
 112//
 113// Revision 1.15.2.6  2000/06/06 15:21:47  dpg1
 114// Comments and pragmas attached to attribute declarators are now
 115// attached to the Python Attribute object.
 116//
 117// Revision 1.15.2.5  2000/06/05 18:13:27  dpg1
 118// Comments can be attached to subsequent declarations (with -K). Better
 119// idea of most recent decl in operation declarations
 120//
 121// Revision 1.15.2.4  2000/03/10 10:04:40  dpg1
 122// Windows file/directory names are case insensitive.
 123//
 124// Revision 1.15.2.3  2000/03/06 15:03:48  dpg1
 125// Minor bug fixes to omniidl. New -nf and -k flags.
 126//
 127// Revision 1.15.2.2  2000/02/17 10:00:38  dpg1
 128// More robust path discovery.
 129//
 130// Revision 1.15.2.1  2000/02/16 16:23:52  dpg1
 131// Support things for Python neophytes.
 132//
 133// Revision 1.15  2000/02/04 12:17:08  dpg1
 134// Support for VMS.
 135//
 136// Revision 1.14  2000/01/18 17:15:05  dpg1
 137// Changes for "small" distribution.
 138//
 139// Revision 1.13  1999/12/15 12:17:18  dpg1
 140// Changes to compile with SunPro CC 5.0.
 141//
 142// Revision 1.12  1999/12/01 11:35:22  dpg1
 143// Include path for Python.h changed to be consistent with omnipy module.
 144//
 145// Revision 1.11  1999/11/17 14:34:42  dpg1
 146// More multi-platform support (NT and AIX).
 147//
 148// Revision 1.10  1999/11/11 15:55:19  dpg1
 149// Python back-end interface now supports valuetype declarations.
 150// Back-ends still don't support them, though.
 151//
 152// Revision 1.9  1999/11/08 11:43:34  dpg1
 153// Changes for NT support.
 154//
 155// Revision 1.8  1999/11/04 17:16:55  dpg1
 156// Changes for NT.
 157//
 158// Revision 1.7  1999/11/04 11:46:19  dpg1
 159// Now uses our own version of the GNU C preprocessor.
 160//
 161// Revision 1.6  1999/11/02 17:07:26  dpg1
 162// Changes to compile on Solaris.
 163//
 164// Revision 1.5  1999/11/02 10:01:47  dpg1
 165// Minor fixes.
 166//
 167// Revision 1.4  1999/11/01 20:19:56  dpg1
 168// Support for union switch types declared inside the switch statement.
 169//
 170// Revision 1.3  1999/11/01 10:05:27  dpg1
 171// New file attribute to AST.
 172// Fix stupid bug in module initialisation.
 173//
 174// Revision 1.2  1999/10/29 18:19:19  dpg1
 175// Added dump() function
 176//
 177// Revision 1.1  1999/10/29 15:44:45  dpg1
 178// First revision.
 179//
 180
 181#if defined(__VMS)
 182#  include <Python.h>
 183#else
 184#  include PYTHON_INCLUDE
 185#endif
 186
 187#include <idlsysdep.h>
 188#include <idlast.h>
 189#include <idltype.h>
 190#include <idlscope.h>
 191#include <idlvisitor.h>
 192#include <idldump.h>
 193#include <idlerr.h>
 194#include <idlconfig.h>
 195
 196
 197// PyLongFromLongLong is broken in Python 1.5.2. Workaround here:
 198#ifdef HAS_LongLong
 199#  if !defined(PY_VERSION_HEX) || (PY_VERSION_HEX < 0x01050200)
 200#    error "omniidl requires Python 1.5.2 or higher"
 201
 202#  elif (PY_VERSION_HEX < 0x02000000)
 203
 204// Don't know when it was fixed -- certainly in 2.0.0
 205
 206static inline PyObject* MyPyLong_FromLongLong(IDL_LongLong ll)
 207{
 208  if (ll >= 0) // Positive numbers work OK
 209    return PyLong_FromLongLong(ll);
 210  else {
 211    IDL_ULongLong ull = (~ll) + 1; // Hope integers are 2's complement...
 212    PyObject* p = PyLong_FromUnsignedLongLong(ull);
 213    PyObject* n = PyNumber_Negative(p);
 214    Py_DECREF(p);
 215    return n;
 216  }
 217}
 218#  else
 219#    define MyPyLong_FromLongLong(ll) PyLong_FromLongLong(ll)
 220#  endif
 221#endif
 222
 223
 224#define ASSERT_RESULT     if (!result_) PyErr_Print(); assert(result_)
 225#define ASSERT_PYOBJ(pyo) if (!pyo)     PyErr_Print(); assert(pyo)
 226
 227class PythonVisitor : public AstVisitor, public TypeVisitor {
 228public:
 229  PythonVisitor();
 230  virtual ~PythonVisitor();
 231
 232  void visitAST              (AST*);
 233  void visitModule           (Module*);
 234  void visitInterface        (Interface*);
 235  void visitForward          (Forward*);
 236  void visitConst            (Const*);
 237  void visitDeclarator       (Declarator*);
 238  void visitTypedef          (Typedef*);
 239  void visitMember           (Member*);
 240  void visitStruct           (Struct*);
 241  void visitStructForward    (StructForward*);
 242  void visitException        (Exception*);
 243  void visitCaseLabel        (CaseLabel*);
 244  void visitUnionCase        (UnionCase*);
 245  void visitUnion            (Union*);
 246  void visitUnionForward     (UnionForward*);
 247  void visitEnumerator       (Enumerator*);
 248  void visitEnum             (Enum*);
 249  void visitAttribute        (Attribute*);
 250  void visitParameter        (Parameter*);
 251  void visitOperation        (Operation*);
 252  void visitNative           (Native*);
 253  void visitStateMember      (StateMember*);
 254  void visitFactory          (Factory*);
 255  void visitValueForward     (ValueForward*);
 256  void visitValueBox         (ValueBox*);
 257  void visitValueAbs         (ValueAbs*);
 258  void visitValue            (Value*);
 259
 260  void visitBaseType    (BaseType*);
 261  void visitStringType  (StringType*);
 262  void visitWStringType (WStringType*);
 263  void visitSequenceType(SequenceType*);
 264  void visitFixedType   (FixedType*);
 265  void visitDeclaredType(DeclaredType*);
 266
 267  PyObject* result() { return result_; }
 268
 269  static PyObject* scopedNameToList(const ScopedName* sn);
 270  static PyObject* wstringToList(const IDL_WChar* ws);
 271
 272private:
 273  PyObject* pragmasToList(const Pragma* ps);
 274  PyObject* commentsToList(const Comment* cs);
 275  void      registerPyDecl(const ScopedName* sn, PyObject* pydecl);
 276  PyObject* findPyDecl(const ScopedName* sn);
 277
 278  PyObject* idlast_;
 279  PyObject* idltype_;
 280
 281  PyObject* result_; // Current working value
 282};
 283
 284PythonVisitor::
 285PythonVisitor()
 286{
 287  idlast_  = PyImport_ImportModule((char*)"idlast");
 288  idltype_ = PyImport_ImportModule((char*)"idltype");
 289  ASSERT_PYOBJ(idlast_);
 290  ASSERT_PYOBJ(idltype_);
 291}
 292
 293PythonVisitor::
 294~PythonVisitor()
 295{
 296  Py_DECREF(idlast_);
 297  Py_DECREF(idltype_);
 298}
 299
 300
 301PyObject*
 302PythonVisitor::
 303scopedNameToList(const ScopedName* sn)
 304{
 305  ScopedName::Fragment* f;
 306  int i;
 307
 308  for (i=0, f = sn->scopeList(); f; f = f->next(), ++i);
 309
 310  PyObject* pylist = PyList_New(i);
 311
 312  for (i=0, f = sn->scopeList(); f; f = f->next(), ++i)
 313    PyList_SetItem(pylist, i, PyString_FromString(f->identifier()));
 314
 315  return pylist;
 316}
 317
 318
 319PyObject*
 320PythonVisitor::
 321pragmasToList(const Pragma* ps)
 322{
 323  const Pragma* p;
 324  int i;
 325
 326  for (i=0, p = ps; p; p = p->next(), ++i);
 327
 328  PyObject* pylist = PyList_New(i);
 329  PyObject* pypragma;
 330
 331  for (i=0, p = ps; p; p = p->next(), ++i) {
 332
 333    pypragma = PyObject_CallMethod(idlast_, (char*)"Pragma", (char*)"ssi",
 334				   p->pragmaText(), p->file(), p->line());
 335    ASSERT_PYOBJ(pypragma);
 336    PyList_SetItem(pylist, i, pypragma);
 337  }
 338  return pylist;
 339}
 340
 341PyObject*
 342PythonVisitor::
 343commentsToList(const Comment* cs)
 344{
 345  const Comment* c;
 346  int i;
 347
 348  for (i=0, c = cs; c; c = c->next(), ++i);
 349
 350  PyObject* pylist = PyList_New(i);
 351  PyObject* pycomment;
 352
 353  for (i=0, c = cs; c; c = c->next(), ++i) {
 354
 355    pycomment = PyObject_CallMethod(idlast_, (char*)"Comment", (char*)"ssi",
 356				    c->commentText(), c->file(), c->line());
 357    ASSERT_PYOBJ(pycomment);
 358    PyList_SetItem(pylist, i, pycomment);
 359  }
 360  return pylist;
 361}
 362
 363
 364void
 365PythonVisitor::
 366registerPyDecl(const ScopedName* sn, PyObject* pydecl)
 367{
 368  PyObject* pysn = scopedNameToList(sn);
 369  PyObject* r    = PyObject_CallMethod(idlast_, (char*)"registerDecl",
 370				       (char*)"NO", pysn, pydecl);
 371  ASSERT_PYOBJ(r); Py_DECREF(r);
 372}
 373
 374PyObject*
 375PythonVisitor::
 376findPyDecl(const ScopedName* sn)
 377{
 378  PyObject* pysn   = scopedNameToList(sn);
 379  PyObject* pydecl = PyObject_CallMethod(idlast_, (char*)"findDecl",
 380					 (char*)"N", pysn);
 381  ASSERT_PYOBJ(pydecl);
 382  return pydecl;
 383}
 384
 385PyObject*
 386PythonVisitor::
 387wstringToList(const IDL_WChar* ws)
 388{
 389  int i;
 390  const IDL_WChar* wc;
 391
 392  for (i=0, wc=ws; *wc; ++wc, ++i);
 393  PyObject* pyl = PyList_New(i);
 394
 395  for (i=0, wc=ws; *wc; ++wc, ++i)
 396    PyList_SetItem(pyl, i, PyInt_FromLong(*wc));
 397
 398  return pyl;
 399}
 400
 401//
 402// AST visit functions
 403//
 404
 405void
 406PythonVisitor::
 407visitAST(AST* a)
 408{
 409  Decl* d;
 410  int   i;
 411  for (i=0, d = a->declarations(); d; d = d->next(), ++i);
 412
 413  PyObject* pydecls = PyList_New(i);
 414
 415  for (i=0, d = a->declarations(); d; d = d->next(), ++i) {
 416    d->accept(*this);
 417    PyList_SetItem(pydecls, i, result_);
 418  }
 419  result_ = PyObject_CallMethod(idlast_, (char*)"AST", (char*)"sNNN",
 420				a->file(), pydecls,
 421				pragmasToList(a->pragmas()),
 422				commentsToList(a->comments()));
 423  ASSERT_RESULT;
 424}
 425
 426void
 427PythonVisitor::
 428visitModule(Module* m)
 429{
 430  Decl* d;
 431  int   i;
 432  for (i=0, d = m->definitions(); d; d = d->next(), ++i);
 433
 434  PyObject* pydecls = PyList_New(i);
 435
 436  for (i=0, d = m->definitions(); d; d = d->next(), ++i) {
 437    d->accept(*this);
 438    PyList_SetItem(pydecls, i, result_);
 439  }
 440  result_ = PyObject_CallMethod(idlast_, (char*)"Module", (char*)"siiNNsNsN",
 441				m->file(), m->line(), (int)m->mainFile(),
 442				pragmasToList(m->pragmas()),
 443				commentsToList(m->comments()),
 444				m->identifier(),
 445				scopedNameToList(m->scopedName()),
 446				m->repoId(),
 447				pydecls);
 448  ASSERT_RESULT;
 449  registerPyDecl(m->scopedName(), result_);
 450}
 451
 452void
 453PythonVisitor::
 454visitInterface(Interface* i)
 455{
 456  int       l;
 457  PyObject* pyobj;
 458  Decl*     d;
 459
 460  // Inherited interfaces
 461  InheritSpec* inh;
 462
 463  for (l=0, inh = i->inherits(); inh; inh = inh->next(), ++l);
 464  PyObject* pyinherits = PyList_New(l);
 465
 466  for (l=0, inh = i->inherits(); inh; inh = inh->next(), ++l) {
 467    d = inh->decl();
 468    if (d->kind() == Decl::D_INTERFACE)
 469      pyobj = findPyDecl(((Interface*)d)->scopedName());
 470    else if (d->kind() == Decl::D_DECLARATOR)
 471      pyobj = findPyDecl(((Declarator*)d)->scopedName());
 472    else
 473      assert(0);
 474    PyList_SetItem(pyinherits, l, pyobj);
 475  }
 476
 477  PyObject* pyintf =
 478    PyObject_CallMethod(idlast_, (char*)"Interface", (char*)"siiNNsNsiiN",
 479			i->file(), i->line(), (int)i->mainFile(),
 480			pragmasToList(i->pragmas()),
 481			commentsToList(i->comments()),
 482			i->identifier(),
 483			scopedNameToList(i->scopedName()),
 484			i->repoId(),
 485			(int)i->abstract(), (int)i->local(), pyinherits);
 486  ASSERT_PYOBJ(pyintf);
 487  registerPyDecl(i->scopedName(), pyintf);
 488
 489  // Contents
 490  for (l=0, d = i->contents(); d; d = d->next(), ++l);
 491  PyObject* pycontents = PyList_New(l);
 492
 493  for (l=0, d = i->contents(); d; d = d->next(), ++l) {
 494    d->accept(*this);
 495    PyList_SetItem(pycontents, l, result_);
 496  }
 497  PyObject* r = PyObject_CallMethod(pyintf, (char*)"_setContents",
 498				    (char*)"N", pycontents);
 499  ASSERT_PYOBJ(r); Py_DECREF(r);
 500  result_ = pyintf;
 501}
 502
 503void
 504PythonVisitor::
 505visitForward(Forward* f)
 506{
 507  result_ = PyObject_CallMethod(idlast_, (char*)"Forward", (char*)"siiNNsNsii",
 508				f->file(), f->line(), (int)f->mainFile(),
 509				pragmasToList(f->pragmas()),
 510				commentsToList(f->comments()),
 511				f->identifier(),
 512				scopedNameToList(f->scopedName()),
 513				f->repoId(),
 514				(int)f->abstract(), (int)f->local());
 515  ASSERT_RESULT;
 516  registerPyDecl(f->scopedName(), result_);
 517}
 518
 519void
 520PythonVisitor::
 521visitConst(Const* c)
 522{
 523  c->constType()->accept(*this);
 524  PyObject* pytype = result_;
 525  PyObject* pyv;
 526
 527  switch(c->constKind()) {
 528  case IdlType::tk_short:  pyv = PyInt_FromLong(c->constAsShort());  break;
 529  case IdlType::tk_long:   pyv = PyInt_FromLong(c->constAsLong());   break;
 530  case IdlType::tk_ushort: pyv = PyInt_FromLong(c->constAsUShort()); break;
 531  case IdlType::tk_ulong:
 532    pyv = PyLong_FromUnsignedLong(c->constAsULong()); break;
 533
 534  case IdlType::tk_float:  pyv = PyFloat_FromDouble(c->constAsFloat());  break;
 535  case IdlType::tk_double: pyv = PyFloat_FromDouble(c->constAsDouble()); break;
 536
 537  case IdlType::tk_boolean:
 538    pyv = PyInt_FromLong(c->constAsBoolean()); break;
 539
 540  case IdlType::tk_char:  pyv = Py_BuildValue((char*)"c", c->constAsChar());
 541    break;
 542  case IdlType::tk_octet: pyv = PyInt_FromLong(c->constAsOctet()); break;
 543
 544  case IdlType::tk_string:
 545    pyv = PyString_FromString(c->constAsString()); break;
 546
 547#ifdef HAS_LongLong
 548  case IdlType::tk_longlong:
 549    pyv = MyPyLong_FromLongLong(c->constAsLongLong()); break;
 550
 551  case IdlType::tk_ulonglong:
 552    pyv = PyLong_FromUnsignedLongLong(c->constAsULongLong()); break;
 553
 554#endif
 555#ifdef HAS_LongDouble
 556  case IdlType::tk_longdouble:
 557    pyv = PyFloat_FromDouble(c->constAsLongDouble());
 558    IdlWarning(c->file(), c->line(),
 559	       "long double constant truncated to double. Sorry.");
 560    break;
 561#endif
 562  case IdlType::tk_wchar:   pyv = PyInt_FromLong(c->constAsWChar());  break;
 563  case IdlType::tk_wstring: pyv = wstringToList(c->constAsWString()); break;
 564
 565  case IdlType::tk_fixed:
 566    {
 567      char* fs = c->constAsFixed()->asString();
 568      pyv = PyString_FromString(fs);
 569      delete [] fs;
 570    }
 571    break;
 572
 573  case IdlType::tk_enum:
 574    pyv = findPyDecl(c->constAsEnumerator()->scopedName());
 575    break;
 576
 577  default:
 578    assert(0);
 579  }
 580  result_ = PyObject_CallMethod(idlast_, (char*)"Const", (char*)"siiNNsNsNiN",
 581				c->file(), c->line(), (int)c->mainFile(),
 582				pragmasToList(c->pragmas()),
 583				commentsToList(c->comments()),
 584				c->identifier(),
 585				scopedNameToList(c->scopedName()),
 586				c->repoId(),
 587				pytype, (int)c->constKind(), pyv);
 588  ASSERT_RESULT;
 589  registerPyDecl(c->scopedName(), result_);
 590}
 591
 592void
 593PythonVisitor::
 594visitDeclarator(Declarator* d)
 595{
 596  ArraySize* s;
 597  int        i;
 598
 599  for (i=0, s = d->sizes(); s; s = s->next(), ++i);
 600  PyObject* pysizes = PyList_New(i);
 601
 602  for (i=0, s = d->sizes(); s; s = s->next(), ++i)
 603    PyList_SetItem(pysizes, i, PyInt_FromLong(s->size()));
 604
 605  result_ =
 606    PyObject_CallMethod(idlast_, (char*)"Declarator",(char*)"siiNNsNsN",
 607			d->file(), d->line(), (int)d->mainFile(),
 608			pragmasToList(d->pragmas()),
 609			commentsToList(d->comments()),
 610			d->identifier(),
 611			scopedNameToList(d->scopedName()),
 612			d->repoId(),
 613			pysizes);
 614  ASSERT_RESULT;
 615  registerPyDecl(d->scopedName(), result_);
 616}
 617
 618void
 619PythonVisitor::
 620visitTypedef(Typedef* t)
 621{
 622  if (t->constrType()) {
 623    ((DeclaredType*)t->aliasType())->decl()->accept(*this);
 624    Py_DECREF(result_);
 625  }
 626  t->aliasType()->accept(*this);
 627  PyObject* pyaliasType = result_;
 628
 629  Declarator* d;
 630  int         i, l;
 631
 632  for (l=0, d = t->declarators(); d; d = (Declarator*)d->next(), ++l);
 633  PyObject* pydeclarators = PyList_New(l);
 634
 635  for (i=0, d = t->declarators(); d; d = (Declarator*)d->next(), ++i) {
 636    d->accept(*this);
 637    PyList_SetItem(pydeclarators, i, result_);
 638  }
 639  result_ = PyObject_CallMethod(idlast_, (char*)"Typedef", (char*)"siiNNNiN",
 640				t->file(), t->line(), (int)t->mainFile(),
 641				pragmasToList(t->pragmas()),
 642				commentsToList(t->comments()),
 643				pyaliasType, (int)t->constrType(),
 644				pydeclarators);
 645  ASSERT_RESULT;
 646
 647  // Give each Declarator a reference to the Typedef. This creates a
 648  // loop which Python's GC won't collect :-(
 649  for (i=0; i<l; ++i) {
 650    PyObject_CallMethod(PyList_GetItem(pydeclarators, i),
 651			(char*)"_setAlias", (char*)"O", result_);
 652  }
 653}
 654
 655void
 656PythonVisitor::
 657visitMember(Member* m)
 658{
 659  if (m->constrType()) {
 660    ((DeclaredType*)m->memberType())->decl()->accept(*this);
 661    Py_DECREF(result_);
 662  }
 663  m->memberType()->accept(*this);
 664  PyObject* pymemberType = result_;
 665
 666  Declarator* d;
 667  int         i;
 668
 669  for (i=0, d = m->declarators(); d; d = (Declarator*)d->next(), ++i);
 670  PyObject* pydeclarators = PyList_New(i);
 671
 672  for (i=0, d = m->declarators(); d; d = (Declarator*)d->next(), ++i) {
 673    d->accept(*this);
 674    PyList_SetItem(pydeclarators, i, result_);
 675  }
 676  result_ = PyObject_CallMethod(idlast_, (char*)"Member", (char*)"siiNNNiN",
 677				m->file(), m->line(), (int)m->mainFile(),
 678				pragmasToList(m->pragmas()),
 679				commentsToList(m->comments()),
 680				pymemberType, (int)m->constrType(),
 681				pydeclarators);
 682  ASSERT_RESULT;
 683}
 684
 685void
 686PythonVisitor::
 687visitStruct(Struct* s)
 688{
 689  Member* m;
 690  int     i;
 691
 692  PyObject* pystruct = 
 693    PyObject_CallMethod(idlast_, (char*)"Struct", (char*)"siiNNsNsi",
 694			s->file(), s->line(), (int)s->mainFile(),
 695			pragmasToList(s->pragmas()),
 696			commentsToList(s->comments()),
 697			s->identifier(),
 698			scopedNameToList(s->scopedName()),
 699			s->repoId(),
 700			(int)s->recursive());
 701  ASSERT_PYOBJ(pystruct);
 702  registerPyDecl(s->scopedName(), pystruct);
 703
 704  for (i=0, m = s->members(); m; m = (Member*)m->next(), ++i);
 705  PyObject* pymembers = PyList_New(i);
 706
 707  for (i=0, m = s->members(); m; m = (Member*)m->next(), ++i) {
 708    m->accept(*this);
 709    PyList_SetItem(pymembers, i, result_);
 710  }
 711  PyObject* r = PyObject_CallMethod(pystruct, (char*)"_setMembers",
 712				    (char*)"N", pymembers);
 713  ASSERT_PYOBJ(r); Py_DECREF(r);
 714  result_ = pystruct;
 715}
 716
 717void
 718PythonVisitor::
 719visitStructForward(StructForward* f)
 720{
 721  result_ = PyObject_CallMethod(idlast_, (char*)"StructForward",
 722				(char*)"siiNNsNs",
 723				f->file(), f->line(), (int)f->mainFile(),
 724				pragmasToList(f->pragmas()),
 725				commentsToList(f->comments()),
 726				f->identifier(),
 727				scopedNameToList(f->scopedName()),
 728				f->repoId());
 729  ASSERT_RESULT;
 730  registerPyDecl(f->scopedName(), result_);
 731}
 732
 733
 734void
 735PythonVisitor::
 736visitException(Exception* e)
 737{
 738  Member* m;
 739  int     i;
 740
 741  for (i=0, m = e->members(); m; m = (Member*)m->next(), ++i);
 742  PyObject* pymembers = PyList_New(i);
 743
 744  for (i=0, m = e->members(); m; m = (Member*)m->next(), ++i) {
 745    m->accept(*this);
 746    PyList_SetItem(pymembers, i, result_);
 747  }
 748  result_ =
 749    PyObject_CallMethod(idlast_, (char*)"Exception", (char*)"siiNNsNsN",
 750			e->file(), e->line(), (int)e->mainFile(),
 751			pragmasToList(e->pragmas()),
 752			commentsToList(e->comments()),
 753			e->identifier(),
 754			scopedNameToList(e->scopedName()),
 755			e->repoId(),
 756			pymembers);
 757  ASSERT_RESULT;
 758  registerPyDecl(e->scopedName(), result_);
 759}
 760
 761void
 762PythonVisitor::
 763visitCaseLabel(CaseLabel* l)
 764{
 765  PyObject* pyv;
 766
 767  switch(l->labelKind()) {
 768  case IdlType::tk_short:  pyv = PyInt_FromLong(l->labelAsShort());  break;
 769  case IdlType::tk_long:   pyv = PyInt_FromLong(l->labelAsLong());   break;
 770  case IdlType::tk_ushort: pyv = PyInt_FromLong(l->labelAsUShort()); break;
 771  case IdlType::tk_ulong:
 772    pyv = PyLong_FromUnsignedLong(l->labelAsULong()); break;
 773
 774  case IdlType::tk_boolean: pyv = PyInt_FromLong(l->labelAsBoolean());  break;
 775  case IdlType::tk_char:    pyv = Py_BuildValue((char*)"c", l->labelAsChar());
 776    break;
 777#ifdef HAS_LongLong
 778  case IdlType::tk_longlong:
 779    pyv = MyPyLong_FromLongLong(l->labelAsLongLong());
 780    break;
 781  case IdlType::tk_ulonglong:
 782    pyv = PyLong_FromUnsignedLongLong(l->labelAsULongLong());
 783    break;
 784#endif
 785  case IdlType::tk_wchar:   pyv = PyInt_FromLong(l->labelAsWChar());  break;
 786  case IdlType::tk_enum:
 787    pyv = findPyDecl(l->labelAsEnumerator()->scopedName());
 788    break;
 789  default:
 790    assert(0);
 791  }
 792  result_ = PyObject_CallMethod(idlast_, (char*)"CaseLabel", (char*)"siiNNiNi",
 793				l->file(), l->line(), (int)l->mainFile(),
 794				pragmasToList(l->pragmas()),
 795				commentsToList(l->comments()),
 796				(int)l->isDefault(), pyv,
 797				(int)l->labelKind());
 798  ASSERT_RESULT;
 799}
 800
 801void
 802PythonVisitor::
 803visitUnionCase(UnionCase* c)
 804{
 805  if (c->constrType()) {
 806    ((DeclaredType*)c->caseType())->decl()->accept(*this);
 807    Py_DECREF(result_);
 808  }
 809  CaseLabel* l;
 810  int        i;
 811
 812  for (i=0, l = c->labels(); l; l = (CaseLabel*)l->next(), ++i);
 813  PyObject* pylabels = PyList_New(i);
 814
 815  for (i=0, l = c->labels(); l; l = (CaseLabel*)l->next(), ++i) {
 816    l->accept(*this);
 817    PyList_SetItem(pylabels, i, result_);
 818  }
 819  c->caseType()->accept(*this);
 820  PyObject* pycaseType = result_;
 821
 822  c->declarator()->accept(*this);
 823  PyObject* pydeclarator = result_;
 824
 825  result_ =
 826    PyObject_CallMethod(idlast_, (char*)"UnionCase", (char*)"siiNNNNiN",
 827			c->file(), c->line(), (int)c->mainFile(),
 828			pragmasToList(c->pragmas()),
 829			commentsToList(c->comments()),
 830			pylabels, pycaseType, (int)c->constrType(),
 831			pydeclarator);
 832  ASSERT_RESULT;
 833}
 834
 835void
 836PythonVisitor::
 837visitUnion(Union* u)
 838{
 839  if (u->constrType()) {
 840    ((DeclaredType*)u->switchType())->decl()->accept(*this);
 841    Py_DECREF(result_);
 842  }
 843  u->switchType()->accept(*this);
 844  PyObject* pyswitchType = result_;
 845
 846  PyObject* pyunion =
 847    PyObject_CallMethod(idlast_, (char*)"Union", (char*)"siiNNsNsNii",
 848			u->file(), u->line(), (int)u->mainFile(),
 849			pragmasToList(u->pragmas()),
 850			commentsToList(u->comments()),
 851			u->identifier(),
 852			scopedNameToList(u->scopedName()),
 853			u->repoId(),
 854			pyswitchType, (int)u->constrType(),
 855			(int)u->recursive());
 856  ASSERT_PYOBJ(pyunion);
 857  registerPyDecl(u->scopedName(), pyunion);
 858
 859  UnionCase* c;
 860  int        i;
 861  for (i=0, c = u->cases(); c; c = (UnionCase*)c->next(), ++i);
 862  PyObject* pycases = PyList_New(i);
 863
 864  for (i=0, c = u->cases(); c; c = (UnionCase*)c->next(), ++i) {
 865    c->accept(*this);
 866    PyList_SetItem(pycases, i, result_);
 867  }
 868
 869  PyObject* r = PyObject_CallMethod(pyunion, (char*)"_setCases",
 870				    (char*)"N", pycases);
 871  ASSERT_PYOBJ(r); Py_DECREF(r);
 872  result_ = pyunion;
 873}
 874
 875void
 876PythonVisitor::
 877visitUnionForward(UnionForward* f)
 878{
 879  result_ = PyObject_CallMethod(idlast_, (char*)"UnionForward",
 880				(char*)"siiNNsNs",
 881				f->file(), f->line(), (int)f->mainFile(),
 882				pragmasToList(f->pragmas()),
 883				commentsToList(f->comments()),
 884				f->identifier(),
 885				scopedNameToList(f->scopedName()),
 886				f->repoId());
 887  ASSERT_RESULT;
 888  registerPyDecl(f->scopedName(), result_);
 889}
 890
 891void
 892PythonVisitor::
 893visitEnumerator(Enumerator* e)
 894{
 895  result_ =
 896    PyObject_CallMethod(idlast_, (char*)"Enumerator", (char*)"siiNNsNsi",
 897			e->file(), e->line(), (int)e->mainFile(),
 898			pragmasToList(e->pragmas()),
 899			commentsToList(e->comments()),
 900			e->identifier(),
 901			scopedNameToList(e->scopedName()),
 902			e->repoId(),
 903			e->value());
 904  ASSERT_RESULT;
 905  registerPyDecl(e->scopedName(), result_);
 906}
 907
 908void
 909PythonVisitor::
 910visitEnum(Enum* e)
 911{
 912  Enumerator* n;
 913  int         i;
 914  for (i=0, n = e->enumerators(); n; n = (Enumerator*)n->next(), ++i);
 915  PyObject* pyenumerators = PyList_New(i);
 916
 917  for (i=0, n = e->enumerators(); n; n = (Enumerator*)n->next(), ++i) {
 918    n->accept(*this);
 919    PyList_SetItem(pyenumerators, i, result_);
 920  }
 921  result_ = PyObject_CallMethod(idlast_, (char*)"Enum", (char*)"siiNNsNsN",
 922				e->file(), e->line(), (int)e->mainFile(),
 923				pragmasToList(e->pragmas()),
 924				commentsToList(e->comments()),
 925				e->identifier(),
 926				scopedNameToList(e->scopedName()),
 927				e->repoId(),
 928				pyenumerators);
 929  ASSERT_RESULT;
 930  registerPyDecl(e->scopedName(), result_);
 931}
 932
 933void
 934PythonVisitor::
 935visitAttribute(Attribute* a)
 936{
 937  a->attrType()->accept(*this);
 938  PyObject* pyattrType = result_;
 939
 940  Declarator* d;
 941  int         i, l;
 942
 943  for (l=0, d = a->declarators(); d; d = (Declarator*)d->next(), ++l);
 944  PyObject* pydeclarators = PyList_New(l);
 945
 946  for (i=0, d = a->declarators(); d; d = (Declarator*)d->next(), ++i) {
 947    d->accept(*this);
 948    PyList_SetItem(pydeclarators, i, result_);
 949  }
 950  result_ = PyObject_CallMethod(idlast_, (char*)"Attribute", (char*)"siiNNiNN",
 951				a->file(), a->line(), (int)a->mainFile(),
 952				pragmasToList(a->pragmas()),
 953				commentsToList(a->comments()),
 954				(int)a->readonly(), pyattrType,
 955				pydeclarators);
 956  ASSERT_RESULT;
 957}
 958
 959void
 960PythonVisitor::
 961visitParameter(Parameter* p)
 962{
 963  p->paramType()->accept(*this);
 964  PyObject* pyparamType = result_;
 965
 966  result_ = PyObject_CallMethod(idlast_, (char*)"Parameter", (char*)"siiNNiNs",
 967				p->file(), p->line(), (int)p->mainFile(),
 968				pragmasToList(p->pragmas()),
 969				commentsToList(p->comments()),
 970				p->direction(), pyparamType, p->identifier());
 971  ASSERT_RESULT;
 972}
 973
 974void
 975PythonVisitor::
 976visitOperation(Operation* o)
 977{
 978  o->returnType()->accept(*this);
 979  PyObject* pyreturnType = result_;
 980
 981  Parameter* p;
 982  int        i;
 983  for (i=0, p = o->parameters(); p; p = (Parameter*)p->next(), ++i);
 984  PyObject* pyparameters = PyList_New(i);
 985
 986  for (i=0, p = o->parameters(); p; p = (Parameter*)p->next(), ++i) {
 987    p->accept(*this);
 988    PyList_SetItem(pyparameters, i, result_);
 989  }
 990
 991  RaisesSpec* r;
 992  for (i=0, r = o->raises(); r; r = r->next(), ++i);
 993  PyObject* pyraises = PyList_New(i);
 994
 995  for (i=0, r = o->raises(); r; r = r->next(), ++i)
 996    PyList_SetItem(pyraises, i, findPyDecl(r->exception()->scopedName()));
 997
 998  ContextSpec* c;
 999  for (i=0, c = o->contexts(); c; c = c->next(), ++i);
1000  PyObject* pycontexts = PyList_New(i);
1001
1002  for (i=0, c = o->contexts(); c; c = c->next(), ++i)
1003    PyList_SetItem(pycontexts, i, PyString_FromString(c->context()));
1004
1005  result_ =
1006    PyObject_CallMethod(idlast_,(char*)"Operation",(char*)"siiNNiNsNsNNN",
1007			o->file(), o->line(), (int)o->mainFile(),
1008			pragmasToList(o->pragmas()),
1009			commentsToList(o->comments()),
1010			(int)o->oneway(), pyreturnType,
1011			o->identifier(),
1012			scopedNameToList(o->scopedName()),
1013			o->repoId(),
1014			pyparameters,
1015			pyraises, pycontexts);
1016  ASSERT_RESULT;
1017  registerPyDecl(o->scopedName(), result_);
1018}
1019
1020void
1021PythonVisitor::
1022visitNative(Native* n)
1023{
1024  result_ = PyObject_CallMethod(idlast_, (char*)"Native", (char*)"siiNNsNs",
1025				n->file(), n->line(), (int)n->mainFile(),
1026				pragmasToList(n->pragmas()),
1027				commentsToList(n->comments()),
1028				n->identifier(),
1029				scopedNameToList(n->scopedName()),
1030				n->repoId());
1031  ASSERT_RESULT;
1032  registerPyDecl(n->scopedName(), result_);
1033}
1034
1035void
1036PythonVisitor::
1037visitStateMember(StateMember* s)
1038{
1039  if (s->constrType()) {
1040    ((DeclaredType*)s->memberType())->decl()->accept(*this);
1041    Py_DECREF(result_);
1042  }
1043  s->memberType()->accept(*this);
1044  PyObject* pymemberType = result_;
1045
1046  Declarator* d;
1047  int         i;
1048
1049  for (i=0, d = s->declarators(); d; d = (Declarator*)d->next(), ++i);
1050  PyObject* pydeclarators = PyList_New(i);
1051
1052  for (i=0, d = s->declarators(); d; d = (Declarator*)d->next(), ++i) {
1053    d->accept(*this);
1054    PyList_SetItem(pydeclarators, i, result_);
1055  }
1056  result_ =
1057    PyObject_CallMethod(idlast_,(char*)"StateMember",(char*)"siiNNiNiN",
1058			s->file(), s->line(), (int)s->mainFile(),
1059			pragmasToList(s->pragmas()),
1060			commentsToList(s->comments()),
1061			s->memberAccess(), pymemberType,
1062			(int)s->constrType(), pydeclarators);
1063  ASSERT_RESULT;
1064}
1065
1066void
1067PythonVisitor::
1068visitFactory(Factory* f)
1069{
1070  Parameter* p;
1071  int        i;
1072  for (i=0, p = f->parameters(); p; p = (Parameter*)p->next(), ++i);
1073  PyObject* pyparameters = PyList_New(i);
1074
1075  for (i=0, p = f->parameters(); p; p = (Parameter*)p->next(), ++i) {
1076    p->accept(*this);
1077    PyList_SetItem(pyparameters, i, result_);
1078  }
1079
1080  RaisesSpec* r;
1081  for (i=0, r = f->raises(); r; r = r->next(), ++i);
1082  PyObject* pyraises = PyList_New(i);
1083
1084  for (i=0, r = f->raises(); r; r = r->next(), ++i)
1085    PyList_SetItem(pyraises, i, findPyDecl(r->exception()->scopedName()));
1086
1087  result_ = PyObject_CallMethod(idlast_, (char*)"Factory", (char*)"siiNNsNN",
1088				f->file(), f->line(), (int)f->mainFile(),
1089				pragmasToList(f->pragmas()),
1090				commentsToList(f->comments()),
1091				f->identifier(), pyparameters, pyraises);
1092  ASSERT_RESULT;
1093}
1094
1095void
1096PythonVisitor::
1097visitValueForward(ValueForward* f)
1098{
1099  result_ = PyObject_CallMethod(idlast_,
1100				(char*)"ValueForward", (char*)"siiNNsNsi",
1101				f->file(), f->line(), (int)f->mainFile(),
1102				pragmasToList(f->pragmas()),
1103				commentsToList(f->comments()),
1104				f->identifier(),
1105				scopedNameToList(f->scopedName()),
1106				f->repoId(),
1107				(int)f->abstract());
1108  ASSERT_RESULT;
1109  registerPyDecl(f->scopedName(), result_);
1110}
1111
1112void
1113PythonVisitor::
1114visitValueBox(ValueBox* b)
1115{
1116  if (b->constrType()) {
1117    ((DeclaredType*)b->boxedType())->decl()->accept(*this);
1118    Py_DECREF(result_);
1119  }
1120  b->boxedType()->accept(*this);
1121  PyObject* pyboxedType = result_;
1122
1123  result_ =
1124    PyObject_CallMethod(idlast_, (char*)"ValueBox", (char*)"siiNNsNsNi",
1125			b->file(), b->line(), (int)b->mainFile(),
1126			pragmasToList(b->pragmas()),
1127			commentsToList(b->comments()),
1128			b->identifier(),
1129			scopedNameToList(b->scopedName()),
1130			b->repoId(),
1131			pyboxedType, (int)b->constrType());
1132  ASSERT_RESULT;
1133  registerPyDecl(b->scopedName(), result_);
1134}
1135
1136void
1137PythonVisitor::
1138visitValueAbs(ValueAbs* a)
1139{
1140  int       l;
1141  PyObject* pyobj;
1142  Decl*     d;
1143
1144  // Inherited values and interfaces
1145  InheritSpec*      inh;
1146  ValueInheritSpec* vinh;
1147
1148  for (l=0, vinh = a->inherits(); vinh; vinh = vinh->next(), ++l);
1149  PyObject* pyinherits = PyList_New(l);
1150
1151  for (l=0, vinh = a->inherits(); vinh; vinh = vinh->next(), ++l) {
1152    d = vinh->decl();
1153    if (d->kind() == Decl::D_VALUEABS)
1154      pyobj = findPyDecl(((ValueAbs*)d)->scopedName());
1155    else if (d->kind() == Decl::D_DECLARATOR)
1156      pyobj = findPyDecl(((Declarator*)d)->scopedName());
1157    else
1158      assert(0);
1159    PyList_SetItem(pyinherits, l, pyobj);
1160  }
1161  for (l=0, inh = a->supports(); inh; inh = inh->next(), ++l);
1162  PyObject* pysupports = PyList_New(l);
1163
1164  for (l=0, inh = a->supports(); inh; inh = inh->next(), ++l) {
1165    d = inh->decl();
1166    if (d->kind() == Decl::D_INTERFACE)
1167      pyobj = findPyDecl(((Interface*)d)->scopedName());
1168    else if (d->kind() == Decl::D_DECLARATOR)
1169      pyobj = findPyDecl(((Declarator*)d)->scopedName());
1170    else
1171      assert(0);
1172    PyList_SetItem(pysupports, l, pyobj);
1173  }
1174
1175  PyObject* pyvalue =
1176    PyObject_CallMethod(idlast_, (char*)"ValueAbs", (char*)"siiNNsNsNN",
1177			a->file(), a->line(), (int)a->mainFile(),
1178			pragmasToList(a->pragmas()),
1179			commentsToList(a->comments()),
1180			a->identifier(),
1181			scopedNameToList(a->scopedName()),
1182			a->repoId(),
1183			pyinherits, pysupports);
1184  ASSERT_PYOBJ(pyvalue);
1185  registerPyDecl(a->scopedName(), pyvalue);
1186
1187  // Contents
1188  for (l=0, d = a->contents(); d; d = d->next(), ++l);
1189  PyObject* pycontents = PyList_New(l);
1190
1191  for (l=0, d = a->contents(); d; d = d->next(), ++l) {
1192    d->accept(*this);
1193    PyList_SetItem(pycontents, l, result_);
1194  }
1195  PyObject* r = PyObject_CallMethod(pyvalue, (char*)"_setContents",
1196				    (char*)"N", pycontents);
1197  ASSERT_PYOBJ(r); Py_DECREF(r);
1198  result_ = pyvalue;
1199}
1200
1201void
1202PythonVisitor::
1203visitValue(Value* v)
1204{
1205  int       l;
1206  PyObject* pyobj;
1207  Decl*     d;
1208
1209  // Inherited values and interfaces
1210  InheritSpec*      inh;
1211  ValueInheritSpec* vinh;
1212  int               truncatable = 0;
1213
1214  if (v->inherits()) truncatable = v->inherits()->truncatable();
1215
1216  for (l=0, vinh = v->inherits(); vinh; vinh = vinh->next(), ++l);
1217  PyObject* pyinherits = PyList_New(l);
1218
1219  for (l=0, vinh = v->inherits(); vinh; vinh = vinh->next(), ++l) {
1220    d = vinh->decl();
1221    if (d->kind() == Decl::D_VALUE)
1222      pyobj = findPyDecl(((Value*)d)->scopedName());
1223    else if (d->kind() == Decl::D_VALUEABS)
1224      pyobj = findPyDecl(((ValueAbs*)d)->scopedName());
1225    else if (d->kind() == Decl::D_DECLARATOR)
1226      pyobj = findPyDecl(((Declarator*)d)->scopedName());
1227    else
1228      assert(0);
1229    PyList_SetItem(pyinherits, l, pyobj);
1230  }
1231  for (l=0, inh = v->supports(); inh; inh = inh->next(), ++l);
1232  PyObject* pysupports = PyList_New(l);
1233
1234  for (l=0, inh = v->supports(); inh; inh = inh->next(), ++l) {
1235    d = inh->decl();
1236    if (d->kind() == Decl::D_INTERFACE)
1237      pyobj = findPyDecl(((Interface*)d)->scopedName());
1238    else if (d->kind() == Decl::D_DECLARATOR)
1239      pyobj = findPyDecl(((Declarator*)d)->scopedName());
1240    else
1241      assert(0);
1242    PyList_SetItem(pysupports, l, pyobj);
1243  }
1244
1245  PyObject* pyvalue =
1246    PyObject_CallMethod(idlast_, (char*)"Value", (char*)"siiNNsNsiNiN",
1247			v->file(), v->line(), (int)v->mainFile(),
1248			pragmasToList(v->pragmas()),
1249			commentsToList(v->comments()),
1250			v->identifier(),
1251			scopedNameToList(v->scopedName()),
1252			v->repoId(),
1253			(int)v->custom(), pyinherits,
1254			truncatable, pysupports);
1255  ASSERT_PYOBJ(pyvalue);
1256  registerPyDecl(v->scopedName(), pyvalue);
1257
1258  // Contents
1259  for (l=0, d = v->contents(); d; d = d->next(), ++l);
1260  PyObject* pycontents = PyList_New(l);
1261
1262  for (l=0, d = v->contents(); d; d = d->next(), ++l) {
1263    d->accept(*this);
1264    PyList_SetItem(pycontents, l, result_);
1265  }
1266  PyObject* r = PyObject_CallMethod(pyvalue, (char*)"_setContents",
1267				    (char*)"N", pycontents);
1268  ASSERT_PYOBJ(r); Py_DECREF(r);
1269  result_ = pyvalue;
1270}
1271
1272// Types
1273
1274void
1275PythonVisitor::
1276visitBaseType(BaseType* t)
1277{
1278  result_ = PyObject_CallMethod(idltype_, (char*)"baseType", (char*)"i",
1279				(int)t->kind());
1280  ASSERT_RESULT;
1281}
1282
1283void
1284PythonVisitor::
1285visitStringType(StringType* t)
1286{
1287  result_ = PyObject_CallMethod(idltype_, (char*)"stringType",
1288				(char*)"i", t->bound());
1289  ASSERT_RESULT;
1290}
1291
1292void
1293PythonVisitor::
1294visitWStringType(WStringType* t)
1295{
1296  result_ = PyObject_CallMethod(idltype_, (char*)"wstringType",
1297				(char*)"i", t->bound());
1298  ASSERT_RESULT;
1299}
1300
1301void
1302PythonVisitor::
1303visitSequenceType(SequenceType* t)
1304{
1305  t->seqType()->accept(*this);
1306  result_ = PyObject_CallMethod(idltype_, (char*)"sequenceType", (char*)"Nii",
1307				result_, t->bound(), (int)t->local());
1308  ASSERT_RESULT;
1309}
1310
1311void
1312PythonVisitor::
1313visitFixedType(FixedType* t)
1314{
1315  result_ = PyObject_CallMethod(idltype_, (char*)"fixedType", (char*)"ii",
1316				t->digits(), t->scale());
1317  ASSERT_RESULT;
1318}
1319
1320void
1321PythonVisitor::
1322visitDeclaredType(DeclaredType* t)
1323{
1324  if (t->decl()) {
1325    result_ =
1326      PyObject_CallMethod(idltype_, (char*)"declaredType", (char*)"NNii",
1327			  findPyDecl(t->declRepoId()->scopedName()),
1328			  scopedNameToList(t->declRepoId()->scopedName()),
1329			  (int)t->kind(), (int)t->local());
1330  }
1331  else {
1332    if (t->kind() == IdlType::tk_objref) {
1333      PyObject* pysn   = Py_BuildValue((char*)"[ss]", (char*)"CORBA",
1334				       (char*)"Object");
1335
1336      PyObject* pydecl = PyObject_CallMethod(idlast_, (char*)"findDecl",
1337					     (char*)"O", pysn);
1338
1339      result_          = PyObject_CallMethod(idltype_, (char*)"declaredType",
1340					     (char*)"NNii", pydecl, pysn,
1341					     (int)t->kind(), (int)t->local());
1342    }
1343    else if (t->kind() == IdlType::tk_value) {
1344      PyObject* pysn   = Py_BuildValue((char*)"[ss]", (char*)"CORBA",
1345				       (char*)"ValueBase");
1346
1347      PyObject* pydecl = PyObject_CallMethod(idlast_, (char*)"findDecl",
1348					     (char*)"O", pysn);
1349
1350      result_          = PyObject_CallMethod(idltype_, (char*)"declaredType",
1351					     (char*)"NNii", pydecl, pysn,
1352					     (int)t->kind(), (int)t->local());
1353    }
1354    else abort();
1355  }
1356  ASSERT_RESULT;
1357}
1358
1359extern "C" {
1360  static PyObject* IdlPyCompile(PyObject* self, PyObject* args)
1361  {
1362    PyObject*   arg;
1363    const char* name;
1364    FILE*       file;
1365    IDL_Boolean to_close = 0;
1366
1367    if (!PyArg_ParseTuple(args, (char*)"O", &arg))
1368      return 0;
1369
1370    if (PyString_Check(arg)) {
1371      name = PyString_AsString(arg);
1372      file = fopen(name, "r");
1373      if (!file) {
1374	PyErr_SetString(PyExc_IOError,
1375			(char*)"Cannot open file");
1376	return 0;
1377      }
1378      to_close = 1;
1379    }
1380    else if (PyFile_Check(arg)) {
1381      PyObject* pyname = PyFile_Name(arg);
1382      file = PyFile_AsFile(arg);
1383      name = PyString_AsString(pyname);
1384    }
1385    else {
1386      PyErr_SetString(PyExc_TypeError,
1387		      (char*)"Argument must be a file or filename");
1388      return 0;
1389    }
1390
1391    IDL_Boolean success = AST::process(file, name);
1392
1393    if (to_close)
1394      fclose(file);
1395
1396    if (success) {
1397      PythonVisitor v;
1398      AST::tree()->accept(v);
1399      return v.result();
1400    }
1401    else {
1402      AST::clear();
1403      Py_INCREF(Py_None);
1404      return Py_None;
1405    }
1406  }
1407
1408  static PyObject* IdlPyClear(PyObject* self, PyObject* args)
1409  {
1410    if (!PyArg_ParseTuple(args, (char*)""))
1411      return 0;
1412
1413    AST::clear();
1414    Py_INCREF(Py_None);
1415    return Py_None;
1416  }
1417
1418  static PyObject* IdlPyDump(PyObject* self, PyObject* args)
1419  {
1420    PyObject*   arg;
1421    const char* name;
1422    FILE*       file;
1423    IDL_Boolean to_close = 0;
1424
1425    if (!PyArg_ParseTuple(args, (char*)"O", &arg))
1426      return 0;
1427
1428    if (PyString_Check(arg)) {
1429      name = PyString_AsString(arg);
1430      file = fopen(name, "r");
1431      if (!file) {
1432	PyErr_SetString(PyExc_IOError,
1433			(char*)"Cannot open file");
1434	return 0;
1435      }
1436      to_close = 1;
1437    }
1438    else if (PyFile_Check(arg)) {
1439      PyObject* pyname = PyFile_Name(arg);
1440      file = PyFile_AsFile(arg);
1441      name = PyString_AsString(pyname);
1442    }
1443    else {
1444      PyErr_SetString(PyExc_TypeError,
1445		      (char*)"Argument must be a file or filename");
1446      return 0;
1447    }
1448
1449    IDL_Boolean success = AST::process(file, name);
1450
1451    if (to_close)
1452      fclose(