PageRenderTime 124ms CodeModel.GetById 13ms app.highlight 99ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Source/Modules/java.cxx

#
C++ | 1775 lines | 1293 code | 246 blank | 236 comment | 357 complexity | 54406e4a0cffbaac552ad8efb693c35a 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 * java.cxx
  10 *
  11 * Java language module for SWIG.
  12 * ----------------------------------------------------------------------------- */
  13
  14char cvsroot_java_cxx[] = "$Id: java.cxx 12891 2012-01-06 18:57:25Z wsfulton $";
  15
  16#include "swigmod.h"
  17#include <limits.h>		// for INT_MAX
  18#include "cparse.h"
  19#include <ctype.h>
  20
  21/* Hash type used for upcalls from C/C++ */
  22typedef DOH UpcallData;
  23
  24class JAVA:public Language {
  25  static const char *usage;
  26  const String *empty_string;
  27  const String *public_string;
  28  const String *protected_string;
  29
  30  Hash *swig_types_hash;
  31  File *f_begin;
  32  File *f_runtime;
  33  File *f_runtime_h;
  34  File *f_header;
  35  File *f_wrappers;
  36  File *f_init;
  37  File *f_directors;
  38  File *f_directors_h;
  39  List *filenames_list;
  40
  41  bool proxy_flag;		// Flag for generating proxy classes
  42  bool nopgcpp_flag;		// Flag for suppressing the premature garbage collection prevention parameter
  43  bool native_function_flag;	// Flag for when wrapping a native function
  44  bool enum_constant_flag;	// Flag for when wrapping an enum or constant
  45  bool static_flag;		// Flag for when wrapping a static functions or member variables
  46  bool variable_wrapper_flag;	// Flag for when wrapping a nonstatic member variable
  47  bool wrapping_member_flag;	// Flag for when wrapping a member variable/enum/const
  48  bool global_variable_flag;	// Flag for when wrapping a global variable
  49  bool old_variable_names;	// Flag for old style variable names in the intermediary class
  50  bool member_func_flag;	// flag set when wrapping a member function
  51
  52  String *imclass_name;		// intermediary class name
  53  String *module_class_name;	// module class name
  54  String *constants_interface_name;	// constants interface name
  55  String *imclass_class_code;	// intermediary class code
  56  String *proxy_class_def;
  57  String *proxy_class_code;
  58  String *module_class_code;
  59  String *proxy_class_name;	// proxy class name
  60  String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
  61  String *full_imclass_name;	// fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
  62  String *variable_name;	//Name of a variable being wrapped
  63  String *proxy_class_constants_code;
  64  String *module_class_constants_code;
  65  String *enum_code;
  66  String *package;		// Optional package name
  67  String *jnipackage;		// Package name used in the JNI code
  68  String *package_path;		// Package name used internally by JNI (slashes)
  69  String *imclass_imports;	//intermediary class imports from %pragma
  70  String *module_imports;	//module imports from %pragma
  71  String *imclass_baseclass;	//inheritance for intermediary class class from %pragma
  72  String *module_baseclass;	//inheritance for module class from %pragma
  73  String *imclass_interfaces;	//interfaces for intermediary class class from %pragma
  74  String *module_interfaces;	//interfaces for module class from %pragma
  75  String *imclass_class_modifiers;	//class modifiers for intermediary class overriden by %pragma
  76  String *module_class_modifiers;	//class modifiers for module class overriden by %pragma
  77  String *upcasts_code;		//C++ casts for inheritance hierarchies C++ code
  78  String *imclass_cppcasts_code;	//C++ casts up inheritance hierarchies intermediary class code
  79  String *imclass_directors;	// Intermediate class director code
  80  String *destructor_call;	//C++ destructor call if any
  81  String *destructor_throws_clause;	//C++ destructor throws clause if any
  82
  83  // Director method stuff:
  84  List *dmethods_seq;
  85  Hash *dmethods_table;
  86  int n_dmethods;
  87  int n_directors;
  88  int first_class_dmethod;
  89  int curr_class_dmethod;
  90
  91  enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
  92
  93public:
  94
  95  /* -----------------------------------------------------------------------------
  96   * JAVA()
  97   * ----------------------------------------------------------------------------- */
  98
  99   JAVA():empty_string(NewString("")),
 100      public_string(NewString("public")),
 101      protected_string(NewString("protected")),
 102      swig_types_hash(NULL),
 103      f_begin(NULL),
 104      f_runtime(NULL),
 105      f_runtime_h(NULL),
 106      f_header(NULL),
 107      f_wrappers(NULL),
 108      f_init(NULL),
 109      f_directors(NULL),
 110      f_directors_h(NULL),
 111      filenames_list(NULL),
 112      proxy_flag(true),
 113      nopgcpp_flag(false),
 114      native_function_flag(false),
 115      enum_constant_flag(false),
 116      static_flag(false),
 117      variable_wrapper_flag(false),
 118      wrapping_member_flag(false),
 119      global_variable_flag(false),
 120      old_variable_names(false),
 121      member_func_flag(false),
 122      imclass_name(NULL),
 123      module_class_name(NULL),
 124      constants_interface_name(NULL),
 125      imclass_class_code(NULL),
 126      proxy_class_def(NULL),
 127      proxy_class_code(NULL),
 128      module_class_code(NULL),
 129      proxy_class_name(NULL),
 130      full_proxy_class_name(NULL),
 131      full_imclass_name(NULL),
 132      variable_name(NULL),
 133      proxy_class_constants_code(NULL),
 134      module_class_constants_code(NULL),
 135      package(NULL),
 136      jnipackage(NULL),
 137      package_path(NULL),
 138      imclass_imports(NULL),
 139      module_imports(NULL),
 140      imclass_baseclass(NULL),
 141      module_baseclass(NULL),
 142      imclass_interfaces(NULL),
 143      module_interfaces(NULL),
 144      imclass_class_modifiers(NULL),
 145      module_class_modifiers(NULL),
 146      upcasts_code(NULL),
 147      imclass_cppcasts_code(NULL),
 148      imclass_directors(NULL),
 149      destructor_call(NULL),
 150      destructor_throws_clause(NULL),
 151      dmethods_seq(NULL),
 152      dmethods_table(NULL),
 153      n_dmethods(0),
 154      n_directors(0) {
 155    /* for now, multiple inheritance in directors is disabled, this
 156       should be easy to implement though */
 157    director_multiple_inheritance = 0;
 158    director_language = 1;
 159  }
 160
 161  /* -----------------------------------------------------------------------------
 162   * getProxyName()
 163   *
 164   * Test to see if a type corresponds to something wrapped with a proxy class.
 165   * Return NULL if not otherwise the proxy class name, fully qualified with
 166   * package name if the nspace feature is used.
 167   * ----------------------------------------------------------------------------- */
 168  
 169   String *getProxyName(SwigType *t) {
 170     String *proxyname = NULL;
 171     if (proxy_flag) {
 172       Node *n = classLookup(t);
 173       if (n) {
 174	 proxyname = Getattr(n, "proxyname");
 175	 if (!proxyname) {
 176	   String *nspace = Getattr(n, "sym:nspace");
 177	   String *symname = Getattr(n, "sym:name");
 178	   if (nspace) {
 179	     if (package)
 180	       proxyname = NewStringf("%s.%s.%s", package, nspace, symname);
 181	     else
 182	       proxyname = NewStringf("%s.%s", nspace, symname);
 183	   } else {
 184	     proxyname = Copy(symname);
 185	   }
 186	   Setattr(n, "proxyname", proxyname);
 187	   Delete(proxyname);
 188	 }
 189       }
 190     }
 191     return proxyname;
 192   }
 193
 194  /* -----------------------------------------------------------------------------
 195   * makeValidJniName()
 196   * ----------------------------------------------------------------------------- */
 197
 198  String *makeValidJniName(const String *name) {
 199    String *valid_jni_name = NewString(name);
 200    Replaceall(valid_jni_name, "_", "_1");
 201    return valid_jni_name;
 202  }
 203
 204  /* -----------------------------------------------------------------------------
 205   * directorClassName()
 206   * ----------------------------------------------------------------------------- */
 207
 208  String *directorClassName(Node *n) {
 209    String *dirclassname;
 210    const char *attrib = "director:classname";
 211
 212    if (!(dirclassname = Getattr(n, attrib))) {
 213      String *classname = Getattr(n, "sym:name");
 214
 215      dirclassname = NewStringf("SwigDirector_%s", classname);
 216      Setattr(n, attrib, dirclassname);
 217    }
 218
 219    return dirclassname;
 220  }
 221
 222  /* ------------------------------------------------------------
 223   * main()
 224   * ------------------------------------------------------------ */
 225
 226  virtual void main(int argc, char *argv[]) {
 227
 228    SWIG_library_directory("java");
 229
 230    // Look for certain command line options
 231    for (int i = 1; i < argc; i++) {
 232      if (argv[i]) {
 233	if (strcmp(argv[i], "-package") == 0) {
 234	  if (argv[i + 1]) {
 235	    package = NewString("");
 236	    Printf(package, argv[i + 1]);
 237	    if (Len(package) == 0) {
 238	      Delete(package);
 239	      package = 0;
 240	    }
 241	    Swig_mark_arg(i);
 242	    Swig_mark_arg(i + 1);
 243	    i++;
 244	  } else {
 245	    Swig_arg_error();
 246	  }
 247	} else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
 248	  Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]);
 249	  Swig_mark_arg(i);
 250	  proxy_flag = true;
 251	} else if ((strcmp(argv[i], "-noproxy") == 0)) {
 252	  Swig_mark_arg(i);
 253	  proxy_flag = false;
 254	} else if (strcmp(argv[i], "-nopgcpp") == 0) {
 255	  Swig_mark_arg(i);
 256	  nopgcpp_flag = true;
 257	} else if (strcmp(argv[i], "-oldvarnames") == 0) {
 258	  Swig_mark_arg(i);
 259	  old_variable_names = true;
 260	} else if (strcmp(argv[i], "-jnic") == 0) {
 261	  Swig_mark_arg(i);
 262	  Printf(stderr, "Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n");
 263	} else if (strcmp(argv[i], "-nofinalize") == 0) {
 264	  Swig_mark_arg(i);
 265	  Printf(stderr, "Deprecated command line option: -nofinalize. Use the new javafinalize typemap instead.\n");
 266	} else if (strcmp(argv[i], "-jnicpp") == 0) {
 267	  Swig_mark_arg(i);
 268	  Printf(stderr, "Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n");
 269	} else if (strcmp(argv[i], "-help") == 0) {
 270	  Printf(stdout, "%s\n", usage);
 271	}
 272      }
 273    }
 274
 275    // Add a symbol to the parser for conditional compilation
 276    Preprocessor_define("SWIGJAVA 1", 0);
 277
 278    // Add typemap definitions
 279    SWIG_typemap_lang("java");
 280    SWIG_config_file("java.swg");
 281
 282    allow_overloading();
 283  }
 284
 285  /* ---------------------------------------------------------------------
 286   * top()
 287   * --------------------------------------------------------------------- */
 288
 289  virtual int top(Node *n) {
 290
 291    // Get any options set in the module directive
 292    Node *optionsnode = Getattr(Getattr(n, "module"), "options");
 293
 294    if (optionsnode) {
 295      if (Getattr(optionsnode, "jniclassname"))
 296	imclass_name = Copy(Getattr(optionsnode, "jniclassname"));
 297      /* check if directors are enabled for this module.  note: this 
 298       * is a "master" switch, without which no director code will be
 299       * emitted.  %feature("director") statements are also required
 300       * to enable directors for individual classes or methods.
 301       *
 302       * use %module(directors="1") modulename at the start of the 
 303       * interface file to enable director generation.
 304       */
 305      if (Getattr(optionsnode, "directors")) {
 306	allow_directors();
 307      }
 308      if (Getattr(optionsnode, "dirprot")) {
 309	allow_dirprot();
 310      }
 311      allow_allprotected(GetFlag(optionsnode, "allprotected"));
 312    }
 313
 314    /* Initialize all of the output files */
 315    String *outfile = Getattr(n, "outfile");
 316    String *outfile_h = Getattr(n, "outfile_h");
 317
 318    if (!outfile) {
 319      Printf(stderr, "Unable to determine outfile\n");
 320      SWIG_exit(EXIT_FAILURE);
 321    }
 322
 323    f_begin = NewFile(outfile, "w", SWIG_output_files());
 324    if (!f_begin) {
 325      FileErrorDisplay(outfile);
 326      SWIG_exit(EXIT_FAILURE);
 327    }
 328
 329    if (directorsEnabled()) {
 330      if (!outfile_h) {
 331        Printf(stderr, "Unable to determine outfile_h\n");
 332        SWIG_exit(EXIT_FAILURE);
 333      }
 334      f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
 335      if (!f_runtime_h) {
 336	FileErrorDisplay(outfile_h);
 337	SWIG_exit(EXIT_FAILURE);
 338      }
 339    }
 340
 341    f_runtime = NewString("");
 342    f_init = NewString("");
 343    f_header = NewString("");
 344    f_wrappers = NewString("");
 345    f_directors_h = NewString("");
 346    f_directors = NewString("");
 347
 348    /* Register file targets with the SWIG file handler */
 349    Swig_register_filebyname("begin", f_begin);
 350    Swig_register_filebyname("header", f_header);
 351    Swig_register_filebyname("wrapper", f_wrappers);
 352    Swig_register_filebyname("runtime", f_runtime);
 353    Swig_register_filebyname("init", f_init);
 354    Swig_register_filebyname("director", f_directors);
 355    Swig_register_filebyname("director_h", f_directors_h);
 356
 357    swig_types_hash = NewHash();
 358    filenames_list = NewList();
 359
 360    // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
 361    if (!imclass_name) {
 362      imclass_name = NewStringf("%sJNI", Getattr(n, "name"));
 363      module_class_name = Copy(Getattr(n, "name"));
 364    } else {
 365      // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
 366      if (Cmp(imclass_name, Getattr(n, "name")) == 0)
 367	module_class_name = NewStringf("%sModule", Getattr(n, "name"));
 368      else
 369	module_class_name = Copy(Getattr(n, "name"));
 370    }
 371    constants_interface_name = NewStringf("%sConstants", module_class_name);
 372
 373    // module class and intermediary classes are always created
 374    addSymbol(imclass_name, n);
 375    addSymbol(module_class_name, n);
 376
 377    imclass_class_code = NewString("");
 378    proxy_class_def = NewString("");
 379    proxy_class_code = NewString("");
 380    module_class_constants_code = NewString("");
 381    imclass_baseclass = NewString("");
 382    imclass_interfaces = NewString("");
 383    imclass_class_modifiers = NewString("");
 384    module_class_code = NewString("");
 385    module_baseclass = NewString("");
 386    module_interfaces = NewString("");
 387    module_imports = NewString("");
 388    module_class_modifiers = NewString("");
 389    imclass_imports = NewString("");
 390    imclass_cppcasts_code = NewString("");
 391    imclass_directors = NewString("");
 392    upcasts_code = NewString("");
 393    dmethods_seq = NewList();
 394    dmethods_table = NewHash();
 395    n_dmethods = 0;
 396    n_directors = 0;
 397    jnipackage = NewString("");
 398    package_path = NewString("");
 399
 400    Swig_banner(f_begin);
 401
 402    Printf(f_runtime, "\n#define SWIGJAVA\n");
 403
 404    if (directorsEnabled()) {
 405      Printf(f_runtime, "#define SWIG_DIRECTORS\n");
 406
 407      /* Emit initial director header and director code: */
 408      Swig_banner(f_directors_h);
 409      Printf(f_directors_h, "\n");
 410      Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name);
 411      Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name);
 412
 413      Printf(f_directors, "\n\n");
 414      Printf(f_directors, "/* ---------------------------------------------------\n");
 415      Printf(f_directors, " * C++ director class methods\n");
 416      Printf(f_directors, " * --------------------------------------------------- */\n\n");
 417      if (outfile_h)
 418	Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
 419    }
 420
 421    Printf(f_runtime, "\n");
 422
 423    String *wrapper_name = NewString("");
 424
 425    if (package) {
 426      String *jniname = makeValidJniName(package);
 427      Printv(jnipackage, jniname, NIL);
 428      Delete(jniname);
 429      Replaceall(jnipackage, ".", "_");
 430      Append(jnipackage, "_");
 431      Printv(package_path, package, NIL);
 432      Replaceall(package_path, ".", "/");
 433    }
 434    String *jniname = makeValidJniName(imclass_name);
 435    Printf(wrapper_name, "Java_%s%s_%%f", jnipackage, jniname);
 436    Delete(jniname);
 437
 438    Swig_name_register("wrapper", Char(wrapper_name));
 439    if (old_variable_names) {
 440      Swig_name_register("set", "set_%n%v");
 441      Swig_name_register("get", "get_%n%v");
 442    }
 443
 444    Delete(wrapper_name);
 445
 446    Printf(f_wrappers, "\n#ifdef __cplusplus\n");
 447    Printf(f_wrappers, "extern \"C\" {\n");
 448    Printf(f_wrappers, "#endif\n\n");
 449
 450    /* Emit code */
 451    Language::top(n);
 452
 453    if (directorsEnabled()) {
 454      // Insert director runtime into the f_runtime file (make it occur before %header section)
 455      Swig_insert_file("director.swg", f_runtime);
 456    }
 457    // Generate the intermediary class
 458    {
 459      String *filen = NewStringf("%s%s.java", SWIG_output_directory(), imclass_name);
 460      File *f_im = NewFile(filen, "w", SWIG_output_files());
 461      if (!f_im) {
 462	FileErrorDisplay(filen);
 463	SWIG_exit(EXIT_FAILURE);
 464      }
 465      Append(filenames_list, Copy(filen));
 466      Delete(filen);
 467      filen = NULL;
 468
 469      // Start writing out the intermediary class file
 470      emitBanner(f_im);
 471
 472      if (package)
 473	Printf(f_im, "package %s;\n", package);
 474
 475      if (imclass_imports)
 476	Printf(f_im, "%s\n", imclass_imports);
 477
 478      if (Len(imclass_class_modifiers) > 0)
 479	Printf(f_im, "%s ", imclass_class_modifiers);
 480      Printf(f_im, "%s ", imclass_name);
 481
 482      if (imclass_baseclass && *Char(imclass_baseclass))
 483	Printf(f_im, "extends %s ", imclass_baseclass);
 484      if (Len(imclass_interfaces) > 0)
 485	Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
 486      Printf(f_im, "{\n");
 487
 488      // Add the intermediary class methods
 489      Replaceall(imclass_class_code, "$module", module_class_name);
 490      Replaceall(imclass_class_code, "$imclassname", imclass_name);
 491      Printv(f_im, imclass_class_code, NIL);
 492      Printv(f_im, imclass_cppcasts_code, NIL);
 493      if (Len(imclass_directors) > 0)
 494	Printv(f_im, "\n", imclass_directors, NIL);
 495
 496      if (n_dmethods > 0) {
 497	Putc('\n', f_im);
 498	Printf(f_im, "  private final static native void swig_module_init();\n");
 499	Printf(f_im, "  static {\n");
 500	Printf(f_im, "    swig_module_init();\n");
 501	Printf(f_im, "  }\n");
 502      }
 503      // Finish off the class
 504      Printf(f_im, "}\n");
 505      Close(f_im);
 506    }
 507
 508    // Generate the Java module class
 509    {
 510      String *filen = NewStringf("%s%s.java", SWIG_output_directory(), module_class_name);
 511      File *f_module = NewFile(filen, "w", SWIG_output_files());
 512      if (!f_module) {
 513	FileErrorDisplay(filen);
 514	SWIG_exit(EXIT_FAILURE);
 515      }
 516      Append(filenames_list, Copy(filen));
 517      Delete(filen);
 518      filen = NULL;
 519
 520      // Start writing out the module class file
 521      emitBanner(f_module);
 522
 523      if (package)
 524	Printf(f_module, "package %s;\n", package);
 525
 526      if (module_imports)
 527	Printf(f_module, "%s\n", module_imports);
 528
 529      if (Len(module_class_modifiers) > 0)
 530	Printf(f_module, "%s ", module_class_modifiers);
 531      Printf(f_module, "%s ", module_class_name);
 532
 533      if (module_baseclass && *Char(module_baseclass))
 534	Printf(f_module, "extends %s ", module_baseclass);
 535      if (Len(module_interfaces) > 0) {
 536	if (Len(module_class_constants_code) != 0)
 537	  Printv(f_module, "implements ", constants_interface_name, ", ", module_interfaces, " ", NIL);
 538	else
 539	  Printv(f_module, "implements ", module_interfaces, " ", NIL);
 540      } else {
 541	if (Len(module_class_constants_code) != 0)
 542	  Printv(f_module, "implements ", constants_interface_name, " ", NIL);
 543      }
 544      Printf(f_module, "{\n");
 545
 546      Replaceall(module_class_code, "$module", module_class_name);
 547      Replaceall(module_class_constants_code, "$module", module_class_name);
 548
 549      Replaceall(module_class_code, "$imclassname", imclass_name);
 550      Replaceall(module_class_constants_code, "$imclassname", imclass_name);
 551
 552      // Add the wrapper methods
 553      Printv(f_module, module_class_code, NIL);
 554
 555      // Finish off the class
 556      Printf(f_module, "}\n");
 557      Close(f_module);
 558    }
 559
 560    // Generate the Java constants interface
 561    if (Len(module_class_constants_code) != 0) {
 562      String *filen = NewStringf("%s%s.java", SWIG_output_directory(), constants_interface_name);
 563      File *f_module = NewFile(filen, "w", SWIG_output_files());
 564      if (!f_module) {
 565	FileErrorDisplay(filen);
 566	SWIG_exit(EXIT_FAILURE);
 567      }
 568      Append(filenames_list, Copy(filen));
 569      Delete(filen);
 570      filen = NULL;
 571
 572      // Start writing out the Java constants interface file
 573      emitBanner(f_module);
 574
 575      if (package)
 576	Printf(f_module, "package %s;\n", package);
 577
 578      if (module_imports)
 579	Printf(f_module, "%s\n", module_imports);
 580
 581      Printf(f_module, "public interface %s {\n", constants_interface_name);
 582
 583      // Write out all the global constants
 584      Printv(f_module, module_class_constants_code, NIL);
 585
 586      // Finish off the Java interface
 587      Printf(f_module, "}\n");
 588      Close(f_module);
 589    }
 590
 591    if (upcasts_code)
 592      Printv(f_wrappers, upcasts_code, NIL);
 593
 594    emitDirectorUpcalls();
 595
 596    Printf(f_wrappers, "#ifdef __cplusplus\n");
 597    Printf(f_wrappers, "}\n");
 598    Printf(f_wrappers, "#endif\n");
 599
 600    // Output a Java type wrapper class for each SWIG type
 601    for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
 602      emitTypeWrapperClass(swig_type.key, swig_type.item);
 603    }
 604
 605    // Check for overwriting file problems on filesystems that are case insensitive
 606    Iterator it1;
 607    Iterator it2;
 608    for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) {
 609      String *item1_lower = Swig_string_lower(it1.item);
 610      for (it2 = Next(it1); it2.item; it2 = Next(it2)) {
 611	String *item2_lower = Swig_string_lower(it2.item);
 612	if (it1.item && it2.item) {
 613	  if (Strcmp(item1_lower, item2_lower) == 0) {
 614	    Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number,
 615			 "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as "
 616			 "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item);
 617	  }
 618	}
 619	Delete(item2_lower);
 620      }
 621      Delete(item1_lower);
 622    }
 623
 624    Delete(swig_types_hash);
 625    swig_types_hash = NULL;
 626    Delete(filenames_list);
 627    filenames_list = NULL;
 628    Delete(imclass_name);
 629    imclass_name = NULL;
 630    Delete(imclass_class_code);
 631    imclass_class_code = NULL;
 632    Delete(proxy_class_def);
 633    proxy_class_def = NULL;
 634    Delete(proxy_class_code);
 635    proxy_class_code = NULL;
 636    Delete(module_class_constants_code);
 637    module_class_constants_code = NULL;
 638    Delete(imclass_baseclass);
 639    imclass_baseclass = NULL;
 640    Delete(imclass_interfaces);
 641    imclass_interfaces = NULL;
 642    Delete(imclass_class_modifiers);
 643    imclass_class_modifiers = NULL;
 644    Delete(module_class_name);
 645    module_class_name = NULL;
 646    Delete(constants_interface_name);
 647    constants_interface_name = NULL;
 648    Delete(module_class_code);
 649    module_class_code = NULL;
 650    Delete(module_baseclass);
 651    module_baseclass = NULL;
 652    Delete(module_interfaces);
 653    module_interfaces = NULL;
 654    Delete(module_imports);
 655    module_imports = NULL;
 656    Delete(module_class_modifiers);
 657    module_class_modifiers = NULL;
 658    Delete(imclass_imports);
 659    imclass_imports = NULL;
 660    Delete(imclass_cppcasts_code);
 661    imclass_cppcasts_code = NULL;
 662    Delete(imclass_directors);
 663    imclass_directors = NULL;
 664    Delete(upcasts_code);
 665    upcasts_code = NULL;
 666    Delete(package);
 667    package = NULL;
 668    Delete(jnipackage);
 669    jnipackage = NULL;
 670    Delete(package_path);
 671    package_path = NULL;
 672    Delete(dmethods_seq);
 673    dmethods_seq = NULL;
 674    Delete(dmethods_table);
 675    dmethods_table = NULL;
 676    n_dmethods = 0;
 677
 678    /* Close all of the files */
 679    Dump(f_header, f_runtime);
 680
 681    if (directorsEnabled()) {
 682      Dump(f_directors, f_runtime);
 683      Dump(f_directors_h, f_runtime_h);
 684
 685      Printf(f_runtime_h, "\n");
 686      Printf(f_runtime_h, "#endif\n");
 687
 688      Close(f_runtime_h);
 689      Delete(f_runtime_h);
 690      f_runtime_h = NULL;
 691      Delete(f_directors);
 692      f_directors = NULL;
 693      Delete(f_directors_h);
 694      f_directors_h = NULL;
 695    }
 696
 697    Dump(f_wrappers, f_runtime);
 698    Wrapper_pretty_print(f_init, f_runtime);
 699    Delete(f_header);
 700    Delete(f_wrappers);
 701    Delete(f_init);
 702    Dump(f_runtime, f_begin);
 703    Delete(f_runtime);
 704    Close(f_begin);
 705    Delete(f_begin);
 706    return SWIG_OK;
 707  }
 708
 709  /* -----------------------------------------------------------------------------
 710   * emitBanner()
 711   * ----------------------------------------------------------------------------- */
 712
 713  void emitBanner(File *f) {
 714    Printf(f, "/* ----------------------------------------------------------------------------\n");
 715    Swig_banner_target_lang(f, " *");
 716    Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
 717  }
 718
 719  /*-----------------------------------------------------------------------
 720   * Add new director upcall signature
 721   *----------------------------------------------------------------------*/
 722
 723  UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *imclass_desc, String *class_desc, String *decl) {
 724    UpcallData *udata;
 725    String *imclass_methodidx;
 726    String *class_methodidx;
 727    Hash *new_udata;
 728    String *key = NewStringf("%s|%s", imclass_method, decl);
 729
 730    ++curr_class_dmethod;
 731
 732    /* Do we know about this director class already? */
 733    if ((udata = Getattr(dmethods_table, key))) {
 734      Delete(key);
 735      return Getattr(udata, "methodoff");
 736    }
 737
 738    imclass_methodidx = NewStringf("%d", n_dmethods);
 739    class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod);
 740    n_dmethods++;
 741
 742    new_udata = NewHash();
 743    Append(dmethods_seq, new_udata);
 744    Setattr(dmethods_table, key, new_udata);
 745
 746    Setattr(new_udata, "method", Copy(class_method));
 747    Setattr(new_udata, "fdesc", Copy(class_desc));
 748    Setattr(new_udata, "imclass_method", Copy(imclass_method));
 749    Setattr(new_udata, "imclass_fdesc", Copy(imclass_desc));
 750    Setattr(new_udata, "imclass_methodidx", imclass_methodidx);
 751    Setattr(new_udata, "class_methodidx", class_methodidx);
 752    Setattr(new_udata, "decl", Copy(decl));
 753
 754    Delete(key);
 755    return new_udata;
 756  }
 757
 758  /*-----------------------------------------------------------------------
 759   * Get director upcall signature
 760   *----------------------------------------------------------------------*/
 761
 762  UpcallData *getUpcallMethodData(String *director_class, String *decl) {
 763    String *key = NewStringf("%s|%s", director_class, decl);
 764    UpcallData *udata = Getattr(dmethods_table, key);
 765
 766    Delete(key);
 767    return udata;
 768  }
 769
 770  /* ----------------------------------------------------------------------
 771   * nativeWrapper()
 772   * ---------------------------------------------------------------------- */
 773
 774  virtual int nativeWrapper(Node *n) {
 775    String *wrapname = Getattr(n, "wrap:name");
 776
 777    if (!addSymbol(wrapname, n, imclass_name))
 778      return SWIG_ERROR;
 779
 780    if (Getattr(n, "type")) {
 781      Swig_save("nativeWrapper", n, "name", NIL);
 782      Setattr(n, "name", wrapname);
 783      native_function_flag = true;
 784      functionWrapper(n);
 785      Swig_restore(n);
 786      native_function_flag = false;
 787    } else {
 788      Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name"));
 789    }
 790
 791    return SWIG_OK;
 792  }
 793
 794  /* ----------------------------------------------------------------------
 795   * functionWrapper()
 796   * ---------------------------------------------------------------------- */
 797
 798  virtual int functionWrapper(Node *n) {
 799    String *symname = Getattr(n, "sym:name");
 800    SwigType *t = Getattr(n, "type");
 801    ParmList *l = Getattr(n, "parms");
 802    String *tm;
 803    Parm *p;
 804    int i;
 805    String *c_return_type = NewString("");
 806    String *im_return_type = NewString("");
 807    String *cleanup = NewString("");
 808    String *outarg = NewString("");
 809    String *body = NewString("");
 810    int num_arguments = 0;
 811    int gencomma = 0;
 812    bool is_void_return;
 813    String *overloaded_name = getOverloadedName(n);
 814    String *nondir_args = NewString("");
 815    bool is_destructor = (Cmp(Getattr(n, "nodeType"), "destructor") == 0);
 816
 817    if (!Getattr(n, "sym:overloaded")) {
 818      if (!addSymbol(Getattr(n, "sym:name"), n, imclass_name))
 819	return SWIG_ERROR;
 820    }
 821
 822    /*
 823       The rest of this function deals with generating the intermediary class wrapper function (that wraps
 824       a c/c++ function) and generating the JNI c code. Each Java wrapper function has a 
 825       matching JNI c function call.
 826     */
 827
 828    // A new wrapper function object
 829    Wrapper *f = NewWrapper();
 830
 831    // Make a wrapper name for this function
 832    String *jniname = makeValidJniName(overloaded_name);
 833    String *wname = Swig_name_wrapper(jniname);
 834
 835    Delete(jniname);
 836
 837    /* Attach the non-standard typemaps to the parameter list. */
 838    Swig_typemap_attach_parms("jni", l, f);
 839    Swig_typemap_attach_parms("jtype", l, f);
 840    Swig_typemap_attach_parms("jstype", l, f);
 841
 842    /* Get return types */
 843    if ((tm = Swig_typemap_lookup("jni", n, "", 0))) {
 844      Printf(c_return_type, "%s", tm);
 845    } else {
 846      Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(t, 0));
 847    }
 848
 849    if ((tm = Swig_typemap_lookup("jtype", n, "", 0))) {
 850      Printf(im_return_type, "%s", tm);
 851    } else {
 852      Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(t, 0));
 853    }
 854
 855    is_void_return = (Cmp(c_return_type, "void") == 0);
 856    if (!is_void_return)
 857      Wrapper_add_localv(f, "jresult", c_return_type, "jresult = 0", NIL);
 858
 859    Printv(f->def, "SWIGEXPORT ", c_return_type, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", NIL);
 860
 861    // Usually these function parameters are unused - The code below ensures
 862    // that compilers do not issue such a warning if configured to do so.
 863
 864    Printv(f->code, "    (void)jenv;\n", NIL);
 865    Printv(f->code, "    (void)jcls;\n", NIL);
 866
 867    // Emit all of the local variables for holding arguments.
 868    emit_parameter_variables(l, f);
 869
 870    /* Attach the standard typemaps */
 871    emit_attach_parmmaps(l, f);
 872
 873    // Parameter overloading
 874    Setattr(n, "wrap:parms", l);
 875    Setattr(n, "wrap:name", wname);
 876
 877    // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
 878    if (Getattr(n, "sym:overloaded")) {
 879      // Emit warnings for the few cases that can't be overloaded in Java and give up on generating wrapper
 880      Swig_overload_check(n);
 881      if (Getattr(n, "overload:ignore"))
 882	return SWIG_OK;
 883    }
 884
 885    Printf(imclass_class_code, "  public final static native %s %s(", im_return_type, overloaded_name);
 886
 887    num_arguments = emit_num_arguments(l);
 888
 889    // Now walk the function parameter list and generate code to get arguments
 890    for (i = 0, p = l; i < num_arguments; i++) {
 891
 892      while (checkAttribute(p, "tmap:in:numinputs", "0")) {
 893	p = Getattr(p, "tmap:in:next");
 894      }
 895
 896      SwigType *pt = Getattr(p, "type");
 897      String *ln = Getattr(p, "lname");
 898      String *im_param_type = NewString("");
 899      String *c_param_type = NewString("");
 900      String *arg = NewString("");
 901
 902      Printf(arg, "j%s", ln);
 903
 904      /* Get the JNI C types of the parameter */
 905      if ((tm = Getattr(p, "tmap:jni"))) {
 906	Printv(c_param_type, tm, NIL);
 907      } else {
 908	Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(pt, 0));
 909      }
 910
 911      /* Get the intermediary class parameter types of the parameter */
 912      if ((tm = Getattr(p, "tmap:jtype"))) {
 913	Printv(im_param_type, tm, NIL);
 914      } else {
 915	Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(pt, 0));
 916      }
 917
 918      /* Add parameter to intermediary class method */
 919      if (gencomma)
 920	Printf(imclass_class_code, ", ");
 921      Printf(imclass_class_code, "%s %s", im_param_type, arg);
 922
 923      // Add parameter to C function
 924      Printv(f->def, ", ", c_param_type, " ", arg, NIL);
 925
 926      ++gencomma;
 927
 928      // Premature garbage collection prevention parameter
 929      if (!is_destructor) {
 930	String *pgc_parameter = prematureGarbageCollectionPreventionParameter(pt, p);
 931	if (pgc_parameter) {
 932	  Printf(imclass_class_code, ", %s %s_", pgc_parameter, arg);
 933	  Printf(f->def, ", jobject %s_", arg);
 934	  Printf(f->code, "    (void)%s_;\n", arg);
 935	}
 936      }
 937      // Get typemap for this argument
 938      if ((tm = Getattr(p, "tmap:in"))) {
 939	addThrows(n, "tmap:in", p);
 940	Replaceall(tm, "$source", arg);	/* deprecated */
 941	Replaceall(tm, "$target", ln);	/* deprecated */
 942	Replaceall(tm, "$arg", arg);	/* deprecated? */
 943	Replaceall(tm, "$input", arg);
 944	Setattr(p, "emit:input", arg);
 945
 946	Printf(nondir_args, "%s\n", tm);
 947
 948	p = Getattr(p, "tmap:in:next");
 949      } else {
 950	Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
 951	p = nextSibling(p);
 952      }
 953
 954      Delete(im_param_type);
 955      Delete(c_param_type);
 956      Delete(arg);
 957    }
 958
 959    Printv(f->code, nondir_args, NIL);
 960    Delete(nondir_args);
 961
 962    /* Insert constraint checking code */
 963    for (p = l; p;) {
 964      if ((tm = Getattr(p, "tmap:check"))) {
 965	addThrows(n, "tmap:check", p);
 966	Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
 967	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 968	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 969	Printv(f->code, tm, "\n", NIL);
 970	p = Getattr(p, "tmap:check:next");
 971      } else {
 972	p = nextSibling(p);
 973      }
 974    }
 975
 976    /* Insert cleanup code */
 977    for (p = l; p;) {
 978      if ((tm = Getattr(p, "tmap:freearg"))) {
 979	addThrows(n, "tmap:freearg", p);
 980	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
 981	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 982	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 983	Printv(cleanup, tm, "\n", NIL);
 984	p = Getattr(p, "tmap:freearg:next");
 985      } else {
 986	p = nextSibling(p);
 987      }
 988    }
 989
 990    /* Insert argument output code */
 991    for (p = l; p;) {
 992      if ((tm = Getattr(p, "tmap:argout"))) {
 993	addThrows(n, "tmap:argout", p);
 994	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
 995	Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
 996	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 997	Replaceall(tm, "$result", "jresult");
 998	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 999	Printv(outarg, tm, "\n", NIL);
1000	p = Getattr(p, "tmap:argout:next");
1001      } else {
1002	p = nextSibling(p);
1003      }
1004    }
1005
1006    // Get any Java exception classes in the throws typemap
1007    ParmList *throw_parm_list = NULL;
1008    if ((throw_parm_list = Getattr(n, "catchlist"))) {
1009      Swig_typemap_attach_parms("throws", throw_parm_list, f);
1010      for (p = throw_parm_list; p; p = nextSibling(p)) {
1011	if ((tm = Getattr(p, "tmap:throws"))) {
1012	  addThrows(n, "tmap:throws", p);
1013	}
1014      }
1015    }
1016
1017    if (!native_function_flag) {
1018      if (Cmp(nodeType(n), "constant") == 0) {
1019        // Wrapping a constant hack
1020        Swig_save("functionWrapper", n, "wrap:action", NIL);
1021
1022        // below based on Swig_VargetToFunction()
1023        SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
1024        Setattr(n, "wrap:action", NewStringf("%s = (%s)(%s);", Swig_cresult_name(), SwigType_lstr(ty, 0), Getattr(n, "value")));
1025      }
1026
1027      // Now write code to make the function call
1028      Swig_director_emit_dynamic_cast(n, f);
1029      String *actioncode = emit_action(n);
1030
1031      // Handle exception classes specified in the "except" feature's "throws" attribute
1032      addThrows(n, "feature:except", n);
1033
1034      if (Cmp(nodeType(n), "constant") == 0)
1035        Swig_restore(n);
1036
1037      /* Return value if necessary  */
1038      if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
1039	addThrows(n, "tmap:out", n);
1040	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
1041	Replaceall(tm, "$target", "jresult");	/* deprecated */
1042	Replaceall(tm, "$result", "jresult");
1043
1044        if (GetFlag(n, "feature:new"))
1045          Replaceall(tm, "$owner", "1");
1046        else
1047          Replaceall(tm, "$owner", "0");
1048
1049	Printf(f->code, "%s", tm);
1050	if (Len(tm))
1051	  Printf(f->code, "\n");
1052      } else {
1053	Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
1054      }
1055      emit_return_variable(n, t, f);
1056    }
1057
1058    /* Output argument output code */
1059    Printv(f->code, outarg, NIL);
1060
1061    /* Output cleanup code */
1062    Printv(f->code, cleanup, NIL);
1063
1064    /* Look to see if there is any newfree cleanup code */
1065    if (GetFlag(n, "feature:new")) {
1066      if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
1067	addThrows(n, "tmap:newfree", n);
1068	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
1069	Printf(f->code, "%s\n", tm);
1070      }
1071    }
1072
1073    /* See if there is any return cleanup code */
1074    if (!native_function_flag) {
1075      if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
1076	addThrows(n, "tmap:ret", n);
1077	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
1078	Printf(f->code, "%s\n", tm);
1079      }
1080    }
1081
1082    /* Finish C function and intermediary class function definitions */
1083    Printf(imclass_class_code, ")");
1084    generateThrowsClause(n, imclass_class_code);
1085    Printf(imclass_class_code, ";\n");
1086
1087    Printf(f->def, ") {");
1088
1089    if (!is_void_return)
1090      Printv(f->code, "    return jresult;\n", NIL);
1091    Printf(f->code, "}\n");
1092
1093    /* Substitute the cleanup code */
1094    Replaceall(f->code, "$cleanup", cleanup);
1095
1096    /* Substitute the function name */
1097    Replaceall(f->code, "$symname", symname);
1098
1099    /* Contract macro modification */
1100    Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ");
1101
1102    if (!is_void_return)
1103      Replaceall(f->code, "$null", "0");
1104    else
1105      Replaceall(f->code, "$null", "");
1106
1107    /* Dump the function out */
1108    if (!native_function_flag)
1109      Wrapper_print(f, f_wrappers);
1110
1111    if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
1112      moduleClassFunctionHandler(n);
1113    }
1114
1115    /* 
1116     * Generate the proxy class getters/setters for public member variables.
1117     * Not for enums and constants.
1118     */
1119    if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
1120      // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
1121      bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0;
1122
1123      String *getter_setter_name = NewString("");
1124      if (!getter_flag)
1125	Printf(getter_setter_name, "set");
1126      else
1127	Printf(getter_setter_name, "get");
1128      Putc(toupper((int) *Char(variable_name)), getter_setter_name);
1129      Printf(getter_setter_name, "%s", Char(variable_name) + 1);
1130
1131      Setattr(n, "proxyfuncname", getter_setter_name);
1132      Setattr(n, "imfuncname", symname);
1133
1134      proxyClassFunctionHandler(n);
1135      Delete(getter_setter_name);
1136    }
1137
1138    Delete(c_return_type);
1139    Delete(im_return_type);
1140    Delete(cleanup);
1141    Delete(outarg);
1142    Delete(body);
1143    Delete(overloaded_name);
1144    DelWrapper(f);
1145    return SWIG_OK;
1146  }
1147
1148  /* -----------------------------------------------------------------------
1149   * variableWrapper()
1150   * ----------------------------------------------------------------------- */
1151
1152  virtual int variableWrapper(Node *n) {
1153    variable_wrapper_flag = true;
1154    Language::variableWrapper(n);	/* Default to functions */
1155    variable_wrapper_flag = false;
1156    return SWIG_OK;
1157  }
1158
1159  /* -----------------------------------------------------------------------
1160   * globalvariableHandler()
1161   * ------------------------------------------------------------------------ */
1162
1163  virtual int globalvariableHandler(Node *n) {
1164
1165    variable_name = Getattr(n, "sym:name");
1166    global_variable_flag = true;
1167    int ret = Language::globalvariableHandler(n);
1168    global_variable_flag = false;
1169    return ret;
1170  }
1171
1172  /* ----------------------------------------------------------------------
1173   * enumDeclaration()
1174   *
1175   * C/C++ enums can be mapped in one of 4 ways, depending on the java:enum feature specified:
1176   * 1) Simple enums - simple constant within the proxy class or module class
1177   * 2) Typeunsafe enums - simple constant in a Java class (class named after the c++ enum name)
1178   * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
1179   * 4) Proper enums - proper Java enum
1180   * Anonymous enums always default to 1)
1181   * ---------------------------------------------------------------------- */
1182
1183  virtual int enumDeclaration(Node *n) {
1184
1185    if (!ImportMode) {
1186      if (getCurrentClass() && (cplus_mode != PUBLIC))
1187	return SWIG_NOWRAP;
1188
1189      String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
1190      if (proxy_flag && !is_wrapping_class()) {
1191	// Global enums / enums in a namespace
1192	assert(!full_imclass_name);
1193
1194	if (!nspace) {
1195	  full_imclass_name = NewStringf("%s", imclass_name);
1196	} else {
1197	  if (package) {
1198	    full_imclass_name = NewStringf("%s.%s", package, imclass_name);
1199	  } else {
1200	    String *name = Getattr(n, "name") ? Getattr(n, "name") : NewString("<unnamed>");
1201	    Swig_error(Getfile(n), Getline(n), "The nspace feature used on '%s' is not supported unless a package is specified with -package - Java does not support types declared in a named package accessing types declared in an unnamed package.\n", name);
1202	    SWIG_exit(EXIT_FAILURE);
1203	  }
1204	}
1205      }
1206
1207      enum_code = NewString("");
1208      String *symname = Getattr(n, "sym:name");
1209      String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
1210      EnumFeature enum_feature = decodeEnumFeature(n);
1211      String *typemap_lookup_type = Getattr(n, "name");
1212
1213      if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
1214	// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
1215
1216	String *scope = 0;
1217	if (nspace || proxy_class_name) {
1218	  scope = NewString("");
1219	  if (nspace)
1220	    Printf(scope, "%s", nspace);
1221	  if (proxy_class_name)
1222	    Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
1223	}
1224	if (!addSymbol(symname, n, scope))
1225	  return SWIG_ERROR;
1226
1227	// Pure Java baseclass and interfaces
1228	const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE);
1229	const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
1230
1231	// Emit the enum
1232	Printv(enum_code, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF),	// Class modifiers (enum modifiers really)
1233	       " ", symname, *Char(pure_baseclass) ?	// Bases
1234	       " extends " : "", pure_baseclass, *Char(pure_interfaces) ?	// Interfaces
1235	       " implements " : "", pure_interfaces, " {\n", NIL);
1236	if (proxy_flag && is_wrapping_class())
1237	  Replaceall(enum_code, "$static ", "static ");
1238	else
1239	  Replaceall(enum_code, "$static ", "");
1240	Delete(scope);
1241      } else {
1242	// Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
1243	if (symname && !Getattr(n, "unnamedinstance"))
1244	  Printf(constants_code, "  // %s \n", symname);
1245      }
1246
1247      // Emit each enum item
1248      Language::enumDeclaration(n);
1249
1250      if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
1251	// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
1252	// Finish the enum declaration
1253	// Typemaps are used to generate the enum definition in a similar manner to proxy classes.
1254	Printv(enum_code, (enum_feature == ProperEnum) ? ";\n" : "", typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF),	// main body of class
1255	       typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE),	// extra Java code
1256	       "}", NIL);
1257
1258	Replaceall(enum_code, "$javaclassname", symname);
1259
1260	// Substitute $enumvalues - intended usage is for typesafe enums
1261	if (Getattr(n, "enumvalues"))
1262	  Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues"));
1263	else
1264	  Replaceall(enum_code, "$enumvalues", "");
1265
1266	if (proxy_flag && is_wrapping_class()) {
1267	  // Enums defined within the C++ class are defined within the proxy class
1268
1269	  // Add extra indentation
1270	  Replaceall(enum_code, "\n", "\n  ");
1271	  Replaceall(enum_code, "  \n", "\n");
1272
1273	  Printv(proxy_class_constants_code, "  ", enum_code, "\n\n", NIL);
1274	} else {
1275	  // Global enums are defined in their own file
1276	  String *output_directory = outputDirectory(nspace);
1277	  String *filen = NewStringf("%s%s.java", output_directory, symname);
1278	  File *f_enum = NewFile(filen, "w", SWIG_output_files());
1279	  if (!f_enum) {
1280	    FileErrorDisplay(filen);
1281	    SWIG_exit(EXIT_FAILURE);
1282	  }
1283	  Append(filenames_list, Copy(filen));
1284	  Delete(filen);
1285	  filen = NULL;
1286
1287	  // Start writing out the enum file
1288	  emitBanner(f_enum);
1289
1290	  if (package || nspace) {
1291	    Printf(f_enum, "package ");
1292	    if (package)
1293	      Printv(f_enum, package, nspace ? "." : "", NIL);
1294	    if (nspace)
1295	      Printv(f_enum, nspace, NIL);
1296	    Printf(f_enum, ";\n");
1297	  }
1298
1299	  Printv(f_enum, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
1300		 "\n", enum_code, "\n", NIL);
1301
1302	  Printf(f_enum, "\n");
1303	  Close(f_enum);
1304	  Delete(output_directory);
1305	}
1306      } else {
1307	// Wrap C++ enum with simple constant
1308	Printf(enum_code, "\n");
1309	if (proxy_flag && is_wrapping_class())
1310	  Printv(proxy_class_constants_code, enum_code, NIL);
1311	else
1312	  Printv(module_class_constants_code, enum_code, NIL);
1313      }
1314
1315      Delete(enum_code);
1316      enum_code = NULL;
1317
1318      if (proxy_flag && !is_wrapping_class()) {
1319	Delete(full_imclass_name);
1320	full_imclass_name = 0;
1321      }
1322    }
1323    return SWIG_OK;
1324  }
1325
1326  /* ----------------------------------------------------------------------
1327   * enumvalueDeclaration()
1328   * ---------------------------------------------------------------------- */
1329
1330  virtual int enumvalueDeclaration(Node *n) {
1331    if (getCurrentClass() && (cplus_mode != PUBLIC))
1332      return SWIG_NOWRAP;
1333
1334    Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
1335    String *symname = Getattr(n, "sym:name");
1336    String *value = Getattr(n, "value");
1337    String *name = Getattr(n, "name");
1338    Node *parent = parentNode(n);
1339    int unnamedinstance = GetFlag(parent, "unnamedinstance");
1340    String *parent_name = Getattr(parent, "name");
1341    String *nspace = getNSpace();
1342    String *tmpValue;
1343
1344    // Strange hack from parent method
1345    if (value)
1346      tmpValue = NewString(value);
1347    else
1348      tmpValue = NewString(name);
1349    // Note that this is used in enumValue() amongst other places
1350    Setattr(n, "value", tmpValue);
1351
1352    // Deal with enum values that are not int
1353    int swigtype = SwigType_type(Getattr(n, "type"));
1354    if (swigtype == T_BOOL) {
1355      const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
1356      Setattr(n, "enumvalue", val);
1357    } else if (swigtype == T_CHAR) {
1358      String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
1359      Setattr(n, "enumvalue", val);
1360      Delete(val);
1361    }
1362
1363    {
1364      EnumFeature enum_feature = decodeEnumFeature(parent);
1365
1366      // Add to language symbol table
1367      String *scope = 0;
1368      if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) {
1369	if (proxy_class_name) {
1370	  scope = NewString("");
1371	  if (nspace)
1372	    Printf(scope, "%s.", nspace);
1373	  Printf(scope, "%s", proxy_class_name);
1374	} else {
1375	  scope = Copy(constants_interface_name);
1376	}
1377      } else {
1378	scope = NewString("");
1379	if (nspace)
1380	  Printf(scope, "%s.", nspace);
1381	if (proxy_class_name)
1382	  Printf(scope, "%s.", proxy_class_name);
1383	Printf(scope, "%s",Getattr(parent, "sym:name"));
1384      }
1385      if (!addSymbol(name, n, scope))
1386	return SWIG_ERROR;
1387
1388      if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
1389	// Wrap (non-anonymous) C/C++ enum with a proper Java enum
1390	// Emit the enum item.
1391	if (!GetFlag(n, "firstenumitem"))
1392	  Printf(enum_code, ",\n");
1393	Printf(enum_code, "  %s", symname);
1394	if (Getattr(n, "enumvalue")) {
1395	  String *value = enumValue(n);
1396	  Printf(enum_code, "(%s)", value);
1397	  Delete(value);
1398	}
1399      } else {
1400	// Wrap C/C++ enums with constant integers or use the typesafe enum pattern
1401	SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
1402	Setattr(n, "type", typemap_lookup_type);
1403	const String *tm = typemapLookup(n, "jstype", typemap_lookup_type, WARN_JAVA_TYPEMAP_JSTYPE_UNDEF);
1404
1405	String *return_type = Copy(tm);
1406	substituteClassname(typemap_lookup_type, return_type);
1407        const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
1408        methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
1409
1410	if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) {
1411	  // Wrap (non-anonymous) enum using the typesafe enum pattern
1412	  if (Getattr(n, "enumvalue")) {
1413	    String *value = enumValue(n);
1414	    Printf(enum_code, "  %s final static %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value);
1415	    Delete(value);
1416	  } else {
1417	    Printf(enum_code, "  %s final static %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname);
1418	  }
1419	} else {
1420	  // Simple integer constants
1421	  // Note these are always generated for anonymous enums, no matter what enum_feature is specified
1422	  // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
1423	  String *value = enumValue(n);
1424	  Printf(enum_code, "  %s final static %s %s = %s;\n", methodmods, return_type, symname, value);
1425	  Delete(value);
1426	}
1427	Delete(return_type);
1428      }
1429
1430      // Add the enum value to the comma separated list being constructed in the enum declaration.
1431      String *enumvalues = Getattr(parent, "enumvalues");
1432      if (!enumvalues)
1433	Setattr(parent, "enumvalues", Copy(symname));
1434      else
1435	Printv(enumvalues, ", ", symname, NIL);
1436      Delete(scope);
1437    }
1438
1439    Delete(tmpValue);
1440    Swig_restore(n);
1441    return SWIG_OK;
1442  }
1443
1444  /* -----------------------…

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