PageRenderTime 939ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/tags/rel-1-3-30rc1-afterbeautify/SWIG/Source/Modules/php4.cxx

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

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