Updated CHANGES.current.

Fixed problems with insert() and unshift() functions in std::vector for ruby.
Updated Ruby documentation.
Improved swig_assert.rb.
Added "second" singleton to std_pair in ruby.
Modified two tests to follow the new STL stuff.



git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9721 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Gonzalo Garramuno 2007-04-30 09:45:10 +00:00
commit 806d9040c5
11 changed files with 2768 additions and 1075 deletions

View file

@ -1,18 +1,33 @@
Version 1.3.32 (in progress)
============================
05/01/2007: gga
[Ruby]
Improved the documentation to document the new features
added, add directorin/out/argout typemaps, etc.
05/01/2007: gga
[Ruby]
Added %initstack and %ignorestack directives for director
functions. These allow you to control whether a director
function should re-init the ruby stack.
This is sometimes needed for an embedded Ruby where the
director method is used as a C++ callback and not called
by the user from ruby code.
04/30/2007: gga
[Ruby]
Ruby will now report the parameter index properly on type
errors.
errors as well as the class and value of the incorrect
argument passed.
(feature request #1699670)
04/30/2007: gga
[Ruby]
std_vector.i and some related STL files have been upgraded
to follow the new swig/python Lib/std conventions.
STL files have been upgraded to follow the new swig/python
Lib/std conventions.
std_vector.i now mimics the behavior of Ruby Arrays much more
closely, supporting slicing, multiple indexing and proper
return values on assignment.
closely, supporting slicing, shifting, unshifting,
multiple indexing and proper return values on assignment.
COMPATABILITY NOTE: this changes the older api a little bit in
that improper indexing would previously (incorrectly) raise
@ -75,7 +90,7 @@ Version 1.3.32 (in progress)
This feature allows you to ignore the output of a function so
that it is not added to a list of outpus values
( ie. argouts ).
This should also become a feature of %typemap(out/directorout)
This should also become a feature of %typemap(directorout)
as "numoutputs"=0, just like "numinputs"=0 exists.
%feature("directors"=1)
@ -126,7 +141,8 @@ Version 1.3.32 (in progress)
to reset the stack will not always do so. This bug is triggered
very rarely, when ruby is called from two very distinct places
in memory, like a branch of main() and another dso. This bug
has now been reported to ruby-core.
has now been reported to ruby-core and is pending further
investigation.
(bug #1700535 and patch #1702907)

File diff suppressed because it is too large Load diff

View file

@ -77,13 +77,13 @@ public:
SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(Flow, Space::Flow)
#endif
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON)||defined(SWIGR)
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON)||defined(SWIGR) || defined(SWIGRUBY)
#define SWIG_GOOD_VECTOR
%ignore std::vector<Space::Flow>::vector(size_type);
%ignore std::vector<Space::Flow>::resize(size_type);
#endif
#if defined(SWIGTCL) || defined(SWIGPERL) || defined(SWIGRUBY)
#if defined(SWIGTCL) || defined(SWIGPERL)
#define SWIG_GOOD_VECTOR
/* here, for languages with bad declaration */
%ignore std::vector<Space::Flow>::vector(unsigned int);

View file

@ -1,13 +1,13 @@
%module ignore_template_constructor
%include std_vector.i
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL)
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL) || defined(SWIGRUBY)
#define SWIG_GOOD_VECTOR
%ignore std::vector<Flow>::vector(size_type);
%ignore std::vector<Flow>::resize(size_type);
#endif
#if defined(SWIGTCL) || defined(SWIGPERL) || defined(SWIGRUBY)
#if defined(SWIGTCL) || defined(SWIGPERL)
#define SWIG_GOOD_VECTOR
/* here, for languages with bad declaration */
%ignore std::vector<Flow>::vector(unsigned int);

View file

@ -40,29 +40,28 @@ end
"@iv[1..-2].to_s" => '12',
"@iv[2..-3]" => nil,
}.each do |k,v|
swig_assert( "#{k} == #{v.inspect}", "was #{eval(k).inspect}" )
swig_assert( "#{k} == #{v.inspect}" )
end
swig_assert( "@iv << 5" )
swig_assert( "@iv.push 5" )
swig_assert( "@iv.pop == 5" )
swig_assert( "@iv.insert(1,5)" )
swig_assert( "@iv.unshift(7)" )
swig_assert( "@iv.shift == 7" )
swig_assert( "@iv.insert(0, 3)" )
swig_assert( "@iv.unshift(7, 3)" )
swig_assert( "x = average(@iv)" )
swig_assert( "y = average([1, 2, 3, 4])" )
swig_assert( "half([10, 10.5, 11, 11.5])" )
swig_assert_each_line(<<'EOF')
@iv << 5
@iv.push 5
@iv.pop == 5
@iv.unshift(7)
@iv.shift == 7
@iv.unshift(7, 3)
@iv.insert(1,5)
@iv.insert(0, 3)
x = average(@iv)
y = average([1, 2, 3, 4])
half([10, 10.5, 11, 11.5])
EOF
@dv = DoubleVector.new(10)
swig_assert( "@dv.respond_to? :each_with_index" )
@dv.each_with_index { |e,i| swig_assert("#{e} == 0.0", "for @dv[#{i}] == 0") }
@dv.each_with_index { |e,i| swig_assert("@dv[#{i}] == 0.0") }
0.upto(9) { |i| @dv[i] = i/2.0 }
@ -72,17 +71,17 @@ swig_assert( "@dv.respond_to? :each_with_index" )
"@dv[0,3].to_s" => "0.00.51.0",
"@dv[3,3].to_s" => "1.52.02.5",
}.each do |k,v|
swig_assert( "#{k} == #{v.inspect}", "was #{eval(k).inspect}" )
swig_assert( "#{k} == #{v.inspect}" )
end
swig_assert( "@dv.delete_at(2)" )
swig_assert( "@dv.delete_if() { |x| x == 2.0 }" )
swig_assert_each_line(<<'EOF')
@dv.delete_at(2)
@dv.delete_if() { |x| x == 2.0 }
@dv.include? 3.0
@dv.find {|x| x==3.0 }
halve_in_place(@dv) == nil
@dv = [0.0,0.25,0.75,1.25,1.5,1.75,2.0,2.25]
@sv = StructVector.new
@sv << Li_std_vector::Struct.new
EOF
swig_assert( "@dv.include? 3.0" )
swig_assert( "@dv.find {|x| x==3.0 }" )
swig_assert( "halve_in_place(@dv) == nil" )
swig_assert( "@dv = [0.0,0.25,0.75,1.25,1.5,1.75,2.0,2.25]", "#@dv" )
swig_assert( "@sv = StructVector.new" )
swig_assert( "@sv << C_Struct.new" )

View file

@ -23,7 +23,7 @@ def swig_assert( condition, *args )
end
unless ok
raise SwigRubyError.new("FAILED CHECK: #{condition} #{args.join(' ')}")
raise SwigRubyError.new("FAILED CHECK: #{condition} was #{ok.inspect} #{args.join(' ')}")
end
if $VERBOSE
@ -39,3 +39,10 @@ rescue => e
end
exit(1)
end
def swig_assert_each_line( lines )
lines.split("\n").each do |line|
swig_assert(line)
end
end

View file

@ -109,6 +109,7 @@
template <class T, class U >
struct traits_from<std::pair<T,U> > {
static PyObject *from(const std::pair<T,U>& val) {
fprintf( stderr, "%s %d\n", __PRETTY_FUNCTION__, __LINE__);
PyObject* obj = PyTuple_New(2);
PyTuple_SetItem(obj,0,swig::from(val.first));
PyTuple_SetItem(obj,1,swig::from(val.second));

View file

@ -807,6 +807,7 @@ namespace swig
%define %swig_sequence_front_inserters( Sequence... )
%extend {
VALUE shift()
@ -822,35 +823,41 @@ namespace swig
$2 = argv + 1;
}
Sequence* insert( difference_type idx, int argc, VALUE* argv, ... )
Sequence* insert( difference_type pos, int argc, VALUE* argv, ... )
{
std::size_t len = $self->size();
std::size_t i = swig::check_index( idx, len, true );
Sequence::value_type val;
std::size_t i = swig::check_index( pos, len, true );
Sequence::iterator start;
int res = swig::asval( argv[0], &val );
if (!SWIG_IsOK(res))
SWIG_exception_fail(SWIG_ArgError(res),
Ruby_Format_TypeError( "",
swig::type_name<Sequence::value_type>(), __FUNCTION__, 2, argv[0] ));
if ( i >= len ) {
$self->resize(i-1, val);
return $self;
}
start = $self->begin();
std::advance( start, i );
$self->insert( start++, val );
for ( int idx = 1; idx < argc; ++idx )
VALUE elem = argv[0];
int idx = 0;
try {
Sequence::value_type val = swig::as<Sequence::value_type>( elem, true );
if ( i >= len ) {
$self->resize(i-1, val);
return $self;
}
start = $self->begin();
std::advance( start, i );
$self->insert( start++, val );
for ( ++idx; idx < argc; ++idx )
{
elem = argv[idx];
val = swig::as<Sequence::value_type>( elem );
$self->insert( start++, val );
}
}
catch( std::invalid_argument )
{
int res = swig::asval( argv[idx], &val );
if (!SWIG_IsOK(res))
SWIG_exception_fail(SWIG_ArgError(res),
Ruby_Format_TypeError( "",
swig::type_name<Sequence::value_type>(), __FUNCTION__, idx+2, argv[idx] ));
$self->insert( start++, val );
rb_raise( rb_eArgError,
Ruby_Format_TypeError( "",
swig::type_name<Sequence::value_type>(),
__FUNCTION__, idx+2, elem ));
}
fail:
return $self;
}
@ -861,19 +868,24 @@ namespace swig
Sequence* unshift( int argc, VALUE* argv, ... )
{
Sequence::value_type val;
for ( int idx = argc-1; idx >= 0; --idx )
{
int res = swig::asval( argv[idx], &val );
if (!SWIG_IsOK(res))
SWIG_exception_fail(SWIG_ArgError(res),
Ruby_Format_TypeError( "",
swig::type_name<Sequence::value_type>(), __FUNCTION__, idx+2, argv[idx] ));
Sequence::iterator start = $self->begin();
$self->insert( start, val );
VALUE elem = argv[idx];
Sequence::value_type val;
try {
Sequence::value_type val = swig::as<Sequence::value_type>( elem, true );
$self->insert( start, val );
}
catch( std::invalid_argument )
{
rb_raise( rb_eArgError,
Ruby_Format_TypeError( "",
swig::type_name<Sequence::value_type>(),
__FUNCTION__, idx+2, elem ));
}
}
fail:
return $self;
}

View file

@ -50,22 +50,22 @@ RUBYKW(when);
RUBYKW(while);
RUBYKW(yield);
RUBYKW(FalseClass);
RUBYKW(TrueClass);
RUBYKW(Numeric);
RUBYKW(Integer);
RUBYKW(Fixnum);
RUBYKW(Float);
RUBYKW(Range);
RUBYKW(Array);
RUBYKW(String);
RUBYKW(IO);
RUBYKW(File);
RUBYKW(FileUtils);
RUBYKW(Find);
RUBYKW(Struct);
RUBYKW(OpenStruct);
RUBYKW(Regexp);
// RUBYKW(FalseClass);
// RUBYKW(TrueClass);
// RUBYKW(Numeric);
// RUBYKW(Integer);
// RUBYKW(Fixnum);
// RUBYKW(Float);
// RUBYKW(Range);
// RUBYKW(Array);
// RUBYKW(String);
// RUBYKW(IO);
// RUBYKW(File);
// RUBYKW(FileUtils);
// RUBYKW(Find);
// RUBYKW(Struct);
// RUBYKW(OpenStruct);
// RUBYKW(Regexp);
#undef RUBYKW

View file

@ -165,10 +165,10 @@ namespace swig {
}
}
};
template <class Type>
inline Type as(VALUE obj, bool te = false) {
return traits_as<Type, typename traits<Type>::category>::as(obj, te);
return traits_as< Type, typename traits< Type >::category >::as(obj, te);
}
template <class Type>
@ -194,46 +194,6 @@ namespace swig {
}
}
//
// Backward compatibility
//
%define %specialize_std_container(Type,Check,As,From)
%{
namespace swig {
template <> struct traits_asval<Type > {
typedef Type value_type;
static int asval(VALUE obj, value_type *val) {
if (Check(obj)) {
if (val) *val = As(obj);
return SWIG_OK;
}
return SWIG_ERROR;
}
};
template <> struct traits_from<Type > {
typedef Type value_type;
static VALUE from(const value_type& val) {
return From(val);
}
};
template <>
struct traits_check<Type, value_category> {
static int check(VALUE obj) {
int res = Check(obj);
return obj && res ? res : 0;
}
};
}
%}
%enddef
#define SWIG_RUBY_THREAD_BEGIN_BLOCK
#define SWIG_RUBY_THREAD_END_BLOCK
#define specialize_std_vector(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)
#define specialize_std_list(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)
#define specialize_std_deque(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)
#define specialize_std_set(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)
#define specialize_std_multiset(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)

View file

@ -2131,7 +2131,7 @@ public:
*
* --------------------------------------------------------------- */
void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args) {
void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args, bool initstack) {
Wrapper *body = NewWrapper();
Wrapper *rescue = NewWrapper();
@ -2187,7 +2187,7 @@ public:
Printv(w->code, "args.argv = 0;\n", NIL);
}
Printf(w->code, "result = rb_protect(PROTECTFUNC(%s), reinterpret_cast<VALUE>(&args), &status);\n", bodyName, rescueName);
Printf(w->code, "SWIG_RELEASE_STACK;\n");
if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
Printf(w->code, "if (status) {\n");
Printf(w->code, "VALUE lastErr = rb_gv_get(\"$!\");\n");
Printf(w->code, "%s(reinterpret_cast<VALUE>(&args), lastErr);\n", rescueName);
@ -2204,7 +2204,7 @@ public:
} else {
Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", methodName);
}
Printf(w->code, "SWIG_RELEASE_STACK;\n");
if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
}
// Clean up
@ -2237,6 +2237,7 @@ public:
int idx;
bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
bool asvoid = bool( checkAttribute( n, "feature:numoutputs", "0") );
bool initstack = bool( checkAttribute( n, "feature:initstack", "1") );
if (Cmp(storage, "virtual") == 0) {
if (Cmp(value, "0") == 0) {
@ -2317,7 +2318,7 @@ public:
Append(w->def, " {");
Append(declaration, ";\n");
if (!(ignored_method && !pure_virtual)) {
if (initstack && !(ignored_method && !pure_virtual)) {
Append(w->def, "\nSWIG_INIT_STACK;\n");
}
@ -2472,7 +2473,7 @@ public:
Printv(w->code, wrap_args, NIL);
/* pass the method call on to the Ruby object */
exceptionSafeMethodCall(classname, n, w, idx, arglist);
exceptionSafeMethodCall(classname, n, w, idx, arglist, initstack);
/*
* Ruby method may return a simple object, or an Array of objects.