27
27
* This is an optimisation - we could handle this case using a PHP
28
28
* default value, but currently we treat it as we would for a default
29
29
* value which is a compound C++ expression (i.e. as if we had a
30
* a method with two overloaded forms instead of a single method with
30
* method with two overloaded forms instead of a single method with
31
31
* a default parameter value).
33
* Create __isset method for PHP 5.1 and later (we can probably just
34
* always generate as PHP 5.0 should just ignore it).
38
35
* Option to generate code to work with PHP4 instead ("public $_cPtr;" ->
147
144
static void (*r_prevtracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
150
static const char *php_header =
152
"\n +----------------------------------------------------------------------+"
153
"\n | PHP version 4.0 |"
154
"\n +----------------------------------------------------------------------+"
155
"\n | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |"
156
"\n +----------------------------------------------------------------------+"
157
"\n | This source file is subject to version 2.02 of the PHP license, |"
158
"\n | that is bundled with this package in the file LICENSE, and is |"
159
"\n | available at through the world-wide-web at |"
160
"\n | http://www.php.net/license/2_02.txt. |"
161
"\n | If you did not receive a copy of the PHP license and are unable to |"
162
"\n | obtain it through the world-wide-web, please send a note to |"
163
"\n | license@php.net so we can mail you a copy immediately. |"
164
"\n +----------------------------------------------------------------------+"
167
"\n +----------------------------------------------------------------------+" "\n */\n";
169
147
void SwigPHP_emit_resource_registrations() {
341
319
Printf(f_make, "CXX_SOURCES=%s\n", withcxx);
342
320
Printf(f_make, "C_SOURCES=%s\n", withc);
343
321
Printf(f_make, "OBJS=%s_wrap.o $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cxx=.o)\n", module);
344
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",
322
Printf(f_make, "MODULE=%s.so\n", module);
346
323
Printf(f_make, "CFLAGS=-fpic\n");
347
324
Printf(f_make, "LDFLAGS=-shared\n");
348
325
Printf(f_make, "PHP_INC=`php-config --includes`\n");
350
327
Printf(f_make, "EXTRA_LIB=\n\n");
351
328
Printf(f_make, "$(MODULE): $(OBJS)\n");
352
329
if (CPlusPlus || (withcxx != NULL)) {
353
Printf(f_make, "\t$(CXX) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
330
Printf(f_make, "\t$(CXX) $(LDFLAGS) $(OBJS) -o $@ $(EXTRA_LIB)\n\n");
355
Printf(f_make, "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
332
Printf(f_make, "\t$(CC) $(LDFLAGS) $(OBJS) -o $@ $(EXTRA_LIB)\n\n");
357
334
Printf(f_make, "%%.o: %%.cpp\n");
358
335
Printf(f_make, "\t$(CXX) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n");
655
632
Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, %s_destroy_globals);\n", module, module, module);
657
634
/* start the header section */
658
Printf(s_header, php_header);
659
635
Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
660
Printf(s_header, "char *error_msg;\n");
636
Printf(s_header, "const char *error_msg;\n");
661
637
Printf(s_header, "int error_code;\n");
662
638
Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
663
639
Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
740
715
Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n");
741
Printf(s_entry, "static function_entry %s_functions[] = {\n", module);
716
Printf(s_entry, "static zend_function_entry %s_functions[] = {\n", module);
743
718
/* start the init section */
744
719
Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n" "#if ZEND_MODULE_API_NO > 20010900\n" " STANDARD_MODULE_HEADER,\n" "#endif\n", NIL);
745
Printf(s_init, " \"%s\",\n", module);
720
Printf(s_init, " (char*)\"%s\",\n", module);
746
721
Printf(s_init, " %s_functions,\n", module);
747
722
Printf(s_init, " PHP_MINIT(%s),\n", module);
748
723
Printf(s_init, " PHP_MSHUTDOWN(%s),\n", module);
811
786
Printf(s_init, " return SUCCESS;\n");
812
787
Printf(s_init, "}\n\n");
814
Printf(s_init, "PHP_MSHUTDOWN_FUNCTION(%s)\n{\n", module);
815
Printf(s_init, "%s\n", s_shutdown);
816
Printf(s_init, " return SUCCESS;\n");
817
Printf(s_init, "}\n\n");
789
Printv(s_init, "PHP_MSHUTDOWN_FUNCTION(", module, ")\n"
793
" ts_free_id(", module, "_globals_id);\n"
819
798
Printf(s_init, "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n", module);
820
799
Printf(s_init, "%s\n", r_shutdown);
877
856
/* Just need to append function names to function table to register with PHP. */
878
857
void create_command(String *cname, String *iname) {
879
// This is for the single main function_entry record
858
// This is for the single main zend_function_entry record
880
859
if (shadow && php_version == 4) {
881
860
if (wrapperType != standard)
884
863
Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
886
Printf(cs_entry, " ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
888
Printf(s_entry, " ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
864
String * s = cs_entry;
866
Printf(s, " SWIG_ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
892
869
/* ------------------------------------------------------------
1142
1120
Replaceall(tm, "$input", source);
1143
1121
Setattr(p, "emit:input", source);
1144
1122
Printf(f->code, "%s\n", tm);
1145
if (i == 0 && HashGetAttr(p, k_self)) {
1123
if (i == 0 && Getattr(p, "self")) {
1146
1124
Printf(f->code, "\tif(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n");
1148
1126
p = Getattr(p, "tmap:in:next");
1207
1185
Replaceall(tm, "$result", "return_value");
1208
1186
Replaceall(tm, "$owner", newobject ? "1" : "0");
1209
1187
Printf(f->code, "%s\n", tm);
1210
// are we returning a wrapable object?
1211
// I don't know if this test is complete, I nicked it
1212
if (is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
1213
Printf(f->code, "/* Wrap this return value */\n");
1188
// Are we returning a wrapable object?
1189
if (shadow && php_version == 4 && is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
1191
Printf(f->code, "{\n/* Wrap this return value */\n");
1192
Printf(f->code, "zval *_cPtr;\n");
1193
Printf(f->code, "ALLOC_ZVAL(_cPtr);\n");
1194
Printf(f->code, "*_cPtr = *return_value;\n");
1195
Printf(f->code, "INIT_ZVAL(*return_value);\n");
1214
1196
if (native_constructor == NATIVE_CONSTRUCTOR) {
1215
Printf(f->code, "if (this_ptr) {\n");
1216
Printf(f->code, "/* NATIVE Constructor, use this_ptr */\n");
1217
Printf(f->code, "zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n");
1218
Printf(f->code, "*_cPtr = *return_value;\n");
1219
Printf(f->code, "INIT_ZVAL(*return_value);\n");
1220
1197
Printf(f->code, "add_property_zval(this_ptr,\"" SWIG_PTR "\",_cPtr);\n");
1221
Printf(f->code, "} else if (! this_ptr) ");
1223
{ // THIS CODE only really needs writing out if the object to be returned
1224
// Is being shadow-wrap-thingied
1225
Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n");
1227
String *shadowrettype = NewStringEmpty();
1228
SwigToPhpType(d, iname, shadowrettype, (shadow && php_version == 4));
1230
Printf(f->code, "zval *obj, *_cPtr;\n");
1231
Printf(f->code, "MAKE_STD_ZVAL(obj);\n");
1232
Printf(f->code, "MAKE_STD_ZVAL(_cPtr);\n");
1233
Printf(f->code, "*_cPtr = *return_value;\n");
1234
Printf(f->code, "INIT_ZVAL(*return_value);\n");
1236
if (shadow && php_version == 4) {
1237
Printf(f->code, "object_init_ex(obj,ptr_ce_swig_%s);\n", shadowrettype);
1238
Printf(f->code, "add_property_zval(obj,\"" SWIG_PTR "\",_cPtr);\n");
1239
Printf(f->code, "*return_value=*obj;\n");
1241
Printf(f->code, "*return_value=*_cPtr;\n");
1243
Printf(f->code, "}\n");
1245
} // end of if-shadow lark
1199
String *shadowrettype = SwigToPhpType(d, iname, true);
1200
Printf(f->code, "object_init_ex(return_value,ptr_ce_swig_%s);\n", shadowrettype);
1201
Delete(shadowrettype);
1202
Printf(f->code, "add_property_zval(return_value,\"" SWIG_PTR "\",_cPtr);\n");
1204
Printf(f->code, "}\n");
1247
1207
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);
1255
1215
Printv(f->code, cleanup, NIL);
1257
// What's this bit for?
1218
/* Look to see if there is any newfree cleanup code */
1219
if (GetFlag(n, "feature:new")) {
1220
if ((tm = Swig_typemap_lookup_new("newfree", n, "result", 0))) {
1221
Printf(f->code, "%s\n", tm);
1226
/* See if there is any return cleanup code */
1258
1227
if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
1259
1228
Printf(f->code, "%s\n", tm);
1264
1235
Printf(f->code, "return _return_value;\n");
1428
1400
l = nextSibling(l);
1432
arg_case = (bool *) malloc(max_num_of_arguments * sizeof(bool));
1434
/* FIXME: How should this be handled? The rest of SWIG just seems
1435
* to not bother checking for malloc failing! */
1436
fprintf(stderr, "Malloc failed!\n");
1439
for (int i = 0; i < max_num_of_arguments; ++i) {
1440
arg_case[i] = false;
1443
o = Getattr(n, "sym:overloaded");
1445
ParmList *l2 = Getattr(o, "wrap:parms");
1446
int num_arguments = emit_num_arguments(l2);
1447
int num_required = emit_num_required(l2);
1448
if (wrapperType == memberfn) {
1452
for (int i = num_required; i <= num_arguments; ++i) {
1455
o = Getattr(o, "sym:nextSibling");
1459
1405
if (wrapperType == memberfn) {
1525
1471
Printf(pname, " or_%s", pname_cstr);
1528
const char *value = GetChar(p, "value");
1474
String *value = NewString(Getattr(p, "value"));
1530
1476
/* Check that value is a valid constant in PHP (and adjust it if
1531
1477
* necessary, or replace it with "?" if it's just not valid). */
1532
1478
SwigType *type = Getattr(p, "type");
1533
1479
switch (SwigType_type(type)) {
1535
if (strcmp(value, "true") == 0 || strcmp(value, "false") == 0)
1481
if (Strcmp(value, "true") == 0 || Strcmp(value, "false") == 0)
1539
1485
int n = strtol(Char(value), &p, 0);
1490
Append(value, "true");
1492
Append(value, "false");
1555
1503
(void) strtol(Char(value), &p, 0);
1566
1516
(void) strtoul(Char(value), &p, 0);
1575
1527
/* FIXME: strtod is locale dependent... */
1576
(void) strtod(Char(value), &p);
1528
double val = strtod(Char(value), &p);
1532
} else if (strchr(Char(value), '.') == NULL) {
1533
// Ensure value is a double constant, not an integer one.
1534
Append(value, ".0");
1535
double val2 = strtod(Char(value), &p);
1536
if (errno || *p || val != val2) {
1587
if (Len(value) < 2) {
1588
// How can a string (including "" be less than 2 characters?)
1550
if (Len(value) < 2) {
1551
// How can a string (including "" be less than 2 characters?)
1555
const char *v = Char(value);
1556
if (v[0] != '"' || v[Len(value) - 1] != '"') {
1560
// Strings containing "$" require special handling, but we do
1591
1568
const char *v = Char(value);
1592
if (v[0] != '"' || v[Len(value) - 1] != '"')
1594
// Strings containing "$" require special handling, but we do that later.
1601
const char *v = value;
1602
1569
if (v[0] == '(') {
1603
1570
// Handle "(void*)0", "(TYPE*)0", "(char*)NULL", etc.
1604
1571
v += strcspn(v + 1, "*()") + 1;
1609
1576
} while (*v == '*');
1610
1577
if (*v++ == ')') {
1611
1578
v += strspn(v, " \t");
1579
String * old = value;
1580
value = NewString(v);
1616
if (strcmp(value, "NULL") == 0 || strcmp(value, "0") == 0 || strcmp(value, "0L") == 0) {
1585
if (Strcmp(value, "NULL") == 0 ||
1586
Strcmp(value, "0") == 0 ||
1587
Strcmp(value, "0L") == 0) {
1589
Append(value, "null");
1625
1598
if (!arg_values[argno]) {
1626
arg_values[argno] = NewString(value);
1599
arg_values[argno] = value;
1627
1601
} else if (Cmp(arg_values[argno], value) != 0) {
1628
1602
// If a parameter has two different default values in
1629
1603
// different overloaded forms of the function, we can't
1632
1606
Delete(arg_values[argno]);
1633
1607
arg_values[argno] = NewString("?");
1609
} else if (arg_values[argno]) {
1610
// This argument already has a default value in another overloaded
1611
// form, but doesn't in this form. So don't try to do anything
1612
// clever, just let the C wrappers resolve the overload and set the
1615
// This handling is safe, but I'm wondering if it may be overly
1616
// conservative (FIXME) in some cases. It seems it's only bad when
1617
// there's an overloaded form with the appropriate number of
1618
// parameters which doesn't want the default value, but I need to
1619
// think about this more.
1620
Delete(arg_values[argno]);
1621
arg_values[argno] = NewString("?");
1636
1624
p = nextSibling(p);
1726
1714
Printf(args, ",");
1727
1715
const char *value = Char(arg_values[i]);
1728
bool non_php_default = (!value || strcmp(value, "?") == 0);
1716
// FIXME: (really_overloaded && handle_as_overload) is perhaps a
1717
// little conservative, but it doesn't hit any cases that it
1718
// shouldn't for Xapian at least (and we need it to handle
1719
// "Enquire::get_mset()" correctly).
1720
bool non_php_default = ((really_overloaded && handle_as_overload) ||
1721
!value || strcmp(value, "?") == 0);
1729
1722
if (non_php_default)
1730
1723
value = "null";
1731
1724
Printf(args, "$%s=%s", arg_names[i], value);
1805
1798
String *mangled = NewString("_p");
1806
1799
Printf(mangled, "%s", SwigType_manglestr(ret_type));
1807
1800
Node *class_node = Getattr(zend_types, mangled);
1802
/* This is needed when we're returning a pointer to a type
1803
* rather than returning the type by value or reference. */
1804
class_node = current_class;
1806
mangled = NewString(SwigType_manglestr(ret_type));
1807
class_node = Getattr(zend_types, mangled);
1809
1810
Printf(output, "case \"%s\": ", mangled);
1811
Printf(output, "default: ", mangled);
1812
Printf(output, "default: ");
1813
1814
const char *classname = GetChar(class_node, "sym:name");
1814
1815
if (!classname)
1815
1816
classname = GetChar(class_node, "name");
1816
Printf(output, "return new %s%s($r);\n", prefix, classname);
1818
Printf(output, "return new %s%s($r);\n", prefix, classname);
1820
Printf(output, "return $r;\n");
1817
1821
Delete(mangled);
1819
1823
Printf(output, "\t\t}\n");
1858
1865
Replaceall(tm, "$target", name);
1859
1866
Printf(s_vinit, "%s\n", tm);
1861
Printf(stderr, "%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0), name);
1868
Printf(stderr, "%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0));
1864
1871
/* Now generate PHP -> C sync blocks */
1868
1875
Replaceall(tm, "$symname", iname);
1869
1876
Printf(f_c->code, "%s\n", tm);
1871
Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
1872
input_file, line_number, SwigType_str(t, 0), name);
1878
Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
1879
input_file, line_number, SwigType_str(t, 0));
1875
1882
/* Now generate C -> PHP sync blocks */
1881
1888
Replaceall(tm, "$symname", iname);
1882
1889
Printf(f_php->code, "%s\n", tm);
1884
Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
1885
input_file, line_number, SwigType_str(t, 0), name);
1891
Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
1892
input_file, line_number, SwigType_str(t, 0));
1916
1923
if (shadow && php_version == 5) {
1924
String *enumvalue = GetChar(n, "enumvalue");
1925
String *set_to = iname;
1928
enumvalue = GetChar(n, "enumvalueex");
1932
// Check for a simple constant expression which is valid in PHP.
1933
// If we find one, initialise the const member with it; otherwise
1934
// we initialise it using the C/C++ wrapped constant.
1936
for (p = Char(enumvalue); *p; ++p) {
1937
if (!isdigit((unsigned char)*p) && !strchr(" +-", *p)) {
1938
// FIXME: enhance to handle `<previous_enum> + 1' which is what
1939
// we get for enums that don't have an explicit value set.
1943
if (!*p) set_to = enumvalue;
1917
1946
if (wrapping_member_constant) {
1918
1947
if (!s_oowrappers)
1919
1948
s_oowrappers = NewStringEmpty();
1920
Printf(s_oowrappers, "\n\tconst %s = %s;\n", wrapping_member_constant, iname);
1949
Printf(s_oowrappers, "\n\tconst %s = %s;\n", wrapping_member_constant, set_to);
1922
1951
if (!s_fakeoowrappers)
1923
1952
s_fakeoowrappers = NewStringEmpty();
1924
Printf(s_fakeoowrappers, "\n\tconst %s = %s;\n", name, iname);
1953
Printf(s_fakeoowrappers, "\n\tconst %s = %s;\n", name, set_to);
2259
2288
if (base.item) {
2260
2289
Printf(s_oinit,
2261
"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
2290
"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL TSRMLS_CC))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
2262
2291
shadow_classname, shadow_classname, GetChar(base.item, "sym:name"), shadow_classname);
2264
2293
Printf(s_oinit,
2265
"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
2294
"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL TSRMLS_CC))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
2266
2295
shadow_classname, shadow_classname, shadow_classname);
2268
2297
Printf(s_oinit, "\n");
2327
2356
Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_set';\n", shadow_classname);
2328
Printf(s_phpclasses, "\t\tif (function_exists($func) call_user_func($func,$this->%s,$value);\n", SWIG_PTR);
2330
Printf(s_phpclasses, "\t}\n");
2331
/* FIXME: also create __isset for PHP 5.1 and later? */
2357
Printf(s_phpclasses, "\t\tif (function_exists($func)) call_user_func($func,$this->%s,$value);\n", SWIG_PTR);
2359
Printf(s_phpclasses, "\t}\n");
2361
/* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */
2362
Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
2363
// FIXME: tune this threshold, but it should probably be different to
2364
// that for __set() and __get() as we don't need to call_user_func()
2366
if (Len(shadow_set_vars) == 1) {
2367
// Only one setter, so just check the name.
2368
Printf(s_phpclasses, "\t\treturn ");
2371
Printf(s_phpclasses, "$var == '%s'", ki.key);
2373
if (ki.key) Printf(s_phpclasses, " || ");
2375
Printf(s_phpclasses, ";\n");
2377
Printf(s_phpclasses, "\t\treturn function_exists('%s_'.$var.'_set');\n", shadow_classname);
2379
Printf(s_phpclasses, "\t}\n");
2333
2381
// Write property GET handlers
2334
2382
ki = First(shadow_get_vars);