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