PageRenderTime 90ms CodeModel.GetById 9ms app.highlight 69ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/rel-1-3-24/SWIG/Source/Modules/csharp.cxx

#
C++ | 1776 lines | 1226 code | 293 blank | 257 comment | 298 complexity | aea27b8ea2204f0bf252365dcfba5a3f MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0

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

   1/* -----------------------------------------------------------------------------
   2 * csharp.cxx
   3 *
   4 *     CSharp wrapper module.
   5 *
   6 * Author(s) : William Fulton
   7 *             Neil Cawse
   8 *
   9 * Copyright (C) 1999-2002.  The University of Chicago
  10 * See the file LICENSE for information on usage and redistribution.
  11 * ----------------------------------------------------------------------------- */
  12
  13char cvsroot_csharp_cxx[] = "$Header$";
  14
  15#include <limits.h> // for INT_MAX
  16#include "swigmod.h"
  17#include <ctype.h>
  18
  19
  20class CSHARP : public Language {
  21  static const char *usage;
  22  const  String *empty_string;
  23  const  String *public_string;
  24  const  String *protected_string;
  25
  26  Hash   *swig_types_hash;
  27  File   *f_runtime;
  28  File   *f_header;
  29  File   *f_wrappers;
  30  File   *f_init;
  31
  32  bool   proxy_flag; // Flag for generating proxy classes
  33  bool   have_default_constructor_flag;
  34  bool   native_function_flag;     // Flag for when wrapping a native function
  35  bool   enum_constant_flag; // Flag for when wrapping an enum or constant
  36  bool   static_flag; // Flag for when wrapping a static functions or member variables
  37  bool   variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable
  38  bool   wrapping_member_flag; // Flag for when wrapping a member variable/enum/const
  39  bool   global_variable_flag; // Flag for when wrapping a global variable
  40
  41  String *imclass_name;  // intermediary class name
  42  String *module_class_name;  // module class name
  43  String *imclass_class_code; // intermediary class code
  44  String *proxy_class_def;
  45  String *proxy_class_code;
  46  String *module_class_code;
  47  String *proxy_class_name;
  48  String *variable_name; //Name of a variable being wrapped
  49  String *proxy_class_constants_code;
  50  String *module_class_constants_code;
  51  String *enum_code;
  52  String *dllimport; // DllImport attribute name
  53  String *namespce; // Optional namespace name
  54  String *imclass_imports; //intermediary class imports from %pragma
  55  String *module_imports; //module imports from %pragma
  56  String *imclass_baseclass; //inheritance for intermediary class class from %pragma
  57  String *module_baseclass; //inheritance for module class from %pragma
  58  String *imclass_interfaces; //interfaces for intermediary class class from %pragma
  59  String *module_interfaces; //interfaces for module class from %pragma
  60  String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
  61  String *module_class_modifiers; //class modifiers for module class overriden by %pragma
  62  String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
  63  String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
  64  String *destructor_call; //C++ destructor call if any
  65
  66  enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
  67
  68  public:
  69
  70  /* -----------------------------------------------------------------------------
  71   * CSHARP()
  72   * ----------------------------------------------------------------------------- */
  73
  74  CSHARP() : 
  75    empty_string(NewString("")),
  76    public_string(NewString("public")),
  77    protected_string(NewString("protected")),
  78
  79    swig_types_hash(NULL),
  80    f_runtime(NULL),
  81    f_header(NULL),
  82    f_wrappers(NULL),
  83    f_init(NULL),
  84
  85    proxy_flag(true),
  86    have_default_constructor_flag(false),
  87    native_function_flag(false),
  88    enum_constant_flag(false),
  89    static_flag(false),
  90    variable_wrapper_flag(false),
  91    wrapping_member_flag(false),
  92    global_variable_flag(false),
  93
  94    imclass_name(NULL),
  95    module_class_name(NULL),
  96    imclass_class_code(NULL),
  97    proxy_class_def(NULL),
  98    proxy_class_code(NULL),
  99    module_class_code(NULL),
 100    proxy_class_name(NULL),
 101    variable_name(NULL),
 102    proxy_class_constants_code(NULL),
 103    module_class_constants_code(NULL),
 104    enum_code(NULL),
 105    dllimport(NULL),
 106    namespce(NULL),
 107    imclass_imports(NULL),
 108    module_imports(NULL),
 109    imclass_baseclass(NULL),
 110    module_baseclass(NULL),
 111    imclass_interfaces(NULL),
 112    module_interfaces(NULL),
 113    imclass_class_modifiers(NULL),
 114    module_class_modifiers(NULL),
 115    upcasts_code(NULL),
 116    imclass_cppcasts_code(NULL),
 117    destructor_call(NULL)
 118
 119    {
 120    }
 121
 122  /* -----------------------------------------------------------------------------
 123   * getProxyName()
 124   *
 125   * Test to see if a type corresponds to something wrapped with a proxy class
 126   * Return NULL if not otherwise the proxy class name
 127   * ----------------------------------------------------------------------------- */
 128
 129  String *getProxyName(SwigType *t) {
 130    if (proxy_flag) {
 131      Node *n = classLookup(t);
 132      if (n) {
 133        return Getattr(n,"sym:name");
 134      }
 135    }
 136    return NULL;
 137  }
 138
 139  /* ------------------------------------------------------------
 140   * main()
 141   * ------------------------------------------------------------ */
 142
 143  virtual void main(int argc, char *argv[]) {
 144
 145    SWIG_library_directory("csharp");
 146
 147    // Look for certain command line options
 148    for (int i = 1; i < argc; i++) {
 149      if (argv[i]) {
 150        if (strcmp(argv[i],"-dllimport") == 0) {
 151          if (argv[i+1]) {
 152            dllimport = NewString("");
 153            Printf(dllimport, argv[i+1]);
 154            Swig_mark_arg(i);
 155            Swig_mark_arg(i+1);
 156            i++;
 157          } else {
 158            Swig_arg_error();
 159          }
 160        } else if (strcmp(argv[i],"-namespace") == 0) {
 161          if (argv[i+1]) {
 162            namespce = NewString("");
 163            Printf(namespce, argv[i+1]);
 164            Swig_mark_arg(i);
 165            Swig_mark_arg(i+1);
 166            i++;
 167          } else {
 168            Swig_arg_error();
 169          }
 170        } else if ((strcmp(argv[i],"-noproxy") == 0)) {
 171          Swig_mark_arg(i);
 172          proxy_flag = false;
 173        } else if (strcmp(argv[i],"-help") == 0) {
 174          Printf(stderr,"%s\n", usage);
 175        }
 176      }
 177    }
 178
 179    // Add a symbol to the parser for conditional compilation
 180    Preprocessor_define("SWIGCSHARP 1",0);
 181
 182    // Add typemap definitions
 183    SWIG_typemap_lang("csharp");
 184    SWIG_config_file("csharp.swg");
 185
 186    allow_overloading();
 187  }
 188
 189  /* ---------------------------------------------------------------------
 190   * top()
 191   * --------------------------------------------------------------------- */
 192
 193  virtual int top(Node *n) {
 194
 195    // Get any options set in the module directive
 196    Node* optionsnode = Getattr( Getattr(n,"module"), "options");
 197
 198    if (optionsnode) {
 199        if (Getattr(optionsnode,"imclassname"))
 200          imclass_name = Copy(Getattr(optionsnode,"imclassname"));
 201    }
 202
 203    /* Initialize all of the output files */
 204    String *outfile = Getattr(n,"outfile");
 205
 206    f_runtime = NewFile(outfile,"w");
 207    if (!f_runtime) {
 208      Printf(stderr,"Unable to open %s\n", outfile);
 209      SWIG_exit(EXIT_FAILURE);
 210    }
 211    f_init = NewString("");
 212    f_header = NewString("");
 213    f_wrappers = NewString("");
 214
 215    /* Register file targets with the SWIG file handler */
 216    Swig_register_filebyname("header",f_header);
 217    Swig_register_filebyname("wrapper",f_wrappers);
 218    Swig_register_filebyname("runtime",f_runtime);
 219    Swig_register_filebyname("init",f_init);
 220
 221    swig_types_hash = NewHash();
 222
 223    // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
 224    if (!imclass_name) {
 225      imclass_name = NewStringf("%sPINVOKE", Getattr(n,"name"));
 226      module_class_name = Copy(Getattr(n,"name"));
 227    } else {
 228      // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
 229      if (Cmp(imclass_name, Getattr(n,"name")) == 0)
 230        module_class_name = NewStringf("%sModule", Getattr(n,"name"));
 231      else
 232        module_class_name = Copy(Getattr(n,"name"));
 233    }
 234
 235    imclass_class_code = NewString("");
 236    proxy_class_def = NewString("");
 237    proxy_class_code = NewString("");
 238    module_class_constants_code = NewString("");
 239    imclass_baseclass = NewString("");
 240    imclass_interfaces = NewString("");
 241    imclass_class_modifiers = NewString("");
 242    module_class_code = NewString("");
 243    module_baseclass = NewString("");
 244    module_interfaces = NewString("");
 245    module_imports = NewString("");
 246    module_class_modifiers = NewString("");
 247    imclass_imports = NewString("");
 248    imclass_cppcasts_code = NewString("");
 249    upcasts_code = NewString("");
 250    if (!namespce) namespce = NewString("");
 251    if (!dllimport) dllimport = Copy(module_class_name);
 252
 253    Swig_banner(f_runtime);               // Print the SWIG banner message
 254
 255    String *wrapper_name = NewString("");
 256
 257    Printf(wrapper_name, "CSharp_%%f", imclass_name);
 258    Swig_name_register((char*)"wrapper", Char(wrapper_name));
 259    Swig_name_register((char*)"set", (char*)"set_%v");
 260    Swig_name_register((char*)"get", (char*)"get_%v");
 261    Swig_name_register((char*)"member", (char*)"%c_%m");
 262
 263    Delete(wrapper_name);
 264
 265    Printf(f_wrappers,"\n#ifdef __cplusplus\n");
 266    Printf(f_wrappers,"extern \"C\" {\n");
 267    Printf(f_wrappers,"#endif\n\n");
 268
 269    /* Emit code */
 270    Language::top(n);
 271
 272    // Generate the intermediary class
 273    {
 274      String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), imclass_name);
 275      File *f_im = NewFile(filen,"w");
 276      if(!f_im) {
 277        Printf(stderr,"Unable to open %s\n", filen);
 278        SWIG_exit(EXIT_FAILURE);
 279      }
 280      Delete(filen); filen = NULL;
 281
 282      // Start writing out the intermediary class file
 283      emitBanner(f_im);
 284
 285      if(Len(namespce) > 0)
 286        Printf(f_im, "namespace %s {\n", namespce);
 287
 288      if(imclass_imports)
 289        Printf(f_im, "%s\n", imclass_imports);
 290
 291      if (Len(imclass_class_modifiers) > 0)
 292        Printf(f_im, "%s ", imclass_class_modifiers);
 293      Printf(f_im, "%s ", imclass_name);
 294
 295      if (imclass_baseclass && *Char(imclass_baseclass))
 296          Printf(f_im, ": %s ", imclass_baseclass);
 297      if (Len(imclass_interfaces) > 0)
 298        Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
 299      Printf(f_im, "{\n");
 300
 301      // Add the intermediary class methods
 302      Replaceall(imclass_class_code, "$module", module_class_name);
 303      Replaceall(imclass_class_code, "$dllimport", dllimport);
 304      Printv(f_im, imclass_class_code, NIL);
 305      Printv(f_im, imclass_cppcasts_code, NIL);
 306
 307      // Finish off the class
 308      Printf(f_im, "}\n");
 309      Printf(f_im, Len(namespce) > 0 ?  "\n}\n" : "");
 310      Close(f_im);
 311    }
 312
 313    // Generate the C# module class
 314    {
 315      String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), module_class_name);
 316      File *f_module = NewFile(filen,"w");
 317      if(!f_module) {
 318        Printf(stderr,"Unable to open %s\n", filen);
 319        SWIG_exit(EXIT_FAILURE);
 320      }
 321      Delete(filen); filen = NULL;
 322
 323      // Start writing out the module class file
 324      emitBanner(f_module);
 325
 326      if(Len(namespce) > 0)
 327        Printf(f_module, "namespace %s {\n", namespce);
 328
 329      if(module_imports)
 330        Printf(f_module, "%s\n", module_imports);
 331
 332      if (Len(module_class_modifiers) > 0)
 333        Printf(f_module, "%s ", module_class_modifiers);
 334      Printf(f_module, "%s ", module_class_name);
 335
 336      if (module_baseclass && *Char(module_baseclass))
 337          Printf(f_module, ": %s ", module_baseclass);
 338      if (Len(module_interfaces) > 0)
 339        Printv(f_module, "implements ", module_interfaces, " ", NIL);
 340      Printf(f_module, "{\n");
 341
 342      Replaceall(module_class_code, "$module", module_class_name);
 343      Replaceall(module_class_constants_code, "$module", module_class_name);
 344
 345      Replaceall(module_class_code, "$dllimport", dllimport);
 346      Replaceall(module_class_constants_code, "$dllimport", dllimport);
 347
 348      // Add the wrapper methods
 349      Printv(f_module, module_class_code, NIL);
 350
 351      // Write out all the global constants
 352      Printv(f_module, module_class_constants_code, NIL);
 353
 354      // Finish off the class
 355      Printf(f_module, "}\n");
 356      Printf(f_module, Len(namespce) > 0 ?  "\n}\n" : "");
 357
 358      Close(f_module);
 359    }
 360
 361    if(upcasts_code)
 362      Printv(f_wrappers,upcasts_code,NIL);
 363
 364    Printf(f_wrappers,"#ifdef __cplusplus\n");
 365    Printf(f_wrappers,"}\n");
 366    Printf(f_wrappers,"#endif\n");
 367
 368    // Output a C# type wrapper class for each SWIG type
 369    for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
 370      emitTypeWrapperClass(swig_type.key, swig_type.item);
 371    }
 372
 373    Delete(swig_types_hash); swig_types_hash = NULL;
 374    Delete(imclass_name); imclass_name = NULL;
 375    Delete(imclass_class_code); imclass_class_code = NULL;
 376    Delete(proxy_class_def); proxy_class_def = NULL;
 377    Delete(proxy_class_code); proxy_class_code = NULL;
 378    Delete(module_class_constants_code); module_class_constants_code = NULL;
 379    Delete(imclass_baseclass); imclass_baseclass = NULL;
 380    Delete(imclass_interfaces); imclass_interfaces = NULL;
 381    Delete(imclass_class_modifiers); imclass_class_modifiers = NULL;
 382    Delete(module_class_name); module_class_name = NULL;
 383    Delete(module_class_code); module_class_code = NULL;
 384    Delete(module_baseclass); module_baseclass = NULL;
 385    Delete(module_interfaces); module_interfaces = NULL;
 386    Delete(module_imports); module_imports = NULL;
 387    Delete(module_class_modifiers); module_class_modifiers = NULL;
 388    Delete(imclass_imports); imclass_imports = NULL;
 389    Delete(imclass_cppcasts_code); imclass_cppcasts_code = NULL;
 390    Delete(upcasts_code); upcasts_code = NULL;
 391    Delete(namespce); namespce = NULL;
 392
 393    /* Close all of the files */
 394    Dump(f_header,f_runtime);
 395    Dump(f_wrappers,f_runtime);
 396    Wrapper_pretty_print(f_init,f_runtime);
 397    Delete(f_header);
 398    Delete(f_wrappers);
 399    Delete(f_init);
 400    Close(f_runtime);
 401    Delete(f_runtime);
 402    return SWIG_OK;
 403  }
 404
 405  /* -----------------------------------------------------------------------------
 406   * emitBanner()
 407   * ----------------------------------------------------------------------------- */
 408
 409  void emitBanner(File *f) {
 410    Printf(f, "/* ----------------------------------------------------------------------------\n");
 411    Printf(f, " * This file was automatically generated by SWIG (http://www.swig.org).\n");
 412    Printf(f, " * Version %s\n", PACKAGE_VERSION);
 413    Printf(f, " *\n");
 414    Printf(f, " * Do not make changes to this file unless you know what you are doing--modify\n");
 415    Printf(f, " * the SWIG interface file instead.\n");
 416    Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
 417  }
 418
 419  /* ----------------------------------------------------------------------
 420   * nativeWrapper()
 421   * ---------------------------------------------------------------------- */
 422
 423  virtual int nativeWrapper(Node *n) {
 424    String *wrapname = Getattr(n,"wrap:name");
 425
 426    if (!addSymbol(wrapname,n)) return SWIG_ERROR;
 427
 428    if (Getattr(n,"type")) {
 429      Swig_save("nativeWrapper",n,"name",NIL);
 430      Setattr(n,"name", wrapname);
 431      native_function_flag = true;
 432      functionWrapper(n);
 433      Swig_restore(n);
 434      native_function_flag = false;
 435    } else {
 436      Printf(stderr,"%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n,"wrap:name"));
 437    }
 438
 439    return SWIG_OK;
 440  }
 441
 442  /* ----------------------------------------------------------------------
 443   * functionWrapper()
 444   * ---------------------------------------------------------------------- */
 445
 446  virtual int functionWrapper(Node *n) {
 447    String   *symname = Getattr(n,"sym:name");
 448    SwigType *t = Getattr(n,"type");
 449    ParmList *l = Getattr(n,"parms");
 450    String    *tm;
 451    Parm      *p;
 452    int       i;
 453    String    *c_return_type = NewString("");
 454    String    *im_return_type = NewString("");
 455    String    *cleanup = NewString("");
 456    String    *outarg = NewString("");
 457    String    *body = NewString("");
 458    int       num_arguments = 0;
 459    int       num_required = 0;
 460    bool      is_void_return;
 461    String    *overloaded_name = getOverloadedName(n);
 462
 463    if (!Getattr(n,"sym:overloaded")) {
 464      if (!addSymbol(Getattr(n,"sym:name"),n)) return SWIG_ERROR;
 465    }
 466
 467    /* 
 468     * Generate the proxy class properties for public member variables.
 469     * Not for enums and constants.
 470     */
 471    if(proxy_flag && wrapping_member_flag && !enum_constant_flag) {
 472      // Capitalize the first letter in the variable in the getter/setter function name
 473      bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0;
 474
 475      String *getter_setter_name = NewString("");
 476      if(!getter_flag)
 477        Printf(getter_setter_name,"set");
 478      else 
 479        Printf(getter_setter_name,"get");
 480      Putc(toupper((int) *Char(variable_name)), getter_setter_name);
 481      Printf(getter_setter_name, "%s", Char(variable_name)+1);
 482
 483      Setattr(n,"proxyfuncname", getter_setter_name);
 484      Setattr(n,"imfuncname", symname);
 485
 486      proxyClassFunctionHandler(n);
 487      Delete(getter_setter_name);
 488    }
 489
 490    /*
 491       The rest of this function deals with generating the intermediary class wrapper function (that wraps
 492       a c/c++ function) and generating the PInvoke c code. Each C# wrapper function has a 
 493       matching PInvoke c function call.
 494       */
 495
 496    // A new wrapper function object
 497    Wrapper *f = NewWrapper();
 498
 499    // Make a wrapper name for this function
 500    String *wname = Swig_name_wrapper(overloaded_name);
 501
 502    /* Attach the non-standard typemaps to the parameter list. */
 503    Swig_typemap_attach_parms("ctype", l, f);
 504    Swig_typemap_attach_parms("imtype", l, f);
 505
 506    /* Get return types */
 507    if ((tm = Swig_typemap_lookup_new("ctype",n,"",0))) {
 508      Printf(c_return_type,"%s", tm);
 509    } else {
 510      Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, 
 511          "No ctype typemap defined for %s\n", SwigType_str(t,0));
 512    }
 513
 514    if ((tm = Swig_typemap_lookup_new("imtype",n,"",0))) {
 515      Printf(im_return_type,"%s", tm);
 516    } else {
 517      Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, 
 518          "No imtype typemap defined for %s\n", SwigType_str(t,0));
 519    }
 520
 521    is_void_return = (Cmp(c_return_type, "void") == 0);
 522    if (!is_void_return)
 523      Wrapper_add_localv(f,"jresult", c_return_type, "jresult = 0",NIL);
 524
 525    Printv(f->def, " DllExport ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL);
 526
 527    // Emit all of the local variables for holding arguments.
 528    emit_args(t,l,f);
 529
 530    /* Attach the standard typemaps */
 531    emit_attach_parmmaps(l,f);
 532
 533    // Parameter overloading
 534    Setattr(n,"wrap:parms",l);
 535    Setattr(n,"wrap:name", wname);
 536
 537    // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
 538    if (Getattr(n,"sym:overloaded")) {
 539      // Emit warnings for the few cases that can't be overloaded in C# and give up on generating wrapper
 540        Swig_overload_check(n);
 541        if (Getattr(n, "overload:ignore"))
 542          return SWIG_OK;
 543    }
 544
 545    Printv(imclass_class_code, 
 546           "\n  [DllImport(\"", dllimport, "\", EntryPoint=\"CSharp_", overloaded_name, "\")]\n", NIL);
 547
 548    Printf(imclass_class_code, "  public static extern %s %s(", im_return_type, overloaded_name);
 549
 550
 551    /* Get number of required and total arguments */
 552    num_arguments = emit_num_arguments(l);
 553    num_required  = emit_num_required(l);
 554    int gencomma = 0;
 555
 556    // Now walk the function parameter list and generate code to get arguments
 557    for (i = 0, p=l; i < num_arguments; i++) {
 558
 559      while (checkAttribute(p,"tmap:in:numinputs","0")) {
 560        p = Getattr(p,"tmap:in:next");
 561      }
 562
 563      SwigType *pt = Getattr(p,"type");
 564      String   *ln = Getattr(p,"lname");
 565      String   *im_param_type = NewString("");
 566      String   *c_param_type = NewString("");
 567      String   *arg = NewString("");
 568
 569      Printf(arg,"j%s", ln);
 570
 571      /* Get the ctype types of the parameter */
 572      if ((tm = Getattr(p,"tmap:ctype"))) {
 573        Printv(c_param_type, tm, NIL);
 574      } else {
 575        Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, 
 576            "No ctype typemap defined for %s\n", SwigType_str(pt,0));
 577      }
 578
 579      /* Get the intermediary class parameter types of the parameter */
 580      if ((tm = Getattr(p,"tmap:imtype"))) {
 581        Printv(im_param_type, tm, NIL);
 582      } else {
 583        Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, 
 584            "No imtype typemap defined for %s\n", SwigType_str(pt,0));
 585      }
 586
 587      /* Add parameter to intermediary class method */
 588      if(gencomma) Printf(imclass_class_code, ", ");
 589      Printf(imclass_class_code, "%s %s", im_param_type, arg);
 590
 591      // Add parameter to C function
 592      Printv(f->def, gencomma?", ":"", c_param_type, " ", arg, NIL);
 593
 594      gencomma = 1;
 595      
 596      // Get typemap for this argument
 597      if ((tm = Getattr(p,"tmap:in"))) {
 598        addThrows(n, "tmap:in", p);
 599        Replaceall(tm,"$source",arg); /* deprecated */
 600        Replaceall(tm,"$target",ln); /* deprecated */
 601        Replaceall(tm,"$arg",arg); /* deprecated? */
 602        Replaceall(tm,"$input", arg);
 603        Setattr(p,"emit:input", arg);
 604        Printf(f->code,"%s\n", tm);
 605        p = Getattr(p,"tmap:in:next");
 606      } else {
 607        Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, 
 608            "Unable to use type %s as a function argument.\n",SwigType_str(pt,0));
 609        p = nextSibling(p);
 610      }
 611      Delete(im_param_type);
 612      Delete(c_param_type);
 613      Delete(arg);
 614    }
 615
 616    /* Insert constraint checking code */
 617    for (p = l; p;) {
 618      if ((tm = Getattr(p,"tmap:check"))) {
 619        addThrows(n, "tmap:check", p);
 620        Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */
 621        Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
 622        Replaceall(tm,"$input",Getattr(p,"emit:input"));
 623        Printv(f->code,tm,"\n",NIL);
 624        p = Getattr(p,"tmap:check:next");
 625      } else {
 626        p = nextSibling(p);
 627      }
 628    }
 629
 630    /* Insert cleanup code */
 631    for (p = l; p;) {
 632      if ((tm = Getattr(p,"tmap:freearg"))) {
 633        addThrows(n, "tmap:freearg", p);
 634        Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */
 635        Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
 636        Replaceall(tm,"$input",Getattr(p,"emit:input"));
 637        Printv(cleanup,tm,"\n",NIL);
 638        p = Getattr(p,"tmap:freearg:next");
 639      } else {
 640        p = nextSibling(p);
 641      }
 642    }
 643
 644    /* Insert argument output code */
 645    for (p = l; p;) {
 646      if ((tm = Getattr(p,"tmap:argout"))) {
 647        addThrows(n, "tmap:argout", p);
 648        Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */
 649        Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */
 650        Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
 651        Replaceall(tm,"$result","jresult");
 652        Replaceall(tm,"$input",Getattr(p,"emit:input"));
 653        Printv(outarg,tm,"\n",NIL);
 654        p = Getattr(p,"tmap:argout:next");
 655      } else {
 656        p = nextSibling(p);
 657      }
 658    }
 659
 660    // Get any C# exception classes in the throws typemap
 661    ParmList *throw_parm_list = NULL;
 662    if ((throw_parm_list = Getattr(n,"throws"))) {
 663      Swig_typemap_attach_parms("throws", throw_parm_list, f);
 664      for (p = throw_parm_list; p; p=nextSibling(p)) {
 665        if ((tm = Getattr(p,"tmap:throws"))) {
 666          addThrows(n, "tmap:throws", p);
 667        }
 668      }
 669    }
 670
 671    if (Cmp(nodeType(n), "constant") == 0) {
 672      // Wrapping a constant hack
 673      Swig_save("functionWrapper",n,"wrap:action",NIL);
 674
 675      // below based on Swig_VargetToFunction()
 676      SwigType *ty = Swig_wrapped_var_type(Getattr(n,"type"));
 677      Setattr(n,"wrap:action", NewStringf("result = (%s) %s;\n", SwigType_lstr(ty,0), Getattr(n, "value")));
 678    }
 679
 680    // Now write code to make the function call
 681    if(!native_function_flag)
 682      emit_action(n,f);
 683
 684    if (Cmp(nodeType(n), "constant") == 0)
 685      Swig_restore(n);
 686
 687    /* Return value if necessary  */
 688    if(!native_function_flag) {
 689      if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
 690        addThrows(n, "tmap:out", n);
 691        Replaceall(tm,"$source", "result"); /* deprecated */
 692        Replaceall(tm,"$target", "jresult"); /* deprecated */
 693        Replaceall(tm,"$result","jresult");
 694        Printf(f->code,"%s", tm);
 695        if (Len(tm))
 696          Printf(f->code,"\n");
 697      } else {
 698        Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
 699            "Unable to use return type %s in function %s.\n", SwigType_str(t,0), Getattr(n,"name"));
 700      }
 701    }
 702
 703    /* Output argument output code */
 704    Printv(f->code,outarg,NIL);
 705
 706    /* Output cleanup code */
 707    Printv(f->code,cleanup,NIL);
 708
 709    /* Look to see if there is any newfree cleanup code */
 710    if (Getattr(n,"feature:new")) {
 711      if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
 712        addThrows(n, "tmap:newfree", n);
 713        Replaceall(tm,"$source","result"); /* deprecated */
 714        Printf(f->code,"%s\n",tm);
 715      }
 716    }
 717
 718    /* See if there is any return cleanup code */
 719    if(!native_function_flag) {
 720      if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
 721        Replaceall(tm,"$source","result"); /* deprecated */
 722        Printf(f->code,"%s\n",tm);
 723      }
 724    }
 725
 726    /* Finish C function and intermediary class function definitions */
 727    Printf(imclass_class_code, ")");
 728    generateThrowsClause(n, imclass_class_code);
 729    Printf(imclass_class_code, ";\n");
 730
 731    Printf(f->def,") {");
 732
 733    if(!is_void_return)
 734      Printv(f->code, "    return jresult;\n", NIL);
 735    Printf(f->code, "}\n");
 736
 737    /* Substitute the cleanup code */
 738    Replaceall(f->code,"$cleanup",cleanup);
 739
 740    /* Contract macro modification */
 741    Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ");
 742
 743    if(!is_void_return)
 744      Replaceall(f->code,"$null","0");
 745    else
 746      Replaceall(f->code,"$null","");
 747
 748    /* Dump the function out */
 749    if(!native_function_flag)
 750      Wrapper_print(f,f_wrappers);
 751
 752    if(!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
 753      moduleClassFunctionHandler(n);
 754    }
 755
 756    Delete(c_return_type);
 757    Delete(im_return_type);
 758    Delete(cleanup);
 759    Delete(outarg);
 760    Delete(body);
 761    Delete(overloaded_name);
 762    DelWrapper(f);
 763    return SWIG_OK;
 764  }
 765
 766  /* -----------------------------------------------------------------------
 767   * variableWrapper()
 768   * ----------------------------------------------------------------------- */
 769
 770  virtual int variableWrapper(Node *n) {
 771    Language::variableWrapper(n);
 772    return SWIG_OK;
 773  }
 774
 775  /* -----------------------------------------------------------------------
 776   * globalvariableHandler()
 777   * ------------------------------------------------------------------------ */
 778
 779  virtual int globalvariableHandler(Node *n) {
 780
 781    SwigType  *t = Getattr(n,"type");
 782    String    *tm;
 783
 784    // Get the variable type
 785    if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) {
 786      substituteClassname(t, tm);
 787    } else {
 788      Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, 
 789          "No cstype typemap defined for %s\n", SwigType_str(t,0));
 790    }
 791
 792    // Output the property's field declaration and accessor methods
 793    Printf(module_class_code, "  public static %s %s {", tm, Getattr(n, "sym:name"));
 794
 795    variable_name = Getattr(n,"sym:name");
 796    global_variable_flag = true;
 797    int ret = Language::globalvariableHandler(n);
 798    global_variable_flag = false;
 799
 800    Printf(module_class_code, "\n  }\n\n");
 801
 802    return ret;
 803  }
 804
 805  /* ----------------------------------------------------------------------
 806   * enumDeclaration()
 807   *
 808   * C/C++ enums can be mapped in one of 4 ways, depending on the cs:enum feature specified:
 809   * 1) Simple enums - simple constant within the proxy class or module class
 810   * 2) Typeunsafe enums - simple constant in a C# class (class named after the c++ enum name)
 811   * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
 812   * 4) Proper enums - proper C# enum
 813   * Anonymous enums always default to 1)
 814   * ---------------------------------------------------------------------- */
 815
 816  virtual int enumDeclaration(Node *n) {
 817
 818    if (!ImportMode) {
 819      if (getCurrentClass() && (cplus_mode != PUBLIC)) return SWIG_NOWRAP;
 820
 821      enum_code = NewString("");
 822      String *symname = Getattr(n,"sym:name");
 823      String *constants_code = (proxy_flag && is_wrapping_class()) ? proxy_class_constants_code : module_class_constants_code;
 824      EnumFeature enum_feature = decodeEnumFeature(n);
 825      String *typemap_lookup_type = Getattr(n,"name");
 826
 827      if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
 828        // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
 829
 830        // Pure C# baseclass and interfaces
 831        const String *pure_baseclass = typemapLookup("csbase", typemap_lookup_type, WARN_NONE);
 832        const String *pure_interfaces = typemapLookup("csinterfaces", typemap_lookup_type, WARN_NONE);
 833
 834        // Emit the enum
 835        Printv(enum_code,
 836            typemapLookup("csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
 837            " ",
 838            symname,
 839            (*Char(pure_baseclass) || *Char(pure_interfaces)) ?
 840            " : " : 
 841            "",
 842            pure_baseclass,
 843            ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
 844            ", " :
 845            "",
 846            pure_interfaces,
 847            " {\n",
 848            NIL);
 849      } else {
 850        // Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
 851        if (symname && !Getattr(n,"unnamedinstance"))
 852          Printf(constants_code, "  // %s \n", symname);
 853      }
 854
 855      // Emit each enum item
 856      Language::enumDeclaration(n);
 857
 858      if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
 859        // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
 860        // Finish the enum declaration
 861        // Typemaps are used to generate the enum definition in a similar manner to proxy classes.
 862        Printv(enum_code,
 863            (enum_feature == ProperEnum) ? 
 864            "\n" :
 865            typemapLookup("csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
 866            typemapLookup("cscode", typemap_lookup_type, WARN_NONE), // extra C# code
 867            "}\n",
 868            "\n",
 869            NIL);
 870
 871        Replaceall(enum_code, "$csclassname", symname);
 872
 873        // Substitute $enumvalues - intended usage is for typesafe enums
 874        if (Getattr(n,"enumvalues"))
 875          Replaceall(enum_code, "$enumvalues", Getattr(n,"enumvalues"));
 876        else
 877          Replaceall(enum_code, "$enumvalues", "");
 878
 879        if (proxy_flag && is_wrapping_class()) {
 880          // Enums defined within the C++ class are defined within the proxy class
 881
 882          // Add extra indentation
 883          Replaceall(enum_code, "\n  ", "\n    ");
 884          Replaceall(enum_code, "\n}\n", "\n  }\n");
 885
 886          Printv(proxy_class_constants_code, "  ", enum_code, NIL);
 887        } else {
 888          // Global enums are defined in their own file
 889          String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), symname);
 890          File *f_enum = NewFile(filen,"w");
 891          if(!f_enum) {
 892            Printf(stderr,"Unable to open %s\n", filen);
 893            SWIG_exit(EXIT_FAILURE);
 894          } 
 895          Delete(filen); filen = NULL;
 896
 897          // Start writing out the enum file
 898          emitBanner(f_enum);
 899
 900          if(Len(namespce) > 0)
 901            Printf(f_enum, "namespace %s {\n", namespce);
 902
 903          Printv(f_enum,
 904              typemapLookup("csimports", typemap_lookup_type, WARN_NONE), // Import statements
 905              "\n",
 906              enum_code,
 907              NIL);
 908
 909          Printf(f_enum, Len(namespce) > 0 ?  "\n}\n" : "\n");
 910          Close(f_enum);
 911        }
 912      } else {
 913        // Wrap C++ enum with simple constant
 914        Printf(enum_code, "\n");
 915        if (proxy_flag && is_wrapping_class())
 916          Printv(proxy_class_constants_code, enum_code, NIL);
 917        else
 918          Printv(module_class_constants_code, enum_code, NIL);
 919      }
 920
 921      Delete(enum_code); enum_code = NULL;
 922    }
 923    return SWIG_OK;
 924  }
 925
 926  /* ----------------------------------------------------------------------
 927   * enumvalueDeclaration()
 928   * ---------------------------------------------------------------------- */
 929
 930  virtual int enumvalueDeclaration(Node *n) {
 931    if (getCurrentClass() && (cplus_mode != PUBLIC)) return SWIG_NOWRAP;
 932
 933    Swig_require("enumvalueDeclaration",n,"*name", "?value",NIL);
 934    String *symname = Getattr(n,"sym:name");
 935    String *value = Getattr(n,"value");
 936    String *name  = Getattr(n,"name");
 937    String *tmpValue;
 938
 939    // Strange hack from parent method
 940    if (value)
 941      tmpValue = NewString(value);
 942    else
 943      tmpValue = NewString(name);
 944    // Note that this is used in enumValue() amongst other places
 945    Setattr(n, "value", tmpValue);
 946
 947    {
 948      EnumFeature enum_feature = decodeEnumFeature(parentNode(n));
 949
 950      if ((enum_feature == ProperEnum) && Getattr(parentNode(n),"sym:name") && !Getattr(parentNode(n),"unnamedinstance")) {
 951        // Wrap (non-anonymous) C/C++ enum with a proper C# enum
 952        // Emit the enum item.
 953        if (!Getattr(n,"_last")) // Only the first enum item has this attribute set
 954          Printf(enum_code, ",\n");
 955        Printf(enum_code, "  %s", symname);
 956
 957        // Check for the %csconstvalue feature
 958        String *value = Getattr(n,"feature:cs:constvalue");
 959
 960        // Note that the enum value must be a true constant and cannot be set from a PINVOKE call, thus no support for %csconst(0)
 961        value = value ? value : Getattr(n,"enumvalue");
 962        if (value) {
 963          Printf(enum_code, " = %s", value);
 964        }
 965      } else {
 966        // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
 967        const String *parent_name = Getattr(parentNode(n),"name");
 968        String *typemap_lookup_type = parent_name ? Copy(parent_name) : NewString("int");
 969        const String *tm = typemapLookup("cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF);
 970        String *return_type = Copy(tm);
 971        Delete(typemap_lookup_type); typemap_lookup_type = NULL;
 972
 973        // The %csconst feature determines how the constant value is obtained
 974        String *const_feature = Getattr(n,"feature:cs:const");
 975        bool const_feature_flag = const_feature && Cmp(const_feature, "0") != 0;
 976
 977        if ((enum_feature == TypesafeEnum) && Getattr(parentNode(n),"sym:name") && !Getattr(parentNode(n),"unnamedinstance")) {
 978          // Wrap (non-anonymouse) enum using the typesafe enum pattern
 979          if (Getattr(n,"enumvalue")) {
 980            String *value = enumValue(n);
 981            Printf(enum_code, "  public static readonly %s %s = new %s(\"%s\", %s);\n", return_type, symname, return_type, symname, value);
 982            Delete(value);
 983          } else {
 984            Printf(enum_code, "  public static readonly %s %s = new %s(\"%s\");\n", return_type, symname, return_type, symname);
 985          }
 986        } else {
 987          // Simple integer constants
 988          // Note these are always generated for anonymous enums, no matter what enum_feature is specified
 989          // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
 990          const char *const_readonly = const_feature_flag ? "const" : "static readonly";
 991          String *value = enumValue(n);
 992          Printf(enum_code, "  public %s %s %s = %s;\n", const_readonly, return_type, symname, value);
 993          Delete(value);
 994        }
 995      }
 996
 997      // Add the enum value to the comma separated list being constructed in the enum declaration.
 998      String *enumvalues = Getattr(parentNode(n), "enumvalues");
 999      if (!enumvalues)
1000        Setattr(parentNode(n), "enumvalues", Copy(symname));
1001      else
1002        Printv(enumvalues, ", ", symname, NIL);
1003    }
1004    
1005    Delete(tmpValue);
1006    Swig_restore(n);
1007    return SWIG_OK;
1008  }
1009
1010  /* -----------------------------------------------------------------------
1011   * constantWrapper()
1012   * Used for wrapping constants - #define or %constant.
1013   * Also for inline initialised const static primitive type member variables (short, int, double, enums etc).
1014   * C# static const variables are generated for these.
1015   * If the %csconst(1) feature is used then the C constant value is used to initialise the C# const variable.
1016   * If not, a PINVOKE method is generated to get the C constant value for initialisation of the C# const variable.
1017   * However, if the %csconstvalue feature is used, it overrides all other ways to generate the initialisation.
1018   * Also note that this method might be called for wrapping enum items (when the enum is using %csconst(0)).
1019   * ------------------------------------------------------------------------ */
1020
1021  virtual int constantWrapper(Node *n) {
1022    String *symname = Getattr(n,"sym:name");
1023    SwigType *t     = Getattr(n,"type");
1024    ParmList  *l    = Getattr(n,"parms");
1025    String *tm;
1026    String *return_type = NewString("");
1027    String *constants_code = NewString("");
1028
1029    if (!addSymbol(symname,n)) return SWIG_ERROR;
1030
1031    bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
1032
1033    // The %csconst feature determines how the constant value is obtained
1034    String *const_feature = Getattr(n,"feature:cs:const");
1035    bool const_feature_flag = const_feature && Cmp(const_feature, "0") != 0;
1036
1037    /* Adjust the enum type for the Swig_typemap_lookup.
1038     * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */
1039    if (is_enum_item) {
1040      t = Getattr(parentNode(n),"enumtype");
1041      Setattr(n,"type", t);
1042    }
1043
1044    /* Attach the non-standard typemaps to the parameter list. */
1045    Swig_typemap_attach_parms("cstype", l, NULL);
1046
1047    /* Get C# return types */
1048    bool classname_substituted_flag = false;
1049    
1050    if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) {
1051      classname_substituted_flag = substituteClassname(t, tm);
1052      Printf(return_type, "%s", tm);
1053    } else {
1054      Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, 
1055          "No cstype typemap defined for %s\n", SwigType_str(t,0));
1056    }
1057
1058    // Add the stripped quotes back in
1059    String *new_value = NewString("");
1060    Swig_save("constantWrapper",n,"value",NIL);
1061    if(SwigType_type(t) == T_STRING) {
1062      Printf(new_value, "\"%s\"", Copy(Getattr(n, "value")));
1063      Setattr(n, "value", new_value);
1064    }
1065    else if(SwigType_type(t) == T_CHAR) {
1066      Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
1067      Setattr(n, "value", new_value);
1068    }
1069
1070      const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
1071      Printf(constants_code, "  public %s %s %s = ", (const_feature_flag ? "const" : "static readonly"), return_type, itemname);
1072
1073    // Check for the %csconstvalue feature
1074    String *value = Getattr(n,"feature:cs:constvalue");
1075
1076    if (value) {
1077      Printf(constants_code, "%s;\n", value);
1078    } else if (!const_feature_flag) {
1079      // Default enum and constant handling will work with any type of C constant and initialises the C# variable from C through a PINVOKE call.
1080
1081      if(classname_substituted_flag) {
1082        if (SwigType_isenum(t)) {
1083          // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
1084          Printf(constants_code, "(%s)%s.%s();\n", return_type, imclass_name, Swig_name_get(symname));
1085        } else {
1086          // This handles function pointers using the %constant directive
1087          Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, imclass_name, Swig_name_get(symname));
1088        }
1089      } else
1090        Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(symname));
1091
1092      // Each constant and enum value is wrapped with a separate PInvoke function call
1093      enum_constant_flag = true;
1094      variableWrapper(n);
1095      enum_constant_flag = false;
1096    } else {
1097      // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
1098      Printf(constants_code, "%s;\n", Getattr(n,"value"));
1099    }
1100
1101    // Emit the generated code to appropriate place
1102    // Enums only emit the intermediate and PINVOKE methods, so no proxy or module class wrapper methods needed
1103    if (!is_enum_item) {
1104      if(proxy_flag && wrapping_member_flag)
1105        Printv(proxy_class_constants_code, constants_code, NIL);
1106      else
1107        Printv(module_class_constants_code, constants_code, NIL);
1108    }
1109
1110    // Cleanup
1111    Swig_restore(n);
1112    Delete(new_value);
1113    Delete(return_type);
1114    Delete(constants_code);
1115    return SWIG_OK;
1116  }
1117
1118  /* -----------------------------------------------------------------------------
1119   * insertDirective()
1120   * ----------------------------------------------------------------------------- */
1121
1122  virtual int insertDirective(Node *n) {
1123    String *code = Getattr(n,"code");
1124    Replaceall(code, "$module", module_class_name);
1125    Replaceall(code, "$dllimport", dllimport);
1126    return Language::insertDirective(n);
1127  }
1128
1129  /* -----------------------------------------------------------------------------
1130   * pragmaDirective()
1131   *
1132   * Valid Pragmas:
1133   * imclassbase            - base (extends) for the intermediary class
1134   * imclassclassmodifiers  - class modifiers for the intermediary class
1135   * imclasscode            - text (C# code) is copied verbatim to the intermediary class
1136   * imclassimports         - import statements for the intermediary class
1137   * imclassinterfaces      - interface (implements) for the intermediary class
1138   *
1139   * modulebase              - base (extends) for the module class
1140   * moduleclassmodifiers    - class modifiers for the module class
1141   * modulecode              - text (C# code) is copied verbatim to the module class
1142   * moduleimports           - import statements for the module class
1143   * moduleinterfaces        - interface (implements) for the module class
1144   *
1145   * ----------------------------------------------------------------------------- */
1146
1147  virtual int pragmaDirective(Node *n) {
1148    if (!ImportMode) {
1149      String *lang = Getattr(n,"lang");
1150      String *code = Getattr(n,"name");
1151      String *value = Getattr(n,"value");
1152
1153      if(Strcmp(lang, "csharp") == 0) {
1154
1155        String *strvalue = NewString(value);
1156        Replaceall(strvalue,"\\\"", "\"");
1157
1158        if(Strcmp(code, "imclassbase") == 0) {
1159          Delete(imclass_baseclass);
1160          imclass_baseclass = Copy(strvalue);
1161        } 
1162        else if(Strcmp(code, "imclassclassmodifiers") == 0) {
1163          Delete(imclass_class_modifiers);
1164          imclass_class_modifiers = Copy(strvalue);
1165        } 
1166        else if(Strcmp(code, "imclasscode") == 0) {
1167          Printf(imclass_class_code, "%s\n", strvalue);
1168        } 
1169        else if(Strcmp(code, "imclassimports") == 0) {
1170          Delete(imclass_imports);
1171          imclass_imports = Copy(strvalue);
1172        } 
1173        else if(Strcmp(code, "imclassinterfaces") == 0) {
1174          Delete(imclass_interfaces);
1175          imclass_interfaces = Copy(strvalue);
1176        } 
1177        else if(Strcmp(code, "modulebase") == 0) {
1178          Delete(module_baseclass);
1179          module_baseclass = Copy(strvalue);
1180        } 
1181        else if(Strcmp(code, "moduleclassmodifiers") == 0) {
1182          Delete(module_class_modifiers);
1183          module_class_modifiers = Copy(strvalue);
1184        } 
1185        else if(Strcmp(code, "modulecode") == 0) {
1186          Printf(module_class_code, "%s\n", strvalue);
1187        } 
1188        else if(Strcmp(code, "moduleimports") == 0) {
1189          Delete(module_imports);
1190          module_imports = Copy(strvalue);
1191        } 
1192        else if(Strcmp(code, "moduleinterfaces") == 0) {
1193          Delete(module_interfaces);
1194          module_interfaces = Copy(strvalue);
1195        } else {
1196          Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number);
1197        }
1198        Delete(strvalue);
1199      }
1200    }
1201    return Language::pragmaDirective(n);
1202  }
1203
1204  /* -----------------------------------------------------------------------------
1205   * emitProxyClassDefAndCPPCasts()
1206   * ----------------------------------------------------------------------------- */
1207
1208  void emitProxyClassDefAndCPPCasts(Node *n) {
1209    String *c_classname = SwigType_namestr(Getattr(n,"name"));
1210    String *c_baseclass = NULL;
1211    String *baseclass = NULL;
1212    String *c_baseclassname = NULL;
1213    String *typemap_lookup_type = Getattr(n,"classtypeobj");
1214
1215    /* Deal with inheritance */
1216    List *baselist = Getattr(n,"bases");
1217    if (baselist) {
1218      Iterator base = First(baselist);
1219      c_baseclassname = Getattr(base.item,"name");
1220      baseclass = Copy(getProxyName(c_baseclassname));
1221      if (baseclass){
1222        c_baseclass = SwigType_namestr(Getattr(base.item,"name"));
1223      }
1224      base = Next(base);
1225      if (base.item) {
1226        Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number, 
1227            "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", typemap_lookup_type, Getattr(base.item,"name"));
1228      }
1229    }
1230
1231    bool derived = baseclass && getProxyName(c_baseclassname);
1232    if (!baseclass)
1233      baseclass = NewString("");
1234
1235    // Inheritance from pure C# classes
1236    const String *pure_baseclass = typemapLookup("csbase", typemap_lookup_type, WARN_NONE);
1237    if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
1238      Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number, 
1239          "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", typemap_lookup_type, pure_baseclass);
1240      pure_baseclass = empty_string;
1241    }
1242
1243    // Pure C# interfaces
1244    const String *pure_interfaces = typemapLookup(derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
1245
1246    // Start writing the proxy class
1247    Printv(proxy_class_def,
1248        typemapLookup("csimports", typemap_lookup_type, WARN_NONE), // Import statements
1249        "\n",
1250        typemapLookup("csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
1251        " $csclassname",       // Class name and base class
1252        (derived || *Char(pure_baseclass) || *Char(pure_interfaces)) ?
1253        " : " : 
1254        "",
1255        baseclass, // Note only one of these base classes should ever be set as multiple inheritance is not permissible
1256        pure_baseclass,
1257        ((derived || *Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
1258        ", " :
1259        "",
1260        pure_interfaces,
1261        " {",
1262        derived ?
1263        typemapLookup("csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class
1264        typemapLookup("csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
1265        NIL);
1266
1267    if(!have_default_constructor_flag) { // All proxy classes need a constructor
1268      Printv(proxy_class_def, 
1269          "\n",
1270          "  protected $csclassname() : this(IntPtr.Zero, false) {\n",
1271          "  }\n",
1272          NIL);
1273    }
1274
1275    // C++ destructor is wrapped by the Dispose method
1276    // Note that the method name is specified in a typemap attribute called methodname
1277    String *destruct = NewString("");
1278    const String *tm = NULL;
1279    Node *attributes = NewHash();
1280    String *destruct_methodname = NULL;
1281    if (derived) {
1282      tm = typemapLookup("csdestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
1283      destruct_methodname = Getattr(attributes, "tmap:csdestruct_derived:methodname");
1284    } else {
1285      tm = typemapLookup("csdestruct", typemap_lookup_type, WARN_NONE, attributes);
1286      destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname");
1287    }
1288    if (!destruct_methodname) {
1289      Swig_error(input_file, line_number, 
1290          "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
1291    }
1292
1293    // Emit the Finalize and Dispose methods
1294    if (tm) {
1295      // Finalize method
1296      if (*Char(destructor_call)) {
1297        Printv(proxy_class_def, 
1298            typemapLookup("csfinalize", typemap_lookup_type, WARN_NONE),
1299            NIL);
1300      }
1301      // Dispose method
1302      Printv(destruct, tm, NIL);
1303      if (*Char(destructor_call))
1304        Replaceall(destruct, "$imcall", destructor_call);
1305      else
1306        Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")");
1307      if (*Char(destruct))
1308        Printv(proxy_class_def, "\n  public ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n", NIL);
1309    }
1310    Delete(attributes);
1311    Delete(destruct);
1312
1313    // Emit extra user code
1314    Printv(proxy_class_def, 
1315        typemapLookup("cscode", typemap_lookup_type, WARN_NONE), // extra C# code
1316        "\n",
1317        NIL);
1318
1319    // Substitute various strings into the above template
1320    Replaceall(proxy_class_code, "$csclassname", proxy_class_name);
1321    Replaceall(proxy_class_def,  "$csclassname", proxy_class_name);
1322
1323    Replaceall(proxy_class_def,  "$module", module_class_name);
1324    Replaceall(proxy_class_code, "$module", module_class_name);
1325
1326    Replaceall(proxy_class_def,  "$dllimport", dllimport);
1327    Replaceall(proxy_class_code, "$dllimport", dllimport);
1328
1329    // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
1330    if(derived){
1331      Printv(imclass_cppcasts_code,"\n  [DllImport(\"", dllimport, "\", EntryPoint=\"CSharp_", proxy_class_name ,"Upcast", "\")]\n", NIL);
1332      Printf(imclass_cppcasts_code,"  p…

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