286 lines
8.8 KiB
Python
Executable File
286 lines
8.8 KiB
Python
Executable File
#! /usr/bin/env python
|
|
# -*- coding: UTF-8 -*-
|
|
#
|
|
# $Id$
|
|
#
|
|
# SWIG based PHP binding for Lasso Library
|
|
#
|
|
# Copyright (C) 2004-2007 Entr'ouvert
|
|
# http://lasso.entrouvert.org
|
|
#
|
|
# Authors: See AUTHORS file in top-level directory.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
"""Correct SWIG output for PHP binding.
|
|
|
|
The PHP binding of SWIG version 1.3.22 has several bugs:
|
|
|
|
(1) It wraps NULL pointers into non NULL PHP objects.
|
|
|
|
(2) It doesn't handle dynamic cast of function results well: After the C object is dynamically
|
|
casted, it creates a statically casted PHP object.
|
|
|
|
(3) It handles badly optional arguments of methods.
|
|
|
|
This program corrects (1) and (2), by replacing things like:
|
|
if (!result) {
|
|
ZVAL_NULL(return_value);
|
|
} else {
|
|
swig_type_info *ty = SWIG_TypeDynamicCast(SWIGTYPE_p_LassoXXX, (void **) &result);
|
|
SWIG_SetPointerZval(return_value, (void *)result, ty, 1);
|
|
}
|
|
|
|
/* Wrap this return value */
|
|
if (this_ptr) {
|
|
/* NATIVE Constructor, use this_ptr */
|
|
zval *_cPtr; MAKE_STD_ZVAL(_cPtr);
|
|
*_cPtr = *return_value;
|
|
INIT_ZVAL(*return_value);
|
|
add_property_zval(this_ptr,"_cPtr",_cPtr);
|
|
} else if (! this_ptr) {
|
|
/* ALTERNATIVE Constructor, make an object wrapper */
|
|
zval *obj, *_cPtr;
|
|
MAKE_STD_ZVAL(obj);
|
|
MAKE_STD_ZVAL(_cPtr);
|
|
*_cPtr = *return_value;
|
|
INIT_ZVAL(*return_value);
|
|
object_init_ex(obj,ptr_ce_swig_LassoXXX);
|
|
add_property_zval(obj,"_cPtr",_cPtr);
|
|
*return_value=*obj;
|
|
}
|
|
with:
|
|
if (!result) {
|
|
ZVAL_NULL(return_value);
|
|
} else {
|
|
swig_type_info *ty = SWIG_TypeDynamicCast(SWIGTYPE_p_LassoXXX, (void **) &result);
|
|
SWIG_SetPointerZval(return_value, (void *)result, ty, 1);
|
|
/* Wrap this return value */
|
|
if (this_ptr) {
|
|
/* NATIVE Constructor, use this_ptr */
|
|
zval *_cPtr; MAKE_STD_ZVAL(_cPtr);
|
|
*_cPtr = *return_value;
|
|
INIT_ZVAL(*return_value);
|
|
add_property_zval(this_ptr,"_cPtr",_cPtr);
|
|
} else if (! this_ptr) {
|
|
/* ALTERNATIVE Constructor, make an object wrapper */
|
|
zval *obj, *_cPtr;
|
|
MAKE_STD_ZVAL(obj);
|
|
MAKE_STD_ZVAL(_cPtr);
|
|
*_cPtr = *return_value;
|
|
INIT_ZVAL(*return_value);
|
|
object_init_ex(obj,get_node_info_with_swig(ty)->php);
|
|
add_property_zval(obj,"_cPtr",_cPtr);
|
|
*return_value=*obj;
|
|
}}
|
|
and
|
|
if (!result) {
|
|
ZVAL_NULL(return_value);
|
|
} else {
|
|
swig_type_info *ty = SWIG_TypeDynamicCast(SWIGTYPE_p_LassoXXX, (void **) &result);
|
|
SWIG_SetPointerZval(return_value, (void *)result, ty, 0);
|
|
}
|
|
|
|
/* Wrap this return value */
|
|
{
|
|
/* ALTERNATIVE Constructor, make an object wrapper */
|
|
zval *obj, *_cPtr;
|
|
MAKE_STD_ZVAL(obj);
|
|
MAKE_STD_ZVAL(_cPtr);
|
|
*_cPtr = *return_value;
|
|
INIT_ZVAL(*return_value);
|
|
object_init_ex(obj,ptr_ce_swig_LassoXXX);
|
|
add_property_zval(obj,"_cPtr",_cPtr);
|
|
*return_value=*obj;
|
|
}
|
|
with:
|
|
if (!result) {
|
|
ZVAL_NULL(return_value);
|
|
} else {
|
|
swig_type_info *ty = SWIG_TypeDynamicCast(SWIGTYPE_p_LassoXXX, (void **) &result);
|
|
SWIG_SetPointerZval(return_value, (void *)result, ty, 0);
|
|
/* Wrap this return value */
|
|
{
|
|
/* ALTERNATIVE Constructor, make an object wrapper */
|
|
zval *obj, *_cPtr;
|
|
MAKE_STD_ZVAL(obj);
|
|
MAKE_STD_ZVAL(_cPtr);
|
|
*_cPtr = *return_value;
|
|
INIT_ZVAL(*return_value);
|
|
object_init_ex(obj,get_node_info_with_swig(ty)->php);
|
|
add_property_zval(obj,"_cPtr",_cPtr);
|
|
*return_value=*obj;
|
|
}}
|
|
|
|
In old SWIG versions, this program corrects (3), by replacing things like:
|
|
if(zend_get_parameters_array_ex(arg_count-argbase,args)!=SUCCESS)
|
|
with:
|
|
if(zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)
|
|
and by replacing:
|
|
if(arg_count > 1) {
|
|
with:
|
|
if(arg_count > 1 - argbase) {
|
|
|
|
In newer SWIG versions, this program corrects (3), by replacing code like:
|
|
if(arg_count<2 || arg_count>4)
|
|
with:
|
|
if(arg_count<1 || arg_count>3)
|
|
whenever the function uses a this_ptr.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
|
|
wrap = sys.stdin.read()
|
|
swig_version = sys.argv[1]
|
|
major, minor, release = re.match('(.*)\.(.*)\.(.*)', swig_version).groups()
|
|
major = int(major)
|
|
minor = int(minor)
|
|
release = int(release)
|
|
if major < 1 or (major == 1 and (minor < 3 or (minor == 3 and release < 32))):
|
|
# (1)
|
|
begin = """
|
|
}
|
|
|
|
/* Wrap this return value */
|
|
"""
|
|
end = """
|
|
*return_value=*obj;
|
|
}
|
|
"""
|
|
i = wrap.find(begin)
|
|
while i >= 0:
|
|
j = wrap.find(end, i) + len(end)
|
|
segment = wrap[i:j]
|
|
segment = segment.replace(begin, """
|
|
/* Wrap this return value */
|
|
""")
|
|
segment = segment.replace(end, """
|
|
*return_value=*obj;
|
|
}}
|
|
""")
|
|
wrap = '%s%s%s' % (wrap[:i], segment, wrap[j:])
|
|
i = wrap.find(begin, i + len(segment))
|
|
|
|
# (2)
|
|
begin = 'swig_type_info *ty = SWIG_TypeDynamicCast('
|
|
end = """
|
|
*return_value=*obj;
|
|
}}
|
|
"""
|
|
i = wrap.find(begin)
|
|
while i >= 0:
|
|
j = wrap.find(end, i) + len(end)
|
|
#print >> sys.stderr, "END:", j, len(end)
|
|
if j < len(end): # bails out if not found
|
|
break
|
|
segment = wrap[i:j]
|
|
x = segment.find('object_init_ex(obj,') + len('object_init_ex(obj,')
|
|
y = segment.find(')', x)
|
|
segment = '%s%s%s' % (segment[:x], 'get_node_info_with_swig(ty)->php', segment[y:])
|
|
wrap = '%s%s%s' % (wrap[:i], segment, wrap[j:])
|
|
i = wrap.find(begin, i + len(segment))
|
|
|
|
# (3)
|
|
wrap = wrap.replace('if(zend_get_parameters_array_ex(arg_count-argbase,args)!=SUCCESS)',
|
|
'if(zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)')
|
|
|
|
|
|
function_pattern = re.compile('ZEND_NAMED_FUNCTION(.*?)\n}', re.DOTALL)
|
|
argcount_less_pattern = re.compile('if\(arg_count<(\d) \|\| arg_count>(\d)')
|
|
argcount_more_pattern = re.compile('if\(arg_count > (\d)\)')
|
|
|
|
|
|
def rep2(match):
|
|
arg1 = int(match.group(1)) - 1
|
|
arg2 = int(match.group(2)) - 1
|
|
return 'if(arg_count<%s || arg_count>%s' % (arg1, arg2)
|
|
|
|
def rep3(match):
|
|
arg1 = int(match.group(1)) - 1
|
|
return 'if(arg_count > %s)' % arg1
|
|
|
|
def rep(match):
|
|
m = match.group(0)
|
|
if not 'This function uses a this_ptr' in m:
|
|
return m
|
|
if not 'arg_count<' in m:
|
|
return m
|
|
lines = match.group(0).splitlines()
|
|
s = []
|
|
for l in lines:
|
|
if l.startswith('if(arg_count<'):
|
|
l = argcount_less_pattern.sub(rep2, l)
|
|
elif l.startswith(' if(arg_count >'):
|
|
l = argcount_more_pattern.sub(rep3, l)
|
|
s.append(l)
|
|
|
|
return ''.join(s)
|
|
|
|
wrap = function_pattern.sub(rep, wrap)
|
|
|
|
wrap = re.sub(r'zend_register_internal_class_ex(.*)NULL,NULL\)',
|
|
r'zend_register_internal_class_ex\1NULL,NULL TSRMLS_CC)', wrap)
|
|
|
|
wrap = re.sub('zend_rsrc_list_get_rsrc_type(.*)lval *\)',
|
|
r'zend_rsrc_list_get_rsrc_type\1lval TSRMLS_CC)', wrap)
|
|
else:
|
|
# Bis for swig 1.3.33
|
|
# (1)
|
|
begin = """
|
|
}
|
|
|
|
{
|
|
/* Wrap this return value */
|
|
"""
|
|
end = """
|
|
}
|
|
"""
|
|
i = wrap.find(begin)
|
|
while i >= 0:
|
|
j = wrap.find(end, i+len(begin)) + len(end)
|
|
segment = wrap[i:j]
|
|
segment = segment.replace(begin, """
|
|
/* Wrap this return value */
|
|
""")
|
|
segment = segment.replace(end, """
|
|
}
|
|
""")
|
|
wrap = '%s%s%s' % (wrap[:i], segment, wrap[j:])
|
|
i = wrap.find(begin, i + len(segment))
|
|
# (2)
|
|
begin = 'swig_type_info *ty = SWIG_TypeDynamicCast('
|
|
end = """
|
|
}
|
|
"""
|
|
i = wrap.find(begin)
|
|
while i >= 0:
|
|
j = wrap.find(end, i+len(begin)) + len(end)
|
|
if j < len(end): # bails out if not found
|
|
i = wrap.find(begin, i + len(segment))
|
|
break
|
|
segment = wrap[i:j]
|
|
if not 'object_init_ex' in segment:
|
|
i = wrap.find(begin, i + len(segment))
|
|
continue
|
|
x = segment.find('object_init_ex(return_value,') + len('object_init_ex(return_value,')
|
|
y = segment.find(')', x)
|
|
segment = '%s%s%s' % (segment[:x], 'get_node_info_with_swig(ty)->php', segment[y:])
|
|
wrap = '%s%s%s' % (wrap[:i], segment, wrap[j:])
|
|
i = wrap.find(begin, i + len(segment))
|
|
|
|
print wrap
|