PageRenderTime 49ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1-3-23/SWIG/Source/Modules/php4.cxx

#
C++ | 1943 lines | 1379 code | 298 blank | 266 comment | 237 complexity | dd1adc7ccbf6f2f682f12c9c16d1357e MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /*
  2. * PHP4 Support
  3. *
  4. * Richard Palmer
  5. * richard@magicality.org
  6. * Nov 2001
  7. *
  8. * Portions copyright Sun Microsystems (c) 2001
  9. * Tim Hockin <thockin@sun.com>
  10. *
  11. * Portions copyright Ananova Ltd (c) 2002
  12. * Sam Liddicott <sam@ananova.com>
  13. *
  14. */
  15. char cvsroot_php4_cxx[] = "$Header$";
  16. #include "swigmod.h"
  17. #include <ctype.h>
  18. static const char *usage = (char*)"\
  19. PHP4 Options (available with -php4)\n\
  20. -cppext - cpp file extension (default to .cpp)\n\
  21. -noproxy - Don't generate proxy classes.\n\
  22. -dlname <name> - Set module prefix to <name>\n\
  23. -make - Create simple makefile\n\
  24. -phpfull - Create full make files\n\
  25. -withincs <libs>- With -phpfull writes needed incs in config.m4\n\
  26. -withlibs <libs>- With -phpfull writes needed libs in config.m4\n\
  27. -withc <libs> - With -phpfull makes extra c files in Makefile.in\n\
  28. -withcxx <libs> - With -phpfull makes extra c++ files in Makefile.in\n\
  29. \n";
  30. static int constructors=0;
  31. static String *NOTCLASS=NewString("Not a class");
  32. static Node *classnode=0;
  33. static String *module = 0;
  34. static String *cap_module = 0;
  35. static String *dlname = 0;
  36. static String *withlibs = 0;
  37. static String *withincs = 0;
  38. static String *withc = 0;
  39. static String *withcxx = 0;
  40. //static char *package = 0; // Name of the package
  41. static char *shadow_classname;
  42. static Wrapper *f_php;
  43. static int gen_extra = 0;
  44. static int gen_make = 0;
  45. static File *f_runtime = 0;
  46. static File *f_h = 0;
  47. static File *f_phpcode = 0;
  48. static String *phpfilename =0;
  49. static String *s_header;
  50. static String *s_wrappers;
  51. static String *s_init;
  52. static String *s_vinit;
  53. static String *s_vdecl;
  54. static String *s_cinit;
  55. static String *s_oinit;
  56. static String *s_entry;
  57. static String *cs_entry;
  58. static String *all_cs_entry;
  59. static String *pragma_incl;
  60. static String *pragma_code;
  61. static String *pragma_phpinfo;
  62. /* Variables for using PHP classes */
  63. static String *class_name = 0;
  64. static String *realpackage = 0;
  65. static String *package = 0;
  66. static Hash *shadow_get_vars;
  67. static Hash *shadow_set_vars;
  68. static String *shadow_classdef;
  69. static String *shadow_code;
  70. static int have_default_constructor = 0;
  71. #define NATIVE_CONSTRUCTOR 1
  72. #define ALTERNATIVE_CONSTRUCTOR 2
  73. static int native_constructor=0;
  74. static int destructor=0;
  75. static int enum_flag = 0; // Set to 1 when wrapping an enum
  76. static int static_flag = 0; // Set to 1 when wrapping a static functions or member variables
  77. static int const_flag = 0; // Set to 1 when wrapping a const member variables
  78. static int variable_wrapper_flag = 0; // Set to 1 when wrapping a member variable/enum/const
  79. static int wrapping_member = 0;
  80. static Hash *zend_types = 0;
  81. static String *shadow_enum_code = 0;
  82. static String *php_enum_code = 0;
  83. static String *all_shadow_extra_code = 0;
  84. //Extra code for all shadow classes from %pragma
  85. static String *this_shadow_extra_code = 0;
  86. //Extra Code for current single shadow class freom %pragma
  87. static String *all_shadow_import = 0;
  88. //import for all shadow classes from %pragma
  89. static String *this_shadow_import = 0;
  90. //import for current shadow classes from %pragma
  91. static String *module_baseclass = 0;
  92. //inheritance for module class from %pragma
  93. static String *all_shadow_baseclass = 0;
  94. //inheritence for all shadow classes from %pragma
  95. static String *this_shadow_baseclass = 0;
  96. //inheritance for shadow class from %pragma and cpp_inherit
  97. static String *this_shadow_multinherit = 0;
  98. static int shadow = 1;
  99. extern "C" {
  100. static void (*r_prevtracefunc)(SwigType *t, String *mangled, String *clientdata) = 0;
  101. }
  102. static const char *php_header =
  103. "/*"
  104. "\n +----------------------------------------------------------------------+"
  105. "\n | PHP version 4.0 |"
  106. "\n +----------------------------------------------------------------------+"
  107. "\n | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |"
  108. "\n +----------------------------------------------------------------------+"
  109. "\n | This source file is subject to version 2.02 of the PHP license, |"
  110. "\n | that is bundled with this package in the file LICENSE, and is |"
  111. "\n | available at through the world-wide-web at |"
  112. "\n | http://www.php.net/license/2_02.txt. |"
  113. "\n | If you did not receive a copy of the PHP license and are unable to |"
  114. "\n | obtain it through the world-wide-web, please send a note to |"
  115. "\n | license@php.net so we can mail you a copy immediately. |"
  116. "\n +----------------------------------------------------------------------+"
  117. "\n | Authors: |"
  118. "\n | |"
  119. "\n +----------------------------------------------------------------------+"
  120. "\n */\n";
  121. void
  122. SwigPHP_emit_resource_registrations() {
  123. DOH *key;
  124. Iterator ki;
  125. String *destructor=0;
  126. String *classname=0;
  127. String *shadow_classname=0;
  128. if (!zend_types) return;
  129. ki = First(zend_types);
  130. if (ki.key) Printf(s_oinit,"\n/* Register resource destructors for pointer types */\n");
  131. while (ki.key) if (1 /* is pointer type*/) {
  132. key = ki.key;
  133. Node *class_node;
  134. if ((class_node=Getattr(zend_types,key))) {
  135. // Write out destructor function header
  136. Printf(s_wrappers,"/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n",key);
  137. // write out body
  138. if ((class_node!=NOTCLASS)) {
  139. classname = Getattr(class_node,"name");
  140. if (! (shadow_classname = Getattr(class_node,"sym:name"))) shadow_classname=classname;
  141. // Do we have a known destructor for this type?
  142. if ((destructor = Getattr(class_node,"destructor"))) {
  143. Printf(s_wrappers,"/* has destructor: %s */\n",destructor);
  144. Printf(s_wrappers,"%s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n",destructor,key);
  145. } else {
  146. Printf(s_wrappers,"/* bah! No destructor for this wrapped class!! */\n");
  147. }
  148. } else {
  149. Printf(s_wrappers,"/* bah! No destructor for this simple type!! */\n");
  150. }
  151. // close function
  152. Printf(s_wrappers,"}\n");
  153. // declare le_swig_<mangled> to store php registration
  154. Printf(s_vdecl,"static int le_swig_%s=0; /* handle for %s */\n", key, shadow_classname);
  155. // register with php
  156. Printf(s_oinit,"le_swig_%s=zend_register_list_destructors_ex"
  157. "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n",
  158. key,key,key);
  159. // store php type in class struct
  160. Printf(s_oinit,"SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n",
  161. key,key);
  162. }
  163. ki = Next(ki);
  164. }
  165. }
  166. class PHP4 : public Language {
  167. public:
  168. /* Test to see if a type corresponds to something wrapped with a shadow class. */
  169. String *is_shadow(SwigType *t) {
  170. String *r = 0;
  171. Node *n = classLookup(t);
  172. if (n) {
  173. r = Getattr(n,"php:proxy"); // Set by classDeclaration()
  174. if (!r) {
  175. r = Getattr(n,"sym:name"); // Not seen by classDeclaration yet, but this is the name
  176. }
  177. }
  178. return r;
  179. }
  180. /* -----------------------------------------------------------------------------
  181. * get_pointer()
  182. * ----------------------------------------------------------------------------- */
  183. void
  184. get_pointer(char *iname, char *srcname, char *src, char *dest,
  185. SwigType *t, String *f, char *ret) {
  186. SwigType_remember(t);
  187. SwigType *lt = SwigType_ltype(t);
  188. Printv(f, "if (SWIG_ConvertPtr(", src, ",(void **) ", dest, ",", NIL);
  189. /* If we're passing a void pointer, we give the pointer conversion a NULL
  190. pointer, otherwise pass in the expected type. */
  191. if (Cmp(lt,"p.void") == 0) {
  192. Printf(f, " 0 ) < 0) {\n");
  193. } else {
  194. Printv(f, "SWIGTYPE", SwigType_manglestr(t), ") < 0) {\n",NIL);
  195. }
  196. Printv(f,
  197. "zend_error(E_ERROR, \"Type error in ", srcname, " of ", iname,
  198. " Expected %s\", SWIGTYPE", SwigType_manglestr(t), "->name);\n", ret,
  199. ";\n",
  200. "}\n",
  201. NIL);
  202. Delete(lt);
  203. }
  204. /* ------------------------------------------------------------
  205. * main()
  206. * ------------------------------------------------------------ */
  207. virtual void main(int argc, char *argv[]) {
  208. int i;
  209. SWIG_library_directory("php4");
  210. SWIG_config_cppext("cpp");
  211. for(i = 1; i < argc; i++) {
  212. if (argv[i]) {
  213. if(strcmp(argv[i], "-phpfull") == 0) {
  214. gen_extra = 1;
  215. Swig_mark_arg(i);
  216. } else if(strcmp(argv[i], "-dlname") == 0) {
  217. if (argv[i+1]) {
  218. dlname = NewString(argv[i+1]);
  219. Swig_mark_arg(i);
  220. Swig_mark_arg(i+1);
  221. i++;
  222. } else {
  223. Swig_arg_error();
  224. }
  225. } else if(strcmp(argv[i], "-withlibs") == 0) {
  226. if (argv[i+1]) {
  227. withlibs = NewString(argv[i+1]);
  228. Swig_mark_arg(i);
  229. Swig_mark_arg(i+1);
  230. i++;
  231. } else {
  232. Swig_arg_error();
  233. }
  234. } else if(strcmp(argv[i], "-withincs") == 0) {
  235. if (argv[i+1]) {
  236. withincs = NewString(argv[i+1]);
  237. Swig_mark_arg(i);
  238. Swig_mark_arg(i+1);
  239. i++;
  240. } else {
  241. Swig_arg_error();
  242. }
  243. } else if(strcmp(argv[i], "-withc") == 0) {
  244. if (argv[i+1]) {
  245. withc = NewString(argv[i+1]);
  246. Swig_mark_arg(i);
  247. Swig_mark_arg(i+1);
  248. i++;
  249. } else {
  250. Swig_arg_error();
  251. }
  252. } else if(strcmp(argv[i], "-withcxx") == 0) {
  253. if (argv[i+1]) {
  254. withcxx = NewString(argv[i+1]);
  255. Swig_mark_arg(i);
  256. Swig_mark_arg(i+1);
  257. i++;
  258. } else {
  259. Swig_arg_error();
  260. }
  261. } else if(strcmp(argv[i], "-cppext") == 0) {
  262. if (argv[i+1]) {
  263. SWIG_config_cppext(argv[i+1]);
  264. Swig_mark_arg(i);
  265. Swig_mark_arg(i+1);
  266. i++;
  267. } else {
  268. Swig_arg_error();
  269. }
  270. } else if((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i],"-noproxy") == 0)) {
  271. shadow = 0;
  272. Swig_mark_arg(i);
  273. } else if(strcmp(argv[i], "-make") == 0) {
  274. gen_make = 1;
  275. Swig_mark_arg(i);
  276. } else if(strcmp(argv[i], "-help") == 0) {
  277. fputs(usage, stderr);
  278. }
  279. }
  280. }
  281. Preprocessor_define((void *) "SWIGPHP 1", 0);
  282. Preprocessor_define((void *) "SWIGPHP4 1", 0);
  283. Preprocessor_define ("SWIG_NO_OVERLOAD 1", 0);
  284. SWIG_typemap_lang("php4");
  285. /* DB: Suggest using a language configuration file */
  286. SWIG_config_file("php4.swg");
  287. }
  288. void create_simple_make(void) {
  289. File *f_make;
  290. f_make = NewFile((void *)"makefile", "w");
  291. if(CPlusPlus)
  292. Printf(f_make, "CC=g++\n");
  293. else
  294. Printf(f_make, "CC=gcc\n");
  295. Printf(f_make,
  296. "OBJS=%s_wrap.o\n"
  297. "PROG=lib%s.so\n"
  298. "CFLAGS=-fpic\n"
  299. "LDFLAGS=-shared\n"
  300. "PHP_INC=`php-config --includes`\n"
  301. "EXTRA_INC=\n"
  302. "EXTRA_LIB=\n\n",
  303. module, module);
  304. Printf(f_make,
  305. "$(PROG): $(OBJS)\n"
  306. "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n"
  307. "%%.o: %%.%s\n"
  308. "\t$(CC) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n",
  309. (CPlusPlus?"cpp":"c"));
  310. Close(f_make);
  311. }
  312. void create_extra_files(String *outfile) {
  313. File *f_extra;
  314. static String *configm4=0;
  315. static String *makefilein=0;
  316. static String *credits=0;
  317. configm4=NewString("");
  318. Printv(configm4, SWIG_output_directory(), "config.m4", NIL);
  319. makefilein=NewString("");
  320. Printv(makefilein, SWIG_output_directory(), "Makefile.in", NIL);
  321. credits=NewString("");
  322. Printv(credits, SWIG_output_directory(), "CREDITS", NIL);
  323. // are we a --with- or --enable-
  324. int with=(withincs || withlibs)?1:0;
  325. // Note makefile.in only copes with one source file
  326. // also withincs and withlibs only take one name each now
  327. // the code they generate should be adapted to take multiple lines
  328. if(gen_extra) {
  329. /* Write out Makefile.in */
  330. f_extra = NewFile(makefilein, "w");
  331. if (!f_extra) {
  332. Printf(stderr,"Unable to open %s\n",makefilein);
  333. SWIG_exit(EXIT_FAILURE);
  334. }
  335. Printf(f_extra,
  336. "# $Id: php4.cxx 6025 2004-07-10 16:42:54Z wsfulton $\n\n"
  337. "LTLIBRARY_NAME = php_%s.la\n",
  338. module);
  339. // CPP has more and different entires to C in Makefile.in
  340. if (! CPlusPlus) Printf(f_extra,"LTLIBRARY_SOURCES = %s %s\n"
  341. "LTLIBRARY_SOURCES_CPP = %s\n",Swig_file_filename(outfile),withc,withcxx);
  342. else Printf(f_extra,"LTLIBRARY_SOURCES = %s\n"
  343. "LTLIBRARY_SOURCES_CPP = %s %s\n"
  344. "LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n"
  345. ,withc,Swig_file_filename(outfile),withcxx);
  346. Printf(f_extra,"LTLIBRARY_SHARED_NAME = php_%s.la\n"
  347. "LTLIBRARY_SHARED_LIBADD = $(%(upper)s_SHARED_LIBADD)\n\n"
  348. "include $(top_srcdir)/build/dynlib.mk\n",
  349. module,module);
  350. Printf(f_extra,"\n# patch in .cxx support to php build system to work like .cpp\n"
  351. ".SUFFIXES: .cxx\n\n"
  352. ".cxx.o:\n"
  353. " $(CXX_COMPILE) -c $<\n\n"
  354. ".cxx.lo:\n"
  355. " $(CXX_PHP_COMPILE)\n\n"
  356. ".cxx.slo:\n"
  357. " $(CXX_SHARED_COMPILE)\n\n");
  358. Printf(f_extra,"\n# make it easy to test module\n"
  359. "testmodule:\n"
  360. " php -q -d extension_dir=modules %s\n\n",Swig_file_filename(phpfilename));
  361. Close(f_extra);
  362. /* Now config.m4 */
  363. // Note: # comments are OK in config.m4 if you don't mind them
  364. // appearing in the final ./configure file
  365. // (which can help with ./configure debugging)
  366. // NOTE2: phpize really ought to be able to write out a sample
  367. // config.m4 based on some simple data, I'll take this up with
  368. // the php folk!
  369. f_extra = NewFile(configm4, "w");
  370. if (!f_extra) {
  371. Printf(stderr, "Unable to open %s\n",configm4);
  372. SWIG_exit(EXIT_FAILURE);
  373. }
  374. Printf(f_extra,
  375. "dnl $Id: php4.cxx 6025 2004-07-10 16:42:54Z wsfulton $\n"
  376. "dnl ***********************************************************************\n"
  377. "dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n"
  378. "dnl ** for any part of the rest of the %s build system\n"
  379. "dnl ***********************************************************************\n\n"
  380. ,module);
  381. if (! with) { // must be enable then
  382. Printf(f_extra,
  383. "PHP_ARG_ENABLE(%s, whether to enable %s support,\n"
  384. "[ --enable-%s Enable %s support])\n\n",
  385. module,module,module,module);
  386. } else {
  387. Printf(f_extra,
  388. "PHP_ARG_WITH(%s, for %s support,\n"
  389. "[ --with-%s[=DIR] Include %s support.])\n\n",
  390. module,module,module,module);
  391. // These tests try and file the library we need
  392. Printf(f_extra,"dnl THESE TESTS try and find the library and header files\n"
  393. "dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n"
  394. "dnl as written they assume your header files are all in the same place\n\n");
  395. Printf(f_extra,"dnl ** are we looking for %s_lib.h or something else?\n",module);
  396. if (withincs) Printf(f_extra,"HNAMES=\"%s\"\n\n",withincs);
  397. else Printf(f_extra,"HNAMES=\"\"; # %s_lib.h ?\n\n",module);
  398. Printf(f_extra,"dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n",module,module);
  399. if (withlibs) Printf(f_extra,"LIBNAMES=\"%s\"\n\n",withlibs);
  400. else Printf(f_extra,"LIBNAMES=\"\"; # lib_%s.so ?\n\n",withlibs);
  401. Printf(f_extra,"dnl IF YOU KNOW one of the symbols in the library and you\n"
  402. "dnl specify it below then we can have a link test to see if it works\n"
  403. "LIBSYMBOL=\"\"\n\n");
  404. }
  405. // Now write out tests to find thing.. they may need to extend tests
  406. Printf(f_extra,"if test \"$PHP_%(upper)s\" != \"no\"; then\n\n",module);
  407. // Ready for when we add libraries as we find them
  408. Printf(f_extra," PHP_SUBST(%(upper)s_SHARED_LIBADD)\n\n",module);
  409. if (withlibs) { // find more than one library
  410. Printf(f_extra," for LIBNAME in $LIBNAMES ; do\n");
  411. Printf(f_extra," LIBDIR=\"\"\n");
  412. // For each path element to try...
  413. Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/lib /usr/lib /usr/local/lib ; do\n",module,module);
  414. Printf(f_extra," if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n"
  415. " LIBDIR=\"$i\"\n"
  416. " break\n"
  417. " fi\n"
  418. " done\n\n");
  419. Printf(f_extra," dnl ** and $LIBDIR should be the library path\n"
  420. " if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n"
  421. " AC_MSG_RESULT(Library files $LIBNAME not found)\n"
  422. " AC_MSG_ERROR(Is the %s distribution installed properly?)\n"
  423. " else\n"
  424. " AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n"
  425. " PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %(upper)s_SHARED_LIBADD)\n"
  426. " fi\n",module,module);
  427. Printf(f_extra," done\n\n");
  428. }
  429. if (withincs) { // Find more than once include
  430. Printf(f_extra," for HNAME in $HNAMES ; do\n");
  431. Printf(f_extra," INCDIR=\"\"\n");
  432. // For each path element to try...
  433. Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/include $PHP_%(upper)s/includes $PHP_%(upper)s/inc $PHP_%(upper)s/incs /usr/local/include /usr/include; do\n",module,module,module,module,module);
  434. // Try and find header files
  435. Printf(f_extra," if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n"
  436. " INCDIR=\"$i\"\n"
  437. " break\n"
  438. " fi\n"
  439. " done\n\n");
  440. Printf(f_extra,
  441. " dnl ** Now $INCDIR should be the include file path\n"
  442. " if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n"
  443. " AC_MSG_RESULT(Include files $HNAME not found)\n"
  444. " AC_MSG_ERROR(Is the %s distribution installed properly?)\n"
  445. " else\n"
  446. " AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n"
  447. " PHP_ADD_INCLUDE($INCDIR)\n"
  448. " fi\n\n",module);
  449. Printf(f_extra," done\n\n");
  450. }
  451. if (CPlusPlus) Printf(f_extra,
  452. " # As this is a C++ module..\n"
  453. " PHP_REQUIRE_CXX\n"
  454. " AC_CHECK_LIB(stdc++, cin)\n");
  455. if (with) {
  456. Printf(f_extra," if test \"$LIBSYMBOL\" != \"\" ; then\n"
  457. " old_LIBS=\"$LIBS\"\n"
  458. " LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n"
  459. " AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1, [ ])],\n"
  460. " [AC_MSG_ERROR(wrong test lib version or lib not found)])\n"
  461. " LIBS=\"$old_LIBS\"\n"
  462. " fi\n\n");
  463. }
  464. Printf(f_extra," AC_DEFINE(HAVE_%(upper)s, 1, [ ])\n",module);
  465. Printf(f_extra,"dnl AC_DEFINE_UNQUOTED(PHP_%(upper)s_DIR, \"$%(upper)s_DIR\", [ ])\n",module,module);
  466. Printf(f_extra," PHP_EXTENSION(%s, $ext_shared)\n",module);
  467. // and thats all!
  468. Printf(f_extra,"fi\n");
  469. Close(f_extra);
  470. /* CREDITS */
  471. f_extra = NewFile(credits, "w");
  472. if (!f_extra) {
  473. Printf(stderr,"Unable to open %s\n",credits);
  474. SWIG_exit(EXIT_FAILURE);
  475. }
  476. Printf(f_extra, "%s\n", module);
  477. Close(f_extra);
  478. }
  479. }
  480. /* ------------------------------------------------------------
  481. * top()
  482. * ------------------------------------------------------------ */
  483. virtual int top(Node *n) {
  484. String *filen;
  485. String *s_type;
  486. /* Initialize all of the output files */
  487. String *outfile = Getattr(n,"outfile");
  488. /* main output file */
  489. f_runtime = NewFile(outfile,"w");
  490. if (!f_runtime) {
  491. Printf(stderr,"*** Can't open '%s'\n", outfile);
  492. SWIG_exit(EXIT_FAILURE);
  493. }
  494. Swig_banner(f_runtime);
  495. /* sections of the output file */
  496. s_init = NewString("/* init section */\n");
  497. s_header = NewString("/* header section */\n");
  498. s_wrappers = NewString("/* wrapper section */\n");
  499. s_type = NewString("");
  500. /* subsections of the init section */
  501. s_vinit = NewString("/* vinit subsection */\n");
  502. s_vdecl = NewString("/* vdecl subsection */\n");
  503. s_cinit = NewString("/* cinit subsection */\n");
  504. s_oinit = NewString("/* oinit subsection */\n");
  505. pragma_phpinfo = NewString("");
  506. /* Register file targets with the SWIG file handler */
  507. Swig_register_filebyname("runtime",f_runtime);
  508. Swig_register_filebyname("init",s_init);
  509. Swig_register_filebyname("header",s_header);
  510. Swig_register_filebyname("wrapper",s_wrappers);
  511. shadow_classdef = NewString("");
  512. shadow_code = NewString("");
  513. php_enum_code = NewString("");
  514. module_baseclass = NewString("");
  515. all_shadow_extra_code = NewString("");
  516. all_shadow_import = NewString("");
  517. all_shadow_baseclass = NewString("");
  518. /* Set the module name */
  519. module = Copy(Getattr(n,"name"));
  520. cap_module = NewStringf("%(upper)s",module);
  521. if(shadow) {
  522. realpackage = module;
  523. package = NewStringf("%sc", module);
  524. }
  525. /* Set the dlname */
  526. if (!dlname) {
  527. #if defined(_WIN32) || defined(__WIN32__)
  528. dlname = NewStringf("%s.dll", module);
  529. #else
  530. dlname = NewStringf("%s.so", module);
  531. #endif
  532. }
  533. /* PHP module file */
  534. filen = NewString("");
  535. Printv(filen, SWIG_output_directory(), module, ".php", NIL);
  536. phpfilename = NewString(filen);
  537. f_phpcode = NewFile(filen, "w");
  538. if (!f_phpcode) {
  539. Printf(stderr, "*** Can't open '%s'\n", filen);
  540. SWIG_exit(EXIT_FAILURE);
  541. }
  542. Printf(f_phpcode, "<?php\n\n");
  543. Swig_banner(f_phpcode);
  544. Printf(f_phpcode,
  545. "global $%s_LOADED__;\n"
  546. "if ($%s_LOADED__) return;\n"
  547. "$%s_LOADED__ = true;\n\n"
  548. "/* if our extension has not been loaded, do what we can */\n"
  549. "if (!extension_loaded(\"php_%s\")) {\n"
  550. " if (!dl(\"php_%s\")) return;\n"
  551. "}\n\n", cap_module, cap_module, cap_module, module, dlname);
  552. /* sub-sections of the php file */
  553. pragma_code = NewString("");
  554. pragma_incl = NewString("");
  555. /* Initialize the rest of the module */
  556. f_php = NewWrapper();// wots this used for now?
  557. /* start the header section */
  558. Printf(s_header, php_header);
  559. Printf(s_header,
  560. "#define SWIG_init init%s\n\n"
  561. "#define SWIG_name \"%s\"\n"
  562. /* "#ifdef HAVE_CONFIG_H\n"
  563. "#include \"config.h\"\n"
  564. "#endif\n\n"
  565. */
  566. "#ifdef __cplusplus\n"
  567. "extern \"C\" {\n"
  568. "#endif\n"
  569. "#include \"php.h\"\n"
  570. "#include \"php_ini.h\"\n"
  571. "#include \"ext/standard/info.h\"\n"
  572. "#include \"php_%s.h\"\n"
  573. "#ifdef __cplusplus\n"
  574. "}\n"
  575. "#endif\n\n",
  576. module, module, module);
  577. /* Create the .h file too */
  578. filen = NewString("");
  579. Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL);
  580. f_h = NewFile(filen, "w");
  581. if (!f_h) {
  582. Printf(stderr,"Unable to open %s\n", filen);
  583. SWIG_exit(EXIT_FAILURE);
  584. }
  585. Swig_banner(f_h);
  586. Printf(f_h, php_header);
  587. Printf(f_h, "\n\n"
  588. "#ifndef PHP_%s_H\n"
  589. "#define PHP_%s_H\n\n"
  590. "extern zend_module_entry %s_module_entry;\n"
  591. "#define phpext_%s_ptr &%s_module_entry\n\n"
  592. "#ifdef PHP_WIN32\n"
  593. "# define PHP_%s_API __declspec(dllexport)\n"
  594. "#else\n"
  595. "# define PHP_%s_API\n"
  596. "#endif\n\n"
  597. "PHP_MINIT_FUNCTION(%s);\n"
  598. "PHP_MSHUTDOWN_FUNCTION(%s);\n"
  599. "PHP_RINIT_FUNCTION(%s);\n"
  600. "PHP_RSHUTDOWN_FUNCTION(%s);\n"
  601. "PHP_MINFO_FUNCTION(%s);\n\n",
  602. cap_module, cap_module, module, module, module, cap_module, cap_module,
  603. module, module, module, module, module);
  604. /* start the function entry section */
  605. s_entry = NewString("/* entry subsection */\n");
  606. /* holds all the per-class function entry sections */
  607. all_cs_entry = NewString("/* class entry subsection */\n");
  608. cs_entry = NULL;
  609. Printf(s_entry,"/* Every non-class user visible function must have an entry here */\n");
  610. Printf(s_entry,"function_entry %s_functions[] = {\n", module);
  611. /* start the init section */
  612. if (gen_extra)
  613. Printf(s_init,"#ifdef COMPILE_DL_%s\n", cap_module);
  614. Printf(s_init,
  615. "#ifdef __cplusplus\n"
  616. "extern \"C\" {\n"
  617. "#endif\n"
  618. "ZEND_GET_MODULE(%s)\n"
  619. "#ifdef __cplusplus\n"
  620. "}\n"
  621. "#endif\n\n",
  622. module);
  623. if (gen_extra)
  624. Printf(s_init,"#endif\n\n");
  625. Printf(s_init,
  626. "PHP_MSHUTDOWN_FUNCTION(%s)\n{\n"
  627. " return SUCCESS;\n"
  628. "}\n",
  629. module);
  630. /* We have to register the constants before they are (possibly) used
  631. * by the pointer typemaps. This all needs re-arranging really as
  632. * things are being called in the wrong order
  633. */
  634. Printf(s_init,"PHP_MINIT_FUNCTION(%s)\n{\n", module);
  635. Printf(s_init,
  636. " int i;\n"
  637. " for (i = 0; swig_types_initial[i]; i++) {\n"
  638. " swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n"
  639. " }\n");
  640. /* Emit all of the code */
  641. Language::top(n);
  642. SwigPHP_emit_resource_registrations();
  643. // Printv(s_init,s_resourcetypes,NIL);
  644. /* We need this after all classes written out by ::top */
  645. Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
  646. Printf(s_oinit, "/* end oinit subsection */\n");
  647. Printf(s_init, "%s\n", s_oinit);
  648. /* Constants generated during top call */
  649. // But save them for RINIT
  650. Printf(s_cinit, "/* end cinit subsection */\n");
  651. /* finish our init section which will have been used by class wrappers */
  652. Printf(s_vinit, "/* end vinit subsection */\n");
  653. Printf(s_init, " return SUCCESS;\n");
  654. Printf(s_init,"}\n");
  655. // Now do REQUEST init which holds cinit and vinit
  656. Printf(s_init,
  657. "PHP_RINIT_FUNCTION(%s)\n{\n",
  658. module);
  659. Printf(s_init, "%s\n", s_cinit);
  660. Clear(s_cinit);
  661. Printf(s_init, "%s\n", s_vinit);
  662. Clear(s_vinit);
  663. Printf(s_init,
  664. " return SUCCESS;\n"
  665. "}\n");
  666. Delete(s_cinit);
  667. Delete(s_vinit);
  668. Printf(s_init,
  669. "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n"
  670. " return SUCCESS;\n"
  671. "}\n",
  672. module);
  673. Printf(s_init,
  674. "PHP_MINFO_FUNCTION(%s)\n{\n"
  675. "%s"
  676. "}\n"
  677. "/* end init section */\n",
  678. module, pragma_phpinfo);
  679. /* Complete header file */
  680. Printf(f_h,
  681. "/*If you declare any globals in php_%s.h uncomment this:\n"
  682. "ZEND_BEGIN_MODULE_GLOBALS(%s)\n"
  683. "ZEND_END_MODULE_GLOBALS(%s)\n"
  684. "*/\n",
  685. module, module, module);
  686. Printf(f_h,
  687. "#ifdef ZTS\n"
  688. "#define %s_D zend_%s_globals *%s_globals\n"
  689. "#define %s_DC , %s_D\n"
  690. "#define %s_C %s_globals\n"
  691. "#define %s_CC , %s_C\n"
  692. "#define %s_SG(v) (%s_globals->v)\n"
  693. "#define %s_FETCH() zend_%s_globals *%s_globals "
  694. "= ts_resource(%s_globals_id)\n"
  695. "#else\n"
  696. "#define %s_D\n"
  697. "#define %s_DC\n"
  698. "#define %s_C\n"
  699. "#define %s_CC\n"
  700. "#define %s_SG(v) (%s_globals.v)\n"
  701. "#define %s_FETCH()\n"
  702. "#endif\n\n"
  703. "#endif /* PHP_%s_H */\n",
  704. cap_module, module, module, cap_module, cap_module, cap_module, module,
  705. cap_module, cap_module, cap_module, module, cap_module, module, module,
  706. module, cap_module, cap_module, cap_module, cap_module, cap_module, module,
  707. cap_module, cap_module);
  708. Close(f_h);
  709. Printf(s_header, "%s\n\n",all_cs_entry);
  710. Printf(s_header,
  711. "%s"
  712. " {NULL, NULL, NULL}\n};\n\n"
  713. "zend_module_entry %s_module_entry = {\n"
  714. "#if ZEND_MODULE_API_NO > 20010900\n"
  715. " STANDARD_MODULE_HEADER,\n"
  716. "#endif\n"
  717. " \"%s\",\n"
  718. " %s_functions,\n"
  719. " PHP_MINIT(%s),\n"
  720. " PHP_MSHUTDOWN(%s),\n"
  721. " PHP_RINIT(%s),\n"
  722. " PHP_RSHUTDOWN(%s),\n"
  723. " PHP_MINFO(%s),\n"
  724. "#if ZEND_MODULE_API_NO > 20010900\n"
  725. " NO_VERSION_YET,\n"
  726. "#endif\n"
  727. " STANDARD_MODULE_PROPERTIES\n"
  728. "};\nzend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n",
  729. s_entry, module, module, module, module, module, module, module,module,module);
  730. String *type_table = NewString("");
  731. SwigType_emit_type_table(f_runtime,type_table);
  732. Printf(s_header,"%s",type_table);
  733. Delete(type_table);
  734. /* Oh dear, more things being called in the wrong order. This whole
  735. * function really needs totally redoing.
  736. */
  737. Printv(f_runtime, s_header, NIL);
  738. // Wrapper_print(f_c, s_wrappers);
  739. Wrapper_print(f_php, s_wrappers);
  740. Printf(s_header, "/* end header section */\n");
  741. Printf(s_wrappers, "/* end wrapper section */\n");
  742. Printf(s_vdecl, "/* end vdecl subsection */\n");
  743. Printv(f_runtime, s_vdecl, s_wrappers, s_init, NIL);
  744. Delete(s_header);
  745. Delete(s_wrappers);
  746. Delete(s_init);
  747. Delete(s_vdecl);
  748. Close(f_runtime);
  749. Printf(f_phpcode, "%s\n%s\n?>\n", pragma_incl, pragma_code);
  750. Close(f_phpcode);
  751. create_extra_files(outfile);
  752. if(!gen_extra && gen_make)
  753. create_simple_make();
  754. return SWIG_OK;
  755. }
  756. /* Just need to append function names to function table to register with
  757. PHP
  758. */
  759. void create_command(char *cname, char *iname) {
  760. // char *lower_cname = Swig_copy_string(cname);
  761. // char *c;
  762. // for(c = lower_cname; *c != '\0'; c++) {
  763. // if(*c >= 'A' && *c <= 'Z')
  764. // *c = *c + 32;
  765. // }
  766. Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
  767. // This is for the single main function_entry record
  768. if (! cs_entry) Printf(s_entry,
  769. " ZEND_NAMED_FE(%(lower)s,\n"
  770. " %s, NULL)\n", cname,iname);
  771. // free(lower_cname);
  772. }
  773. /* ------------------------------------------------------------
  774. * functionWrapper()
  775. * ------------------------------------------------------------ */
  776. virtual int functionWrapper(Node *n) {
  777. char *name = GetChar(n,"name");
  778. char *iname = GetChar(n,"sym:name");
  779. SwigType *d = Getattr(n,"type");
  780. ParmList *l = Getattr(n,"parms");
  781. int newobject = (Getattr(n,"feature:new"))?1:0;
  782. Parm *p;
  783. char source[256],target[256],temp[256],argnum[32],args[32];
  784. int i,numopt;
  785. String *tm;
  786. Wrapper *f;
  787. int num_saved = (Getattr(n,"feature:new"))?1:0;
  788. String *cleanup, *outarg;
  789. bool mvr=(shadow && variable_wrapper_flag && !enum_flag);
  790. bool mvrset=0;
  791. if (!addSymbol(iname,n)) return SWIG_ERROR;
  792. mvrset=(mvr && (strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0));
  793. // if shadow and variable wrapper we want to snag the main contents
  794. // of this function to stick in to the property handler....
  795. if (mvr) { //shadow && variable_wrapper_flag && !enum_flag) {
  796. String *member_function_name = NewString("");
  797. String *php_function_name = NewString(iname);
  798. if(strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0) {
  799. Setattr(shadow_set_vars, php_function_name, name);
  800. }
  801. if(strcmp(iname, Char(Swig_name_get(Swig_name_member(shadow_classname, name)))) == 0) {
  802. Setattr(shadow_get_vars, php_function_name, name);
  803. }
  804. Putc(toupper((int )*iname), member_function_name);
  805. Printf(member_function_name, "%s", iname+1);
  806. cpp_func(l, php_function_name);
  807. Delete(php_function_name);
  808. Delete(member_function_name);
  809. }
  810. outarg = cleanup = NULL;
  811. f = NewWrapper();
  812. numopt = 0;
  813. outarg = NewString("");
  814. cleanup = NewString("");
  815. // Special action for shadowing destructors under php.
  816. // The real destructor is the resource list destructor, this is
  817. // merely the thing that actually knows how to destroy...
  818. if (destructor) {
  819. String *destructorname=NewString("");
  820. Printf(destructorname,"_%s",Swig_name_wrapper(iname));
  821. Setattr(classnode,"destructor",destructorname);
  822. Wrapper *df = NewWrapper();
  823. Printf(df->def,"/* This function is designed to be called by the zend list destructors to typecast and do the actual destruction */\n"
  824. "void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n",destructorname);
  825. Wrapper_add_localv(df, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL);
  826. Wrapper_add_localv(df, "ptr", "void *ptr=value->ptr", NIL);
  827. Wrapper_add_localv(df, "newobject", "int newobject=value->newobject", NIL);
  828. // Magic spell nicked from further down.
  829. emit_args(d, l, df);
  830. emit_attach_parmmaps(l,f);
  831. // Get type of first arg, thing to be destructed
  832. // Skip ignored arguments
  833. {
  834. p=l;
  835. //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");}
  836. while (checkAttribute(p,"tmap:in:numinputs","0")) {
  837. p = Getattr(p,"tmap:in:next");
  838. }
  839. SwigType *pt = Getattr(p,"type");
  840. Printf(df->code,
  841. " efree(value);\n"
  842. " if (! newobject) return; /* can't delete it! */\n"
  843. " SWIG_ZTS_ConvertResourceData(ptr,rsrc->type,type_name,(void **) &arg1,SWIGTYPE%s TSRMLS_CC);\n"
  844. " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n"
  845. ,SwigType_manglestr(pt), shadow_classname);
  846. }
  847. emit_action(n,df);
  848. Printf(df->code,"}\n");
  849. Wrapper_print(df,s_wrappers);
  850. }
  851. if (mvr) { // do prop[gs]et header
  852. if (mvrset) Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n",iname);
  853. else Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n",iname);
  854. } else { // regular header
  855. create_command(iname, Char(Swig_name_wrapper(iname)));
  856. Printv(f->def, "ZEND_NAMED_FUNCTION(" , Swig_name_wrapper(iname), ") {\n", NIL);
  857. }
  858. emit_args(d, l, f);
  859. /* Attach standard typemaps */
  860. emit_attach_parmmaps(l,f);
  861. int num_arguments = emit_num_arguments(l);
  862. int num_required = emit_num_required(l);
  863. numopt = num_arguments - num_required;
  864. // we do +1 because we are going to push in this_ptr as arg0 if present
  865. // or do we need to?
  866. sprintf(args, "%s[%d]", "zval **args", num_arguments+1);
  867. Wrapper_add_local(f, "args",args);
  868. Wrapper_add_localv(f, "argbase", "int argbase=0", NIL);
  869. // This generated code may be called
  870. // 1) as an object method, or
  871. // 2) as a class-method/function (without a "this_ptr")
  872. // Option (1) has "this_ptr" for "this", option (2) needs it as
  873. // first parameter
  874. // NOTE: possible we ignore this_ptr as a param for native constructor
  875. if (native_constructor) {
  876. if (native_constructor==NATIVE_CONSTRUCTOR) Printf(f->code, "/* NATIVE Constructor */\nint self_constructor=1;\n");
  877. else Printf(f->code, "/* ALTERNATIVE Constructor */\n");
  878. }
  879. if (mvr && ! mvrset) {
  880. Wrapper_add_local(f, "_return_value", "zval _return_value");
  881. Wrapper_add_local(f, "return_value", "zval *return_value=&_return_value");
  882. };
  883. // only let this_ptr count as arg[-1] if we are not a constructor
  884. // if we are a constructor and this_ptr is null we are called as a class
  885. // method and can make one of us
  886. if (! mvr && native_constructor==0) Printf(f->code,
  887. "if (this_ptr && this_ptr->type==IS_OBJECT) {\n"
  888. " /* fake this_ptr as first arg (till we can work out how to do it better */\n"
  889. " argbase++;\n"
  890. "}\n");
  891. // I'd like to write out:
  892. //" //args[argbase++]=&this_ptr;\n"
  893. // but zend_get_parameters_array_ex can't then be told to leave
  894. // the first slot alone, so we have to check whether or not to access
  895. // this_ptr explicitly in each case where we normally just read args[]
  896. if(numopt > 0) { // membervariable wrappers do not have optional args
  897. Wrapper_add_local(f, "arg_count", "int arg_count");
  898. Printf(f->code,
  899. "arg_count = ZEND_NUM_ARGS();\n"
  900. "if(arg_count<(%d-argbase) || arg_count>(%d-argbase))\n"
  901. "\tWRONG_PARAM_COUNT;\n\n",
  902. num_required, num_arguments);
  903. /* Verified args, retrieve them... */
  904. Printf(f->code,
  905. "if(zend_get_parameters_array_ex(arg_count-argbase,args)!=SUCCESS)"
  906. "\n\t\tWRONG_PARAM_COUNT;\n\n");
  907. } else if (!mvr) {
  908. Printf(f->code,
  909. "if(((ZEND_NUM_ARGS() + argbase )!= %d) || (zend_get_parameters_array_ex(%d-argbase, args)"
  910. "!= SUCCESS)) {\n"
  911. "WRONG_PARAM_COUNT;\n}\n\n",
  912. num_arguments, num_arguments);
  913. }
  914. /* Now convert from php to C variables */
  915. // At this point, argcount if used is the number of deliberatly passed args
  916. // not including this_ptr even if it is used.
  917. // It means error messages may be out by argbase with error
  918. // reports. We can either take argbase into account when raising
  919. // errors, or find a better way of dealing with _thisptr
  920. // I would like, if objects are wrapped, to assume _thisptr is always
  921. // _this and the and not the first argument
  922. // This may mean looking at Lang::memberfunctionhandler
  923. for (i = 0, p = l; i < num_arguments; i++) {
  924. /* Skip ignored arguments */
  925. //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
  926. while (checkAttribute(p,"tmap:in:numinputs","0")) {
  927. p = Getattr(p,"tmap:in:next");
  928. }
  929. SwigType *pt = Getattr(p,"type");
  930. if (mvr) { // do we assert that numargs=2, that i<2
  931. if (i==0) sprintf(source,"&(property_reference->object)");
  932. else sprintf(source,"&value");
  933. } else {
  934. // Do we fake this_ptr as arg0, or just possibly shift other args by 1 if we did fake?
  935. if (i==0) sprintf(source, "((%d<argbase)?(&this_ptr):(args[%d-argbase]))", i, i);
  936. else sprintf(source, "args[%d-argbase]", i); }
  937. sprintf(target, "%s", Char(Getattr(p,"lname")));
  938. sprintf(argnum, "%d", i+1);
  939. /* Check if optional */
  940. if(i>= (num_required))
  941. Printf(f->code,"\tif(arg_count > %d) {\n", i);
  942. Setattr(p,"emit:input", source);
  943. if ((tm = Getattr(p,"tmap:in"))) {
  944. Replaceall(tm,"$target",target);
  945. Replaceall(tm,"$source",source);
  946. Replaceall(tm,"$input", source);
  947. Printf(f->code,"%s\n",tm);
  948. p = Getattr(p,"tmap:in:next");
  949. if (i >= num_required) {
  950. Printf(f->code,"}\n");
  951. }
  952. continue;
  953. } else {
  954. Printf(stderr,"%s : Line %d, Unable to use type %s as a function argument.\n", input_file, line_number, SwigType_str(pt,0));
  955. }
  956. if (i>= num_required)
  957. Printf(f->code,"\t}\n");
  958. }
  959. /* Insert constraint checking code */
  960. for (p = l; p;) {
  961. if ((tm = Getattr(p,"tmap:check"))) {
  962. Replaceall(tm,"$target",Getattr(p,"lname"));
  963. Printv(f->code,tm,"\n",NIL);
  964. p = Getattr(p,"tmap:check:next");
  965. } else {
  966. p = nextSibling(p);
  967. }
  968. }
  969. /* Insert cleanup code */
  970. for (i = 0, p = l; p; i++) {
  971. if ((tm = Getattr(p,"tmap:freearg"))) {
  972. Replaceall(tm,"$source",Getattr(p,"lname"));
  973. Printv(cleanup,tm,"\n",NIL);
  974. p = Getattr(p,"tmap:freearg:next");
  975. } else {
  976. p = nextSibling(p);
  977. }
  978. }
  979. /* Insert argument output code */
  980. num_saved = 0;
  981. for (i=0,p = l; p;i++) {
  982. if ((tm = Getattr(p,"tmap:argout"))) {
  983. Replaceall(tm,"$source",Getattr(p,"lname"));
  984. Replaceall(tm,"$input",Getattr(p,"lname"));
  985. Replaceall(tm,"$target","return_value");
  986. Replaceall(tm,"$result","return_value");
  987. String *in = Getattr(p,"emit:input");
  988. if (in) {
  989. sprintf(temp,"_saved[%d]", num_saved);
  990. Replaceall(tm,"$arg",temp);
  991. Printf(f->code,"_saved[%d] = %s;\n", num_saved, in);
  992. num_saved++;
  993. }
  994. Printv(outarg,tm,"\n",NIL);
  995. p = Getattr(p,"tmap:argout:next");
  996. } else {
  997. p = nextSibling(p);
  998. }
  999. }
  1000. // These are saved for argout again...
  1001. if(num_saved) {
  1002. sprintf(temp, "_saved[%d]",num_saved);
  1003. // Used to be zval *, perhaps above we should use * %s
  1004. Wrapper_add_localv(f,"_saved","zval **",temp,NIL);
  1005. }
  1006. /* emit function call*/
  1007. if (destructor) {
  1008. // If it is a registered resource (and it always should be)
  1009. // then destroy it the resource way
  1010. Printf(f->code,
  1011. "/*if ((*args[0])->type==IS_RESOURCE) { */\n"
  1012. "/* Get zend list destructor to free it */\n"
  1013. "/* zend_list_delete(Z_LVAL_PP(args[0])); */\n"
  1014. "/* } else {*/ \n",name,name
  1015. );
  1016. // but leave the old way in for as long as we accept strings as swig objects
  1017. emit_action(n,f);
  1018. Printf(f->code,"/*}*/\n");
  1019. } else {
  1020. emit_action(n,f);
  1021. }
  1022. if((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"result",(char*)"return_value",0))) {
  1023. Replaceall(tm, "$input", "result");
  1024. Replaceall(tm, "$source", "result");
  1025. Replaceall(tm, "$target", "return_value");
  1026. Replaceall(tm, "$result", "return_value");
  1027. Replaceall(tm,"$owner", newobject ? "1" : "0");
  1028. Printf(f->code, "%s\n", tm);
  1029. // are we returning a wrapable object?
  1030. // I don't know if this test is comlete, I nicked it
  1031. if(is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
  1032. Printf(f->code,"/* Wrap this return value */\n");
  1033. if (native_constructor==NATIVE_CONSTRUCTOR) {
  1034. Printf(f->code, "if (this_ptr) {\n/* NATIVE Constructor, use this_ptr */\n");
  1035. Printf(f->code,"zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n"
  1036. "*_cPtr = *return_value;\n"
  1037. "INIT_ZVAL(*return_value);\n"
  1038. "add_property_zval(this_ptr,\"_cPtr\",_cPtr);\n"
  1039. "} else if (! this_ptr) ",shadow_classname);
  1040. }
  1041. { // THIS CODE only really needs writing out if the object to be returned
  1042. // Is being shadow-wrap-thingied
  1043. Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n");
  1044. // Make object
  1045. String *shadowrettype = NewString("");
  1046. SwigToPhpType(d, iname, shadowrettype, shadow);
  1047. Printf(f->code,
  1048. "zval *obj, *_cPtr;\n"
  1049. "MAKE_STD_ZVAL(obj);\n"
  1050. "MAKE_STD_ZVAL(_cPtr);\n"
  1051. "*_cPtr = *return_value;\n"
  1052. "INIT_ZVAL(*return_value);\n");
  1053. if (! shadow) {
  1054. Printf(f->code,
  1055. "*return_value=*_cPtr;\n");
  1056. } else {
  1057. Printf(f->code,
  1058. "object_init_ex(obj,ptr_ce_swig_%s);\n"
  1059. "add_property_zval(obj,\"_cPtr\",_cPtr);\n"
  1060. "*return_value=*obj;\n",
  1061. shadowrettype);
  1062. }
  1063. Printf(f->code, "}\n");
  1064. }
  1065. } // end of if-shadow lark
  1066. } else {
  1067. Printf(stderr,"%s: Line %d, Unable to use return type %s in function %s.\n", input_file, line_number, SwigType_str(d,0), name);
  1068. }
  1069. if(outarg)
  1070. Printv(f->code,outarg,NIL);
  1071. if(cleanup)
  1072. Printv(f->code,cleanup,NIL);
  1073. // Whats this bit for?
  1074. if((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char *)"result", (char*)"result",(char*)"",0))) {
  1075. Printf(f->code,"%s\n", tm);
  1076. }
  1077. Replaceall(f->code,"$cleanup",cleanup);
  1078. Replaceall(f->code,"$symname",iname);
  1079. if (mvr) {
  1080. if (! mvrset) Printf(f->code,"return _return_value;\n");
  1081. else Printf(f->code,"return SUCCESS;\n");
  1082. }
  1083. Printf(f->code, "}\n");
  1084. Wrapper_print(f,s_wrappers);
  1085. return SWIG_OK;
  1086. }
  1087. /* ------------------------------------------------------------
  1088. * variableWrapper()
  1089. * ------------------------------------------------------------ */
  1090. virtual int OLDvariableWrapper(Node *n) {
  1091. char *name = GetChar(n,"name");
  1092. char *iname = GetChar(n,"sym:name");
  1093. SwigType *t = Getattr(n,"type");
  1094. String *tm;
  1095. if (!addSymbol(iname,n)) return SWIG_ERROR;
  1096. SwigType_remember(t);
  1097. /* First link C variables to PHP */
  1098. tm = Swig_typemap_lookup_new("varinit", n, name, 0);
  1099. if(tm) {
  1100. Replaceall(tm, "$target", name);
  1101. Printf(s_vinit, "%s\n", tm);
  1102. } else {
  1103. Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
  1104. input_file, line_number, SwigType_str(t,0), name);
  1105. }
  1106. /* Now generate PHP -> C sync blocks */
  1107. tm = Swig_typemap_lookup_new("varin", n, name, 0);
  1108. /*
  1109. if(tm) {
  1110. Replaceall(tm, "$symname", iname);
  1111. Printf(f_c->code, "%s\n", tm);
  1112. } else {
  1113. Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
  1114. input_file, line_number, SwigType_str(t, 0), name);
  1115. }
  1116. */
  1117. /* Now generate C -> PHP sync blocks */
  1118. /*
  1119. if(!Getattr(n,"feature:immutable")) {
  1120. tm = Swig_typemap_lookup_new("varout", n, name, 0);
  1121. if(tm) {
  1122. Replaceall(tm, "$symname", iname);
  1123. Printf(f_php->code, "%s\n", tm);
  1124. } else {
  1125. Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
  1126. input_file, line_number, SwigType_str(t, 0), name);
  1127. }
  1128. }
  1129. */
  1130. return SWIG_OK;
  1131. }
  1132. /* ------------------------------------------------------------
  1133. * constantWrapper()
  1134. * ------------------------------------------------------------ */
  1135. virtual int constantWrapper(Node *n) {
  1136. char *name = GetChar(n,"name");
  1137. char *iname = GetChar(n,"sym:name");
  1138. SwigType *type = Getattr(n,"type");
  1139. char *value = GetChar(n,"value");
  1140. if (!addSymbol(iname,n)) return SWIG_ERROR;
  1141. String *rval;
  1142. String *tm;
  1143. SwigType_remember(type);
  1144. switch(SwigType_type(type)) {
  1145. case T_STRING:
  1146. rval = NewStringf("\"%s\"", value);
  1147. break;
  1148. case T_CHAR:
  1149. rval = NewStringf("\'%s\'", value);
  1150. break;
  1151. default:
  1152. rval = NewString(value);
  1153. }
  1154. if((tm = Swig_typemap_lookup_new("consttab", n, name, 0))) {
  1155. Replaceall(tm, "$source", value);
  1156. Replaceall(tm, "$target", name);
  1157. Replaceall(tm, "$value", value);
  1158. Printf(s_cinit, "%s\n", tm);
  1159. }
  1160. return SWIG_OK;
  1161. }
  1162. /*
  1163. * PHP4::pragma()
  1164. *
  1165. * Pragma directive.
  1166. *
  1167. * %pragma(php4) code="String" # Includes a string in the .php file
  1168. * %pragma(php4) include="file.pl" # Includes a file in the .php file
  1169. */
  1170. virtual int pragmaDirective(Node *n) {
  1171. if (!ImportMode) {
  1172. String *lang = Getattr(n,"lang");
  1173. String *type = Getattr(n,"name");
  1174. String *value = Getattr(n,"value");
  1175. if (Strcmp(lang,"php4") == 0) {
  1176. if (Strcmp(type, "code") == 0) {
  1177. if (value)
  1178. Printf(pragma_code, "%s\n", value);
  1179. } else if (Strcmp(type, "include") == 0) {
  1180. if (value)
  1181. Printf(pragma_incl, "include \"%s\";\n", value);
  1182. } else if (Strcmp(type, "phpinfo") == 0) {
  1183. if (value)
  1184. Printf(pragma_phpinfo, "%s\n", value);
  1185. } else {
  1186. Printf(stderr, "%s : Line %d. Unrecognized pragma.\n",
  1187. input_file, line_number);
  1188. }
  1189. }
  1190. }
  1191. return Language::pragmaDirective(n);
  1192. }
  1193. /* ------------------------------------------------------------
  1194. * classDeclaration()
  1195. * ------------------------------------------------------------ */
  1196. virtual int classDeclaration(Node *n) {
  1197. String *symname = Getattr(n,"sym:name");
  1198. Setattr(n,"php:proxy",symname);
  1199. return Language::classDeclaration(n);
  1200. }
  1201. /* ------------------------------------------------------------
  1202. * classHandler()
  1203. * ------------------------------------------------------------ */
  1204. virtual int classHandler(Node *n) {
  1205. constructors=0;
  1206. //SwigType *t = Getattr(n, "classtype");
  1207. if(class_name) free(class_name);
  1208. class_name = Swig_copy_string(GetChar(n, "name"));
  1209. // String *use_class_name=SwigType_manglestr(SwigType_ltype(t));
  1210. if(shadow) {
  1211. char *rename = GetChar(n, "sym:name");
  1212. if (!addSymbol(rename,n)) return SWIG_ERROR;
  1213. shadow_classname = Swig_copy_string(rename);
  1214. cs_entry = NewString("");
  1215. Printf(cs_entry,"/* Function entries for %s */\n"
  1216. "static zend_function_entry %s_functions[] = {\n"
  1217. ,shadow_classname, shadow_classname);
  1218. if(Strcmp(shadow_classname, module) == 0) {
  1219. Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname);
  1220. SWIG_exit(1);
  1221. }
  1222. Clear(shadow_classdef);
  1223. Clear(shadow_code);
  1224. have_default_constructor = 0;
  1225. shadow_enum_code = NewString("");
  1226. this_shadow_baseclass = NewString("");
  1227. this_shadow_multinherit = NewString("");
  1228. this_shadow_extra_code = NewString("");
  1229. this_shadow_import = NewString("");
  1230. shadow_get_vars = NewHash();
  1231. shadow_set_vars = NewHash();
  1232. /* Deal with inheritance */
  1233. List *baselist = Getattr(n, "bases");
  1234. if(baselist) {
  1235. int class_count = 0;
  1236. Iterator base = First(baselist);
  1237. while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base);
  1238. if (base.item && is_shadow(Getattr(base.item, "name"))) {
  1239. class_count++;
  1240. Printf(this_shadow_baseclass, "%s", Getattr(base.item, "name"));
  1241. }
  1242. if (base.item) for(base = Next(base); base.item; base = Next(base)) {
  1243. if (Getattr(base.item,"feature:ignore")) continue;
  1244. if(is_shadow(Getattr(base.item, "name"))) {
  1245. class_count++;
  1246. Printf(this_shadow_multinherit, "%s ", Getattr(base.item, "name"));
  1247. }
  1248. }
  1249. if(class_count > 1) Printf(stderr, "Error: %s inherits from multiple base classes(%s %s). Multiple inheritance is not directly supported by PHP4, SWIG may support it at some point in the future.\n", shadow_classname, base.item, this_shadow_multinherit);
  1250. }
  1251. /* Write out class init code */
  1252. Printf(s_vdecl,"static zend_class_entry ce_swig_%s;\n",shadow_classname);
  1253. Printf(s_vdecl,"static zend_class_entry* ptr_ce_swig_%s=NULL;\n",shadow_classname);
  1254. }
  1255. classnode=n;
  1256. Language::classHandler(n);
  1257. classnode=0;
  1258. if(shadow) {
  1259. DOH *key;
  1260. int gcount, scount;
  1261. String *s_propget=NewString("");
  1262. String *s_propset=NewString("");
  1263. List *baselist = Getattr(n, "bases");
  1264. Iterator ki, base;
  1265. // If no constructor was generated (abstract class) we had better
  1266. // generate a constructor that raises an error about instantiating
  1267. // abstract classes
  1268. if (! constructors || Getattr(n,"abstract")) {
  1269. // have to write out fake constructor which raises an error when called
  1270. abstractConstructorHandler(n);
  1271. }
  1272. Printf(s_oinit,"/* Define class %s */\n"
  1273. "INIT_OVERLOADED_CLASS_ENTRY(ce_swig_%s,\"%(lower)s\",%s_functions,"
  1274. "NULL,_wrap_propget_%s,_wrap_propset_%s);\n",
  1275. shadow_classname,shadow_classname,shadow_classname,
  1276. shadow_classname,shadow_classname,shadow_classname);
  1277. // ******** Write property SET handlers
  1278. Printf(s_header,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
  1279. Printf(s_propset,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value) { \n"
  1280. " zval * _value;\n"
  1281. " zend_llist_element *element = property_reference->elements_list->head;\n"
  1282. " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
  1283. " if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n"
  1284. " /* set it ourselves as it is %s */\n"
  1285. " MAKE_STD_ZVAL(_value);\n"
  1286. " *_value=*value;\n"
  1287. " INIT_PZVAL(_value);\n"
  1288. " zval_copy_ctor(_value);\n"
  1289. " return add_property_zval_ex(property_reference->object,Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),_value);\n"
  1290. "}\n", shadow_classname, shadow_classname,shadow_classname);
  1291. Printf(s_header,"static int _propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
  1292. Printf(s_propset,"static int _propset_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname);
  1293. if (baselist) base=First(baselist);
  1294. else base.item = NULL;
  1295. while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base);
  1296. ki = First(shadow_set_vars);
  1297. key = ki.key;
  1298. // Print function header; we only need to find property name if there
  1299. // are properties for this class to look up...
  1300. if (key || ! base.item) { // or if we are base class and set it ourselves
  1301. Printf(s_propset," /* get the property name */\n"
  1302. " zend_llist_element *element = property_reference->elements_list->head;\n"
  1303. " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
  1304. " char *propname=Z_STRVAL_P(&(property->element));\n");
  1305. } else {
  1306. if (base.item) {
  1307. Printf(s_propset," /* No extra properties for subclass %s */\n",shadow_classname);
  1308. } else {
  1309. Printf(s_propset," /* No properties for base class %s */\n",shadow_classname);
  1310. }
  1311. }
  1312. scount=0;
  1313. while (ki.key) {
  1314. key = ki.key;
  1315. if (scount++) Printf(s_propset," else");
  1316. Printf(s_propset," if (strcmp(propname,\"%s\")==0) {\n"
  1317. " return _wrap_%s(property_reference, value);\n"
  1318. " }",Getattr(shadow_set_vars,key),key);
  1319. ki=Next(ki);
  1320. }
  1321. if (scount) Printf(s_propset," else");
  1322. // If there is a base class then chain it's handler else set directly
  1323. // try each base class handler, else set directly...
  1324. if (base.item) {
  1325. Printf(s_propset, " {\n /* chain to base class */\n");
  1326. while(base.item) {
  1327. Printf(s_propset," if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n",
  1328. GetChar(base.item, "sym:name"));
  1329. base=Next(base);
  1330. while (base.item && Getattr(base.item,"feature:ignore")) base=Next(base);
  1331. }
  1332. Printf(s_propset," }\n");
  1333. }
  1334. Printf(s_propset," return FAILURE;\n}\n\n");
  1335. // ******** Write property GET handlers
  1336. Printf(s_header,"static pval _wrap_propget_%s(zend_property_reference *property_reference);\n", shadow_classname);
  1337. Printf(s_propget,"static pval _wrap_propget_%s(zend_property_reference *property_reference) {\n"
  1338. " pval result;\n"
  1339. " pval **_result;\n"
  1340. " zend_llist_element *element = property_reference->elements_list->head;\n"
  1341. " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
  1342. " result.type = IS_NULL;\n"
  1343. " if (_propget_%s(property_reference, &result)==SUCCESS) return result;\n"
  1344. " /* return it ourselves */\n"
  1345. " if (zend_hash_find(Z_OBJPROP_P(property_reference->object),Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),(void**)&_result)==SUCCESS) {\n"
  1346. " zval *_value;\n"
  1347. " MAKE_STD_ZVAL(_value);"
  1348. " *_value=**_result;\n"
  1349. " INIT_PZVAL(_value);\n"
  1350. " zval_copy_ctor(_value);\n"
  1351. " return *_value;\n"
  1352. " }\n"
  1353. " result.type = IS_NULL;\n"
  1354. " return result;\n"
  1355. "}\n", shadow_classname, shadow_classname);
  1356. Printf(s_header,"static int _propget_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
  1357. Printf(s_propget,"static int _propget_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname);
  1358. if (baselist) base=First(baselist);
  1359. else base.item=NULL;
  1360. while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base);
  1361. ki = First(shadow_get_vars);
  1362. key = ki.key;
  1363. // Print function header; we only need to find property name if there
  1364. // are properties for this class to look up...
  1365. if (key || !base.item ) { // or if we are base class...
  1366. Printf(s_propget," /* get the property name */\n"
  1367. " zend_llist_element *element = property_reference->elements_list->head;\n"
  1368. " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
  1369. " char *propname=Z_STRVAL_P(&(property->element));\n");
  1370. } else {
  1371. if (base.item) {
  1372. Printf(s_propget," /* No extra properties for subclass %s */\n",shadow_classname);
  1373. } else {
  1374. Printf(s_propget," /* No properties for base class %s */\n",shadow_classname);
  1375. }
  1376. }
  1377. gcount=0;
  1378. while (ki.key) {
  1379. key = ki.key;
  1380. if (gcount++) Printf(s_propget," else");
  1381. Printf(s_propget," if (strcmp(propname,\"%s\")==0) {\n"
  1382. " *value=_wrap_%s(property_reference);\n"
  1383. " return SUCCESS;\n"
  1384. " }",Getattr(shadow_get_vars,key),key);
  1385. ki=Next(ki);
  1386. }
  1387. if (gcount) Printf(s_propget," else");
  1388. // If there is a base class then chain it's handler else return null
  1389. if (base.item) {
  1390. Printf(s_propget, " {\n /* chain to base class */\n");
  1391. while(base.item) {
  1392. Printf(s_propget," if (_propget_%s(property_reference, value)==SUCCESS) return SUCCESS;\n",
  1393. GetChar(base.item, "sym:name"));
  1394. base=Next(base);
  1395. while (base.item && Getattr(base.item,"feature:ignore")) base=Next(base);
  1396. }
  1397. Printf(s_propget," }\n");
  1398. }
  1399. Printf(s_propget," return FAILURE;\n}\n\n");
  1400. // wrappers generated now...
  1401. // add wrappers to output code
  1402. Printf(s_wrappers,"/* property handler for class %s */\n",shadow_classname);
  1403. Printv(s_wrappers,s_propget,s_propset,NIL);
  1404. // Save class in class table
  1405. if (baselist) base=First(baselist);
  1406. else base.item=NULL;
  1407. while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base);
  1408. if (base.item) {
  1409. Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
  1410. shadow_classname,shadow_classname,GetChar(base.item, "sym:name"), shadow_classname);
  1411. } else {
  1412. Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
  1413. shadow_classname,shadow_classname, shadow_classname);
  1414. }
  1415. Printf(s_oinit,"\n");
  1416. Printv(f_phpcode, shadow_classdef, shadow_code, NIL);
  1417. // Write the enum initialisation code in a static block
  1418. // These are all the enums defined withing the c++ class.
  1419. // PHP Needs to handle shadow enums properly still
  1420. if(strlen(Char(shadow_enum_code)) != 0 ) Printv(f_phpcode, "{\n /* enum */\n", shadow_enum_code, " }\n", NIL);
  1421. free(shadow_classname);
  1422. shadow_classname = NULL;
  1423. Delete(shadow_enum_code); shadow_enum_code = NULL;
  1424. Delete(this_shadow_baseclass); this_shadow_baseclass = NULL;
  1425. Delete(this_shadow_extra_code); this_shadow_extra_code = NULL;
  1426. Delete(this_shadow_import); this_shadow_import = NULL;
  1427. Delete(shadow_set_vars); shadow_set_vars = NULL;
  1428. Delete(shadow_get_vars); shadow_get_vars = NULL;
  1429. Delete(this_shadow_multinherit); this_shadow_multinherit = NULL;
  1430. Printf(all_cs_entry,"%s { NULL, NULL, NULL}\n};\n",cs_entry);
  1431. //??delete cs_entry;
  1432. cs_entry=NULL;
  1433. }
  1434. return SWIG_OK;
  1435. }
  1436. /* ------------------------------------------------------------
  1437. * memberfunctionHandler()
  1438. * ------------------------------------------------------------ */
  1439. virtual int memberfunctionHandler(Node *n) {
  1440. char *name = GetChar(n, "name");
  1441. char *iname = GetChar(n, "sym:name");
  1442. ParmList *l = Getattr(n, "parms");
  1443. this->Language::memberfunctionHandler(n);
  1444. if(shadow) {
  1445. char *realname = iname ? iname : name;
  1446. String *php_function_name = Swig_name_member(shadow_classname, realname);
  1447. cpp_func(l, realname, php_function_name);
  1448. }
  1449. return SWIG_OK;
  1450. }
  1451. /* ------------------------------------------------------------
  1452. * membervariableHandler()
  1453. * ------------------------------------------------------------ */
  1454. virtual int membervariableHandler(Node *n) {
  1455. wrapping_member = 1;
  1456. variable_wrapper_flag = 1;
  1457. Language::membervariableHandler(n);
  1458. wrapping_member = 0;
  1459. variable_wrapper_flag = 0;
  1460. return SWIG_OK;
  1461. }
  1462. /* ------------------------------------------------------------
  1463. * staticmemberfunctionHandler()
  1464. * ------------------------------------------------------------ */
  1465. virtual int staticmemberfunctionHandler(Node *n) {
  1466. char *name = GetChar(n, "name");
  1467. char *iname = GetChar(n, "sym:name");
  1468. Language::staticmemberfunctionHandler(n);
  1469. if(shadow) {
  1470. String *symname = Getattr(n, "sym:name");
  1471. static_flag = 1;
  1472. char *realname = iname ? iname : name;
  1473. String *php_function_name = Swig_name_member(shadow_classname, realname);
  1474. cpp_func(Getattr(n, "parms"), symname, php_function_name);
  1475. static_flag = 0;
  1476. }
  1477. return SWIG_OK;
  1478. }
  1479. /* ------------------------------------------------------------
  1480. * staticmembervariableHandler()
  1481. * ------------------------------------------------------------ */
  1482. virtual int staticmembervariableHandler(Node *n) {
  1483. SwigType *d = Getattr(n, "type");
  1484. char *iname = GetChar(n, "sym:name");
  1485. char *name = GetChar(n, "name");
  1486. String *static_name = NewStringf("%s::%s", class_name, name);
  1487. // String *use_class_name=SwigType_manglestr(SwigType_ltype(t));
  1488. Wrapper *f;
  1489. /* A temporary(!) hack for static member variables.
  1490. * Php currently supports class functions, but not class variables.
  1491. * Until it does, we convert a class variable to a class function
  1492. * that returns the current value of the variable. E.g.
  1493. *
  1494. * class Example {
  1495. * public:
  1496. * static int ncount;
  1497. * };
  1498. *
  1499. * would be available in php as Example::ncount()
  1500. */
  1501. static_flag = 1;
  1502. if(Getattr(n,"feature:immutable")) {
  1503. const_flag = 1;
  1504. }
  1505. cpp_func(0, iname);
  1506. static_flag = 0;
  1507. create_command(iname, Char(Swig_name_wrapper(iname)));
  1508. f = NewWrapper();
  1509. Printv(f->def, "ZEND_NAMED_FUNCTION(", Swig_name_wrapper(iname), ") {\n", NIL);
  1510. /* If a argument is given we set the variable. Then we return
  1511. * the current value
  1512. */
  1513. Printf(f->code,
  1514. "zval **args[1];\n"
  1515. "int argcount;\n\n"
  1516. "argcount = ZEND_NUM_ARGS();\n"
  1517. "if(argcount > %d) WRONG_PARAM_COUNT;\n\n", (const_flag? 0 : 1));
  1518. if(!const_flag) {
  1519. Printf(f->code, "if(argcount) {\n");
  1520. Printf(f->code, "if(zend_get_parameters_array_ex(argcount, args) != SUCCESS) WRONG_PARAM_COUNT;\n");
  1521. switch(SwigType_type(d)) {
  1522. case T_BOOL:
  1523. case T_INT:
  1524. case T_SHORT:
  1525. case T_LONG:
  1526. case T_SCHAR:
  1527. case T_UINT:
  1528. case T_USHORT:
  1529. case T_ULONG:
  1530. case T_UCHAR:
  1531. Printf(f->code,
  1532. "convert_to_long_ex(args[0]);\n"
  1533. "%s = Z_LVAL_PP(args[0]);\n", static_name);
  1534. break;
  1535. case T_CHAR:
  1536. Printf(f->code,
  1537. "convert_to_string_ex(args[0]);\n"
  1538. "%s = estrdup(Z_STRVAL(args[0]));\n", static_name);
  1539. break;
  1540. case T_DOUBLE:
  1541. case T_FLOAT:
  1542. Printf(f->code,
  1543. "convert_to_double_ex(args[0]);\n"
  1544. "%s = Z_DVAL_PP(args[0]);\n",
  1545. static_name);
  1546. break;
  1547. case T_VOID:
  1548. break;
  1549. case T_USER:
  1550. Printf(f->code, "convert_to_string_ex(args[0]);\n");
  1551. get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char *)"RETURN_FALSE");
  1552. break;
  1553. case T_POINTER:
  1554. case T_ARRAY:
  1555. case T_REFERENCE:
  1556. Printf(f->code, "convert_to_string_ex(args[0]);\n");
  1557. get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char*)"RETURN_FALSE");
  1558. break;
  1559. default:
  1560. Printf(stderr,"%s : Line %d, Unable to use type %s as a class variable.\n", input_file, line_number, SwigType_str(d,0));
  1561. break;
  1562. }
  1563. Printf(f->code, "}\n\n");
  1564. } /* end of const_flag */
  1565. switch(SwigType_type(d)) {
  1566. case T_BOOL:
  1567. case T_INT:
  1568. case T_SHORT:
  1569. case T_LONG:
  1570. case T_SCHAR:
  1571. case T_UINT:
  1572. case T_USHORT:
  1573. case T_ULONG:
  1574. case T_UCHAR:
  1575. Printf(f->code,
  1576. "RETURN_LONG(%s);\n", static_name);
  1577. break;
  1578. case T_DOUBLE:
  1579. case T_FLOAT:
  1580. Printf(f->code,
  1581. "RETURN_DOUBLE(%s);\n", static_name);
  1582. break;
  1583. case T_CHAR:
  1584. Printf(f->code,
  1585. "{\nchar ctemp[2];\n"
  1586. "ctemp[0] = %s;\n"
  1587. "ctemp[1] = 0;\n"
  1588. "RETURN_STRING(ctemp, 1);\n}\n",
  1589. static_name);
  1590. break;
  1591. case T_USER:
  1592. case T_POINTER:
  1593. Printf(f->code,
  1594. "SWIG_SetPointerZval(return_value, (void *)%s, "
  1595. "SWIGTYPE%s);\n", static_name, SwigType_manglestr(d));
  1596. break;
  1597. case T_STRING:
  1598. Printf(f->code, "RETURN_STRING(%s, 1);\n", static_name);
  1599. break;
  1600. }
  1601. Printf(f->code, "}\n");
  1602. const_flag = 0;
  1603. Wrapper_print(f, s_wrappers);
  1604. return SWIG_OK;
  1605. }
  1606. void SwigToPhpType(SwigType *t, String_or_char *pname, String* php_type, int shadow_flag) {
  1607. char *ptype = 0;
  1608. if(shadow_flag)
  1609. ptype = PhpTypeFromTypemap((char*)"pstype", t, pname,(char*)"");
  1610. if(!ptype)
  1611. ptype = PhpTypeFromTypemap((char*)"ptype",t,pname,(char*)"");
  1612. if(ptype) {
  1613. Printf(php_type, ptype);
  1614. free(ptype);
  1615. }
  1616. else {
  1617. /* Map type here */
  1618. switch(SwigType_type(t)) {
  1619. case T_CHAR:
  1620. case T_SCHAR:
  1621. case T_UCHAR:
  1622. case T_SHORT:
  1623. case T_USHORT:
  1624. case T_INT:
  1625. case T_UINT:
  1626. case T_LONG:
  1627. case T_ULONG:
  1628. case T_FLOAT:
  1629. case T_DOUBLE:
  1630. case T_BOOL:
  1631. case T_STRING:
  1632. case T_VOID:
  1633. Printf(php_type, "");
  1634. break;
  1635. case T_POINTER:
  1636. case T_REFERENCE:
  1637. case T_USER:
  1638. if(shadow_flag && is_shadow(t))
  1639. Printf(php_type, Char(is_shadow(t)));
  1640. else
  1641. Printf(php_type, "");
  1642. break;
  1643. case T_ARRAY:
  1644. /* TODO */