PageRenderTime 91ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

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

#
C++ | 1851 lines | 1302 code | 300 blank | 249 comment | 240 complexity | 401b4f4b2ce028773126b53b2e710248 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0

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

  1. /*
  2. * 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. * TODO: Replace stderr messages with Swig_warning
  15. *
  16. */
  17. char cvsroot_php4_cxx[] = "$Header$";
  18. #include "swigmod.h"
  19. #include <ctype.h>
  20. static const char *usage = (char*)"\
  21. PHP4 Options (available with -php4)\n\
  22. -cppext - cpp file extension (default to .cpp)\n\
  23. -noproxy - Don't generate proxy classes.\n\
  24. -dlname <name> - Set module prefix to <name>\n\
  25. -make - Create simple makefile\n\
  26. -phpfull - Create full make files\n\
  27. -withincs <libs>- With -phpfull writes needed incs in config.m4\n\
  28. -withlibs <libs>- With -phpfull writes needed libs in config.m4\n\
  29. -withc <libs> - With -phpfull makes extra c files in Makefile.in\n\
  30. -withcxx <libs> - With -phpfull makes extra c++ files in Makefile.in\n\
  31. \n";
  32. static int constructors=0;
  33. static String *NOTCLASS=NewString("Not a class");
  34. static Node *classnode=0;
  35. static String *module = 0;
  36. static String *cap_module = 0;
  37. static String *dlname = 0;
  38. static String *withlibs = 0;
  39. static String *withincs = 0;
  40. static String *withc = 0;
  41. static String *withcxx = 0;
  42. static char *shadow_classname;
  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 *r_init; // RINIT user code
  53. static String *s_shutdown; // MSHUTDOWN user code
  54. static String *r_shutdown; // RSHUTDOWN user code
  55. static String *s_vinit; // varinit initialization code.
  56. static String *s_vdecl;
  57. static String *s_cinit; // consttab initialization code.
  58. static String *s_oinit;
  59. static String *s_entry;
  60. static String *cs_entry;
  61. static String *all_cs_entry;
  62. static String *pragma_incl;
  63. static String *pragma_code;
  64. static String *pragma_phpinfo;
  65. /* Variables for using PHP classes */
  66. static String *class_name = 0;
  67. static Hash *shadow_get_vars;
  68. static Hash *shadow_set_vars;
  69. #define NATIVE_CONSTRUCTOR 1
  70. #define ALTERNATIVE_CONSTRUCTOR 2
  71. static int native_constructor=0;
  72. static Hash *zend_types = 0;
  73. static int shadow = 1;
  74. // These static variables are used to pass some state from Handlers into functionWrapper
  75. static enum {
  76. standard = 0,
  77. memberfn,
  78. staticmemberfn,
  79. membervar,
  80. staticmembervar,
  81. constructor,
  82. destructor
  83. } wrapperType = standard;
  84. extern "C" {
  85. static void (*r_prevtracefunc)(SwigType *t, String *mangled, String *clientdata) = 0;
  86. }
  87. static const char *php_header =
  88. "/*"
  89. "\n +----------------------------------------------------------------------+"
  90. "\n | PHP version 4.0 |"
  91. "\n +----------------------------------------------------------------------+"
  92. "\n | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |"
  93. "\n +----------------------------------------------------------------------+"
  94. "\n | This source file is subject to version 2.02 of the PHP license, |"
  95. "\n | that is bundled with this package in the file LICENSE, and is |"
  96. "\n | available at through the world-wide-web at |"
  97. "\n | http://www.php.net/license/2_02.txt. |"
  98. "\n | If you did not receive a copy of the PHP license and are unable to |"
  99. "\n | obtain it through the world-wide-web, please send a note to |"
  100. "\n | license@php.net so we can mail you a copy immediately. |"
  101. "\n +----------------------------------------------------------------------+"
  102. "\n | Authors: |"
  103. "\n | |"
  104. "\n +----------------------------------------------------------------------+"
  105. "\n */\n";
  106. void
  107. SwigPHP_emit_resource_registrations() {
  108. DOH *key;
  109. Iterator ki;
  110. String *destructor=0;
  111. String *classname=0;
  112. String *shadow_classname=0;
  113. if (!zend_types) return;
  114. ki = First(zend_types);
  115. if (ki.key) Printf(s_oinit,"\n/* Register resource destructors for pointer types */\n");
  116. while (ki.key) if (1 /* is pointer type*/) {
  117. key = ki.key;
  118. Node *class_node;
  119. if ((class_node=Getattr(zend_types,key))) {
  120. // Write out destructor function header
  121. Printf(s_wrappers,"/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n",key);
  122. // write out body
  123. if ((class_node!=NOTCLASS)) {
  124. classname = Getattr(class_node,"name");
  125. if (! (shadow_classname = Getattr(class_node,"sym:name"))) {
  126. shadow_classname=classname;
  127. }
  128. // Do we have a known destructor for this type?
  129. if ((destructor = Getattr(class_node,"destructor"))) {
  130. Printf(s_wrappers," /* has destructor: %s */\n",destructor);
  131. Printf(s_wrappers," %s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n",destructor,key);
  132. } else {
  133. Printf(s_wrappers," /* bah! No destructor for this wrapped class!! */\n");
  134. }
  135. } else {
  136. Printf(s_wrappers," /* bah! No destructor for this simple type!! */\n");
  137. }
  138. // close function
  139. Printf(s_wrappers,"}\n");
  140. // declare le_swig_<mangled> to store php registration
  141. Printf(s_vdecl,"static int le_swig_%s=0; /* handle for %s */\n", key, shadow_classname);
  142. // register with php
  143. Printf(s_oinit,"le_swig_%s=zend_register_list_destructors_ex"
  144. "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n",
  145. key,key,key);
  146. // store php type in class struct
  147. Printf(s_oinit,"SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n",
  148. key,key);
  149. }
  150. ki = Next(ki);
  151. }
  152. }
  153. class PHP4 : public Language {
  154. public:
  155. /* Test to see if a type corresponds to something wrapped with a shadow class. */
  156. String *is_shadow(SwigType *t) {
  157. String *r = 0;
  158. Node *n = classLookup(t);
  159. if (n) {
  160. r = Getattr(n,"php:proxy"); // Set by classDeclaration()
  161. if (!r) {
  162. r = Getattr(n,"sym:name"); // Not seen by classDeclaration yet, but this is the name
  163. }
  164. }
  165. return r;
  166. }
  167. /* ------------------------------------------------------------
  168. * main()
  169. * ------------------------------------------------------------ */
  170. virtual void main(int argc, char *argv[]) {
  171. int i;
  172. SWIG_library_directory("php4");
  173. SWIG_config_cppext("cpp");
  174. for(i = 1; i < argc; i++) {
  175. if (argv[i]) {
  176. if(strcmp(argv[i], "-phpfull") == 0) {
  177. gen_extra = 1;
  178. Swig_mark_arg(i);
  179. } else if(strcmp(argv[i], "-dlname") == 0) {
  180. if (argv[i+1]) {
  181. dlname = NewString(argv[i+1]);
  182. Swig_mark_arg(i);
  183. Swig_mark_arg(i+1);
  184. i++;
  185. } else {
  186. Swig_arg_error();
  187. }
  188. } else if(strcmp(argv[i], "-withlibs") == 0) {
  189. if (argv[i+1]) {
  190. withlibs = NewString(argv[i+1]);
  191. Swig_mark_arg(i);
  192. Swig_mark_arg(i+1);
  193. i++;
  194. } else {
  195. Swig_arg_error();
  196. }
  197. } else if(strcmp(argv[i], "-withincs") == 0) {
  198. if (argv[i+1]) {
  199. withincs = NewString(argv[i+1]);
  200. Swig_mark_arg(i);
  201. Swig_mark_arg(i+1);
  202. i++;
  203. } else {
  204. Swig_arg_error();
  205. }
  206. } else if(strcmp(argv[i], "-withc") == 0) {
  207. if (argv[i+1]) {
  208. withc = NewString(argv[i+1]);
  209. Swig_mark_arg(i);
  210. Swig_mark_arg(i+1);
  211. i++;
  212. } else {
  213. Swig_arg_error();
  214. }
  215. } else if(strcmp(argv[i], "-withcxx") == 0) {
  216. if (argv[i+1]) {
  217. withcxx = NewString(argv[i+1]);
  218. Swig_mark_arg(i);
  219. Swig_mark_arg(i+1);
  220. i++;
  221. } else {
  222. Swig_arg_error();
  223. }
  224. } else if(strcmp(argv[i], "-cppext") == 0) {
  225. if (argv[i+1]) {
  226. SWIG_config_cppext(argv[i+1]);
  227. Swig_mark_arg(i);
  228. Swig_mark_arg(i+1);
  229. i++;
  230. } else {
  231. Swig_arg_error();
  232. }
  233. } else if((strcmp(argv[i], "-noshadow") == 0)
  234. || (strcmp(argv[i],"-noproxy") == 0)) {
  235. shadow = 0;
  236. Swig_mark_arg(i);
  237. } else if(strcmp(argv[i], "-make") == 0) {
  238. gen_make = 1;
  239. Swig_mark_arg(i);
  240. } else if(strcmp(argv[i], "-help") == 0) {
  241. fputs(usage, stdout);
  242. }
  243. }
  244. }
  245. Preprocessor_define((void *) "SWIGPHP 1", 0);
  246. Preprocessor_define((void *) "SWIGPHP4 1", 0);
  247. SWIG_typemap_lang("php4");
  248. /* DB: Suggest using a language configuration file */
  249. SWIG_config_file("php4.swg");
  250. allow_overloading();
  251. }
  252. void create_simple_make(void) {
  253. File *f_make;
  254. f_make = NewFile((void *)"makefile", "w");
  255. Printf(f_make, "CC=gcc\n");
  256. Printf(f_make, "CXX=g++\n");
  257. Printf(f_make, "CXX_SOURCES=%s\n", withcxx );
  258. Printf(f_make, "C_SOURCES=%s\n", withc );
  259. Printf(f_make, "OBJS=%s_wrap.o $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cxx=.o)\n", module );
  260. Printf(f_make, "PROG=%s\n", dlname);
  261. Printf(f_make, "CFLAGS=-fpic\n" );
  262. Printf(f_make, "LDFLAGS=-shared\n");
  263. Printf(f_make, "PHP_INC=`php-config --includes`\n");
  264. Printf(f_make, "EXTRA_INC=\n");
  265. Printf(f_make, "EXTRA_LIB=\n\n" );
  266. Printf(f_make, "$(PROG): $(OBJS)\n");
  267. if ( CPlusPlus || (withcxx != NULL) ) {
  268. Printf(f_make, "\t$(CXX) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
  269. } else {
  270. Printf(f_make, "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
  271. }
  272. Printf(f_make, "%%.o: %%.cpp\n");
  273. Printf(f_make, "\t$(CXX) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n");
  274. Printf(f_make, "%%.o: %%.cxx\n");
  275. Printf(f_make, "\t$(CXX) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n");
  276. Printf(f_make, "%%.o: %%.c\n");
  277. Printf(f_make, "\t$(CC) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n");
  278. Close(f_make);
  279. }
  280. void create_extra_files(String *outfile) {
  281. File *f_extra;
  282. static String *configm4=0;
  283. static String *makefilein=0;
  284. static String *credits=0;
  285. configm4=NewString("");
  286. Printv(configm4, SWIG_output_directory(), "config.m4", NIL);
  287. makefilein=NewString("");
  288. Printv(makefilein, SWIG_output_directory(), "Makefile.in", NIL);
  289. credits=NewString("");
  290. Printv(credits, SWIG_output_directory(), "CREDITS", NIL);
  291. // are we a --with- or --enable-
  292. int with=(withincs || withlibs)?1:0;
  293. // Note makefile.in only copes with one source file
  294. // also withincs and withlibs only take one name each now
  295. // the code they generate should be adapted to take multiple lines
  296. /* Write out Makefile.in */
  297. f_extra = NewFile(makefilein, "w");
  298. if (!f_extra) {
  299. FileErrorDisplay(makefilein);
  300. SWIG_exit(EXIT_FAILURE);
  301. }
  302. Printf(f_extra,
  303. "# $Id: php4.cxx 8798 2006-02-11 22:01:31Z marcelomatus $\n\n"
  304. "LTLIBRARY_NAME = php_%s.la\n",
  305. module);
  306. // CPP has more and different entires to C in Makefile.in
  307. if (! CPlusPlus) {
  308. Printf(f_extra,"LTLIBRARY_SOURCES = %s %s\n", Swig_file_filename(outfile),withc);
  309. Printf(f_extra,"LTLIBRARY_SOURCES_CPP = %s\n", withcxx);
  310. } else {
  311. Printf(f_extra,"LTLIBRARY_SOURCES = %s\n", withc );
  312. Printf(f_extra,"LTLIBRARY_SOURCES_CPP = %s %s\n", Swig_file_filename(outfile),withcxx);
  313. Printf(f_extra,"LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n");
  314. }
  315. Printf(f_extra,"LTLIBRARY_SHARED_NAME = php_%s.la\n", module);
  316. Printf(f_extra,"LTLIBRARY_SHARED_LIBADD = $(%(upper)s_SHARED_LIBADD)\n\n",module);
  317. Printf(f_extra,"include $(top_srcdir)/build/dynlib.mk\n");
  318. Printf(f_extra,"\n# patch in .cxx support to php build system to work like .cpp\n");
  319. Printf(f_extra,".SUFFIXES: .cxx\n\n");
  320. Printf(f_extra,".cxx.o:\n");
  321. Printf(f_extra," $(CXX_COMPILE) -c $<\n\n");
  322. Printf(f_extra,".cxx.lo:\n");
  323. Printf(f_extra," $(CXX_PHP_COMPILE)\n\n");
  324. Printf(f_extra,".cxx.slo:\n");
  325. Printf(f_extra," $(CXX_SHARED_COMPILE)\n\n");
  326. Printf(f_extra,"\n# make it easy to test module\n");
  327. Printf(f_extra,"testmodule:\n");
  328. Printf(f_extra," php -q -d extension_dir=modules %s\n\n",Swig_file_filename(phpfilename));
  329. Close(f_extra);
  330. /* Now config.m4 */
  331. // Note: # comments are OK in config.m4 if you don't mind them
  332. // appearing in the final ./configure file
  333. // (which can help with ./configure debugging)
  334. // NOTE2: phpize really ought to be able to write out a sample
  335. // config.m4 based on some simple data, I'll take this up with
  336. // the php folk!
  337. f_extra = NewFile(configm4, "w");
  338. if (!f_extra) {
  339. FileErrorDisplay(configm4);
  340. SWIG_exit(EXIT_FAILURE);
  341. }
  342. Printf(f_extra,"dnl $Id: php4.cxx 8798 2006-02-11 22:01:31Z marcelomatus $\n");
  343. Printf(f_extra,"dnl ***********************************************************************\n");
  344. Printf(f_extra,"dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n");
  345. Printf(f_extra,"dnl ** for any part of the rest of the %s build system\n",module);
  346. Printf(f_extra,"dnl ***********************************************************************\n\n");
  347. if (! with) { // must be enable then
  348. Printf(f_extra,"PHP_ARG_ENABLE(%s, whether to enable %s support,\n",module,module);
  349. Printf(f_extra,"[ --enable-%s Enable %s support])\n\n",module,module);
  350. } else {
  351. Printf(f_extra,"PHP_ARG_WITH(%s, for %s support,\n",module,module);
  352. Printf(f_extra,"[ --with-%s[=DIR] Include %s support.])\n\n",module,module);
  353. // These tests try and file the library we need
  354. Printf(f_extra,"dnl THESE TESTS try and find the library and header files\n");
  355. Printf(f_extra,"dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n");
  356. Printf(f_extra,"dnl as written they assume your header files are all in the same place\n\n");
  357. Printf(f_extra,"dnl ** are we looking for %s_lib.h or something else?\n",module);
  358. if (withincs)
  359. Printf(f_extra,"HNAMES=\"%s\"\n\n",withincs);
  360. else
  361. Printf(f_extra,"HNAMES=\"\"; # %s_lib.h ?\n\n",module);
  362. Printf(f_extra,"dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n",module,module);
  363. if (withlibs)
  364. Printf(f_extra,"LIBNAMES=\"%s\"\n\n",withlibs);
  365. else
  366. Printf(f_extra,"LIBNAMES=\"\"; # lib_%s.so ?\n\n",withlibs);
  367. Printf(f_extra,"dnl IF YOU KNOW one of the symbols in the library and you\n");
  368. Printf(f_extra,"dnl specify it below then we can have a link test to see if it works\n");
  369. Printf(f_extra,"LIBSYMBOL=\"\"\n\n");
  370. }
  371. // Now write out tests to find thing.. they may need to extend tests
  372. Printf(f_extra,"if test \"$PHP_%(upper)s\" != \"no\"; then\n\n",module);
  373. // Ready for when we add libraries as we find them
  374. Printf(f_extra," PHP_SUBST(%(upper)s_SHARED_LIBADD)\n\n",module);
  375. if (withlibs) { // find more than one library
  376. Printf(f_extra," for LIBNAME in $LIBNAMES ; do\n");
  377. Printf(f_extra," LIBDIR=\"\"\n");
  378. // For each path element to try...
  379. Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/lib /usr/lib /usr/local/lib ; do\n",module,module);
  380. Printf(f_extra," if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n");
  381. Printf(f_extra," LIBDIR=\"$i\"\n");
  382. Printf(f_extra," break\n");
  383. Printf(f_extra," fi\n");
  384. Printf(f_extra," done\n\n");
  385. Printf(f_extra," dnl ** and $LIBDIR should be the library path\n");
  386. Printf(f_extra," if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n");
  387. Printf(f_extra," AC_MSG_RESULT(Library files $LIBNAME not found)\n");
  388. Printf(f_extra," AC_MSG_ERROR(Is the %s distribution installed properly?)\n",module);
  389. Printf(f_extra," else\n");
  390. Printf(f_extra," AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n");
  391. Printf(f_extra," PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %(upper)s_SHARED_LIBADD)\n",module);
  392. Printf(f_extra," fi\n");
  393. Printf(f_extra," done\n\n");
  394. }
  395. if (withincs) { // Find more than once include
  396. Printf(f_extra," for HNAME in $HNAMES ; do\n");
  397. Printf(f_extra," INCDIR=\"\"\n");
  398. // For each path element to try...
  399. 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);
  400. // Try and find header files
  401. Printf(f_extra," if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n");
  402. Printf(f_extra," INCDIR=\"$i\"\n");
  403. Printf(f_extra," break\n");
  404. Printf(f_extra," fi\n");
  405. Printf(f_extra," done\n\n");
  406. Printf(f_extra," dnl ** Now $INCDIR should be the include file path\n");
  407. Printf(f_extra," if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n");
  408. Printf(f_extra," AC_MSG_RESULT(Include files $HNAME not found)\n");
  409. Printf(f_extra," AC_MSG_ERROR(Is the %s distribution installed properly?)\n",module);
  410. Printf(f_extra," else\n");
  411. Printf(f_extra," AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n");
  412. Printf(f_extra," PHP_ADD_INCLUDE($INCDIR)\n");
  413. Printf(f_extra," fi\n\n");
  414. Printf(f_extra," done\n\n");
  415. }
  416. if (CPlusPlus) {
  417. Printf(f_extra," # As this is a C++ module..\n");
  418. }
  419. Printf(f_extra," PHP_REQUIRE_CXX\n");
  420. Printf(f_extra," AC_CHECK_LIB(stdc++, cin)\n");
  421. if (with) {
  422. Printf(f_extra," if test \"$LIBSYMBOL\" != \"\" ; then\n");
  423. Printf(f_extra," old_LIBS=\"$LIBS\"\n");
  424. Printf(f_extra," LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n");
  425. Printf(f_extra," AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1, [ ])],\n");
  426. Printf(f_extra," [AC_MSG_ERROR(wrong test lib version or lib not found)])\n");
  427. Printf(f_extra," LIBS=\"$old_LIBS\"\n");
  428. Printf(f_extra," fi\n\n");
  429. }
  430. Printf(f_extra," AC_DEFINE(HAVE_%(upper)s, 1, [ ])\n",module);
  431. Printf(f_extra,"dnl AC_DEFINE_UNQUOTED(PHP_%(upper)s_DIR, \"$%(upper)s_DIR\", [ ])\n",module,module);
  432. Printf(f_extra," PHP_EXTENSION(%s, $ext_shared)\n",module);
  433. // and thats all!
  434. Printf(f_extra,"fi\n");
  435. Close(f_extra);
  436. /* CREDITS */
  437. f_extra = NewFile(credits, "w");
  438. if (!f_extra) {
  439. FileErrorDisplay(credits);
  440. SWIG_exit(EXIT_FAILURE);
  441. }
  442. Printf(f_extra, "%s\n", module);
  443. Close(f_extra);
  444. }
  445. /* ------------------------------------------------------------
  446. * top()
  447. * ------------------------------------------------------------ */
  448. virtual int top(Node *n) {
  449. String *filen;
  450. String *s_type;
  451. /* Initialize all of the output files */
  452. String *outfile = Getattr(n,"outfile");
  453. /* main output file */
  454. f_runtime = NewFile(outfile,"w");
  455. if (!f_runtime) {
  456. FileErrorDisplay(outfile);
  457. SWIG_exit(EXIT_FAILURE);
  458. }
  459. Swig_banner(f_runtime);
  460. /* sections of the output file */
  461. s_init = NewString("/* init section */\n");
  462. r_init = NewString("/* rinit section */\n");
  463. s_shutdown = NewString("/* shutdown section */\n");
  464. r_shutdown = NewString("/* rshutdown section */\n");
  465. s_header = NewString("/* header section */\n");
  466. s_wrappers = NewString("/* wrapper section */\n");
  467. s_type = NewString("");
  468. /* subsections of the init section */
  469. s_vinit = NewString("/* vinit subsection */\n");
  470. s_vdecl = NewString("/* vdecl subsection */\n");
  471. s_cinit = NewString("/* cinit subsection */\n");
  472. s_oinit = NewString("/* oinit subsection */\n");
  473. pragma_phpinfo = NewString("");
  474. /* Register file targets with the SWIG file handler */
  475. Swig_register_filebyname("runtime",f_runtime);
  476. Swig_register_filebyname("init",s_init);
  477. Swig_register_filebyname("rinit",r_init);
  478. Swig_register_filebyname("shutdown",s_shutdown);
  479. Swig_register_filebyname("rshutdown",r_shutdown);
  480. Swig_register_filebyname("header",s_header);
  481. Swig_register_filebyname("wrapper",s_wrappers);
  482. /* Set the module name */
  483. module = Copy(Getattr(n,"name"));
  484. cap_module = NewStringf("%(upper)s",module);
  485. /* Set the dlname */
  486. if (!dlname) {
  487. #if defined(_WIN32) || defined(__WIN32__)
  488. dlname = NewStringf("php_%s.dll", module);
  489. #else
  490. dlname = NewStringf("php_%s.so", module);
  491. #endif
  492. }
  493. /* PHP module file */
  494. filen = NewString("");
  495. Printv(filen, SWIG_output_directory(), module, ".php", NIL);
  496. phpfilename = NewString(filen);
  497. f_phpcode = NewFile(filen, "w");
  498. if (!f_phpcode) {
  499. FileErrorDisplay(filen);
  500. SWIG_exit(EXIT_FAILURE);
  501. }
  502. Printf(f_phpcode, "<?php\n\n");
  503. Swig_banner(f_phpcode);
  504. Printf(f_phpcode,"global $%s_LOADED__;\n", cap_module);
  505. Printf(f_phpcode,"if ($%s_LOADED__) return;\n", cap_module);
  506. Printf(f_phpcode,"$%s_LOADED__ = true;\n\n", cap_module);
  507. Printf(f_phpcode,"/* if our extension has not been loaded, do what we can */\n");
  508. Printf(f_phpcode,"if (!extension_loaded(\"php_%s\")) {\n", module);
  509. Printf(f_phpcode," if (!dl(\"%s\")) return;\n", dlname);
  510. Printf(f_phpcode,"}\n\n");
  511. /* sub-sections of the php file */
  512. pragma_code = NewString("");
  513. pragma_incl = NewString("");
  514. /* Initialize the rest of the module */
  515. Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, %s_destroy_globals);\n",module,module,module);
  516. /* start the header section */
  517. Printf(s_header, php_header);
  518. Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
  519. Printf(s_header, "char *error_msg;\n");
  520. Printf(s_header, "int error_code;\n");
  521. Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module );
  522. Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n",module );
  523. Printf(s_header, "#ifdef ZTS\n" );
  524. Printf(s_header, "#define ErrorMsg() TSRMG(%s_globals_id, zend_%s_globals *, error_msg );\n",module,module);
  525. Printf(s_header, "#define ErrorCode() TSRMG(%s_globals_id, zend_%s_globals *, error_code );\n",module,module);
  526. Printf(s_header, "#else\n" );
  527. Printf(s_header, "#define ErrorMsg() (%s_globals.error_msg)\n",module);
  528. Printf(s_header, "#define ErrorCode() (%s_globals.error_code)\n",module);
  529. Printf(s_header, "#endif\n\n" );
  530. Printf(s_header, "static void %s_init_globals(zend_%s_globals *%s_globals ) {\n",module,module,module);
  531. Printf(s_header, " %s_globals->error_msg = default_error_msg;\n", module);
  532. Printf(s_header, " %s_globals->error_code = default_error_code;\n",module);
  533. Printf(s_header, "}\n");
  534. Printf(s_header, "static void %s_destroy_globals(zend_%s_globals *%s_globals) { }\n",module,module,module);
  535. Printf(s_header, "\n");
  536. Printf(s_header, "void SWIG_ResetError() {\n");
  537. Printf(s_header, " ErrorMsg() = default_error_msg;\n");
  538. Printf(s_header, " ErrorCode() = default_error_code;\n");
  539. Printf(s_header, "}\n");
  540. Printf(s_header,"#define SWIG_name \"%s\"\n", module);
  541. /* Printf(s_header,"#ifdef HAVE_CONFIG_H\n");
  542. Printf(s_header,"#include \"config.h\"\n");
  543. Printf(s_header,"#endif\n\n");
  544. */
  545. Printf(s_header,"#ifdef __cplusplus\n");
  546. Printf(s_header,"extern \"C\" {\n");
  547. Printf(s_header,"#endif\n");
  548. Printf(s_header,"#include \"php.h\"\n");
  549. Printf(s_header,"#include \"php_ini.h\"\n");
  550. Printf(s_header,"#include \"ext/standard/info.h\"\n");
  551. Printf(s_header,"#include \"php_%s.h\"\n", module);
  552. Printf(s_header,"#ifdef __cplusplus\n");
  553. Printf(s_header,"}\n");
  554. Printf(s_header,"#endif\n\n");
  555. /* Create the .h file too */
  556. filen = NewString("");
  557. Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL);
  558. f_h = NewFile(filen, "w");
  559. if (!f_h) {
  560. FileErrorDisplay(filen);
  561. SWIG_exit(EXIT_FAILURE);
  562. }
  563. Swig_banner(f_h);
  564. Printf(f_h, php_header);
  565. Printf(f_h, "\n\n");
  566. Printf(f_h, "#ifndef PHP_%s_H\n", cap_module );
  567. Printf(f_h, "#define PHP_%s_H\n\n", cap_module );
  568. Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module );
  569. Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module );
  570. Printf(f_h, "#ifdef PHP_WIN32\n" );
  571. Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module );
  572. Printf(f_h, "#else\n" );
  573. Printf(f_h, "# define PHP_%s_API\n", cap_module );
  574. Printf(f_h, "#endif\n\n" );
  575. Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module );
  576. Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module );
  577. Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module );
  578. Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module );
  579. Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n\n", module );
  580. /* start the function entry section */
  581. s_entry = NewString("/* entry subsection */\n");
  582. /* holds all the per-class function entry sections */
  583. all_cs_entry = NewString("/* class entry subsection */\n");
  584. cs_entry = NULL;
  585. Printf(s_entry,"/* Every non-class user visible function must have an entry here */\n");
  586. Printf(s_entry,"function_entry %s_functions[] = {\n", module);
  587. /* start the init section */
  588. if (gen_extra) {
  589. Printf(s_init,"#ifdef COMPILE_DL_%s\n", cap_module);
  590. }
  591. Printf(s_init,"#ifdef __cplusplus\n");
  592. Printf(s_init,"extern \"C\" {\n");
  593. Printf(s_init,"#endif\n");
  594. Printf(s_init,"ZEND_GET_MODULE(%s)\n",module);
  595. Printf(s_init,"#ifdef __cplusplus\n");
  596. Printf(s_init,"}\n");
  597. Printf(s_init,"#endif\n\n");
  598. if (gen_extra) {
  599. Printf(s_init,"#endif\n\n");
  600. }
  601. /* We have to register the constants before they are (possibly) used
  602. * by the pointer typemaps. This all needs re-arranging really as
  603. * things are being called in the wrong order
  604. */
  605. Printf(s_init,"#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n", module);
  606. /* Emit all of the code */
  607. Language::top(n);
  608. SwigPHP_emit_resource_registrations();
  609. // Printv(s_init,s_resourcetypes,NIL);
  610. /* We need this after all classes written out by ::top */
  611. Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
  612. Printf(s_oinit, "/* end oinit subsection */\n");
  613. Printf(s_init, "%s\n", s_oinit);
  614. /* Constants generated during top call */
  615. // But save them for RINIT
  616. Printf(s_cinit, "/* end cinit subsection */\n");
  617. /* finish our init section which will have been used by class wrappers */
  618. Printf(s_vinit, "/* end vinit subsection */\n");
  619. Printf(s_init, " return SUCCESS;\n");
  620. Printf(s_init,"}\n");
  621. // Now do REQUEST init which holds cinit and vinit
  622. Printf(s_init,"PHP_RINIT_FUNCTION(%s)\n{\n",module);
  623. Printf(s_init,"%s\n",r_init);
  624. Printf(s_init,"%s\n",s_cinit);
  625. Clear(s_cinit);
  626. Delete(s_cinit);
  627. Printf(s_init, "%s\n", s_vinit);
  628. Clear(s_vinit);
  629. Delete(s_vinit);
  630. Printf(s_init," return SUCCESS;\n");
  631. Printf(s_init,"}\n");
  632. Printf(s_init,"PHP_MSHUTDOWN_FUNCTION(%s)\n{\n",module);
  633. Printf(s_init,"%s\n",s_shutdown);
  634. Printf(s_init," return SUCCESS;\n");
  635. Printf(s_init,"}\n");
  636. Printf(s_init,"PHP_RSHUTDOWN_FUNCTION(%s)\n{\n",module);
  637. Printf(s_init,"%s\n",r_shutdown);
  638. Printf(s_init," return SUCCESS;\n");
  639. Printf(s_init,"}\n");
  640. Printf(s_init,"PHP_MINFO_FUNCTION(%s)\n{\n",module);
  641. Printf(s_init,"%s", pragma_phpinfo);
  642. Printf(s_init,"}\n");
  643. Printf(s_init,"/* end init section */\n");
  644. Printf(f_h, "#endif /* PHP_%s_H */\n", cap_module);
  645. Close(f_h);
  646. Printf(s_header, "%s\n\n",all_cs_entry);
  647. Printf(s_header, "%s {NULL, NULL, NULL}\n};\n\n",s_entry);
  648. Printf(s_header, "zend_module_entry %s_module_entry = {\n", module );
  649. Printf(s_header, "#if ZEND_MODULE_API_NO > 20010900\n" );
  650. Printf(s_header, " STANDARD_MODULE_HEADER,\n");
  651. Printf(s_header, "#endif\n");
  652. Printf(s_header, " \"%s\",\n", module);
  653. Printf(s_header, " %s_functions,\n", module);
  654. Printf(s_header, " PHP_MINIT(%s),\n", module);
  655. Printf(s_header, " PHP_MSHUTDOWN(%s),\n", module);
  656. Printf(s_header, " PHP_RINIT(%s),\n", module);
  657. Printf(s_header, " PHP_RSHUTDOWN(%s),\n", module);
  658. Printf(s_header, " PHP_MINFO(%s),\n",module);
  659. Printf(s_header, "#if ZEND_MODULE_API_NO > 20010900\n");
  660. Printf(s_header, " NO_VERSION_YET,\n");
  661. Printf(s_header, "#endif\n");
  662. Printf(s_header, " STANDARD_MODULE_PROPERTIES\n");
  663. Printf(s_header, "};\nzend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n",module);
  664. String *type_table = NewString("");
  665. SwigType_emit_type_table(f_runtime,type_table);
  666. Printf(s_header,"%s",type_table);
  667. Delete(type_table);
  668. /* Oh dear, more things being called in the wrong order. This whole
  669. * function really needs totally redoing.
  670. */
  671. Printf(s_header, "/* end header section */\n");
  672. Printf(s_wrappers, "/* end wrapper section */\n");
  673. Printf(s_vdecl, "/* end vdecl subsection */\n");
  674. Printv(f_runtime, s_header, s_vdecl, s_wrappers, s_init, NIL);
  675. Delete(s_header);
  676. Delete(s_wrappers);
  677. Delete(s_init);
  678. Delete(s_vdecl);
  679. Close(f_runtime);
  680. Printf(f_phpcode, "%s\n%s\n?>\n", pragma_incl, pragma_code);
  681. Close(f_phpcode);
  682. if ( gen_extra ) {
  683. create_extra_files(outfile);
  684. }
  685. else if( gen_make ) {
  686. create_simple_make();
  687. }
  688. return SWIG_OK;
  689. }
  690. /* Just need to append function names to function table to register with
  691. PHP
  692. */
  693. void create_command(String *cname, String *iname) {
  694. Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
  695. // This is for the single main function_entry record
  696. if (cs_entry) {
  697. Printf(cs_entry," ZEND_NAMED_FE(%(lower)s,%s, NULL)\n", cname,iname );
  698. } else {
  699. Printf(s_entry," ZEND_NAMED_FE(%(lower)s,%s, NULL)\n", cname,iname );
  700. }
  701. }
  702. /* ------------------------------------------------------------
  703. * dispatchFunction()
  704. * ------------------------------------------------------------ */
  705. void dispatchFunction(Node *n) {
  706. /* Last node in overloaded chain */
  707. int maxargs;
  708. String *tmp = NewString("");
  709. String *dispatch = Swig_overload_dispatch(n,"return %s(INTERNAL_FUNCTION_PARAM_PASSTHRU);",&maxargs);
  710. int has_this_ptr = (wrapperType==memberfn)?shadow:0;
  711. /* Generate a dispatch wrapper for all overloaded functions */
  712. Wrapper *f = NewWrapper();
  713. String *symname = Getattr(n,"sym:name");
  714. String *wname = Swig_name_wrapper(symname);
  715. create_command( symname, wname );
  716. Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL );
  717. Wrapper_add_local(f,"argc","int argc");
  718. Printf(tmp,"zval **argv[%d]", maxargs);
  719. Wrapper_add_local(f,"argv",tmp);
  720. Wrapper_add_local(f,"ii","int ii");
  721. Printf(f->code,"argc = ZEND_NUM_ARGS();\n");
  722. if ( has_this_ptr ) {
  723. Printf(f->code,"argv[0] = &this_ptr;\n");
  724. Printf(f->code,"zend_get_parameters_array_ex(argc,argv+1);\n");
  725. Printf(f->code,"argc++;\n");
  726. }
  727. else {
  728. Printf(f->code,"zend_get_parameters_array_ex(argc,argv);\n");
  729. }
  730. Replaceall(dispatch,"$args","self,args");
  731. Printv(f->code,dispatch,"\n",NIL);
  732. Printf(f->code,"/*No matching function for overloaded '%s'*/\n", symname);
  733. Printf(f->code,"\n");
  734. Printv(f->code,"}\n",NIL);
  735. Wrapper_print(f,s_wrappers);
  736. DelWrapper(f);
  737. Delete(dispatch);
  738. Delete(tmp);
  739. Delete(wname);
  740. }
  741. /* ------------------------------------------------------------
  742. * functionWrapper()
  743. * ------------------------------------------------------------ */
  744. virtual int functionWrapper(Node *n) {
  745. String *name = GetChar(n,"name");
  746. String *iname = GetChar(n,"sym:name");
  747. SwigType *d = Getattr(n,"type");
  748. ParmList *l = Getattr(n,"parms");
  749. String *nodeType = Getattr(n, "nodeType");
  750. int newobject = GetFlag(n,"feature:new");
  751. Parm *p;
  752. char source[256];
  753. char argnum[32];
  754. char args[32];
  755. int i,numopt;
  756. String *tm;
  757. Wrapper *f;
  758. bool mvr=(shadow && wrapperType == membervar);
  759. bool mvrset=(mvr && (Strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, name)))==0) );
  760. char wname[256];
  761. int overloaded = 0;
  762. String *overname = 0;
  763. int destructor = ( Cmp(nodeType, "destructor") == 0 );
  764. if ( destructor ) {
  765. // We only generate the Zend List Destructor. Have
  766. // Zend manage the reference counting.
  767. return CreateZendListDestructor(n);
  768. #if 0
  769. //If a script accessible destructor is desired/required, this code needs to be
  770. //put back into play.
  771. // Then we modify the wrap_action so it nulls out the self variable.
  772. String *del = Getattr(n,"wrap:action");
  773. Printf(del,"\nRETVAL_NULL();\n");
  774. Setattr(n,"wrap:action",del);
  775. #endif
  776. }
  777. // Test for overloading;
  778. if (Getattr(n,"sym:overloaded")) {
  779. overloaded = 1;
  780. overname = Getattr(n,"sym:overname");
  781. } else {
  782. if (!addSymbol(iname,n))
  783. return SWIG_ERROR;
  784. }
  785. strcpy(wname,Char(Swig_name_wrapper(iname)));
  786. if (overname) {
  787. strcat(wname,Char(overname));
  788. }
  789. // if shadow and variable wrapper we want to snag the main contents
  790. // of this function to stick in to the property handler....
  791. if (mvr) {
  792. String *php_function_name = NewString(iname);
  793. if( Strcmp( iname, Swig_name_set(Swig_name_member(shadow_classname, name)))== 0) {
  794. Setattr(shadow_set_vars, php_function_name, name);
  795. }
  796. if( Strcmp(iname, Swig_name_get(Swig_name_member(shadow_classname, name))) == 0) {
  797. Setattr(shadow_get_vars, php_function_name, name);
  798. }
  799. Delete(php_function_name);
  800. }
  801. f = NewWrapper();
  802. numopt = 0;
  803. String *outarg = NewString("");
  804. String *cleanup = NewString("");
  805. if (mvr) { // do prop[gs]et header
  806. if (mvrset) {
  807. Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n",iname);
  808. }
  809. else {
  810. Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n",iname);
  811. }
  812. } else {
  813. // regular header
  814. // We don't issue these for overloaded functions.
  815. // destructors when using shadows.
  816. // And for static member variables
  817. if (!overloaded &&
  818. !(destructor && shadow) &&
  819. wrapperType != staticmembervar ) {
  820. create_command( iname, wname );
  821. }
  822. Printv(f->def, "ZEND_NAMED_FUNCTION(" , wname, ") {\n", NIL);
  823. }
  824. emit_args(d, l, f);
  825. /* Attach standard typemaps */
  826. emit_attach_parmmaps(l,f);
  827. // wrap:parms is used by overload resolution.
  828. Setattr(n,"wrap:parms",l);
  829. int num_arguments = emit_num_arguments(l);
  830. int num_required = emit_num_required(l);
  831. numopt = num_arguments - num_required;
  832. int has_this_ptr = (wrapperType==memberfn)?shadow:0;
  833. sprintf(args, "%s[%d]", "zval **args", num_arguments-has_this_ptr);
  834. Wrapper_add_local(f, "args",args);
  835. // This generated code may be called
  836. // 1) as an object method, or
  837. // 2) as a class-method/function (without a "this_ptr")
  838. // Option (1) has "this_ptr" for "this", option (2) needs it as
  839. // first parameter
  840. // NOTE: possible we ignore this_ptr as a param for native constructor
  841. Printf(f->code, "SWIG_ResetError();\n");
  842. if (has_this_ptr)
  843. Printf(f->code, "/* This function uses a this_ptr*/\n");
  844. if (native_constructor) {
  845. if (native_constructor==NATIVE_CONSTRUCTOR) {
  846. Printf(f->code, "/* NATIVE Constructor */\n");
  847. }
  848. else {
  849. Printf(f->code, "/* ALTERNATIVE Constructor */\n");
  850. }
  851. }
  852. if (mvr && ! mvrset) {
  853. Wrapper_add_local(f, "_return_value", "zval _return_value");
  854. Wrapper_add_local(f, "return_value", "zval *return_value=&_return_value");
  855. };
  856. if(numopt > 0) { // membervariable wrappers do not have optional args
  857. Wrapper_add_local(f, "arg_count", "int arg_count");
  858. Printf(f->code,"arg_count = ZEND_NUM_ARGS();\n");
  859. Printf(f->code,"if(arg_count<%d || arg_count>%d)\n",num_required, num_arguments);
  860. Printf(f->code,"\tWRONG_PARAM_COUNT;\n\n");
  861. /* Verified args, retrieve them... */
  862. Printf(f->code,"if(zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
  863. Printf(f->code,"\t\tWRONG_PARAM_COUNT;\n\n");
  864. } else if (!mvr) {
  865. Printf(f->code, "if(((ZEND_NUM_ARGS() )!= %d) || (zend_get_parameters_array_ex(%d, args)",
  866. num_arguments-has_this_ptr, num_arguments-has_this_ptr);
  867. Printf(f->code, "!= SUCCESS)) {\n");
  868. Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");
  869. }
  870. /* Now convert from php to C variables */
  871. // At this point, argcount if used is the number of deliberatly passed args
  872. // not including this_ptr even if it is used.
  873. // It means error messages may be out by argbase with error
  874. // reports. We can either take argbase into account when raising
  875. // errors, or find a better way of dealing with _thisptr
  876. // I would like, if objects are wrapped, to assume _thisptr is always
  877. // _this and the and not the first argument
  878. // This may mean looking at Lang::memberfunctionhandler
  879. for (i = 0, p = l; i < num_arguments; i++) {
  880. /* Skip ignored arguments */
  881. //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
  882. while (checkAttribute(p,"tmap:in:numinputs","0")) {
  883. p = Getattr(p,"tmap:in:next");
  884. }
  885. SwigType *pt = Getattr(p,"type");
  886. if (mvr) { // do we assert that numargs=2, that i<2
  887. if (i==0) {
  888. sprintf(source,"&(property_reference->object)");
  889. }
  890. else {
  891. sprintf(source,"&value");
  892. }
  893. } else {
  894. if (i==0 && has_this_ptr ) {
  895. sprintf(source,"&this_ptr");
  896. } else {
  897. sprintf(source, "args[%d]", i-has_this_ptr);
  898. }
  899. }
  900. String *ln = Getattr(p,"lname");
  901. sprintf(argnum, "%d", i+1);
  902. /* Check if optional */
  903. if(i>= (num_required)) {
  904. Printf(f->code,"\tif(arg_count > %d) {\n", i);
  905. }
  906. if ((tm = Getattr(p,"tmap:in"))) {
  907. Replaceall(tm,"$source",source);
  908. Replaceall(tm,"$target",ln);
  909. Replaceall(tm,"$input", source);
  910. Setattr(p,"emit:input", source);
  911. Printf(f->code,"%s\n",tm);
  912. p = Getattr(p,"tmap:in:next");
  913. if (i >= num_required) {
  914. Printf(f->code,"}\n");
  915. }
  916. continue;
  917. } else {
  918. Printf(stderr,"%s : Line %d, Unable to use type %s as a function argument.\n",
  919. input_file, line_number, SwigType_str(pt,0));
  920. }
  921. if (i>= num_required) {
  922. Printf(f->code,"\t}\n");
  923. }
  924. }
  925. /* Insert constraint checking code */
  926. for (p = l; p;) {
  927. if ((tm = Getattr(p,"tmap:check"))) {
  928. Replaceall(tm,"$target",Getattr(p,"lname"));
  929. Printv(f->code,tm,"\n",NIL);
  930. p = Getattr(p,"tmap:check:next");
  931. } else {
  932. p = nextSibling(p);
  933. }
  934. }
  935. /* Insert cleanup code */
  936. for (i = 0, p = l; p; i++) {
  937. if ((tm = Getattr(p,"tmap:freearg"))) {
  938. Replaceall(tm,"$source",Getattr(p,"lname"));
  939. Printv(cleanup,tm,"\n",NIL);
  940. p = Getattr(p,"tmap:freearg:next");
  941. } else {
  942. p = nextSibling(p);
  943. }
  944. }
  945. /* Insert argument output code */
  946. for (i=0,p = l; p;i++) {
  947. if ((tm = Getattr(p,"tmap:argout"))) {
  948. Replaceall(tm,"$source",Getattr(p,"lname"));
  949. // Replaceall(tm,"$input",Getattr(p,"lname"));
  950. Replaceall(tm,"$target","return_value");
  951. Replaceall(tm,"$result","return_value");
  952. Replaceall(tm,"$arg", Getattr(p,"emit:input"));
  953. Replaceall(tm,"$input", Getattr(p,"emit:input"));
  954. Printv(outarg,tm,"\n",NIL);
  955. p = Getattr(p,"tmap:argout:next");
  956. } else {
  957. p = nextSibling(p);
  958. }
  959. }
  960. /* emit function call*/
  961. emit_action(n,f);
  962. if((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
  963. Replaceall(tm, "$input", "result");
  964. Replaceall(tm, "$source", "result");
  965. Replaceall(tm, "$target", "return_value");
  966. Replaceall(tm, "$result", "return_value");
  967. Replaceall(tm,"$owner", newobject ? "1" : "0");
  968. Printf(f->code, "%s\n", tm);
  969. // are we returning a wrapable object?
  970. // I don't know if this test is comlete, I nicked it
  971. if(is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
  972. Printf(f->code,"/* Wrap this return value */\n");
  973. if (native_constructor==NATIVE_CONSTRUCTOR) {
  974. Printf(f->code, "if (this_ptr) {\n");
  975. Printf(f->code, "/* NATIVE Constructor, use this_ptr */\n");
  976. Printf(f->code, "zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n");
  977. Printf(f->code, "*_cPtr = *return_value;\n");
  978. Printf(f->code, "INIT_ZVAL(*return_value);\n");
  979. Printf(f->code, "add_property_zval(this_ptr,\"_cPtr\",_cPtr);\n");
  980. Printf(f->code, "} else if (! this_ptr) ");
  981. }
  982. { // THIS CODE only really needs writing out if the object to be returned
  983. // Is being shadow-wrap-thingied
  984. Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n");
  985. // Make object
  986. String *shadowrettype = NewString("");
  987. SwigToPhpType(d, iname, shadowrettype, shadow);
  988. Printf(f->code,"zval *obj, *_cPtr;\n");
  989. Printf(f->code,"MAKE_STD_ZVAL(obj);\n");
  990. Printf(f->code,"MAKE_STD_ZVAL(_cPtr);\n");
  991. Printf(f->code,"*_cPtr = *return_value;\n");
  992. Printf(f->code,"INIT_ZVAL(*return_value);\n");
  993. if (! shadow) {
  994. Printf(f->code,"*return_value=*_cPtr;\n");
  995. } else {
  996. Printf(f->code,"object_init_ex(obj,ptr_ce_swig_%s);\n",shadowrettype);
  997. Printf(f->code,"add_property_zval(obj,\"_cPtr\",_cPtr);\n");
  998. Printf(f->code,"*return_value=*obj;\n");
  999. }
  1000. Printf(f->code, "}\n");
  1001. }
  1002. } // end of if-shadow lark
  1003. } else {
  1004. Printf(stderr,"%s: Line %d, Unable to use return type %s in function %s.\n",
  1005. input_file, line_number, SwigType_str(d,0), name);
  1006. }
  1007. if(outarg) {
  1008. Printv(f->code,outarg,NIL);
  1009. }
  1010. if(cleanup) {
  1011. Printv(f->code,cleanup,NIL);
  1012. }
  1013. // Whats this bit for?
  1014. if((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
  1015. Printf(f->code,"%s\n", tm);
  1016. }
  1017. if (mvr) {
  1018. if (! mvrset) {
  1019. Printf(f->code,"return _return_value;\n");
  1020. }
  1021. else{
  1022. Printf(f->code,"return SUCCESS;\n");
  1023. }
  1024. }
  1025. else {
  1026. Printf(f->code,"return;\n");
  1027. }
  1028. /* Error handling code */
  1029. Printf(f->code,"fail:\n");
  1030. Printv(f->code,cleanup,NIL);
  1031. Printv(f->code,"zend_error(ErrorCode(),ErrorMsg());",NIL);
  1032. Printf(f->code, "}\n");
  1033. // These were cribbed from python.cxx
  1034. Replaceall(f->code,"$cleanup",cleanup);
  1035. Replaceall(f->code,"$symname",iname);
  1036. Wrapper_print(f,s_wrappers);
  1037. // wrap:name is used by overload resolution
  1038. Setattr(n,"wrap:name",wname);
  1039. if (overloaded && !Getattr(n,"sym:nextSibling")) {
  1040. dispatchFunction(n);
  1041. }
  1042. return SWIG_OK;
  1043. }
  1044. /* ------------------------------------------------------------
  1045. * globalvariableHandler()
  1046. * ------------------------------------------------------------ */
  1047. virtual int globalvariableHandler(Node *n) {
  1048. char *name = GetChar(n,"name");
  1049. char *iname = GetChar(n,"sym:name");
  1050. SwigType *t = Getattr(n,"type");
  1051. String *tm;
  1052. /* First do the wrappers such as name_set(), name_get()
  1053. * as provided by the baseclass's implementation of variableWrapper
  1054. */
  1055. if (Language::globalvariableHandler(n) == SWIG_NOWRAP ) {
  1056. return SWIG_NOWRAP;
  1057. }
  1058. if (!addSymbol(iname,n))
  1059. return SWIG_ERROR;
  1060. SwigType_remember(t);
  1061. /* First link C variables to PHP */
  1062. tm = Swig_typemap_lookup_new("varinit", n, name, 0);
  1063. if(tm) {
  1064. Replaceall(tm, "$target", name);
  1065. Printf(s_vinit, "%s\n", tm);
  1066. } else {
  1067. Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
  1068. input_file, line_number, SwigType_str(t,0), name);
  1069. }
  1070. /* Now generate PHP -> C sync blocks */
  1071. /*
  1072. tm = Swig_typemap_lookup_new("varin", n, name, 0);
  1073. if(tm) {
  1074. Replaceall(tm, "$symname", iname);
  1075. Printf(f_c->code, "%s\n", tm);
  1076. } else {
  1077. Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
  1078. input_file, line_number, SwigType_str(t, 0), name);
  1079. }
  1080. */
  1081. /* Now generate C -> PHP sync blocks */
  1082. /*
  1083. if(!GetFlag(n,"feature:immutable")) {
  1084. tm = Swig_typemap_lookup_new("varout", n, name, 0);
  1085. if(tm) {
  1086. Replaceall(tm, "$symname", iname);
  1087. Printf(f_php->code, "%s\n", tm);
  1088. } else {
  1089. Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
  1090. input_file, line_number, SwigType_str(t, 0), name);
  1091. }
  1092. }
  1093. */
  1094. return SWIG_OK;
  1095. }
  1096. /* ------------------------------------------------------------
  1097. * constantWrapper()
  1098. * ------------------------------------------------------------ */
  1099. virtual int constantWrapper(Node *n) {
  1100. String *name = GetChar(n,"name");
  1101. String *iname = GetChar(n,"sym:name");
  1102. SwigType *type = Getattr(n,"type");
  1103. String *rawval = Getattr(n,"rawval");
  1104. String *value = rawval ? rawval : Getattr(n,"value");
  1105. String *tm;
  1106. if (!addSymbol(iname,n)) return SWIG_ERROR;
  1107. SwigType_remember(type);
  1108. if((tm = Swig_typemap_lookup_new("consttab", n, name, 0))) {
  1109. Replaceall(tm, "$source", value);
  1110. Replaceall(tm, "$target", name);
  1111. Replaceall(tm, "$value", value);
  1112. Printf(s_cinit, "%s\n", tm);
  1113. }
  1114. return SWIG_OK;
  1115. }
  1116. /*
  1117. * PHP4::pragma()
  1118. *
  1119. * Pragma directive.
  1120. *
  1121. * %pragma(php4) code="String" # Includes a string in the .php file
  1122. * %pragma(php4) include="file.pl" # Includes a file in the .php file
  1123. */
  1124. virtual int pragmaDirective(Node *n) {
  1125. if (!ImportMode) {
  1126. String *lang = Getattr(n,"lang");
  1127. String *type = Getattr(n,"name");
  1128. String *value = Getattr(n,"value");
  1129. if (Strcmp(lang,"php4") == 0) {
  1130. if (Strcmp(type, "code") == 0) {
  1131. if (value) {
  1132. Printf(pragma_code, "%s\n", value);
  1133. }
  1134. } else if (Strcmp(type, "include") == 0) {
  1135. if (value) {
  1136. Printf(pragma_incl, "include \"%s\";\n", value);
  1137. }
  1138. } else if (Strcmp(type, "phpinfo") == 0) {
  1139. if (value) {
  1140. Printf(pragma_phpinfo, "%s\n", value);
  1141. }
  1142. } else {
  1143. Printf(stderr, "%s : Line %d. Unrecognized pragma.\n",
  1144. input_file, line_number);
  1145. }
  1146. }
  1147. }
  1148. return Language::pragmaDirective(n);
  1149. }
  1150. /* ------------------------------------------------------------
  1151. * classDeclaration()
  1152. * ------------------------------------------------------------ */
  1153. virtual int classDeclaration(Node *n) {
  1154. if (!Getattr(n,"feature:onlychildren")) {
  1155. String *symname = Getattr(n,"sym:name");
  1156. Setattr(n,"php:proxy",symname);
  1157. }
  1158. return Language::classDeclaration(n);
  1159. }
  1160. /* ------------------------------------------------------------
  1161. * classHandler()
  1162. * ------------------------------------------------------------ */
  1163. virtual int classHandler(Node *n) {
  1164. constructors=0;
  1165. //SwigType *t = Getattr(n, "classtype");
  1166. class_name = Getattr(n, "sym:name");
  1167. // String *use_class_name=SwigType_manglestr(SwigType_ltype(t));
  1168. if(shadow) {
  1169. char *rename = GetChar(n, "sym:name");
  1170. if (!addSymbol(rename,n)) return SWIG_ERROR;
  1171. shadow_classname = Swig_copy_string(rename);
  1172. cs_entry = NewString("");
  1173. Printf(cs_entry,"/* Function entries for %s */\n",shadow_classname);
  1174. Printf(cs_entry,"static zend_function_entry %s_functions[] = {\n", shadow_classname);
  1175. if(Strcmp(shadow_classname, module) == 0) {
  1176. Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname);
  1177. SWIG_exit(1);
  1178. }
  1179. shadow_get_vars = NewHash();
  1180. shadow_set_vars = NewHash();
  1181. /* Deal with inheritance */
  1182. List *baselist = Getattr(n,"bases");
  1183. if (baselist) {
  1184. Iterator base = First(baselist);
  1185. while(base.item && GetFlag(base.item,"feature:ignore")) {
  1186. base = Next(base);
  1187. }
  1188. base = Next(base);
  1189. if (base.item) {
  1190. /* Warn about multiple inheritance for additional base class(es) */
  1191. while (base.item) {
  1192. if (GetFlag(base.item,"feature:ignore")) {
  1193. base = Next(base);
  1194. continue;
  1195. }
  1196. String *proxyclassname = SwigType_str(Getattr(n,"classtypeobj"),0);
  1197. String *baseclassname = SwigType_str(Getattr(base.item,"name"),0);
  1198. Swig_warning(WARN_PHP4_MULTIPLE_INHERITANCE, input_file, line_number,
  1199. "Wa…

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