/tags/Root-branch-php-utl/SWIG/Source/Modules/java.cxx

# · C++ · 1722 lines · 1227 code · 257 blank · 238 comment · 313 complexity · cbe6a34f208bc5466d9c7f7a53d895e9 MD5 · raw file

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