PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/Source/Modules/pike.cxx

https://github.com/sunaku/swig-ruby-ffi
C++ | 903 lines | 562 code | 154 blank | 187 comment | 96 complexity | 2d6072c253491ffdc2456ad5292fcb8e MD5 | raw file
Possible License(s): 0BSD, GPL-2.0, LGPL-2.1
  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. * pike.cxx
  6. *
  7. * Pike language module for SWIG.
  8. * ----------------------------------------------------------------------------- */
  9. /*
  10. * Notes:
  11. *
  12. * - The current approach used for "out" typemaps is inconsistent with
  13. * how "out" typemaps are handled by other language modules. Instead
  14. * of converting the C/C++ type ($1) to a Pike object type (e.g. a
  15. * struct svalue), we're just calling the appropriate push_XXX
  16. * (e.g. push_int) to push the return value onto the stack.
  17. *
  18. * - Pike classes can't have static member functions or data, so we need
  19. * to find some other appropriate mapping for C++ static member functions
  20. * and data.
  21. *
  22. * - Pike doesn't seem to provide any default way to print the memory
  23. * address, etc. for extension objects. Should we do something here?
  24. *
  25. */
  26. char cvsroot_pike_cxx[] = "$Id$";
  27. #include "swigmod.h"
  28. #include <ctype.h> // for isalnum()
  29. static const char *usage = (char *) "\
  30. Pike Options (available with -pike)\n\
  31. [None]\n\
  32. \n";
  33. class PIKE:public Language {
  34. private:
  35. File *f_begin;
  36. File *f_runtime;
  37. File *f_header;
  38. File *f_wrappers;
  39. File *f_init;
  40. File *f_classInit;
  41. String *PrefixPlusUnderscore;
  42. int current;
  43. // Wrap modes
  44. enum {
  45. NO_CPP,
  46. MEMBER_FUNC,
  47. CONSTRUCTOR,
  48. DESTRUCTOR,
  49. MEMBER_VAR,
  50. CLASS_CONST,
  51. STATIC_FUNC,
  52. STATIC_VAR
  53. };
  54. public:
  55. /* ---------------------------------------------------------------------
  56. * PIKE()
  57. *
  58. * Initialize member data
  59. * --------------------------------------------------------------------- */
  60. PIKE() {
  61. f_begin = 0;
  62. f_runtime = 0;
  63. f_header = 0;
  64. f_wrappers = 0;
  65. f_init = 0;
  66. f_classInit = 0;
  67. PrefixPlusUnderscore = 0;
  68. current = NO_CPP;
  69. }
  70. /* ---------------------------------------------------------------------
  71. * main()
  72. *
  73. * Parse command line options and initializes variables.
  74. * --------------------------------------------------------------------- */
  75. virtual void main(int argc, char *argv[]) {
  76. /* Set location of SWIG library */
  77. SWIG_library_directory("pike");
  78. /* Look for certain command line options */
  79. for (int i = 1; i < argc; i++) {
  80. if (argv[i]) {
  81. if (strcmp(argv[i], "-help") == 0) {
  82. fputs(usage, stdout);
  83. }
  84. }
  85. }
  86. /* Add a symbol to the parser for conditional compilation */
  87. Preprocessor_define("SWIGPIKE 1", 0);
  88. /* Set language-specific configuration file */
  89. SWIG_config_file("pike.swg");
  90. /* Set typemap language */
  91. SWIG_typemap_lang("pike");
  92. /* Enable overloaded methods support */
  93. allow_overloading();
  94. }
  95. /* ---------------------------------------------------------------------
  96. * top()
  97. * --------------------------------------------------------------------- */
  98. virtual int top(Node *n) {
  99. /* Get the module name */
  100. String *module = Getattr(n, "name");
  101. /* Get the output file name */
  102. String *outfile = Getattr(n, "outfile");
  103. /* Open the output file */
  104. f_begin = NewFile(outfile, "w", SWIG_output_files());
  105. if (!f_begin) {
  106. FileErrorDisplay(outfile);
  107. SWIG_exit(EXIT_FAILURE);
  108. }
  109. f_runtime = NewString("");
  110. f_init = NewString("");
  111. f_classInit = NewString("");
  112. f_header = NewString("");
  113. f_wrappers = NewString("");
  114. /* Register file targets with the SWIG file handler */
  115. Swig_register_filebyname("header", f_header);
  116. Swig_register_filebyname("wrapper", f_wrappers);
  117. Swig_register_filebyname("begin", f_begin);
  118. Swig_register_filebyname("runtime", f_runtime);
  119. Swig_register_filebyname("init", f_init);
  120. Swig_register_filebyname("classInit", f_classInit);
  121. /* Standard stuff for the SWIG runtime section */
  122. Swig_banner(f_begin);
  123. Printf(f_runtime, "\n");
  124. Printf(f_runtime, "#define SWIGPIKE\n");
  125. Printf(f_runtime, "\n");
  126. Printf(f_header, "#define SWIG_init pike_module_init\n");
  127. Printf(f_header, "#define SWIG_name \"%s\"\n\n", module);
  128. /* Change naming scheme for constructors and destructors */
  129. Swig_name_register("construct", "%c_create");
  130. Swig_name_register("destroy", "%c_destroy");
  131. /* Current wrap type */
  132. current = NO_CPP;
  133. /* Emit code for children */
  134. Language::top(n);
  135. /* Close the initialization function */
  136. Printf(f_init, "}\n");
  137. SwigType_emit_type_table(f_runtime, f_wrappers);
  138. /* Close all of the files */
  139. Dump(f_runtime, f_begin);
  140. Dump(f_header, f_begin);
  141. Dump(f_wrappers, f_begin);
  142. Wrapper_pretty_print(f_init, f_begin);
  143. Delete(f_header);
  144. Delete(f_wrappers);
  145. Delete(f_init);
  146. Delete(f_classInit);
  147. Close(f_begin);
  148. Delete(f_runtime);
  149. Delete(f_begin);
  150. /* Done */
  151. return SWIG_OK;
  152. }
  153. /* ------------------------------------------------------------
  154. * validIdentifier()
  155. * ------------------------------------------------------------ */
  156. virtual int validIdentifier(String *s) {
  157. char *c = Char(s);
  158. const char *c0 = c;
  159. const char *c1 = c0 + 1;
  160. while (*c) {
  161. if (*c == '`' && c == c0) {
  162. c++;
  163. continue;
  164. }
  165. if ((*c == '+' || *c == '-' || *c == '*' || *c == '/') && c == c1) {
  166. c++;
  167. continue;
  168. }
  169. if (!(isalnum(*c) || (*c == '_')))
  170. return 0;
  171. c++;
  172. }
  173. return 1;
  174. }
  175. /* ------------------------------------------------------------
  176. * importDirective()
  177. * ------------------------------------------------------------ */
  178. virtual int importDirective(Node *n) {
  179. String *modname = Getattr(n, "module");
  180. if (modname) {
  181. Printf(f_init, "pike_require(\"%s\");\n", modname);
  182. }
  183. return Language::importDirective(n);
  184. }
  185. /* ------------------------------------------------------------
  186. * strip()
  187. *
  188. * For names that begin with the current class prefix plus an
  189. * underscore (e.g. "Foo_enum_test"), return the base function
  190. * name (i.e. "enum_test").
  191. * ------------------------------------------------------------ */
  192. String *strip(const DOHconst_String_or_char_ptr name) {
  193. String *s = Copy(name);
  194. if (Strncmp(name, PrefixPlusUnderscore, Len(PrefixPlusUnderscore)) != 0) {
  195. return s;
  196. }
  197. Replaceall(s, PrefixPlusUnderscore, "");
  198. return s;
  199. }
  200. /* ------------------------------------------------------------
  201. * add_method()
  202. * ------------------------------------------------------------ */
  203. void add_method(const DOHconst_String_or_char_ptr name, const DOHconst_String_or_char_ptr function, const DOHconst_String_or_char_ptr description) {
  204. String *rename = NULL;
  205. switch (current) {
  206. case NO_CPP:
  207. rename = NewString(name);
  208. Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
  209. break;
  210. case STATIC_FUNC:
  211. case STATIC_VAR:
  212. rename = NewString(name);
  213. Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
  214. break;
  215. case CONSTRUCTOR:
  216. case DESTRUCTOR:
  217. case MEMBER_FUNC:
  218. case MEMBER_VAR:
  219. rename = strip(name);
  220. Printf(f_classInit, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
  221. break;
  222. case CLASS_CONST:
  223. assert(false); // shouldn't have gotten here for CLASS_CONST nodes
  224. default:
  225. assert(false); // what is this?
  226. }
  227. Delete(rename);
  228. }
  229. /* ---------------------------------------------------------------------
  230. * functionWrapper()
  231. *
  232. * Create a function declaration and register it with the interpreter.
  233. * --------------------------------------------------------------------- */
  234. virtual int functionWrapper(Node *n) {
  235. String *name = Getattr(n, "name");
  236. String *iname = Getattr(n, "sym:name");
  237. SwigType *d = Getattr(n, "type");
  238. ParmList *l = Getattr(n, "parms");
  239. Parm *p;
  240. String *tm;
  241. int i;
  242. String *overname = 0;
  243. if (Getattr(n, "sym:overloaded")) {
  244. overname = Getattr(n, "sym:overname");
  245. } else {
  246. if (!addSymbol(iname, n))
  247. return SWIG_ERROR;
  248. }
  249. Wrapper *f = NewWrapper();
  250. // Emit all of the local variables for holding arguments.
  251. emit_parameter_variables(l, f);
  252. /* Attach the standard typemaps */
  253. emit_attach_parmmaps(l, f);
  254. Setattr(n, "wrap:parms", l);
  255. /* Get number of required and total arguments */
  256. int num_arguments = emit_num_arguments(l);
  257. int varargs = emit_isvarargs(l);
  258. /* Which input argument to start with? */
  259. int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0;
  260. /* Offset to skip over the attribute name */
  261. // int offset = (current == MEMBER_VAR) ? 1 : 0;
  262. int offset = 0;
  263. String *wname = Swig_name_wrapper(iname);
  264. if (overname) {
  265. Append(wname, overname);
  266. }
  267. Setattr(n, "wrap:name", wname);
  268. Printv(f->def, "static void ", wname, "(INT32 args) {", NIL);
  269. /* Generate code for argument marshalling */
  270. String *description = NewString("");
  271. char source[64];
  272. for (i = 0, p = l; i < num_arguments; i++) {
  273. while (checkAttribute(p, "tmap:in:numinputs", "0")) {
  274. p = Getattr(p, "tmap:in:next");
  275. }
  276. SwigType *pt = Getattr(p, "type");
  277. String *ln = Getattr(p, "lname");
  278. if (i < start) {
  279. String *lstr = SwigType_lstr(pt, 0);
  280. Printf(f->code, "%s = (%s) THIS;\n", ln, lstr);
  281. Delete(lstr);
  282. } else {
  283. /* Look for an input typemap */
  284. sprintf(source, "Pike_sp[%d-args]", i - start + offset);
  285. if ((tm = Getattr(p, "tmap:in"))) {
  286. Replaceall(tm, "$source", source);
  287. Replaceall(tm, "$target", ln);
  288. Replaceall(tm, "$input", source);
  289. Setattr(p, "emit:input", source);
  290. Printf(f->code, "%s\n", tm);
  291. String *pikedesc = Getattr(p, "tmap:in:pikedesc");
  292. if (pikedesc) {
  293. Printv(description, pikedesc, " ", NIL);
  294. }
  295. p = Getattr(p, "tmap:in:next");
  296. continue;
  297. } else {
  298. Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
  299. break;
  300. }
  301. }
  302. p = nextSibling(p);
  303. }
  304. /* Check for trailing varargs */
  305. if (varargs) {
  306. if (p && (tm = Getattr(p, "tmap:in"))) {
  307. Replaceall(tm, "$input", "varargs");
  308. Printv(f->code, tm, "\n", NIL);
  309. }
  310. }
  311. /* Insert constraint checking code */
  312. for (p = l; p;) {
  313. if ((tm = Getattr(p, "tmap:check"))) {
  314. Replaceall(tm, "$target", Getattr(p, "lname"));
  315. Printv(f->code, tm, "\n", NIL);
  316. p = Getattr(p, "tmap:check:next");
  317. } else {
  318. p = nextSibling(p);
  319. }
  320. }
  321. /* Insert cleanup code */
  322. String *cleanup = NewString("");
  323. for (p = l; p;) {
  324. if ((tm = Getattr(p, "tmap:freearg"))) {
  325. Replaceall(tm, "$source", Getattr(p, "lname"));
  326. Printv(cleanup, tm, "\n", NIL);
  327. p = Getattr(p, "tmap:freearg:next");
  328. } else {
  329. p = nextSibling(p);
  330. }
  331. }
  332. /* Insert argument output code */
  333. String *outarg = NewString("");
  334. for (p = l; p;) {
  335. if ((tm = Getattr(p, "tmap:argout"))) {
  336. Replaceall(tm, "$source", Getattr(p, "lname"));
  337. Replaceall(tm, "$target", "resultobj");
  338. Replaceall(tm, "$arg", Getattr(p, "emit:input"));
  339. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  340. Printv(outarg, tm, "\n", NIL);
  341. p = Getattr(p, "tmap:argout:next");
  342. } else {
  343. p = nextSibling(p);
  344. }
  345. }
  346. /* Emit the function call */
  347. String *actioncode = emit_action(n);
  348. /* Clear the return stack */
  349. Printf(actioncode, "pop_n_elems(args);\n");
  350. /* Return the function value */
  351. if (current == CONSTRUCTOR) {
  352. Printv(actioncode, "THIS = (void *) result;\n", NIL);
  353. Printv(description, ", tVoid", NIL);
  354. } else if (current == DESTRUCTOR) {
  355. Printv(description, ", tVoid", NIL);
  356. } else {
  357. Printv(description, ", ", NIL);
  358. if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
  359. actioncode = 0;
  360. Replaceall(tm, "$source", "result");
  361. Replaceall(tm, "$target", "resultobj");
  362. Replaceall(tm, "$result", "resultobj");
  363. if (GetFlag(n, "feature:new")) {
  364. Replaceall(tm, "$owner", "1");
  365. } else {
  366. Replaceall(tm, "$owner", "0");
  367. }
  368. String *pikedesc = Getattr(n, "tmap:out:pikedesc");
  369. if (pikedesc) {
  370. Printv(description, pikedesc, NIL);
  371. }
  372. Printf(f->code, "%s\n", tm);
  373. } else {
  374. Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
  375. }
  376. }
  377. if (actioncode) {
  378. Append(f->code, actioncode);
  379. Delete(actioncode);
  380. }
  381. emit_return_variable(n, d, f);
  382. /* Output argument output code */
  383. Printv(f->code, outarg, NIL);
  384. /* Output cleanup code */
  385. Printv(f->code, cleanup, NIL);
  386. /* Look to see if there is any newfree cleanup code */
  387. if (GetFlag(n, "feature:new")) {
  388. if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
  389. Replaceall(tm, "$source", "result");
  390. Printf(f->code, "%s\n", tm);
  391. }
  392. }
  393. /* See if there is any return cleanup code */
  394. if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
  395. Replaceall(tm, "$source", "result");
  396. Printf(f->code, "%s\n", tm);
  397. }
  398. /* Close the function */
  399. Printf(f->code, "}\n");
  400. /* Substitute the cleanup code */
  401. Replaceall(f->code, "$cleanup", cleanup);
  402. /* Substitute the function name */
  403. Replaceall(f->code, "$symname", iname);
  404. Replaceall(f->code, "$result", "resultobj");
  405. /* Dump the function out */
  406. Wrapper_print(f, f_wrappers);
  407. /* Now register the function with the interpreter. */
  408. if (!Getattr(n, "sym:overloaded")) {
  409. add_method(iname, wname, description);
  410. } else {
  411. if (!Getattr(n, "sym:nextSibling")) {
  412. dispatchFunction(n);
  413. }
  414. }
  415. Delete(cleanup);
  416. Delete(outarg);
  417. Delete(description);
  418. Delete(wname);
  419. DelWrapper(f);
  420. return SWIG_OK;
  421. }
  422. /* ------------------------------------------------------------
  423. * dispatchFunction()
  424. *
  425. * Emit overloading dispatch function
  426. * ------------------------------------------------------------ */
  427. void dispatchFunction(Node *n) {
  428. /* Last node in overloaded chain */
  429. int maxargs;
  430. String *tmp = NewString("");
  431. String *dispatch = Swig_overload_dispatch(n, "%s(args); return;", &maxargs);
  432. /* Generate a dispatch wrapper for all overloaded functions */
  433. Wrapper *f = NewWrapper();
  434. String *symname = Getattr(n, "sym:name");
  435. String *wname = Swig_name_wrapper(symname);
  436. Printf(f->def, "static void %s(INT32 args) {", wname);
  437. Wrapper_add_local(f, "argc", "INT32 argc");
  438. Printf(tmp, "struct svalue argv[%d]", maxargs);
  439. Wrapper_add_local(f, "argv", tmp);
  440. Wrapper_add_local(f, "ii", "INT32 ii");
  441. Printf(f->code, "argc = args;\n");
  442. Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
  443. Printf(f->code, "argv[ii] = Pike_sp[ii-args];\n");
  444. Printf(f->code, "}\n");
  445. Replaceall(dispatch, "$args", "self, args");
  446. Printv(f->code, dispatch, "\n", NIL);
  447. Printf(f->code, "Pike_error(\"No matching function for overloaded '%s'.\");\n", symname);
  448. Printv(f->code, "}\n", NIL);
  449. Wrapper_print(f, f_wrappers);
  450. String *description = NewString("");
  451. Printf(description, "tAny,");
  452. if (current == CONSTRUCTOR || current == DESTRUCTOR) {
  453. Printf(description, " tVoid");
  454. } else {
  455. String *pd = Getattr(n, "tmap:out:pikedesc");
  456. if (pd)
  457. Printf(description, " %s", pd);
  458. }
  459. add_method(symname, wname, description);
  460. Delete(description);
  461. DelWrapper(f);
  462. Delete(dispatch);
  463. Delete(tmp);
  464. Delete(wname);
  465. }
  466. /* ------------------------------------------------------------
  467. * variableWrapper()
  468. * ------------------------------------------------------------ */
  469. virtual int variableWrapper(Node *n) {
  470. return Language::variableWrapper(n);
  471. }
  472. /* ------------------------------------------------------------
  473. * constantWrapper()
  474. * ------------------------------------------------------------ */
  475. virtual int constantWrapper(Node *n) {
  476. Swig_require("constantWrapper", n, "*sym:name", "type", "value", NIL);
  477. String *symname = Getattr(n, "sym:name");
  478. SwigType *type = Getattr(n, "type");
  479. String *value = Getattr(n, "value");
  480. /* Special hook for member pointer */
  481. if (SwigType_type(type) == T_MPOINTER) {
  482. String *wname = Swig_name_wrapper(symname);
  483. Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
  484. value = wname;
  485. }
  486. /* Perform constant typemap substitution */
  487. String *tm = Swig_typemap_lookup("constant", n, value, 0);
  488. if (tm) {
  489. Replaceall(tm, "$source", value);
  490. Replaceall(tm, "$target", symname);
  491. Replaceall(tm, "$symname", symname);
  492. Replaceall(tm, "$value", value);
  493. Printf(f_init, "%s\n", tm);
  494. } else {
  495. Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
  496. }
  497. Swig_restore(n);
  498. return SWIG_OK;
  499. }
  500. /* ------------------------------------------------------------
  501. * nativeWrapper()
  502. * ------------------------------------------------------------ */
  503. virtual int nativeWrapper(Node *n) {
  504. // return Language::nativeWrapper(n);
  505. String *name = Getattr(n, "sym:name");
  506. String *wrapname = Getattr(n, "wrap:name");
  507. if (!addSymbol(wrapname, n))
  508. return SWIG_ERROR;
  509. add_method(name, wrapname, 0);
  510. return SWIG_OK;
  511. }
  512. /* ------------------------------------------------------------
  513. * enumDeclaration()
  514. * ------------------------------------------------------------ */
  515. virtual int enumDeclaration(Node *n) {
  516. return Language::enumDeclaration(n);
  517. }
  518. /* ------------------------------------------------------------
  519. * enumvalueDeclaration()
  520. * ------------------------------------------------------------ */
  521. virtual int enumvalueDeclaration(Node *n) {
  522. return Language::enumvalueDeclaration(n);
  523. }
  524. /* ------------------------------------------------------------
  525. * classDeclaration()
  526. * ------------------------------------------------------------ */
  527. virtual int classDeclaration(Node *n) {
  528. return Language::classDeclaration(n);
  529. }
  530. /* ------------------------------------------------------------
  531. * classHandler()
  532. * ------------------------------------------------------------ */
  533. virtual int classHandler(Node *n) {
  534. String *symname = Getattr(n, "sym:name");
  535. if (!addSymbol(symname, n))
  536. return SWIG_ERROR;
  537. PrefixPlusUnderscore = NewStringf("%s_", getClassPrefix());
  538. Printf(f_classInit, "start_new_program();\n");
  539. /* Handle inheritance */
  540. List *baselist = Getattr(n, "bases");
  541. if (baselist && Len(baselist) > 0) {
  542. Iterator base = First(baselist);
  543. while (base.item) {
  544. String *basename = Getattr(base.item, "name");
  545. SwigType *basetype = NewString(basename);
  546. SwigType_add_pointer(basetype);
  547. SwigType_remember(basetype);
  548. String *basemangle = SwigType_manglestr(basetype);
  549. Printf(f_classInit, "low_inherit((struct program *) SWIGTYPE%s->clientdata, 0, 0, 0, 0, 0);\n", basemangle);
  550. Delete(basemangle);
  551. Delete(basetype);
  552. base = Next(base);
  553. }
  554. } else {
  555. Printf(f_classInit, "ADD_STORAGE(swig_object_wrapper);\n");
  556. }
  557. Language::classHandler(n);
  558. /* Accessors for member variables */
  559. /*
  560. List *membervariables = Getattr(n,"membervariables");
  561. if (membervariables && Len(membervariables) > 0) {
  562. membervariableAccessors(membervariables);
  563. }
  564. */
  565. /* Done, close the class and dump its definition to the init function */
  566. Printf(f_classInit, "add_program_constant(\"%s\", pr = end_program(), 0);\n", symname);
  567. Dump(f_classInit, f_init);
  568. Clear(f_classInit);
  569. SwigType *tt = NewString(symname);
  570. SwigType_add_pointer(tt);
  571. SwigType_remember(tt);
  572. String *tm = SwigType_manglestr(tt);
  573. Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) pr);\n", tm);
  574. Delete(tm);
  575. Delete(tt);
  576. Delete(PrefixPlusUnderscore);
  577. PrefixPlusUnderscore = 0;
  578. return SWIG_OK;
  579. }
  580. /* ------------------------------------------------------------
  581. * memberfunctionHandler()
  582. *
  583. * Method for adding C++ member function
  584. * ------------------------------------------------------------ */
  585. virtual int memberfunctionHandler(Node *n) {
  586. current = MEMBER_FUNC;
  587. Language::memberfunctionHandler(n);
  588. current = NO_CPP;
  589. return SWIG_OK;
  590. }
  591. /* ------------------------------------------------------------
  592. * constructorHandler()
  593. *
  594. * Method for adding C++ member constructor
  595. * ------------------------------------------------------------ */
  596. virtual int constructorHandler(Node *n) {
  597. current = CONSTRUCTOR;
  598. Language::constructorHandler(n);
  599. current = NO_CPP;
  600. return SWIG_OK;
  601. }
  602. /* ------------------------------------------------------------
  603. * destructorHandler()
  604. * ------------------------------------------------------------ */
  605. virtual int destructorHandler(Node *n) {
  606. current = DESTRUCTOR;
  607. Language::destructorHandler(n);
  608. current = NO_CPP;
  609. return SWIG_OK;
  610. }
  611. /* ------------------------------------------------------------
  612. * membervariableAccessors()
  613. * ------------------------------------------------------------ */
  614. void membervariableAccessors(List *membervariables) {
  615. String *name;
  616. Iterator i;
  617. bool need_setter;
  618. String *funcname;
  619. /* If at least one of them is mutable, we need a setter */
  620. need_setter = false;
  621. i = First(membervariables);
  622. while (i.item) {
  623. if (!GetFlag(i.item, "feature:immutable")) {
  624. need_setter = true;
  625. break;
  626. }
  627. i = Next(i);
  628. }
  629. /* Create a function to set the values of the (mutable) variables */
  630. if (need_setter) {
  631. Wrapper *wrapper = NewWrapper();
  632. String *setter = Swig_name_member(getClassPrefix(), (char *) "`->=");
  633. String *wname = Swig_name_wrapper(setter);
  634. Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
  635. Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n");
  636. i = First(membervariables);
  637. while (i.item) {
  638. if (!GetFlag(i.item, "feature:immutable")) {
  639. name = Getattr(i.item, "name");
  640. funcname = Swig_name_wrapper(Swig_name_set(Swig_name_member(getClassPrefix(), name)));
  641. Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
  642. Printf(wrapper->code, "%s(args);\n", funcname);
  643. Printf(wrapper->code, "return;\n");
  644. Printf(wrapper->code, "}\n");
  645. Delete(funcname);
  646. }
  647. i = Next(i);
  648. }
  649. /* Close the function */
  650. Printf(wrapper->code, "pop_n_elems(args);\n");
  651. Printf(wrapper->code, "}\n");
  652. /* Dump wrapper code to the output file */
  653. Wrapper_print(wrapper, f_wrappers);
  654. /* Register it with Pike */
  655. String *description = NewString("tStr tFloat, tVoid");
  656. add_method("`->=", wname, description);
  657. Delete(description);
  658. /* Clean up */
  659. Delete(wname);
  660. Delete(setter);
  661. DelWrapper(wrapper);
  662. }
  663. /* Create a function to get the values of the (mutable) variables */
  664. Wrapper *wrapper = NewWrapper();
  665. String *getter = Swig_name_member(getClassPrefix(), (char *) "`->");
  666. String *wname = Swig_name_wrapper(getter);
  667. Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
  668. Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n");
  669. i = First(membervariables);
  670. while (i.item) {
  671. name = Getattr(i.item, "name");
  672. funcname = Swig_name_wrapper(Swig_name_get(Swig_name_member(getClassPrefix(), name)));
  673. Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
  674. Printf(wrapper->code, "%s(args);\n", funcname);
  675. Printf(wrapper->code, "return;\n");
  676. Printf(wrapper->code, "}\n");
  677. Delete(funcname);
  678. i = Next(i);
  679. }
  680. /* Close the function */
  681. Printf(wrapper->code, "pop_n_elems(args);\n");
  682. Printf(wrapper->code, "}\n");
  683. /* Dump wrapper code to the output file */
  684. Wrapper_print(wrapper, f_wrappers);
  685. /* Register it with Pike */
  686. String *description = NewString("tStr, tMix");
  687. add_method("`->", wname, description);
  688. Delete(description);
  689. /* Clean up */
  690. Delete(wname);
  691. Delete(getter);
  692. DelWrapper(wrapper);
  693. }
  694. /* ------------------------------------------------------------
  695. * membervariableHandler()
  696. * ------------------------------------------------------------ */
  697. virtual int membervariableHandler(Node *n) {
  698. List *membervariables = Getattr(getCurrentClass(), "membervariables");
  699. if (!membervariables) {
  700. membervariables = NewList();
  701. Setattr(getCurrentClass(), "membervariables", membervariables);
  702. }
  703. Append(membervariables, n);
  704. current = MEMBER_VAR;
  705. Language::membervariableHandler(n);
  706. current = NO_CPP;
  707. return SWIG_OK;
  708. }
  709. /* -----------------------------------------------------------------------
  710. * staticmemberfunctionHandler()
  711. *
  712. * Wrap a static C++ function
  713. * ---------------------------------------------------------------------- */
  714. virtual int staticmemberfunctionHandler(Node *n) {
  715. current = STATIC_FUNC;
  716. Language::staticmemberfunctionHandler(n);
  717. current = NO_CPP;
  718. return SWIG_OK;
  719. }
  720. /* ------------------------------------------------------------
  721. * memberconstantHandler()
  722. *
  723. * Create a C++ constant
  724. * ------------------------------------------------------------ */
  725. virtual int memberconstantHandler(Node *n) {
  726. current = CLASS_CONST;
  727. constantWrapper(n);
  728. current = NO_CPP;
  729. return SWIG_OK;
  730. }
  731. /* ---------------------------------------------------------------------
  732. * staticmembervariableHandler()
  733. * --------------------------------------------------------------------- */
  734. virtual int staticmembervariableHandler(Node *n) {
  735. current = STATIC_VAR;
  736. Language::staticmembervariableHandler(n);
  737. current = NO_CPP;
  738. return SWIG_OK;
  739. }
  740. };
  741. /* -----------------------------------------------------------------------------
  742. * swig_pike() - Instantiate module
  743. * ----------------------------------------------------------------------------- */
  744. static Language *new_swig_pike() {
  745. return new PIKE();
  746. }
  747. extern "C" Language *swig_pike(void) {
  748. return new_swig_pike();
  749. }