Add Ruby support contributed by Masaki Fukushima.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@518 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Thien-Thi Nguyen 2000-07-05 18:58:49 +00:00
commit 618e0eff61
39 changed files with 3754 additions and 10 deletions

42
Lib/ruby/Makefile.swig Normal file
View file

@ -0,0 +1,42 @@
# File : Makefile.swig
# Makefile for a SWIG module. Use this file if you are
# producing a Ruby extension for general use or distribution.
#
# 1. Prepare extconf.rb.
# 2. Modify this file as appropriate.
# 3. Type 'make -f Makefile.swig' to generate wrapper code and Makefile.
# 4. Type 'make' to build your extension.
# 5. Type 'make install' to install your extension.
#
MODULE = yourmodule
FEATURE = $(MODULE)
INTERFACE = $(MODULE).i
RUBY = ruby
SWIG = swig
# for C extension
SWIGOPT = -ruby
WRAPPER = $(MODULE)_wrap.c
## for C++ extension
#SWIGOPT = -ruby -c++
#WRAPPER = $(MODULE)_wrap.cc
swigall: $(WRAPPER) Makefile
$(WRAPPER): $(INTERFACE)
$(SWIG) $(SWIGOPT) -o $@ $(INTERFACE)
Makefile: extconf.rb
$(RUBY) extconf.rb
@if [ -f Makefile ] ; then\
echo "include Makefile.swig" >> Makefile;\
fi
swigclean:
@if [ -f Makefile ] ; then\
make -f Makefile clean;\
fi
rm -f Makefile $(WRAPPER)

16
Lib/ruby/embed.i Normal file
View file

@ -0,0 +1,16 @@
%wrapper %{
#include "ruby.h"
int
main(argc, argv)
int argc;
char **argv;
{
ruby_init();
ruby_options(argc, argv);
ruby_run();
return 0;
}
%}

27
Lib/ruby/exception.i Normal file
View file

@ -0,0 +1,27 @@
//
// SWIG exception handling for Ruby
//
// $Header$
//
// Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
// Copyright (C) 2000 Information-technology Promotion Agency, Japan
//
// Masaki Fukushima
//
%{
#define SWIG_MemoryError rb_eFatal
#define SWIG_IOError rb_eIOError
#define SWIG_RuntimeError rb_eRuntimeError
#define SWIG_IndexError rb_eIndexError
#define SWIG_TypeError rb_eTypeError
#define SWIG_DivisionByZero rb_eZeroDivError
#define SWIG_OverflowError rb_eRuntimeException
#define SWIG_SyntaxError rb_eSyntaxError
#define SWIG_ValueError rb_eArgError
#define SWIG_SystemError rb_eSystemError
#define SWIG_UnknownError rb_eRuntimeError
#define SWIG_exception(a,b) rb_raise(a,b)
%}

9
Lib/ruby/extconf.rb Normal file
View file

@ -0,0 +1,9 @@
require 'mkmf'
dir_config('yourlib')
if have_header('yourlib.h') and have_library('yourlib', 'yourlib_init')
# If you use swig -c option, you may have to link libswigrb.
# have_library('swigrb')
create_makefile('yourlib')
end

646
Lib/ruby/ptrlang.i Normal file
View file

@ -0,0 +1,646 @@
//
// SWIG pointer conversion and utility library for Ruby
//
// $Header$
//
// Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
// Copyright (C) 2000 Information-technology Promotion Agency, Japan
//
// Masaki Fukushima
//
// This file is originally derived from python/ptrlang.i
//
// SWIG pointer conversion and utility library
//
// Dave Beazley
// April 19, 1997
//
// Python specific implementation. This file is included
// by the file ../pointer.i
%{
#include <ctype.h>
/*------------------------------------------------------------------
ptrcast(value,type)
Constructs a new pointer value. Value may either be a string
or an integer. Type is a string corresponding to either the
C datatype or mangled datatype.
ptrcast(0,"Vector *")
or
ptrcast(0,"Vector_p")
------------------------------------------------------------------ */
static VALUE ptrcast(VALUE _PTRVALUE, char *type) {
char *r,*s;
void *ptr;
VALUE obj;
char *typestr,*c;
/* Produce a "mangled" version of the type string. */
typestr = (char *) xmalloc(strlen(type)+2);
/* Go through and munge the typestring */
r = typestr;
*(r++) = '_';
c = type;
while (*c) {
if (!isspace(*c)) {
if ((*c == '*') || (*c == '&')) {
*(r++) = 'p';
}
else *(r++) = *c;
} else {
*(r++) = '_';
}
c++;
}
*(r++) = 0;
/* Check to see what kind of object _PTRVALUE is */
switch (TYPE(_PTRVALUE)) {
case T_FIXNUM:
case T_BIGNUM:
ptr = (void *) NUM2ULONG(_PTRVALUE);
/* Received a numerical value. Make a pointer out of it */
r = (char *) xmalloc(strlen(typestr)+22);
if (ptr) {
SWIG_MakePtr(r, ptr, typestr);
} else {
sprintf(r,"_0%s",typestr);
}
obj = rb_str_new2(r);
free(r);
break;
case T_STRING:
/* Have a real pointer value now. Try to strip out the pointer
value */
s = STR2CSTR(_PTRVALUE);
r = (char *) xmalloc(strlen(type)+22);
/* Now extract the pointer value */
if (!SWIG_GetPtr(s,&ptr,0)) {
if (ptr) {
SWIG_MakePtr(r,ptr,typestr);
} else {
sprintf(r,"_0%s",typestr);
}
obj = rb_str_new2(r);
} else {
obj = Qnil;
}
free(r);
break;
default:
obj = Qnil;
break;
}
free(typestr);
if (!obj)
rb_raise(rb_eTypeError,"Type error in ptrcast. Argument is not a valid pointer value.");
return obj;
}
/*------------------------------------------------------------------
ptrvalue(ptr,type = 0)
Attempts to dereference a pointer value. If type is given, it
will try to use that type. Otherwise, this function will attempt
to "guess" the proper datatype by checking against all of the
builtin C datatypes.
------------------------------------------------------------------ */
static VALUE ptrvalue(VALUE _PTRVALUE, int index, char *type) {
void *ptr;
char *s;
VALUE obj;
Check_Type(_PTRVALUE, T_STRING);
s = STR2CSTR(_PTRVALUE);
if (SWIG_GetPtr(s,&ptr,0)) {
rb_raise(rb_eTypeError,"Type error in ptrvalue. Argument is not a valid pointer value.");
}
/* If no datatype was passed, try a few common datatypes first */
if (!type) {
/* No datatype was passed. Type to figure out if it's a common one */
if (!SWIG_GetPtr(s,&ptr,"int_p")) {
type = "int";
} else if (!SWIG_GetPtr(s,&ptr,"double_p")) {
type = "double";
} else if (!SWIG_GetPtr(s,&ptr,"short_p")) {
type = "short";
} else if (!SWIG_GetPtr(s,&ptr,"long_p")) {
type = "long";
} else if (!SWIG_GetPtr(s,&ptr,"float_p")) {
type = "float";
} else if (!SWIG_GetPtr(s,&ptr,"char_p")) {
type = "char";
} else if (!SWIG_GetPtr(s,&ptr,"char_pp")) {
type = "char *";
} else {
type = "unknown";
}
}
if (!ptr) {
rb_raise(rb_eTypeError,"Unable to dereference NULL pointer.");
}
/* Now we have a datatype. Try to figure out what to do about it */
if (strcmp(type,"int") == 0) {
obj = INT2NUM(*(((int *) ptr) + index));
} else if (strcmp(type,"double") == 0) {
obj = rb_float_new((double) *(((double *) ptr)+index));
} else if (strcmp(type,"short") == 0) {
obj = INT2NUM(*(((short *) ptr)+index));
} else if (strcmp(type,"long") == 0) {
obj = INT2NUM(*(((long *) ptr)+index));
} else if (strcmp(type,"float") == 0) {
obj = rb_float_new((double) *(((float *) ptr)+index));
} else if (strcmp(type,"char") == 0) {
obj = rb_str_new2(((char *) ptr)+index);
} else if (strcmp(type,"char *") == 0) {
char *c = *(((char **) ptr)+index);
if (c) obj = rb_str_new2(c);
else obj = rb_str_new2("NULL");
} else {
rb_raise(rb_eTypeError,"Unable to dereference unsupported datatype.");
}
return obj;
}
/*------------------------------------------------------------------
ptrcreate(type,value = 0,numelements = 1)
Attempts to create a new object of given type. Type must be
a basic C datatype. Will not create complex objects.
------------------------------------------------------------------ */
static VALUE ptrcreate(char *type, VALUE _RBVALUE, int numelements) {
void *ptr;
VALUE obj;
int sz;
char *cast;
char temp[40];
/* Check the type string against a variety of possibilities */
if (strcmp(type,"int") == 0) {
sz = sizeof(int)*numelements;
cast = "int_p";
} else if (strcmp(type,"short") == 0) {
sz = sizeof(short)*numelements;
cast = "short_p";
} else if (strcmp(type,"long") == 0) {
sz = sizeof(long)*numelements;
cast = "long_p";
} else if (strcmp(type,"double") == 0) {
sz = sizeof(double)*numelements;
cast = "double_p";
} else if (strcmp(type,"float") == 0) {
sz = sizeof(float)*numelements;
cast = "float_p";
} else if (strcmp(type,"char") == 0) {
sz = sizeof(char)*numelements;
cast = "char_p";
} else if (strcmp(type,"char *") == 0) {
sz = sizeof(char *)*(numelements+1);
cast = "char_pp";
} else {
rb_raise(rb_eTypeError,"Unable to create unknown datatype.");
}
/* Create the new object */
ptr = (void *) xmalloc(sz);
/* Now try to set its default value */
if (_RBVALUE) {
if (strcmp(type,"int") == 0) {
int *ip,i,ivalue;
ivalue = NUM2INT(_RBVALUE);
ip = (int *) ptr;
for (i = 0; i < numelements; i++)
ip[i] = ivalue;
} else if (strcmp(type,"short") == 0) {
short *ip,ivalue;
int i;
ivalue = (short) NUM2INT(_RBVALUE);
ip = (short *) ptr;
for (i = 0; i < numelements; i++)
ip[i] = ivalue;
} else if (strcmp(type,"long") == 0) {
long *ip,ivalue;
int i;
ivalue = NUM2LONG(_RBVALUE);
ip = (long *) ptr;
for (i = 0; i < numelements; i++)
ip[i] = ivalue;
} else if (strcmp(type,"double") == 0) {
double *ip,ivalue;
int i;
ivalue = (double) NUM2DBL(_RBVALUE);
ip = (double *) ptr;
for (i = 0; i < numelements; i++)
ip[i] = ivalue;
} else if (strcmp(type,"float") == 0) {
float *ip,ivalue;
int i;
ivalue = (float) NUM2DBL(_RBVALUE);
ip = (float *) ptr;
for (i = 0; i < numelements; i++)
ip[i] = ivalue;
} else if (strcmp(type,"char") == 0) {
char *ip,*ivalue;
ivalue = (char *) STR2CSTR(_RBVALUE);
ip = (char *) ptr;
strncpy(ip,ivalue,numelements-1);
} else if (strcmp(type,"char *") == 0) {
char **ip, *ivalue;
int i;
ivalue = (char *) STR2CSTR(_RBVALUE);
ip = (char **) ptr;
for (i = 0; i < numelements; i++) {
if (ivalue) {
ip[i] = (char *) xmalloc(strlen(ivalue)+1);
strcpy(ip[i],ivalue);
} else {
ip[i] = 0;
}
}
ip[numelements] = 0;
}
}
/* Create the pointer value */
SWIG_MakePtr(temp,ptr,cast);
obj = rb_str_new2(temp);
return obj;
}
/*------------------------------------------------------------------
ptrset(ptr,value,index = 0,type = 0)
Attempts to set the value of a pointer variable. If type is
given, we will use that type. Otherwise, we'll guess the datatype.
------------------------------------------------------------------ */
static VALUE ptrset(VALUE _PTRVALUE, VALUE _RBVALUE, int index, char *type) {
void *ptr;
char *s;
VALUE obj;
Check_Type(_PTRVALUE, T_STRING);
s = STR2CSTR(_PTRVALUE);
if (SWIG_GetPtr(s,&ptr,0)) {
rb_raise(rb_eTypeError,"Type error in ptrset. Argument is not a valid pointer value.");
}
/* If no datatype was passed, try a few common datatypes first */
if (!type) {
/* No datatype was passed. Type to figure out if it's a common one */
if (!SWIG_GetPtr(s,&ptr,"int_p")) {
type = "int";
} else if (!SWIG_GetPtr(s,&ptr,"double_p")) {
type = "double";
} else if (!SWIG_GetPtr(s,&ptr,"short_p")) {
type = "short";
} else if (!SWIG_GetPtr(s,&ptr,"long_p")) {
type = "long";
} else if (!SWIG_GetPtr(s,&ptr,"float_p")) {
type = "float";
} else if (!SWIG_GetPtr(s,&ptr,"char_p")) {
type = "char";
} else if (!SWIG_GetPtr(s,&ptr,"char_pp")) {
type = "char *";
} else {
type = "unknown";
}
}
if (!ptr) {
rb_raise(rb_eTypeError,"Unable to set NULL pointer.");
}
/* Now we have a datatype. Try to figure out what to do about it */
if (strcmp(type,"int") == 0) {
*(((int *) ptr)+index) = NUM2INT(_RBVALUE);
} else if (strcmp(type,"double") == 0) {
*(((double *) ptr)+index) = (double) NUM2DBL(_RBVALUE);
} else if (strcmp(type,"short") == 0) {
*(((short *) ptr)+index) = (short) NUM2INT(_RBVALUE);
} else if (strcmp(type,"long") == 0) {
*(((long *) ptr)+index) = NUM2LONG(_RBVALUE);
} else if (strcmp(type,"float") == 0) {
*(((float *) ptr)+index) = (float) NUM2DBL(_RBVALUE);
} else if (strcmp(type,"char") == 0) {
char *c = STR2CSTR(_RBVALUE);
strcpy(((char *) ptr)+index, c);
} else if (strcmp(type,"char *") == 0) {
char *c = STR2CSTR(_RBVALUE);
char **ca = (char **) ptr;
if (ca[index]) free(ca[index]);
if (strcmp(c,"NULL") == 0) {
ca[index] = 0;
} else {
ca[index] = (char *) xmalloc(strlen(c)+1);
strcpy(ca[index],c);
}
} else {
rb_raise(rb_eTypeError,"Unable to set unsupported datatype.");
}
return Qnil;
}
/*------------------------------------------------------------------
ptradd(ptr,offset)
Adds a value to an existing pointer value. Will do a type-dependent
add for basic datatypes. For other datatypes, will do a byte-add.
------------------------------------------------------------------ */
static VALUE ptradd(VALUE _PTRVALUE, int offset) {
char *r,*s;
void *ptr,*junk;
VALUE obj;
char *type;
/* Check to see what kind of object _PTRVALUE is */
Check_Type(_PTRVALUE, T_STRING);
/* Have a potential pointer value now. Try to strip out the value */
s = STR2CSTR(_PTRVALUE);
/* Try to handle a few common datatypes first */
if (!SWIG_GetPtr(s,&ptr,"int_p")) {
ptr = (void *) (((int *) ptr) + offset);
} else if (!SWIG_GetPtr(s,&ptr,"double_p")) {
ptr = (void *) (((double *) ptr) + offset);
} else if (!SWIG_GetPtr(s,&ptr,"short_p")) {
ptr = (void *) (((short *) ptr) + offset);
} else if (!SWIG_GetPtr(s,&ptr,"long_p")) {
ptr = (void *) (((long *) ptr) + offset);
} else if (!SWIG_GetPtr(s,&ptr,"float_p")) {
ptr = (void *) (((float *) ptr) + offset);
} else if (!SWIG_GetPtr(s,&ptr,"char_p")) {
ptr = (void *) (((char *) ptr) + offset);
} else if (!SWIG_GetPtr(s,&ptr,0)) {
ptr = (void *) (((char *) ptr) + offset);
} else {
rb_raise(rb_eTypeError,"Type error in ptradd. Argument is not a valid pointer value.");
}
type = SWIG_GetPtr(s,&junk,"INVALID POINTER");
r = (char *) xmalloc(strlen(type)+20);
if (ptr) {
SWIG_MakePtr(r,ptr,type);
} else {
sprintf(r,"_0%s",type);
}
obj = rb_str_new2(r);
free(r);
return obj;
}
/*------------------------------------------------------------------
ptrmap(type1,type2)
Allows a mapping between type1 and type2. (Like a typedef)
------------------------------------------------------------------ */
static void ptrmap(char *type1, char *type2) {
char *typestr1,*typestr2,*c,*r;
/* Produce a "mangled" version of the type string. */
typestr1 = (char *) xmalloc(strlen(type1)+2);
/* Go through and munge the typestring */
r = typestr1;
*(r++) = '_';
c = type1;
while (*c) {
if (!isspace(*c)) {
if ((*c == '*') || (*c == '&')) {
*(r++) = 'p';
}
else *(r++) = *c;
} else {
*(r++) = '_';
}
c++;
}
*(r++) = 0;
typestr2 = (char *) xmalloc(strlen(type2)+2);
/* Go through and munge the typestring */
r = typestr2;
*(r++) = '_';
c = type2;
while (*c) {
if (!isspace(*c)) {
if ((*c == '*') || (*c == '&')) {
*(r++) = 'p';
}
else *(r++) = *c;
} else {
*(r++) = '_';
}
c++;
}
*(r++) = 0;
SWIG_RegisterMapping(typestr1,typestr2,0);
SWIG_RegisterMapping(typestr2,typestr1,0);
}
/*------------------------------------------------------------------
ptrfree(ptr)
Destroys a pointer value
------------------------------------------------------------------ */
VALUE ptrfree(VALUE _PTRVALUE) {
void *ptr, *junk;
char *s;
Check_Type(_PTRVALUE, T_STRING);
s = STR2CSTR(_PTRVALUE);
if (SWIG_GetPtr(s,&ptr,0)) {
rb_raise(rb_eTypeError,"Type error in ptrfree. Argument is not a valid pointer value.");
}
/* Check to see if this pointer is a char ** */
if (!SWIG_GetPtr(s,&junk,"char_pp")) {
char **c = (char **) ptr;
if (c) {
int i = 0;
while (c[i]) {
free(c[i]);
i++;
}
}
}
if (ptr)
free((char *) ptr);
return Qnil;
}
%}
%typemap(ruby,in) VALUE ptr, VALUE value {
$target = $source;
}
%typemap(ruby,out) VALUE ptrcast,
VALUE ptrvalue,
VALUE ptrcreate,
VALUE ptrset,
VALUE ptradd,
VALUE ptrfree
{
$target = $source;
}
%typemap(ruby,ret) int ptrset {
if ($source == -1) return Qnil;
}
VALUE ptrcast(VALUE ptr, char *type);
// Casts a pointer ptr to a new datatype given by the string type.
// type may be either the SWIG generated representation of a datatype
// or the C representation. For example :
//
// ptrcast(ptr,"double_p"); # Ruby representation
// ptrcast(ptr,"double *"); # C representation
//
// A new pointer value is returned. ptr may also be an integer
// value in which case the value will be used to set the pointer
// value. For example :
//
// a = ptrcast(0,"Vector_p");
//
// Will create a NULL pointer of type "Vector_p"
//
// The casting operation is sensitive to formatting. As a result,
// "double *" is different than "double*". As a result of thumb,
// there should always be exactly one space between the C datatype
// and any pointer specifiers (*).
VALUE ptrvalue(VALUE ptr, int index = 0, char *type = 0);
// Returns the value that a pointer is pointing to (ie. dereferencing).
// The type is automatically inferred by the pointer type--thus, an
// integer pointer will return an integer, a double will return a double,
// and so on. The index and type fields are optional parameters. When
// an index is specified, this function returns the value of ptr[index].
// This allows array access. When a type is specified, it overrides
// the given pointer type. Examples :
//
// ptrvalue(a) # Returns the value *a
// ptrvalue(a,10) # Returns the value a[10]
// ptrvalue(a,10,"double") # Returns a[10] assuming a is a double *
VALUE ptrset(VALUE ptr, VALUE value, int index = 0, char *type = 0);
// Sets the value pointed to by a pointer. The type is automatically
// inferred from the pointer type so this function will work for
// integers, floats, doubles, etc... The index and type fields are
// optional. When an index is given, it provides array access. When
// type is specified, it overrides the given pointer type. Examples :
//
// ptrset(a,3) # Sets the value *a = 3
// ptrset(a,3,10) # Sets a[10] = 3
// ptrset(a,3,10,"int") # Sets a[10] = 3 assuming a is a int *
VALUE ptrcreate(char *type, VALUE value = 0, int nitems = 1);
// Creates a new object and returns a pointer to it. This function
// can be used to create various kinds of objects for use in C functions.
// type specifies the basic C datatype to create and value is an
// optional parameter that can be used to set the initial value of the
// object. nitems is an optional parameter that can be used to create
// an array. This function results in a memory allocation using
// malloc(). Examples :
//
// a = ptrcreate("double") # Create a new double, return pointer
// a = ptrcreate("int",7) # Create an integer, set value to 7
// a = ptrcreate("int",0,1000) # Create an integer array with initial
// # values all set to zero
//
// This function only recognizes a few common C datatypes as listed below :
//
// int, short, long, float, double, char, char *, void
//
// All other datatypes will result in an error. However, other
// datatypes can be created by using the ptrcast function. For
// example:
//
// a = ptrcast(ptrcreate("int",0,100),"unsigned int *")
VALUE ptrfree(VALUE ptr);
// Destroys the memory pointed to by ptr. This function calls free()
// and should only be used with objects created by ptrcreate(). Since
// this function calls free, it may work with other objects, but this
// is generally discouraged unless you absolutely know what you're
// doing.
VALUE ptradd(VALUE ptr, int offset);
// Adds a value to the current pointer value. For the C datatypes of
// int, short, long, float, double, and char, the offset value is the
// number of objects and works in exactly the same manner as in C. For
// example, the following code steps through the elements of an array
//
// a = ptrcreate("double",0,100); # Create an array double a[100]
// b = a;
// for i in range(0,100):
// ptrset(b,0.0025*i); # set *b = 0.0025*i
// b = ptradd(b,1); # b++ (go to next double)
//
// In this case, adding one to b goes to the next double.
//
// For all other datatypes (including all complex datatypes), the
// offset corresponds to bytes. This function does not perform any
// bounds checking and negative offsets are perfectly legal.
void ptrmap(char *type1, char *type2);
// This is a rarely used function that performs essentially the same
// operation as a C typedef. To manage datatypes at run-time, SWIG
// modules manage an internal symbol table of type mappings. This
// table keeps track of which types are equivalent to each other. The
// ptrmap() function provides a mechanism for scripts to add symbols
// to this table. For example :
//
// ptrmap("double_p","Real_p");
//
// would make the types "doublePtr" and "RealPtr" equivalent to each
// other. Pointers of either type could now be used interchangably.
//
// Normally this function is not needed, but it can be used to
// circumvent SWIG's normal type-checking behavior or to work around
// weird type-handling problems.

44
Lib/ruby/ruby.swg Normal file
View file

@ -0,0 +1,44 @@
/* ruby.swg */
#include "ruby.h"
#define UINT2NUM(v) rb_uint2inum(v)
#define NUM2USHRT(n) NUM2UINT(n)
#define NUM2SHRT(n) (\
(SHRT_MIN <= NUM2INT(n) && NUM2INT(n) <= SHRT_MAX)\
? (short)NUM2INT(n)\
: (rb_raise(rb_eArgError, "integer %d out of range of `short'",\
NUM2INT(n)), (short)0)\
)
#ifdef __cplusplus
# define VALUEFUNC(f) ((VALUE (*)(...))f)
# define VOIDFUNC(f) ((void (*)(...))f)
#else
# define VALUEFUNC(f) (f)
# define VOIDFUNC(f) (f)
#endif
#if defined(_WIN32) || defined(__WIN32__)
# if defined(_MSC_VER)
# if defined(STATIC_LINKED)
# define SWIGEXPORT(a) a
# else
# define SWIGEXPORT(a) __declspec(dllexport) a
# endif
# else
# if defined(__BORLANDC__)
# define SWIGEXPORT(a) a _export
# else
# define SWIGEXPORT(a) a
# endif
#endif
#else
# define SWIGEXPORT(a) a
#endif
#ifdef SWIG_GLOBAL
#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a)
#else
#define SWIGSTATICRUNTIME(a) static a
#endif

15
Lib/ruby/rubydec.swg Normal file
View file

@ -0,0 +1,15 @@
/* rubydec.swg */
#ifdef __cplusplus
extern "C" {
#endif
SWIGEXPORT(void) SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *));
SWIGEXPORT(void) SWIG_MakePtr(char *_c, const void *_ptr, char *type);
SWIGEXPORT(char *) SWIG_GetPtr(char *_c, void **ptr, char *_t);
SWIGEXPORT(VALUE) SWIG_NewPointerObj(void *ptr, char *type);
SWIGEXPORT(void *) SWIG_ConvertPtr(VALUE obj, char *type);
#ifdef __cplusplus
}
#endif

297
Lib/ruby/rubydef.swg Normal file
View file

@ -0,0 +1,297 @@
/* rubydef.swg */
#ifdef __cplusplus
extern "C" {
#endif
/* SWIG pointer structure */
typedef struct SwigPtrType {
char *name; /* Datatype name */
int len; /* Length (used for optimization) */
void *(*cast)(void *); /* Pointer casting function */
struct SwigPtrType *next; /* Linked list pointer */
} SwigPtrType;
/* Pointer cache structure */
typedef struct {
int stat; /* Status (valid) bit */
SwigPtrType *tp; /* Pointer to type structure */
char name[256]; /* Given datatype name */
char mapped[256]; /* Equivalent name */
} SwigCacheType;
/* Some variables */
static int SwigPtrMax = 64; /* Max entries that can be currently held */
/* This value may be adjusted dynamically */
static int SwigPtrN = 0; /* Current number of entries */
static int SwigPtrSort = 0; /* Status flag indicating sort */
static int SwigStart[256]; /* Starting positions of types */
/* Pointer table */
static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */
/* Cached values */
#define SWIG_CACHESIZE 8
#define SWIG_CACHEMASK 0x7
static SwigCacheType SwigCache[SWIG_CACHESIZE];
static int SwigCacheIndex = 0;
static int SwigLastCache = 0;
/* Sort comparison function */
static int swigsort(const void *data1, const void *data2) {
SwigPtrType *d1 = (SwigPtrType *) data1;
SwigPtrType *d2 = (SwigPtrType *) data2;
return strcmp(d1->name,d2->name);
}
/* Binary Search function */
static int swigcmp(const void *key, const void *data) {
char *k = (char *) key;
SwigPtrType *d = (SwigPtrType *) data;
return strncmp(k,d->name,d->len);
}
/* Register a new datatype with the type-checker */
SWIGSTATICRUNTIME(void)
SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) {
int i;
SwigPtrType *t = 0,*t1;
/* Allocate the pointer table if necessary */
if (!SwigPtrTable) {
SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType));
SwigPtrN = 0;
}
/* Grow the table */
if (SwigPtrN >= SwigPtrMax) {
SwigPtrMax = 2*SwigPtrMax;
SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType));
}
for (i = 0; i < SwigPtrN; i++)
if (strcmp(SwigPtrTable[i].name,origtype) == 0) {
t = &SwigPtrTable[i];
break;
}
if (!t) {
t = &SwigPtrTable[SwigPtrN];
t->name = origtype;
t->len = strlen(t->name);
t->cast = 0;
t->next = 0;
SwigPtrN++;
}
/* Check for existing entry */
while (t->next) {
if ((strcmp(t->name,newtype) == 0)) {
if (cast) t->cast = cast;
return;
}
t = t->next;
}
/* Now place entry (in sorted order) */
t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType));
t1->name = newtype;
t1->len = strlen(t1->name);
t1->cast = cast;
t1->next = 0;
t->next = t1;
SwigPtrSort = 0;
}
/* Make a pointer value string */
SWIGSTATICRUNTIME(void)
SWIG_MakePtr(char *_c, const void *_ptr, char *type) {
static char _hex[16] =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
unsigned long _p, _s;
char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */
_r = _result;
_p = (unsigned long) _ptr;
if (_p > 0) {
while (_p > 0) {
_s = _p & 0xf;
*(_r++) = _hex[_s];
_p = _p >> 4;
}
*_r = '_';
while (_r >= _result)
*(_c++) = *(_r--);
*(_c++) = '_';
} else {
strcpy (_c, "NULL");
}
if (_ptr)
strcpy (_c, type);
}
/* Define for backwards compatibility */
#define _swig_make_hex SWIG_MakePtr
/* Function for getting a pointer value */
SWIGSTATICRUNTIME(char *)
SWIG_GetPtr(char *_c, void **ptr, char *_t)
{
unsigned long _p;
char temp_type[256];
char *name;
int i, len;
SwigPtrType *sp,*tp;
SwigCacheType *cache;
int start, end;
_p = 0;
/* Pointer values must start with leading underscore */
if (*_c == '_') {
_c++;
/* Extract hex value from pointer */
while (*_c) {
if ((*_c >= '0') && (*_c <= '9'))
_p = (_p << 4) + (*_c - '0');
else if ((*_c >= 'a') && (*_c <= 'f'))
_p = (_p << 4) + ((*_c - 'a') + 10);
else
break;
_c++;
}
_c++;
if (_t) {
if (strcmp(_t,_c)) {
if (!SwigPtrSort) {
qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort);
for (i = 0; i < 256; i++) {
SwigStart[i] = SwigPtrN;
}
for (i = SwigPtrN-1; i >= 0; i--) {
SwigStart[(int) (SwigPtrTable[i].name[1])] = i;
}
for (i = 255; i >= 1; i--) {
if (SwigStart[i-1] > SwigStart[i])
SwigStart[i-1] = SwigStart[i];
}
SwigPtrSort = 1;
for (i = 0; i < SWIG_CACHESIZE; i++)
SwigCache[i].stat = 0;
}
/* First check cache for matches. Uses last cache value as starting point */
cache = &SwigCache[SwigLastCache];
for (i = 0; i < SWIG_CACHESIZE; i++) {
if (cache->stat) {
if (strcmp(_t,cache->name) == 0) {
if (strcmp(_c,cache->mapped) == 0) {
cache->stat++;
*ptr = (void *) _p;
if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr);
return (char *) 0;
}
}
}
SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK;
if (!SwigLastCache) cache = SwigCache;
else cache++;
}
/* We have a type mismatch. Will have to look through our type
mapping table to figure out whether or not we can accept this datatype */
start = SwigStart[(int) _t[1]];
end = SwigStart[(int) _t[1]+1];
sp = &SwigPtrTable[start];
while (start < end) {
if (swigcmp(_t,sp) == 0) break;
sp++;
start++;
}
if (start >= end) sp = 0;
/* Try to find a match for this */
if (sp) {
while (swigcmp(_t,sp) == 0) {
name = sp->name;
len = sp->len;
tp = sp->next;
/* Try to find entry for our given datatype */
while(tp) {
if (tp->len >= 255) {
return _c;
}
strcpy(temp_type,tp->name);
strncat(temp_type,_t+len,255-tp->len);
if (strcmp(_c,temp_type) == 0) {
strcpy(SwigCache[SwigCacheIndex].mapped,_c);
strcpy(SwigCache[SwigCacheIndex].name,_t);
SwigCache[SwigCacheIndex].stat = 1;
SwigCache[SwigCacheIndex].tp = tp;
SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK;
/* Get pointer value */
*ptr = (void *) _p;
if (tp->cast) *ptr = (*(tp->cast))(*ptr);
return (char *) 0;
}
tp = tp->next;
}
sp++;
/* Hmmm. Didn't find it this time */
}
}
/* Didn't find any sort of match for this data.
Get the pointer value and return the received type */
*ptr = (void *) _p;
return _c;
} else {
/* Found a match on the first try. Return pointer value */
*ptr = (void *) _p;
return (char *) 0;
}
} else {
/* No type specified. Good luck */
*ptr = (void *) _p;
return (char *) 0;
}
} else {
if (strcmp (_c, "NULL") == 0) {
*ptr = (void *) 0;
return (char *) 0;
}
*ptr = (void *) 0;
return _c;
}
}
SWIGSTATICRUNTIME(VALUE)
SWIG_NewPointerObj(void *ptr, char *type)
{
char *temp = ALLOCA_N(char, strlen(type)+22);
SWIG_MakePtr(temp, ptr, type);
return rb_str_new2(temp);
}
SWIGSTATICRUNTIME(void *)
SWIG_ConvertPtr(VALUE obj, char *type)
{
void *ptr;
Check_Type(obj, T_STRING);
if (SWIG_GetPtr(RSTRING(obj)->ptr, &ptr, type)) {
rb_raise(rb_eTypeError, "Expected a %s", type);
}
return ptr;
}
#ifdef __cplusplus
}
#endif

501
Lib/ruby/typemaps.i Normal file
View file

@ -0,0 +1,501 @@
//
// typemaps for Ruby
//
// $Header$
//
// Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
// Copyright (C) 2000 Information-technology Promotion Agency, Japan
//
// Masaki Fukushima
//
#ifdef AUTODOC
%section "Typemap Library (Ruby)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0
%text %{
%include typemaps.i
The SWIG typemap library provides a language independent mechanism for
supporting output arguments, input values, and other C function
calling mechanisms. The primary use of the library is to provide a
better interface to certain C function--especially those involving
pointers.
%}
#endif
// ------------------------------------------------------------------------
// Pointer handling
//
// These mappings provide support for input/output arguments and common
// uses for C/C++ pointers.
// ------------------------------------------------------------------------
// INPUT typemaps.
// These remap a C pointer to be an "INPUT" value which is passed by value
// instead of reference.
#ifdef AUTODOC
%subsection "Input Methods"
%text %{
The following methods can be applied to turn a pointer into a simple
"input" value. That is, instead of passing a pointer to an object,
you would use a real value instead.
int *INPUT
short *INPUT
long *INPUT
unsigned int *INPUT
unsigned short *INPUT
unsigned long *INPUT
unsigned char *INPUT
float *INPUT
double *INPUT
To use these, suppose you had a C function like this :
double fadd(double *a, double *b) {
return *a+*b;
}
You could wrap it with SWIG as follows :
%include typemaps.i
double fadd(double *INPUT, double *INPUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *INPUT { double *a, double *b };
double fadd(double *a, double *b);
%}
#endif
%typemap(ruby,in) double *INPUT(double temp)
{
temp = NUM2DBL($source);
$target = &temp;
}
%typemap(ruby,in) float *INPUT(float temp)
{
temp = (float) NUM2DBL($source);
$target = &temp;
}
%typemap(ruby,in) int *INPUT(int temp)
{
temp = NUM2INT($source);
$target = &temp;
}
%typemap(ruby,in) short *INPUT(short temp)
{
temp = NUM2SHRT($source);
$target = &temp;
}
%typemap(ruby,in) long *INPUT(long temp)
{
temp = NUM2LONG($source);
$target = &temp;
}
%typemap(ruby,in) unsigned int *INPUT(unsigned int temp)
{
temp = NUM2UINT($source);
$target = &temp;
}
%typemap(ruby,in) unsigned short *INPUT(unsigned short temp)
{
temp = NUM2USHRT($source);
$target = &temp;
}
%typemap(ruby,in) unsigned long *INPUT(unsigned long temp)
{
temp = NUM2ULONG($source);
$target = &temp;
}
%typemap(ruby,in) unsigned char *INPUT(unsigned char temp)
{
temp = (unsigned char)NUM2UINT($source);
$target = &temp;
}
%typemap(ruby,in) signed char *INPUT(signed char temp)
{
temp = (signed char)NUM2INT($source);
$target = &temp;
}
// OUTPUT typemaps. These typemaps are used for parameters that
// are output only. The output value is appended to the result as
// a array element.
#ifdef AUTODOC
%subsection "Output Methods"
%text %{
The following methods can be applied to turn a pointer into an "output"
value. When calling a function, no input value would be given for
a parameter, but an output value would be returned. In the case of
multiple output values, they are returned in the form of a Ruby Array.
int *OUTPUT
short *OUTPUT
long *OUTPUT
unsigned int *OUTPUT
unsigned short *OUTPUT
unsigned long *OUTPUT
unsigned char *OUTPUT
float *OUTPUT
double *OUTPUT
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
returns the integer part in one of its parameters).K:
double modf(double x, double *ip);
You could wrap it with SWIG as follows :
%include typemaps.i
double modf(double x, double *OUTPUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
The Ruby output of the function would be a Array containing both
output values.
%}
#endif
// Helper function for Array output
%{
static VALUE output_helper(VALUE target, VALUE o) {
if (NIL_P(target)) {
target = o;
} else {
if (TYPE(target) != T_ARRAY) {
VALUE o2 = target;
target = rb_ary_new();
rb_ary_push(target, o2);
}
rb_ary_push(target, o);
}
return target;
}
%}
// Force the argument to be ignored.
%typemap(ruby,ignore) int *OUTPUT(int temp),
short *OUTPUT(short temp),
long *OUTPUT(long temp),
unsigned int *OUTPUT(unsigned int temp),
unsigned short *OUTPUT(unsigned short temp),
unsigned long *OUTPUT(unsigned long temp),
unsigned char *OUTPUT(unsigned char temp),
signed char *OUTPUT(signed char temp),
float *OUTPUT(float temp),
double *OUTPUT(double temp)
{
$target = &temp;
}
%typemap(ruby,argout) int *OUTPUT,
short *OUTPUT,
long *OUTPUT,
signed char *OUTPUT
{
$target = output_helper($target, INT2NUM(*$source));
}
%typemap(ruby,argout) unsigned int *OUTPUT,
unsigned short *OUTPUT,
unsigned long *OUTPUT,
unsigned char *OUTPUT
{
$target = output_helper($target, UINT2NUM(*$source));
}
%typemap(ruby,argout) float *OUTPUT,
double *OUTPUT
{
$target = output_helper($target, rb_float_new(*$source));
}
// INOUT
// Mappings for an argument that is both an input and output
// parameter
#ifdef AUTODOC
%subsection "Input/Output Methods"
%text %{
The following methods can be applied to make a function parameter both
an input and output value. This combines the behavior of both the
"INPUT" and "OUTPUT" methods described earlier. Output values are
returned in the form of a Ruby array.
int *INOUT
short *INOUT
long *INOUT
unsigned int *INOUT
unsigned short *INOUT
unsigned long *INOUT
unsigned char *INOUT
float *INOUT
double *INOUT
For example, suppose you were trying to wrap the following function :
void neg(double *x) {
*x = -(*x);
}
You could wrap it with SWIG as follows :
%include typemaps.i
void neg(double *INOUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *INOUT { double *x };
void neg(double *x);
Unlike C, this mapping does not directly modify the input value (since
this makes no sense in Ruby). Rather, the modified input value shows
up as the return value of the function. Thus, to apply this function
to a Ruby variable you might do this :
x = neg(x)
Note : previous versions of SWIG used the symbol 'BOTH' to mark
input/output arguments. This is still supported, but will be slowly
phased out in future releases.
%}
#endif
%typemap(ruby,in) int *INOUT = int *INPUT;
%typemap(ruby,in) short *INOUT = short *INPUT;
%typemap(ruby,in) long *INOUT = long *INPUT;
%typemap(ruby,in) unsigned *INOUT = unsigned *INPUT;
%typemap(ruby,in) unsigned short *INOUT = unsigned short *INPUT;
%typemap(ruby,in) unsigned long *INOUT = unsigned long *INPUT;
%typemap(ruby,in) unsigned char *INOUT = unsigned char *INPUT;
%typemap(ruby,in) float *INOUT = float *INPUT;
%typemap(ruby,in) double *INOUT = double *INPUT;
%typemap(ruby,argout) int *INOUT = int *OUTPUT;
%typemap(ruby,argout) short *INOUT = short *OUTPUT;
%typemap(ruby,argout) long *INOUT = long *OUTPUT;
%typemap(ruby,argout) unsigned *INOUT = unsigned *OUTPUT;
%typemap(ruby,argout) unsigned short *INOUT = unsigned short *OUTPUT;
%typemap(ruby,argout) unsigned long *INOUT = unsigned long *OUTPUT;
%typemap(ruby,argout) unsigned char *INOUT = unsigned char *OUTPUT;
%typemap(ruby,argout) float *INOUT = float *OUTPUT;
%typemap(ruby,argout) double *INOUT = double *OUTPUT;
// Backwards compatibility
%typemap(ruby,in) int *BOTH = int *INOUT;
%typemap(ruby,in) short *BOTH = short *INOUT;
%typemap(ruby,in) long *BOTH = long *INOUT;
%typemap(ruby,in) unsigned *BOTH = unsigned *INOUT;
%typemap(ruby,in) unsigned short *BOTH = unsigned short *INOUT;
%typemap(ruby,in) unsigned long *BOTH = unsigned long *INOUT;
%typemap(ruby,in) unsigned char *BOTH = unsigned char *INOUT;
%typemap(ruby,in) float *BOTH = float *INOUT;
%typemap(ruby,in) double *BOTH = double *INOUT;
%typemap(ruby,argout) int *BOTH = int *INOUT;
%typemap(ruby,argout) short *BOTH = short *INOUT;
%typemap(ruby,argout) long *BOTH = long *INOUT;
%typemap(ruby,argout) unsigned *BOTH = unsigned *INOUT;
%typemap(ruby,argout) unsigned short *BOTH = unsigned short *INOUT;
%typemap(ruby,argout) unsigned long *BOTH = unsigned long *INOUT;
%typemap(ruby,argout) unsigned char *BOTH = unsigned char *INOUT;
%typemap(ruby,argout) float *BOTH = float *INOUT;
%typemap(ruby,argout) double *BOTH = double *INOUT;
// --------------------------------------------------------------------
// OUTPUT typemaps for user defined type.
//
// --------------------------------------------------------------------
#ifdef AUTODOC
%subsection "Output Methods for User-defined types"
%text %{
The following method can be applied to turn a pointer to
user-defined type returned through function aruguments into
an output value.
User **OUTPUT
You can use the %apply directive :
%include typemaps.i
%apply User **OUTPUT { Foo **OUTPUT };
int foo_func(Foo **OUTPUT);
%}
#endif
%typemap(ruby,ignore) User **OUTPUT(void *temp)
{
$target = ($type)&temp;
}
%typemap(ruby,argout) User **OUTPUT
{
$target = output_helper($target, Wrap_$basetype(*$source));
}
// --------------------------------------------------------------------
// Special types
//
// --------------------------------------------------------------------
#ifdef AUTODOC
%subsection "Special Methods"
%text %{
The typemaps.i library also provides the following mappings :
struct timeval *
time_t
Ruby has builtin class Time. INPUT/OUPUT typemap for timeval and
time_t is provided.
int PROG_ARGC
char **PROG_ARGV
Some C function receive argc and argv from C main function.
This typemap provides ignore typemap which pass Ruby ARGV contents
as argc and argv to C function.
%}
#endif
// struct timeval *
%{
#ifdef __cplusplus
extern "C" {
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
struct timeval rb_time_timeval(VALUE);
#endif
#ifdef __cplusplus
}
#endif
%}
%typemap(ruby,in) struct timeval *INPUT (struct timeval temp)
{
if (NIL_P($source))
$target = NULL;
else {
temp = rb_time_timeval($source);
$target = &temp;
}
}
%typemap(ruby,ignore) struct timeval *OUTPUT(struct timeval temp)
{
$target = &temp;
}
%typemap(ruby,argout) struct timeval *OUTPUT
{
$target = rb_time_new($source->tv_sec, $source->tv_usec);
}
%typemap(ruby,out) struct timeval *
{
$target = rb_time_new($source->tv_sec, $source->tv_usec);
}
%typemap(ruby,out) struct timespec *
{
$target = rb_time_new($source->tv_sec, $source->tv_nsec / 1000);
}
// time_t
%typemap(ruby,in) time_t
{
if (NIL_P($source))
$target = (time_t)-1;
else
$target = NUM2LONG(rb_funcall($source, rb_intern("tv_sec"), 0));
}
%typemap(ruby,out) time_t
{
$target = rb_time_new($source, 0);
}
// argc and argv
%typemap(ruby,ignore) int PROG_ARGC {
$target = RARRAY(rb_argv)->len + 1;
}
%typemap(ruby,ignore) char **PROG_ARGV {
int i, n;
VALUE ary = rb_eval_string("[$0] + ARGV");
n = RARRAY(ary)->len;
$target = (char **)malloc(n + 1);
for (i = 0; i < n; i++) {
VALUE v = rb_obj_as_string(RARRAY(ary)->ptr[i]);
$target[i] = (char *)malloc(RSTRING(v)->len + 1);
strcpy($target[i], RSTRING(v)->ptr);
}
}
%typemap(ruby,freearg) char **PROG_ARGV {
int i, n = RARRAY(rb_argv)->len + 1;
for (i = 0; i < n; i++) free($source[i]);
free($source);
}
// FILE *
%{
#ifdef __cplusplus
extern "C" {
#endif
#include "rubyio.h"
#ifdef __cplusplus
}
#endif
%}
%typemap(ruby,in) FILE *READ {
OpenFile *of;
GetOpenFile($source, of);
rb_io_check_readable(of);
$target = GetReadFile(of);
rb_read_check($target);
}
%typemap(ruby,in) FILE *READ_NOCHECK {
OpenFile *of;
GetOpenFile($source, of);
rb_io_check_readable(of);
$target = GetReadFile(of);
}
%typemap(ruby,in) FILE *WRITE {
OpenFile *of;
GetOpenFile($source, of);
rb_io_check_writable(of);
$target = GetWriteFile(of);
}