PageRenderTime 152ms CodeModel.GetById 19ms app.highlight 119ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Source/Modules/ruby.cxx

#
C++ | 2137 lines | 1935 code | 101 blank | 101 comment | 145 complexity | 98f00cb5c0518d222270d2e3ee10f02c MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* ----------------------------------------------------------------------------- 
   2 * This file is part of SWIG, which is licensed as a whole under version 3 
   3 * (or any later version) of the GNU General Public License. Some additional
   4 * terms also apply to certain portions of SWIG. The full details of the SWIG
   5 * license and copyrights can be found in the LICENSE and COPYRIGHT files
   6 * included with the SWIG source code as distributed by the SWIG developers
   7 * and at http://www.swig.org/legal.html.
   8 *
   9 * ruby.cxx
  10 *
  11 * Ruby language module for SWIG.
  12 * ----------------------------------------------------------------------------- */
  13
  14char cvsroot_ruby_cxx[] = "$Id: ruby.cxx 12883 2011-12-22 21:14:09Z wsfulton $";
  15
  16#include "swigmod.h"
  17#include "cparse.h"
  18static int treduce = SWIG_cparse_template_reduce(0);
  19
  20#define SWIG_PROTECTED_TARGET_METHODS 1
  21
  22#include <ctype.h>
  23#include <string.h>
  24#include <limits.h>		/* for INT_MAX */
  25
  26class RClass {
  27private:
  28  String *temp;
  29
  30public:
  31  String *name;			/* class name (renamed) */
  32  String *cname;		/* original C class/struct name */
  33  String *mname;		/* Mangled name */
  34
  35  /**
  36   * The C variable name used in the SWIG-generated wrapper code to refer to
  37   * this class; usually it is of the form "SwigClassXXX.klass", where SwigClassXXX
  38   * is a swig_class struct instance and klass is a member of that struct.
  39   */
  40  String *vname;
  41
  42  /**
  43   * The C variable name used in the SWIG-generated wrapper code to refer to
  44   * the module that implements this class's methods (when we're trying to
  45   * support C++ multiple inheritance). Usually it is of the form
  46   * "SwigClassClassName.mImpl", where SwigClassXXX is a swig_class struct instance
  47   * and mImpl is a member of that struct.
  48   */
  49  String *mImpl;
  50
  51  String *type;
  52  String *prefix;
  53  String *init;
  54
  55
  56  int constructor_defined;
  57  int destructor_defined;
  58
  59   RClass() {
  60    temp = NewString("");
  61    name = NewString("");
  62    cname = NewString("");
  63    mname = NewString("");
  64    vname = NewString("");
  65    mImpl = NewString("");
  66    type = NewString("");
  67    prefix = NewString("");
  68    init = NewString("");
  69    constructor_defined = 0;
  70    destructor_defined = 0;
  71  }
  72  
  73  ~RClass() {
  74    Delete(name);
  75    Delete(cname);
  76    Delete(vname);
  77    Delete(mImpl);
  78    Delete(mname);
  79    Delete(type);
  80    Delete(prefix);
  81    Delete(init);
  82    Delete(temp);
  83  }
  84
  85  void set_name(const_String_or_char_ptr cn, const_String_or_char_ptr rn, const_String_or_char_ptr valn) {
  86    /* Original C/C++ class (or struct) name */
  87    Clear(cname);
  88    Append(cname, cn);
  89
  90    /* Mangled name */
  91    Delete(mname);
  92    mname = Swig_name_mangle(cname);
  93
  94    /* Renamed class name */
  95    Clear(name);
  96    Append(name, valn);
  97
  98    /* Variable name for the VALUE that refers to the Ruby Class object */
  99    Clear(vname);
 100    Printf(vname, "SwigClass%s.klass", name);
 101
 102    /* Variable name for the VALUE that refers to the Ruby Class object */
 103    Clear(mImpl);
 104    Printf(mImpl, "SwigClass%s.mImpl", name);
 105
 106    /* Prefix */
 107    Clear(prefix);
 108    Printv(prefix, (rn ? rn : cn), "_", NIL);
 109  }
 110
 111  char *strip(const_String_or_char_ptr s) {
 112    Clear(temp);
 113    Append(temp, s);
 114    if (Strncmp(s, prefix, Len(prefix)) == 0) {
 115      Replaceall(temp, prefix, "");
 116    }
 117    return Char(temp);
 118  }
 119};
 120
 121
 122/* flags for the make_autodoc function */
 123enum autodoc_t {
 124  AUTODOC_CLASS,
 125  AUTODOC_CTOR,
 126  AUTODOC_DTOR,
 127  AUTODOC_STATICFUNC,
 128  AUTODOC_FUNC,
 129  AUTODOC_METHOD,
 130  AUTODOC_GETTER,
 131  AUTODOC_SETTER
 132};
 133
 134static const char *usage = (char *) "\
 135Ruby Options (available with -ruby)\n\
 136     -autorename     - Enable renaming of classes and methods to follow Ruby coding standards\n\
 137     -cppcast        - Enable C++ casting operators (default)\n\
 138     -globalmodule   - Wrap everything into the global module\n\
 139     -initname <name>- Set entry function to Init_<name> (used by `require')\n\
 140     -minherit       - Attempt to support multiple inheritance\n\
 141     -noautorename   - Disable renaming of classes and methods (default)\n\
 142     -nocppcast      - Disable C++ casting operators, useful for generating bugs\n\
 143     -prefix <name>  - Set a prefix <name> to be prepended to all names\n\
 144";
 145
 146
 147#define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0)
 148#define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0))
 149
 150
 151class RUBY:public Language {
 152private:
 153
 154  String *module;
 155  String *modvar;
 156  String *feature;
 157  String *prefix;
 158  int current;
 159  Hash *classes;		/* key=cname val=RClass */
 160  RClass *klass;		/* Currently processing class */
 161  Hash *special_methods;	/* Python style special method name table */
 162
 163  File *f_directors;
 164  File *f_directors_h;
 165  File *f_directors_helpers;
 166  File *f_begin;
 167  File *f_runtime;
 168  File *f_runtime_h;
 169  File *f_header;
 170  File *f_wrappers;
 171  File *f_init;
 172  File *f_initbeforefunc;
 173
 174  bool useGlobalModule;
 175  bool multipleInheritance;
 176
 177  // Wrap modes
 178  enum WrapperMode {
 179    NO_CPP,
 180    MEMBER_FUNC,
 181    CONSTRUCTOR_ALLOCATE,
 182    CONSTRUCTOR_INITIALIZE,
 183    DESTRUCTOR,
 184    MEMBER_VAR,
 185    CLASS_CONST,
 186    STATIC_FUNC,
 187    STATIC_VAR
 188  };
 189
 190  /* ------------------------------------------------------------
 191   * autodoc level declarations
 192   * ------------------------------------------------------------ */
 193
 194  enum autodoc_l {
 195    NO_AUTODOC = -2,		// no autodoc
 196    STRING_AUTODOC = -1,	// use provided string
 197    NAMES_AUTODOC = 0,		// only parameter names
 198    TYPES_AUTODOC = 1,		// parameter names and types
 199    EXTEND_AUTODOC = 2,		// extended documentation and parameter names
 200    EXTEND_TYPES_AUTODOC = 3	// extended documentation and parameter types + names
 201  };
 202
 203  autodoc_t last_mode;
 204  String*   last_autodoc;
 205
 206
 207
 208  autodoc_l autodoc_level(String *autodoc) {
 209    autodoc_l dlevel = NO_AUTODOC;
 210    if (autodoc) {
 211      char *c = Char(autodoc);
 212      if (c && isdigit(c[0])) {
 213	dlevel = (autodoc_l) atoi(c);
 214      } else {
 215	if (strcmp(c, "extended") == 0) {
 216	  dlevel = EXTEND_AUTODOC;
 217	} else {
 218	  dlevel = STRING_AUTODOC;
 219	}
 220      }
 221    }
 222    return dlevel;
 223  }
 224
 225
 226
 227  /* ------------------------------------------------------------
 228   * have_docstring()
 229   *    Check if there is a docstring directive and it has text,
 230   *    or there is an autodoc flag set
 231   * ------------------------------------------------------------ */
 232
 233  bool have_docstring(Node *n) {
 234    String *str = Getattr(n, "feature:docstring");
 235    return (str && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
 236  }
 237
 238  /* ------------------------------------------------------------
 239   * docstring()
 240   *    Get the docstring text, stripping off {} if neccessary,
 241   *    and enclose in triple double quotes.  If autodoc is also
 242   *    set then it will build a combined docstring.
 243   * ------------------------------------------------------------ */
 244
 245  String *docstring(Node *n, autodoc_t ad_type) {
 246
 247    String *str = Getattr(n, "feature:docstring");
 248    bool have_ds = (str && Len(str) > 0);
 249    bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
 250    String *autodoc = NULL;
 251    String *doc = NULL;
 252
 253    if (have_ds) {
 254      char *t = Char(str);
 255      if (*t == '{') {
 256	Delitem(str, 0);
 257	Delitem(str, DOH_END);
 258      }
 259    }
 260
 261    if (have_auto) {
 262      autodoc = make_autodoc(n, ad_type);
 263      have_auto = (autodoc && Len(autodoc) > 0);
 264    }
 265    // If there is more than one line then make docstrings like this:
 266    //
 267    //      This is line1
 268    //      And here is line2 followed by the rest of them
 269    //
 270    // otherwise, put it all on a single line
 271    //
 272    if (have_auto && have_ds) {	// Both autodoc and docstring are present
 273      doc = NewString("");
 274      Printv(doc, "\n", autodoc, "\n", str, NIL);
 275    } else if (!have_auto && have_ds) {	// only docstring
 276      if (Strchr(str, '\n') == 0) {
 277	doc = NewString(str);
 278      } else {
 279	doc = NewString("");
 280	Printv(doc, str, NIL);
 281      }
 282    } else if (have_auto && !have_ds) {	// only autodoc
 283      if (Strchr(autodoc, '\n') == 0) {
 284	doc = NewStringf("%s", autodoc);
 285      } else {
 286	doc = NewString("");
 287	Printv(doc, "\n", autodoc, NIL);
 288      }
 289    } else
 290      doc = NewString("");
 291
 292    // Save the generated strings in the parse tree in case they are used later
 293    // by post processing tools
 294    Setattr(n, "ruby:docstring", doc);
 295    Setattr(n, "ruby:autodoc", autodoc);
 296    return doc;
 297  }
 298
 299  /* -----------------------------------------------------------------------------
 300   * addMissingParameterNames()
 301   *  For functions that have not had nameless parameters set in the Language class.
 302   *
 303   * Inputs: 
 304   *   plist - entire parameter list
 305   *   arg_offset - argument number for first parameter
 306   * Side effects:
 307   *   The "lname" attribute in each parameter in plist will be contain a parameter name
 308   * ----------------------------------------------------------------------------- */
 309
 310  void addMissingParameterNames(ParmList *plist, int arg_offset) {
 311    Parm *p = plist;
 312    int i = arg_offset;
 313    while (p) {
 314      if (!Getattr(p, "lname")) {
 315	String *pname = Swig_cparm_name(p, i);
 316	Delete(pname);
 317      }
 318      i++;
 319      p = nextSibling(p);
 320    }
 321  }
 322
 323  /* ------------------------------------------------------------
 324   * make_autodocParmList()
 325   *   Generate the documentation for the function parameters
 326   * ------------------------------------------------------------ */
 327
 328  String *make_autodocParmList(Node *n, bool showTypes) {
 329    String *doc = NewString("");
 330    String *pdocs = 0;
 331    ParmList *plist = CopyParmList(Getattr(n, "parms"));
 332    Parm *p;
 333    Parm *pnext;
 334    int lines = 0;
 335    int start_arg_num = is_wrapping_class() ? 1 : 0;
 336    const int maxwidth = 80;
 337
 338    addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
 339
 340    Swig_typemap_attach_parms("in", plist, 0);
 341    Swig_typemap_attach_parms("doc", plist, 0);
 342
 343    if (Strcmp(ParmList_protostr(plist), "void") == 0) {
 344      //No parameters actually
 345      return doc;
 346    }
 347
 348    for (p = plist; p; p = pnext) {
 349
 350      String *tm = Getattr(p, "tmap:in");
 351      if (tm) {
 352	pnext = Getattr(p, "tmap:in:next");
 353	if (checkAttribute(p, "tmap:in:numinputs", "0")) {
 354	  continue;
 355	}
 356      } else {
 357	pnext = nextSibling(p);
 358      }
 359
 360      String *name = 0;
 361      String *type = 0;
 362      String *value = 0;
 363      String *pdoc = Getattr(p, "tmap:doc");
 364      if (pdoc) {
 365	name = Getattr(p, "tmap:doc:name");
 366	type = Getattr(p, "tmap:doc:type");
 367	value = Getattr(p, "tmap:doc:value");
 368      }
 369
 370      // Note: the generated name should be consistent with that in kwnames[]
 371      name = name ? name : Getattr(p, "name");
 372      name = name ? name : Getattr(p, "lname");
 373      name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
 374
 375      type = type ? type : Getattr(p, "type");
 376      value = value ? value : Getattr(p, "value");
 377
 378      if (SwigType_isvarargs(type))
 379	break;
 380
 381      // Skip the 'self' parameter which in ruby is implicit
 382      if ( Cmp(name, "self") == 0 )
 383	continue;
 384
 385      // Make __p parameters just p (as used in STL)
 386      Replace( name, "__", "", DOH_REPLACE_FIRST );
 387
 388      if (Len(doc)) {
 389	// add a comma to the previous one if any
 390	Append(doc, ", ");
 391
 392	// Do we need to wrap a long line?
 393	if ((Len(doc) - lines * maxwidth) > maxwidth) {
 394	  Printf(doc, "\n%s", tab4);
 395	  lines += 1;
 396	}
 397      }
 398
 399      // Do the param type too?
 400      Node *nn = classLookup(Getattr(p, "type"));
 401      String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
 402      if (showTypes)
 403	Printf(doc, "%s ", type_str);
 404
 405      Append(doc, name);
 406      if (pdoc) {
 407	if (!pdocs)
 408	  pdocs = NewString("Parameters:\n");
 409	Printf(pdocs, "    %s.\n", pdoc);
 410      }
 411
 412      if (value) {
 413	String *new_value = convertValue(value, Getattr(p, "type"));
 414	if (new_value) {
 415	  value = new_value;
 416	} else {
 417	  Node *lookup = Swig_symbol_clookup(value, 0);
 418	  if (lookup)
 419	    value = Getattr(lookup, "sym:name");
 420	}
 421	Printf(doc, "=%s", value);
 422      }
 423      Delete(type_str);
 424      Delete(name);
 425    }
 426    if (pdocs)
 427      Setattr(n, "feature:pdocs", pdocs);
 428    Delete(plist);
 429    return doc;
 430  }
 431
 432  /* ------------------------------------------------------------
 433   * make_autodoc()
 434   *    Build a docstring for the node, using parameter and other
 435   *    info in the parse tree.  If the value of the autodoc
 436   *    attribute is "0" then do not include parameter types, if
 437   *    it is "1" (the default) then do.  If it has some other
 438   *    value then assume it is supplied by the extension writer
 439   *    and use it directly.
 440   * ------------------------------------------------------------ */
 441
 442  String *make_autodoc(Node *n, autodoc_t ad_type) {
 443    int extended = 0;
 444    // If the function is overloaded then this funciton is called
 445    // for the last one.  Rewind to the first so the docstrings are
 446    // in order.
 447    while (Getattr(n, "sym:previousSibling"))
 448      n = Getattr(n, "sym:previousSibling");
 449
 450    Node *pn = Swig_methodclass(n);
 451    String* super_names = NewString(""); 
 452    String* class_name = Getattr(pn, "sym:name") ; 
 453
 454    if ( !class_name ) {
 455      class_name = NewString("");
 456    } else {
 457      class_name = Copy(class_name);
 458      List *baselist = Getattr(pn, "bases");
 459      if (baselist && Len(baselist)) {
 460	Iterator base = First(baselist);
 461	while (base.item && GetFlag(base.item, "feature:ignore")) {
 462	  base = Next(base);
 463	}
 464
 465	int count = 0;
 466	for ( ;base.item; ++count) {
 467	  if ( count ) Append(super_names, ", ");
 468	  String *basename = Getattr(base.item, "sym:name");
 469
 470	  String* basenamestr = NewString(basename);
 471	  Node* parent = parentNode(base.item);
 472	  while (parent)
 473	  {
 474	    String *parent_name = Copy( Getattr(parent, "sym:name") );
 475	    if ( !parent_name ) {
 476	      Node* mod = Getattr(parent, "module");
 477	      if ( mod )
 478		parent_name = Copy( Getattr(mod, "name") );
 479	      if ( parent_name )
 480		(Char(parent_name))[0] = (char)toupper((Char(parent_name))[0]);
 481	    }
 482	    if ( parent_name ) {
 483	      Insert(basenamestr, 0, "::");
 484	      Insert(basenamestr, 0, parent_name);
 485	      Delete(parent_name);
 486	    }
 487	    parent = parentNode(parent);
 488	  }
 489
 490	  Append(super_names, basenamestr );
 491	  Delete(basenamestr);
 492	  base = Next(base);
 493	}
 494      }
 495    }
 496    String* full_name;
 497    if ( module ) {
 498      full_name = NewString(module);
 499      if (class_name && Len(class_name) > 0)
 500       	Append(full_name, "::");
 501    }
 502    else
 503      full_name = NewString("");
 504    Append(full_name, class_name);
 505
 506    String* symname = Getattr(n, "sym:name");
 507    if ( Getattr( special_methods, symname ) )
 508      symname = Getattr( special_methods, symname );
 509
 510    String* methodName = NewString(full_name);
 511    Append(methodName, symname);
 512
 513
 514    // Each overloaded function will try to get documented,
 515    // so we keep the name of the last overloaded function and its type.
 516    // Documenting just from functionWrapper() is not possible as
 517    // sym:name has already been changed to include the class name
 518    if ( last_mode == ad_type && Cmp(methodName, last_autodoc) == 0 ) {
 519      Delete(full_name);
 520      Delete(class_name);
 521      Delete(super_names);
 522      Delete(methodName);
 523      return NewString("");
 524    }
 525
 526
 527    last_mode    = ad_type;
 528    last_autodoc = Copy(methodName);
 529
 530    String *doc = NewString("/*\n");
 531    int counter = 0;
 532    bool skipAuto = false;
 533    Node* on = n;
 534    for ( ; n; ++counter ) {
 535      String *type_str = NULL;
 536      skipAuto = false;
 537      bool showTypes = false;
 538      String *autodoc = Getattr(n, "feature:autodoc");
 539      autodoc_l dlevel = autodoc_level(autodoc);
 540      switch (dlevel) {
 541      case NO_AUTODOC:
 542	break;
 543      case NAMES_AUTODOC:
 544	showTypes = false;
 545	break;
 546      case TYPES_AUTODOC:
 547	showTypes = true;
 548	break;
 549      case EXTEND_AUTODOC:
 550	extended = 1;
 551	showTypes = false;
 552	break;
 553      case EXTEND_TYPES_AUTODOC:
 554	extended = 1;
 555	showTypes = true;
 556	break;
 557      case STRING_AUTODOC:
 558	skipAuto = true;
 559	break;
 560      }
 561
 562      SwigType *type = Getattr(n, "type");
 563
 564      if (type) {
 565	if (Strcmp(type, "void") == 0) {
 566	  type_str = NULL;
 567	} else {
 568	  SwigType *qt = SwigType_typedef_resolve_all(type);
 569	  if (SwigType_isenum(qt)) {
 570	    type_str = NewString("int");
 571	  } else {
 572	    Node *nn = classLookup(type);
 573	    type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0);
 574	  }
 575	}
 576      }
 577
 578      if (counter == 0) {
 579	switch (ad_type) {
 580	case AUTODOC_CLASS:
 581	  Printf(doc, "  Document-class: %s", full_name);
 582	  if ( Len(super_names) > 0 )
 583	    Printf( doc, " < %s", super_names);
 584	  Append(doc, "\n\n");
 585	  break;
 586	case AUTODOC_CTOR:
 587 	  Printf(doc, "  Document-method: %s.new\n\n", full_name);
 588	  break;
 589
 590	case AUTODOC_DTOR:
 591	  break;
 592
 593	case AUTODOC_STATICFUNC:
 594 	  Printf(doc, "  Document-method: %s.%s\n\n", full_name, symname);
 595	  break;
 596
 597	case AUTODOC_FUNC:
 598	case AUTODOC_METHOD:
 599	case AUTODOC_GETTER:
 600 	  Printf(doc, "  Document-method: %s.%s\n\n", full_name, symname);
 601	  break;
 602	case AUTODOC_SETTER:
 603 	  Printf(doc, "  Document-method: %s.%s=\n\n", full_name, symname);
 604	  break;
 605	}
 606      }
 607
 608      if (skipAuto) {
 609	if ( counter == 0 ) Printf(doc, "  call-seq:\n");
 610	switch( ad_type )
 611	  {
 612	  case AUTODOC_STATICFUNC:
 613	  case AUTODOC_FUNC:
 614	  case AUTODOC_METHOD:
 615	  case AUTODOC_GETTER:
 616	    {
 617	      String *paramList = make_autodocParmList(n, showTypes);
 618	      if (Len(paramList))
 619		Printf(doc, "    %s(%s)", symname, paramList);
 620	      else
 621		Printf(doc, "    %s", symname);
 622	      if (type_str)
 623		Printf(doc, " -> %s", type_str);
 624	      break;
 625	    }
 626	  case AUTODOC_SETTER:
 627	    {
 628	      Printf(doc, "    %s=(x)", symname);
 629	      if (type_str)
 630	       	Printf(doc, " -> %s", type_str);
 631	      break;
 632	    }
 633	  default:
 634	    break;
 635	  }
 636      } else {
 637	switch (ad_type) {
 638	case AUTODOC_CLASS:
 639	  {
 640	    // Only do the autodoc if there isn't a docstring for the class
 641	    String *str = Getattr(n, "feature:docstring");
 642	    if (counter == 0 && (str == 0 || Len(str) == 0)) {
 643	      if (CPlusPlus) {
 644		Printf(doc, "  Proxy of C++ %s class", full_name);
 645	      } else {
 646		Printf(doc, "  Proxy of C %s struct", full_name);
 647	      }
 648	    }
 649	  }
 650	  break;
 651	case AUTODOC_CTOR:
 652	  if (counter == 0)
 653	    Printf(doc, "  call-seq:\n");
 654	  if (Strcmp(class_name, symname) == 0) {
 655	    String *paramList = make_autodocParmList(n, showTypes);
 656	    if (Len(paramList))
 657	      Printf(doc, "    %s.new(%s)", class_name, paramList);
 658	    else
 659	      Printf(doc, "    %s.new", class_name);
 660	  } else {
 661	    Printf(doc, "    %s.new(%s)", class_name, make_autodocParmList(n, showTypes));
 662	  }
 663	  break;
 664
 665	case AUTODOC_DTOR:
 666	  break;
 667
 668	case AUTODOC_STATICFUNC:
 669	case AUTODOC_FUNC:
 670	case AUTODOC_METHOD:
 671	case AUTODOC_GETTER:
 672	  {
 673	    if (counter == 0)
 674	      Printf(doc, "  call-seq:\n");
 675	    String *paramList = make_autodocParmList(n, showTypes);
 676	    if (Len(paramList))
 677	      Printf(doc, "    %s(%s)", symname, paramList);
 678	    else
 679	      Printf(doc, "    %s", symname);
 680	    if (type_str)
 681	      Printf(doc, " -> %s", type_str);
 682	    break;
 683	  }
 684	case AUTODOC_SETTER:
 685	  {
 686	    Printf(doc, "  call-seq:\n");
 687	    Printf(doc, "    %s=(x)", symname);
 688	    if (type_str)
 689	      Printf(doc, " -> %s", type_str);
 690	    break;
 691	  }
 692	}
 693      }
 694
 695      // if it's overloaded then get the next decl and loop around again
 696      n = Getattr(n, "sym:nextSibling");
 697      if (n)
 698	Append(doc, "\n");
 699      Delete(type_str);
 700    }
 701
 702    Printf(doc, "\n\n");
 703    if (!skipAuto) {
 704      switch (ad_type) {
 705      case AUTODOC_CLASS:
 706      case AUTODOC_DTOR:
 707	break;
 708      case AUTODOC_CTOR:
 709	Printf(doc, "Class constructor.\n");
 710	break;
 711      case AUTODOC_STATICFUNC:
 712	Printf(doc, "A class method.\n");
 713	break;
 714      case AUTODOC_FUNC:
 715	Printf(doc, "A module function.\n");
 716	break;
 717      case AUTODOC_METHOD:
 718	Printf(doc, "An instance method.\n");
 719	break;
 720      case AUTODOC_GETTER:
 721	Printf(doc, "Get value of attribute.\n");
 722	break;
 723      case AUTODOC_SETTER:
 724	Printf(doc, "Set new value for attribute.\n");
 725	break;
 726      }
 727    }
 728
 729
 730    n = on;
 731    while ( n ) {
 732      String *autodoc = Getattr(n, "feature:autodoc");
 733      autodoc_l dlevel = autodoc_level(autodoc);
 734
 735      symname = Getattr(n, "sym:name");
 736      if ( Getattr( special_methods, symname ) )
 737	symname = Getattr( special_methods, symname );
 738
 739      switch (dlevel) {
 740      case NO_AUTODOC:
 741      case NAMES_AUTODOC:
 742      case TYPES_AUTODOC:
 743	extended = 0;
 744	break;
 745      case STRING_AUTODOC:
 746	extended = 2;
 747	Replaceall( autodoc, "$class", class_name );
 748	Printv(doc, autodoc, ".", NIL);
 749	break;
 750      case EXTEND_AUTODOC:
 751      case EXTEND_TYPES_AUTODOC:
 752	extended = 1;
 753	break;
 754      }
 755
 756
 757      if (extended) {
 758	String *pdocs = Getattr(n, "feature:pdocs");
 759	if (pdocs) {
 760	  Printv(doc, "\n\n", pdocs, NULL);
 761	  break;
 762	}
 763	if ( extended == 2 ) break;
 764      }
 765      n = Getattr(n, "sym:nextSibling");
 766    }
 767
 768    Append(doc, "\n*/\n");
 769    Delete(full_name);
 770    Delete(class_name);
 771    Delete(super_names);
 772    Delete(methodName);
 773
 774    return doc;
 775  }
 776
 777  /* ------------------------------------------------------------
 778   * convertValue()
 779   *    Check if string v can be a Ruby value literal,
 780   *    (eg. number or string), or translate it to a Ruby literal.
 781   * ------------------------------------------------------------ */
 782  String *convertValue(String *v, SwigType *t) {
 783    if (v && Len(v) > 0) {
 784      char fc = (Char(v))[0];
 785      if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) {
 786	/* number or string (or maybe NULL pointer) */
 787	if (SwigType_ispointer(t) && Strcmp(v, "0") == 0)
 788	  return NewString("None");
 789	else
 790	  return v;
 791      }
 792      if (Strcmp(v, "NULL") == 0)
 793	return SwigType_ispointer(t) ? NewString("nil") : NewString("0");
 794      else if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
 795	return NewString("true");
 796      else if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
 797	return NewString("false");
 798      if (Strcmp(v, "true") == 0 || Strcmp(v, "FALSE") == 0)
 799	return NewString("True");
 800      if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
 801	return NewString("False");
 802    }
 803    return 0;
 804  }
 805
 806public:
 807
 808  /* ---------------------------------------------------------------------
 809   * RUBY()
 810   *
 811   * Initialize member data
 812   * --------------------------------------------------------------------- */
 813
 814   RUBY() {
 815    module = 0;
 816    modvar = 0;
 817    feature = 0;
 818    prefix = 0;
 819    last_autodoc = NewString("");
 820    current = NO_CPP;
 821    classes = 0;
 822    klass = 0;
 823    special_methods = 0;
 824    f_begin = 0;
 825    f_runtime = 0;
 826    f_header = 0;
 827    f_wrappers = 0;
 828    f_init = 0;
 829    f_initbeforefunc = 0;
 830    useGlobalModule = false;
 831    multipleInheritance = false;
 832    director_prot_ctor_code = NewString("");
 833    Printv(director_prot_ctor_code,
 834	   "if ( $comparison ) { /* subclassed */\n",
 835	   "  $director_new \n",
 836	   "} else {\n", "  rb_raise(rb_eRuntimeError,\"accessing abstract class or protected constructor\"); \n", "  return Qnil;\n", "}\n", NIL);
 837    director_multiple_inheritance = 0;
 838    director_language = 1;
 839  }
 840
 841  /* ---------------------------------------------------------------------
 842   * main()
 843   *
 844   * Parse command line options and initializes variables.
 845   * --------------------------------------------------------------------- */
 846  
 847  virtual void main(int argc, char *argv[]) {
 848
 849    int cppcast = 1;
 850    int autorename = 0;
 851
 852    /* Set location of SWIG library */
 853    SWIG_library_directory("ruby");
 854
 855    /* Look for certain command line options */
 856    for (int i = 1; i < argc; i++) {
 857      if (argv[i]) {
 858	if (strcmp(argv[i], "-initname") == 0) {
 859	  if (argv[i + 1]) {
 860	    char *name = argv[i + 1];
 861	    feature = NewString(name);
 862	    Swig_mark_arg(i);
 863	    Swig_mark_arg(i + 1);
 864	    i++;
 865	  } else {
 866	    Swig_arg_error();
 867	  }
 868	}
 869	else if (strcmp(argv[i], "-feature") == 0) {
 870	  fprintf( stderr, "Warning: Ruby -feature option is deprecated, "
 871		   "please use -initname instead.\n");
 872	  if (argv[i + 1]) {
 873	    char *name = argv[i + 1];
 874	    feature = NewString(name);
 875	    Swig_mark_arg(i);
 876	    Swig_mark_arg(i + 1);
 877	    i++;
 878	  } else {
 879	    Swig_arg_error();
 880	  }
 881	} else if (strcmp(argv[i], "-globalmodule") == 0) {
 882	  useGlobalModule = true;
 883	  Swig_mark_arg(i);
 884	} else if (strcmp(argv[i], "-minherit") == 0) {
 885	  multipleInheritance = true;
 886	  director_multiple_inheritance = 1;
 887	  Swig_mark_arg(i);
 888	} else if (strcmp(argv[i], "-cppcast") == 0) {
 889	  cppcast = 1;
 890	  Swig_mark_arg(i);
 891	} else if (strcmp(argv[i], "-nocppcast") == 0) {
 892	  cppcast = 0;
 893	  Swig_mark_arg(i);
 894	} else if (strcmp(argv[i], "-autorename") == 0) {
 895	  autorename = 1;
 896	  Swig_mark_arg(i);
 897	} else if (strcmp(argv[i], "-noautorename") == 0) {
 898	  autorename = 0;
 899	  Swig_mark_arg(i);
 900	} else if (strcmp(argv[i], "-prefix") == 0) {
 901	  if (argv[i + 1]) {
 902	    char *name = argv[i + 1];
 903	    prefix = NewString(name);
 904	    Swig_mark_arg(i);
 905	    Swig_mark_arg(i + 1);
 906	    i++;
 907	  } else {
 908	    Swig_arg_error();
 909	  }
 910	} else if (strcmp(argv[i], "-help") == 0) {
 911	  Printf(stdout, "%s\n", usage);
 912	}
 913      }
 914    }
 915
 916    if (cppcast) {
 917      /* Turn on cppcast mode */
 918      Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
 919    }
 920
 921    if (autorename) {
 922      /* Turn on the autorename mode */
 923      Preprocessor_define((DOH *) "SWIG_RUBY_AUTORENAME", 0);
 924    }
 925
 926    /* Add a symbol to the parser for conditional compilation */
 927    Preprocessor_define("SWIGRUBY 1", 0);
 928
 929    /* Add typemap definitions */
 930    SWIG_typemap_lang("ruby");
 931    SWIG_config_file("ruby.swg");
 932    allow_overloading();
 933  }
 934
 935  /**
 936   * Generate initialization code to define the Ruby module(s),
 937   * accounting for nested modules as necessary.
 938   */
 939  void defineRubyModule() {
 940    List *modules = Split(module, ':', INT_MAX);
 941    if (modules != 0 && Len(modules) > 0) {
 942      String *mv = 0;
 943      Iterator m;
 944      m = First(modules);
 945      while (m.item) {
 946	if (Len(m.item) > 0) {
 947	  if (mv != 0) {
 948	    Printv(f_init, tab4, modvar, " = rb_define_module_under(", modvar, ", \"", m.item, "\");\n", NIL);
 949	  } else {
 950	    Printv(f_init, tab4, modvar, " = rb_define_module(\"", m.item, "\");\n", NIL);
 951	    mv = NewString(modvar);
 952	  }
 953	}
 954	m = Next(m);
 955      }
 956      Delete(mv);
 957      Delete(modules);
 958    }
 959  }
 960
 961  void registerMagicMethods() {
 962
 963    special_methods = NewHash();
 964
 965    /* Python->Ruby style special method name. */
 966    /* Basic */
 967    Setattr(special_methods, "__repr__", "inspect");
 968    Setattr(special_methods, "__str__", "to_s");
 969    Setattr(special_methods, "__cmp__", "<=>");
 970    Setattr(special_methods, "__hash__", "hash");
 971    Setattr(special_methods, "__nonzero__", "nonzero?");
 972
 973    /* Callable */
 974    Setattr(special_methods, "__call__", "call");
 975
 976    /* Collection */
 977    Setattr(special_methods, "__len__", "length");
 978    Setattr(special_methods, "__getitem__", "[]");
 979    Setattr(special_methods, "__setitem__", "[]=");
 980
 981    /* Operators */
 982    Setattr(special_methods, "__add__", "+");
 983    Setattr(special_methods, "__pos__", "+@");
 984    Setattr(special_methods, "__sub__", "-");
 985    Setattr(special_methods, "__neg__", "-@");
 986    Setattr(special_methods, "__mul__", "*");
 987    Setattr(special_methods, "__div__", "/");
 988    Setattr(special_methods, "__mod__", "%");
 989    Setattr(special_methods, "__lshift__", "<<");
 990    Setattr(special_methods, "__rshift__", ">>");
 991    Setattr(special_methods, "__and__", "&");
 992    Setattr(special_methods, "__or__", "|");
 993    Setattr(special_methods, "__xor__", "^");
 994    Setattr(special_methods, "__invert__", "~");
 995    Setattr(special_methods, "__lt__", "<");
 996    Setattr(special_methods, "__le__", "<=");
 997    Setattr(special_methods, "__gt__", ">");
 998    Setattr(special_methods, "__ge__", ">=");
 999    Setattr(special_methods, "__eq__", "==");
1000
1001    /* Other numeric */
1002    Setattr(special_methods, "__divmod__", "divmod");
1003    Setattr(special_methods, "__pow__", "**");
1004    Setattr(special_methods, "__abs__", "abs");
1005    Setattr(special_methods, "__int__", "to_i");
1006    Setattr(special_methods, "__float__", "to_f");
1007    Setattr(special_methods, "__coerce__", "coerce");
1008  }
1009
1010  /* ---------------------------------------------------------------------
1011   * top()
1012   * --------------------------------------------------------------------- */
1013
1014  virtual int top(Node *n) {
1015
1016    /**
1017     * See if any Ruby module options have been specified as options
1018     * to the %module directive.
1019     */
1020    Node *swigModule = Getattr(n, "module");
1021    if (swigModule) {
1022      Node *options = Getattr(swigModule, "options");
1023      if (options) {
1024	if (Getattr(options, "directors")) {
1025	  allow_directors();
1026	}
1027	if (Getattr(options, "dirprot")) {
1028	  allow_dirprot();
1029	}
1030	if (Getattr(options, "ruby_globalmodule")) {
1031	  useGlobalModule = true;
1032	}
1033	if (Getattr(options, "ruby_minherit")) {
1034	  multipleInheritance = true;
1035	  director_multiple_inheritance = 1;
1036	}
1037      }
1038    }
1039
1040    /* Set comparison with none for ConstructorToFunction */
1041
1042
1043    setSubclassInstanceCheck(NewStringf("strcmp(rb_obj_classname(self), classname) != 0"));
1044    // setSubclassInstanceCheck(NewString("CLASS_OF(self) != cFoo.klass"));
1045
1046    /* Initialize all of the output files */
1047    String *outfile = Getattr(n, "outfile");
1048    String *outfile_h = Getattr(n, "outfile_h");
1049
1050    if (!outfile) {
1051      Printf(stderr, "Unable to determine outfile\n");
1052      SWIG_exit(EXIT_FAILURE);
1053    }
1054
1055    f_begin = NewFile(outfile, "w", SWIG_output_files());
1056    if (!f_begin) {
1057      FileErrorDisplay(outfile);
1058      SWIG_exit(EXIT_FAILURE);
1059    }
1060
1061    f_runtime = NewString("");
1062    f_init = NewString("");
1063    f_header = NewString("");
1064    f_wrappers = NewString("");
1065    f_directors_h = NewString("");
1066    f_directors = NewString("");
1067    f_directors_helpers = NewString("");
1068    f_initbeforefunc = NewString("");
1069
1070    if (directorsEnabled()) {
1071      if (!outfile_h) {
1072        Printf(stderr, "Unable to determine outfile_h\n");
1073        SWIG_exit(EXIT_FAILURE);
1074      }
1075      f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
1076      if (!f_runtime_h) {
1077	FileErrorDisplay(outfile_h);
1078	SWIG_exit(EXIT_FAILURE);
1079      }
1080    }
1081
1082    /* Register file targets with the SWIG file handler */
1083    Swig_register_filebyname("header", f_header);
1084    Swig_register_filebyname("wrapper", f_wrappers);
1085    Swig_register_filebyname("begin", f_begin);
1086    Swig_register_filebyname("runtime", f_runtime);
1087    Swig_register_filebyname("init", f_init);
1088    Swig_register_filebyname("director", f_directors);
1089    Swig_register_filebyname("director_h", f_directors_h);
1090    Swig_register_filebyname("director_helpers", f_directors_helpers);
1091    Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
1092
1093    modvar = 0;
1094    current = NO_CPP;
1095    klass = 0;
1096    classes = NewHash();
1097
1098    registerMagicMethods();
1099
1100    Swig_banner(f_begin);
1101
1102    Printf(f_runtime, "\n");
1103    Printf(f_runtime, "#define SWIGRUBY\n");
1104
1105    if (directorsEnabled()) {
1106      Printf(f_runtime, "#define SWIG_DIRECTORS\n");
1107    }
1108
1109    Printf(f_runtime, "\n");
1110
1111    /* typedef void *VALUE */
1112    SwigType *value = NewSwigType(T_VOID);
1113    SwigType_add_pointer(value);
1114    SwigType_typedef(value, (char *) "VALUE");
1115    Delete(value);
1116
1117    /* Set module name */
1118    set_module(Char(Getattr(n, "name")));
1119
1120    if (directorsEnabled()) {
1121      /* Build a version of the module name for use in a C macro name. */
1122      String *module_macro = Copy(module);
1123      Replaceall(module_macro, "::", "__");
1124
1125      Swig_banner(f_directors_h);
1126      Printf(f_directors_h, "\n");
1127      Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_macro);
1128      Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_macro);
1129      Printf(f_directors_h, "namespace Swig {\n");
1130      Printf(f_directors_h, "  class Director;\n");
1131      Printf(f_directors_h, "}\n\n");
1132
1133      Printf(f_directors_helpers, "/* ---------------------------------------------------\n");
1134      Printf(f_directors_helpers, " * C++ director class helpers\n");
1135      Printf(f_directors_helpers, " * --------------------------------------------------- */\n\n");
1136
1137      Printf(f_directors, "\n\n");
1138      Printf(f_directors, "/* ---------------------------------------------------\n");
1139      Printf(f_directors, " * C++ director class methods\n");
1140      Printf(f_directors, " * --------------------------------------------------- */\n\n");
1141      if (outfile_h)
1142	Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
1143
1144      Delete(module_macro);
1145    }
1146
1147    Printf(f_header, "#define SWIG_init    Init_%s\n", feature);
1148    Printf(f_header, "#define SWIG_name    \"%s\"\n\n", module);
1149    Printf(f_header, "static VALUE %s;\n", modvar);
1150
1151    /* Start generating the initialization function */
1152    String* docs = docstring(n, AUTODOC_CLASS);
1153    Printf(f_init, "/*\n%s\n*/", docs );
1154    Printv(f_init, "\n", "#ifdef __cplusplus\n", "extern \"C\"\n", "#endif\n", "SWIGEXPORT void Init_", feature, "(void) {\n", "size_t i;\n", "\n", NIL);
1155
1156    Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL);
1157
1158    if (!useGlobalModule)
1159      defineRubyModule();
1160
1161    Printv(f_init, "\n", "SWIG_InitializeModule(0);\n", "for (i = 0; i < swig_module.size; i++) {\n", "SWIG_define_class(swig_module.types[i]);\n", "}\n", NIL);
1162    Printf(f_init, "\n");
1163
1164    /* Initialize code to keep track of objects */
1165    Printf(f_init, "SWIG_RubyInitializeTrackings();\n");
1166
1167    Language::top(n);
1168
1169    if (directorsEnabled()) {
1170      // Insert director runtime into the f_runtime file (make it occur before %header section)
1171      Swig_insert_file("director.swg", f_runtime);
1172    }
1173
1174    /* Finish off our init function */
1175    Printf(f_init, "}\n");
1176    SwigType_emit_type_table(f_runtime, f_wrappers);
1177
1178    /* Close all of the files */
1179    Dump(f_runtime, f_begin);
1180    Dump(f_header, f_begin);
1181
1182    if (directorsEnabled()) {
1183      Dump(f_directors_helpers, f_begin);
1184      Dump(f_directors, f_begin);
1185      Dump(f_directors_h, f_runtime_h);
1186      Printf(f_runtime_h, "\n");
1187      Printf(f_runtime_h, "#endif\n");
1188      Close(f_runtime_h);
1189    }
1190
1191    Dump(f_wrappers, f_begin);
1192    Dump(f_initbeforefunc, f_begin);
1193    Wrapper_pretty_print(f_init, f_begin);
1194
1195    Delete(f_header);
1196    Delete(f_wrappers);
1197    Delete(f_init);
1198    Delete(f_initbeforefunc);
1199    Close(f_begin);
1200    Delete(f_runtime);
1201    Delete(f_begin);
1202
1203    return SWIG_OK;
1204  }
1205
1206  /* -----------------------------------------------------------------------------
1207   * importDirective()
1208   * ----------------------------------------------------------------------------- */
1209
1210  virtual int importDirective(Node *n) {
1211    String *modname = Getattr(n, "module");
1212    if (modname) {
1213      if (prefix) {
1214	Insert(modname, 0, prefix);
1215      }
1216
1217      List *modules = Split(modname, ':', INT_MAX);
1218      if (modules && Len(modules) > 0) {
1219	modname = NewString("");
1220	String *last = NULL;
1221	Iterator m = First(modules);
1222	while (m.item) {
1223	  if (Len(m.item) > 0) {
1224	    if (last) {
1225	      Append(modname, "/");
1226	    }
1227	    Append(modname, m.item);
1228	    last = m.item;
1229	  }
1230	  m = Next(m);
1231	}
1232	Printf(f_init, "rb_require(\"%s\");\n", modname);
1233	Delete(modname);
1234      }
1235      Delete(modules);
1236    }
1237    return Language::importDirective(n);
1238  }
1239
1240  /* ---------------------------------------------------------------------
1241   * set_module(const char *mod_name)
1242   *
1243   * Sets the module name.  Does nothing if it's already set (so it can
1244   * be overridden as a command line option).
1245   *---------------------------------------------------------------------- */
1246
1247  void set_module(const char *s) {
1248    String *mod_name = NewString(s);
1249    if (module == 0) {
1250      /* Start with the empty string */
1251      module = NewString("");
1252
1253      if (prefix) {
1254	Insert(mod_name, 0, prefix);
1255      }
1256
1257      /* Account for nested modules */
1258      List *modules = Split(mod_name, ':', INT_MAX);
1259      if (modules != 0 && Len(modules) > 0) {
1260	String *last = 0;
1261	Iterator m = First(modules);
1262	while (m.item) {
1263	  if (Len(m.item) > 0) {
1264	    String *cap = NewString(m.item);
1265	    (Char(cap))[0] = (char)toupper((Char(cap))[0]);
1266	    if (last != 0) {
1267	      Append(module, "::");
1268	    }
1269	    Append(module, cap);
1270	    last = m.item;
1271	  }
1272	  m = Next(m);
1273	}
1274	if (feature == 0) {
1275	  feature = Copy(last);
1276	}
1277	(Char(last))[0] = (char)toupper((Char(last))[0]);
1278	modvar = NewStringf("m%s", last);
1279	Delete(modules);
1280      }
1281    }
1282    Delete(mod_name);
1283  }
1284
1285  /* --------------------------------------------------------------------------
1286   * nativeWrapper()
1287   * -------------------------------------------------------------------------- */
1288  virtual int nativeWrapper(Node *n) {
1289    String *funcname = Getattr(n, "wrap:name");
1290    Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, "Adding native function %s not supported (ignored).\n", funcname);
1291    return SWIG_NOWRAP;
1292  }
1293
1294  /**
1295   * Process the comma-separated list of aliases (if any).
1296   */
1297  void defineAliases(Node *n, const_String_or_char_ptr iname) {
1298    String *aliasv = Getattr(n, "feature:alias");
1299    if (aliasv) {
1300      List *aliases = Split(aliasv, ',', INT_MAX);
1301      if (aliases && Len(aliases) > 0) {
1302	Iterator alias = First(aliases);
1303	while (alias.item) {
1304	  if (Len(alias.item) > 0) {
1305	    if (multipleInheritance) {
1306	      Printv(klass->init, tab4, "rb_define_alias(", klass->mImpl, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
1307	    } else {
1308	      Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
1309	    }
1310	  }
1311	  alias = Next(alias);
1312	}
1313      }
1314      Delete(aliases);
1315    }
1316  }
1317
1318  /* ---------------------------------------------------------------------
1319   * create_command(Node *n, char *iname)
1320   *
1321   * Creates a new command from a C function.
1322   *              iname = Name of function in scripting language
1323   *
1324   * A note about what "protected" and "private" mean in Ruby:
1325   *
1326   * A private method is accessible only within the class or its subclasses,
1327   * and it is callable only in "function form", with 'self' (implicit or
1328   * explicit) as a receiver.
1329   *
1330   * A protected method is callable only from within its class, but unlike
1331   * a private method, it can be called with a receiver other than self, such
1332   * as another instance of the same class.
1333   * --------------------------------------------------------------------- */
1334
1335  void create_command(Node *n, const_String_or_char_ptr iname) {
1336
1337    String *alloc_func = Swig_name_wrapper(iname);
1338    String *wname = Swig_name_wrapper(iname);
1339    if (CPlusPlus) {
1340      Insert(wname, 0, "VALUEFUNC(");
1341      Append(wname, ")");
1342    }
1343    if (current != NO_CPP)
1344      iname = klass->strip(iname);
1345    if (Getattr(special_methods, iname)) {
1346      iname = GetChar(special_methods, iname);
1347    }
1348
1349    String *s = NewString("");
1350    String *temp = NewString("");
1351
1352#ifdef SWIG_PROTECTED_TARGET_METHODS
1353    const char *rb_define_method = is_public(n) ? "rb_define_method" : "rb_define_protected_method";
1354#else
1355    const char *rb_define_method = "rb_define_method";
1356#endif
1357    switch (current) {
1358    case MEMBER_FUNC:
1359      {
1360	if (multipleInheritance) {
1361	  Printv(klass->init, tab4, rb_define_method, "(", klass->mImpl, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
1362	} else {
1363	  Printv(klass->init, tab4, rb_define_method, "(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
1364	}
1365      }
1366      break;
1367    case CONSTRUCTOR_ALLOCATE:
1368      Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL);
1369      Replaceall(klass->init, "$allocator", s);
1370      break;
1371    case CONSTRUCTOR_INITIALIZE:
1372      Printv(s, tab4, rb_define_method, "(", klass->vname, ", \"initialize\", ", wname, ", -1);\n", NIL);
1373      Replaceall(klass->init, "$initializer", s);
1374      break;
1375    case MEMBER_VAR:
1376      Append(temp, iname);
1377      /* Check for _set or _get at the end of the name. */
1378      if (Len(temp) > 4) {
1379	const char *p = Char(temp) + (Len(temp) - 4);
1380	if (strcmp(p, "_set") == 0) {
1381	  Delslice(temp, Len(temp) - 4, DOH_END);
1382	  Append(temp, "=");
1383	} else if (strcmp(p, "_get") == 0) {
1384	  Delslice(temp, Len(temp) - 4, DOH_END);
1385	}
1386      }
1387      if (multipleInheritance) {
1388	Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"", temp, "\", ", wname, ", -1);\n", NIL);
1389      } else {
1390	Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", temp, "\", ", wname, ", -1);\n", NIL);
1391      }
1392      break;
1393    case STATIC_FUNC:
1394      Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
1395      break;
1396    case NO_CPP:
1397      if (!useGlobalModule) {
1398	Printv(s, tab4, "rb_define_module_function(", modvar, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
1399	Printv(f_init, s, NIL);
1400      } else {
1401	Printv(s, tab4, "rb_define_global_function(\"", iname, "\", ", wname, ", -1);\n", NIL);
1402	Printv(f_init, s, NIL);
1403      }
1404      break;
1405    case DESTRUCTOR:
1406    case CLASS_CONST:
1407    case STATIC_VAR:
1408      assert(false);		// Should not have gotten here for these types
1409    default:
1410      assert(false);
1411    }
1412
1413    defineAliases(n, iname);
1414
1415    Delete(temp);
1416    Delete(s);
1417    Delete(wname);
1418    Delete(alloc_func);
1419  }
1420
1421  /* ---------------------------------------------------------------------
1422   * applyInputTypemap()
1423   *
1424   * Look up the appropriate "in" typemap for this parameter (p),
1425   * substitute the correct strings for the $target and $input typemap
1426   * parameters, and dump the resulting code to the wrapper file.
1427   * --------------------------------------------------------------------- */
1428
1429  Parm *applyInputTypemap(Parm *p, String *ln, String *source, Wrapper *f, String *symname) {
1430    String *tm;
1431    SwigType *pt = Getattr(p, "type");
1432    if ((tm = Getattr(p, "tmap:in"))) {
1433      Replaceall(tm, "$target", ln);
1434      Replaceall(tm, "$source", source);
1435      Replaceall(tm, "$input", source);
1436      Replaceall(tm, "$symname", symname);
1437
1438      if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
1439	Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
1440      } else {
1441	Replaceall(tm, "$disown", "0");
1442      }
1443
1444      Setattr(p, "emit:input", Copy(source));
1445      Printf(f->code, "%s\n", tm);
1446      p = Getattr(p, "tmap:in:next");
1447    } else {
1448      Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
1449      p = nextSibling(p);
1450    }
1451    return p;
1452  }
1453
1454  Parm *skipIgnoredArgs(Parm *p) {
1455    while (checkAttribute(p, "tmap:in:numinputs", "0")) {
1456      p = Getattr(p, "tmap:in:next");
1457    }
1458    return p;
1459  }
1460
1461  /* ---------------------------------------------------------------------
1462   * marshalInputArgs()
1463   *
1464   * Process all of the arguments passed into the scripting language
1465   * method and convert them into C/C++ function arguments using the
1466   * supplied typemaps.
1467   * --------------------------------------------------------------------- */
1468
1469  void marshalInputArgs(Node *n, ParmList *l, int numarg, int numreq, String *kwargs, bool allow_kwargs, Wrapper *f) {
1470    int i;
1471    Parm *p;
1472    String *tm;
1473    String *source;
1474    String *target;
1475
1476    source = NewString("");
1477    target = NewString("");
1478
1479    bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
1480
1481    /**
1482     * The 'start' value indicates which of the C/C++ function arguments
1483     * produced here corresponds to the first value in Ruby's argv[] array.
1484     * The value of start is either zero or one. If start is zero, then
1485     * the first argument (with name arg1) is based on the value of argv[0].
1486     * If start is one, then arg1 is based on the value of argv[1].
1487     */
1488    int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0;
1489
1490    int varargs = emit_isvarargs(l);
1491
1492    Printf(kwargs, "{ ");
1493    for (i = 0, p = l; i < numarg; i++) {
1494
1495      p = skipIgnoredArgs(p);
1496
1497      String *pn = Getattr(p, "name");
1498      String *ln = Getattr(p, "lname");
1499
1500      /* Produce string representation of source argument */
1501      Clear(source);
1502
1503      /* First argument is a special case */
1504      if (i == 0) {
1505	Printv(source, (start == 0) ? "argv[0]" : "self", NIL);
1506      } else {
1507	Printf(source, "argv[%d]", i - start);
1508      }
1509
1510      /* Produce string representation of target argument */
1511      Clear(target);
1512      Printf(target, "%s", Char(ln));
1513
1514      if (i >= (numreq)) {	/* Check if parsing an optional argument */
1515	Printf(f->code, "    if (argc > %d) {\n", i - start);
1516      }
1517
1518      /* Record argument name for keyword argument handling */
1519      if (Len(pn)) {
1520	Printf(kwargs, "\"%s\",", pn);
1521      } else {
1522	Printf(kwargs, "\"arg%d\",", i + 1);
1523      }
1524
1525      /* Look for an input typemap */
1526      p = applyInputTypemap(p, ln, source, f, Getattr(n, "name"));
1527      if (i >= numreq) {
1528	Printf(f->code, "}\n");
1529      }
1530    }
1531
1532    /* Finish argument marshalling */
1533    Printf(kwargs, " NULL }");
1534    if (allow_kwargs) {
1535      Printv(f->locals, tab4, "const char *kwnames[] = ", kwargs, ";\n", NIL);
1536    }
1537
1538    /* Trailing varargs */
1539    if (varargs) {
1540      if (p && (tm = Getattr(p, "tmap:in"))) {
1541	Clear(source);
1542	Printf(source, "argv[%d]", i - start);
1543	Replaceall(tm, "$input", source);
1544	Setattr(p, "emit:input", Copy(source));
1545	Printf(f->code, "if (argc > %d) {\n", i - start);
1546	Printv(f->code, tm, "\n", NIL);
1547	Printf(f->code, "}\n");
1548      }
1549    }
1550
1551    Delete(source);
1552    Delete(target);
1553  }
1554
1555  /* ---------------------------------------------------------------------
1556   * insertConstraintCheckingCode(ParmList *l, Wrapper *f)
1557   *
1558   * Checks each of the parameters in the parameter list for a "check"
1559   * typemap and (if it finds one) inserts the typemapping code into
1560   * the function wrapper.
1561   * --------------------------------------------------------------------- */
1562
1563  void insertConstraintCheckingCode(ParmList *l, Wrapper *f) {
1564    Parm *p;
1565    String *tm;
1566    for (p = l; p;) {
1567      if ((tm = Getattr(p, "tmap:check"))) {
1568	Replaceall(tm, "$target", Getattr(p, "lname"));
1569	Printv(f->code, tm, "\n", NIL);
1570	p = Getattr(p, "tmap:check:next");
1571      } else {
1572	p = nextSibling(p);
1573      }
1574    }
1575  }
1576
1577  /* ---------------------------------------------------------------------
1578   * insertCleanupCode(ParmList *l, String *cleanup)
1579   *
1580   * Checks each of the parameters in the parameter list for a "freearg"
1581   * typemap and (if it finds one) inserts the typemapping code into
1582   * the function wrapper.
1583   * --------------------------------------------------------------------- */
1584
1585  void insertCleanupCode(ParmList *l, String *cleanup) {
1586    String *tm;
1587    for (Parm *p = l; p;) {
1588      if ((tm = Getattr(p, "tmap:freearg"))) {
1589	if (Len(tm) != 0) {
1590	  Replaceall(tm, "$source", Getattr(p, "lname"));
1591	  Printv(cleanup, tm, "\n", NIL);
1592	}
1593	p = Getattr(p, "tmap:freearg:next");
1594      } else {
1595	p = nextSibling(p);
1596      }
1597    }
1598  }
1599
1600  /* ---------------------------------------------------------------------
1601   * insertArgOutputCode(ParmList *l, String *outarg, int& need_result)
1602   *
1603   * Checks each of the parameters in the parameter list for a "argout"
1604   * typemap and (if it finds one) inserts the typemapping code into
1605   * the function wrapper.
1606   * --------------------------------------------------------------------- */
1607
1608  void insertArgOutputCode(ParmList *l, String *outarg, int &need_result) {
1609    String *tm;
1610    for (Parm *p = l; p;) {
1611      if ((tm = Getattr(p, "tmap:argout"))) {
1612	Replaceall(tm, "$source", Getattr(p, "lname"));
1613	Replaceall(tm, "$target", "vresult");
1614	Replaceall(tm, "$result", "vresult");
1615	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
1616	Replaceall(tm, "$input", Getattr(p, "emit:input"));
1617
1618	Printv(outarg, tm, "\n", NIL);
1619	need_result += 1;
1620	p = Getattr(p, "tmap:argout:next");
1621      } else {
1622	p = nextSibling(p);
1623      }
1624    }
1625  }
1626
1627  /* ---------------------------------------------------------------------
1628   * validIdentifier()
1629   *
1630   * Is this a valid identifier in the scripting language?
1631   * Ruby method names can include any combination of letters, numbers
1632   * and underscores. A Ruby method name may optionally end with
1633   * a question mark ("?"), exclamation point ("!") or equals sign ("=").
1634   *
1635   * Methods whose names end with question marks are, by convention,
1636   * predicate methods that return true or false (e.g. Array#empty?).
1637   *
1638   * Methods whose names end with exclamation points are, by convention,
1639   * called bang methods that modify the instance in place (e.g. Array#sort!).
1640   *
1641   * Methods whose names end with an equals sign are attribute setters
1642   * (e.g. Thread#critical=).
1643   * --------------------------------------------------------------------- */
1644
1645  virtual int validIdentifier(String *s) {
1646    char *c = Char(s);
1647    while (*c) {
1648      if (!(isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=')))
1649	return 0;
1650      c++;
1651    }
1652    return 1;
1653  }
1654
1655  /* ---------------------------------------------------------------------
1656   * functionWrapper()
1657   *
1658   * Create a function declaration and register it with the interpreter.
1659   * --------------------------------------------------------------------- */
1660
1661  virtual int functionWrapper(Node *n) {
1662
1663    String *nodeType;
1664    bool destructor;
1665
1666    String *symname = Copy(Getattr(n, "sym:name"));
1667    SwigType *t = Getattr(n, "type");
1668    ParmList *l = Getattr(n, "parms");
1669    int director_method = 0;
1670    String *tm;
1671
1672    int need_result = 0;
1673
1674    /* Ruby needs no destructor wrapper */
1675    if (current == DESTRUCTOR)
1676      return SWIG_NOWRAP;
1677
1678    nodeType = Getattr(n, "nodeType");
1679    destructor = (!Cmp(nodeType, "destructor"));
1680
1681    /* If the C++ class constructor is overloaded, we only want to
1682     * write out the "new" singleton method once since it is always
1683     * the same. (It's the "initialize" method that will handle the
1684     * overloading). */
1685
1686    if (current == CONSTRUCTOR_ALLOCATE && Swig_symbol_isoverloaded(n) && Getattr(n, "sym:nextSibling") != 0)
1687      return SWIG_OK;
1688
1689    String *overname = 0;
1690    if (Getattr(n, "sym:overloaded")) {
1691      overname = Getattr(n, "sym:overname");
1692    } else {
1693      if (!addSymbol(symname, n))
1694	return SWIG

Large files files are truncated, but you can click here to view the full file