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:
parent
b2a45de097
commit
806d9040c5
11 changed files with 2768 additions and 1075 deletions
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
|||
3581
Doc/Manual/Ruby.html
3581
Doc/Manual/Ruby.html
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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" )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue