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

View file

@ -4,8 +4,8 @@ GIFPlot
To illustrate various SWIG features, the following examples involve
building an interface to a small, but somewhat useful graphics library
for creating 2D and 3D images in the form of GIF files. The Perl,
Python, and Tcl directories contain various examples specific to those
languages.
Python, Tcl, and Ruby directories contain various examples specific to
those languages.
This library was originally developed as part of the SPaSM molecular
dynamics project at Los Alamos National Laboratory. However, due to
@ -36,8 +36,8 @@ On Windows, you can probably just do this:
Running the Examples
====================
Once the library has been built, go the Perl, Python, or Tcl directory to see
various SWIG examples. Each example should have a README file with a
Once the library has been built, go the Perl, Python, Tcl, or Ruby directory
to see various SWIG examples. Each example should have a README file with a
description.
The examples are compiled using the makefile located in the top level "Examples"

View file

@ -0,0 +1,23 @@
TOP = ../../..
SWIG = $(TOP)/../swig
SWIGOPT = -I../../Include
SRCS =
TARGET = gifplot
INTERFACE = gifplot.i
LIBS = -L../.. -lgifplot
INCLUDE = -I../../Include
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static
clean::
rm -f *_wrap* *.o *~ *.so myruby .~* core *.gif

View file

@ -0,0 +1,8 @@
This example runs the entire gifplot.h header file through SWIG without
any changes. The script 'runme.rb' does something a little more
interesting. You'll have to go look at the header file to get a complete
listing of the functions.

View file

@ -0,0 +1,15 @@
/* Oh what the heck, let's just grab the whole darn header file
and see what happens. */
%module gifplot
%{
/* Note: You still need this part because the %include directive
merely causes SWIG to interpret the contents of a file. It doesn't
include the right include headers for the resulting C code */
#include "gifplot.h"
%}
%include gifplot.h

View file

@ -0,0 +1,66 @@
# Plot a 3D function
require 'gifplot'
include Gifplot
include Math
# Here is the function to plot
def func(x,y)
return 5*cos(2*sqrt(x*x+y*y))*exp(-0.3*sqrt(x*x+y*y))
end
# Here are some plotting parameters
XMIN = -5.0
XMAX = 5.0
YMIN = -5.0
YMAX = 5.0
ZMIN = -5.0
ZMAX = 5.0
# Grid resolution
NXPOINTS = 60
NYPOINTS = 60
cmap = new_ColorMap("cmap")
frame = new_FrameBuffer(500,500)
FrameBuffer_clear(frame,BLACK)
P3 = new_Plot3D(frame,XMIN,YMIN,ZMIN,XMAX,YMAX,ZMAX)
Plot3D_lookat(P3,2*[XMAX-XMIN,YMAX-YMIN,ZMAX-ZMIN].max)
Plot3D_autoperspective(P3,40)
Plot3D_rotu(P3,60)
Plot3D_rotr(P3,30)
Plot3D_rotd(P3,10)
def drawsolid()
Plot3D_clear(P3,BLACK)
Plot3D_start(P3)
dx = 1.0*(XMAX-XMIN)/NXPOINTS
dy = 1.0*(YMAX-YMIN)/NYPOINTS
cscale = 240.0/(ZMAX-ZMIN)
x = XMIN
for i in 0...NXPOINTS
y = YMIN
for j in 0...NYPOINTS
z1 = func(x,y)
z2 = func(x+dx,y)
z3 = func(x+dx,y+dy)
z4 = func(x,y+dy)
c1 = cscale*(z1-ZMIN)
c2 = cscale*(z2-ZMIN)
c3 = cscale*(z3-ZMIN)
c4 = cscale*(z4-ZMIN)
c = (c1+c2+c3+c4)/4
c = 0 if (c < 0)
c = 239 if c > 239
Plot3D_solidquad(P3,x,y,z1,x+dx,y,z2,x+dx,y+dy,z3,x,y+dy,z4,c+16)
y = y + dy
end
x = x + dx
end
end
puts "Making a nice 3D plot..."
drawsolid()
FrameBuffer_writeGIF(frame,cmap,"image.gif")
puts "Wrote image.gif"

View file

@ -0,0 +1,23 @@
TOP = ../../..
SWIG = $(TOP)/../swig
SWIGOPT =
SRCS =
TARGET = simple
INTERFACE = simple.i
LIBS = -L../.. -lgifplot
INCLUDE = -I../../Include
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
INCLUDE='$(INCLUDE)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static
clean::
rm -f *_wrap* *.o *~ *.so myruby .~* core *.gif

View file

@ -0,0 +1,5 @@
This is a very minimalistic example in which just a few functions
and constants from library are wrapped and used to draw some simple
shapes. The script 'runme.rb' runs the example.

View file

@ -0,0 +1,27 @@
# Draw some simple shapes
puts "Drawing some basic shapes"
require 'simple'
cmap = Simple.new_ColorMap()
f = Simple.new_FrameBuffer(400,400)
# Clear the picture
Simple.FrameBuffer_clear(f,Simple::BLACK)
# Make a red box
Simple.FrameBuffer_box(f,40,40,200,200,Simple::RED)
# Make a blue circle
Simple.FrameBuffer_circle(f,200,200,40,Simple::BLUE)
# Make green line
Simple.FrameBuffer_line(f,10,390,390,200, Simple::GREEN)
# Write an image out to disk
Simple.FrameBuffer_writeGIF(f,cmap,"image.gif")
puts "Wrote image.gif"
Simple.delete_FrameBuffer(f)
Simple.delete_ColorMap(cmap)

View file

@ -0,0 +1,38 @@
/* This example shows a very simple interface wrapping a few
primitive declarations */
%module simple
%{
#include "gifplot.h"
%}
typedef unsigned char Pixel;
/* Here are a few useful functions */
ColorMap *new_ColorMap(char *filename = 0);
void delete_ColorMap(ColorMap *cmap);
FrameBuffer *new_FrameBuffer(unsigned int width, unsigned int height);
void delete_FrameBuffer(FrameBuffer *frame);
void FrameBuffer_clear(FrameBuffer *frame, Pixel color);
void FrameBuffer_line(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color);
void FrameBuffer_box(FrameBuffer *frame, int x1, int y1, int x2, int y2, Pixel color);
void FrameBuffer_circle(FrameBuffer *frame, int x1, int y1, int radius, Pixel color);
int FrameBuffer_writeGIF(FrameBuffer *f, ColorMap *c, char *filename);
/* And some useful constants */
#define BLACK 0
#define WHITE 1
#define RED 2
#define GREEN 3
#define BLUE 4
#define YELLOW 5
#define CYAN 6
#define MAGENTA 7

View file

@ -337,6 +337,52 @@ mzscheme: $(SRCS)
mzc --cc $(ISRCS) $(SRCS)
mzc --ld $(TARGET)$(SO) $(OBJS) $(IOBJS)
##################################################################
##### RUBY ######
##################################################################
# Make sure these locate your Ruby installation
RUBY_INCLUDE= -DHAVE_CONFIG_H @RUBYINCLUDE@
# ----------------------------------------------------------------
# Build a C dynamically loadable module
# ----------------------------------------------------------------
ruby: $(SRCS)
$(SWIG) -ruby $(SWIGOPT) $(INTERFACE)
$(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDE) $(RUBY_INCLUDE)
$(LDSHARED) $(OBJS) $(IOBJS) $(LIBS) -o $(TARGET)$(SO)
# -----------------------------------------------------------------
# Build a C++ dynamically loadable module
# -----------------------------------------------------------------
ruby_cpp: $(SRCS)
$(SWIG) -c++ -ruby $(SWIGOPT) $(INTERFACE)
$(CXX) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDE) $(RUBY_INCLUDE)
$(CXXSHARED) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(TARGET)$(SO)
# -----------------------------------------------------------------
# Build statically linked Ruby interpreter
#
# These should only be used in conjunction with the %include embed.i
# library file
# -----------------------------------------------------------------
RUBY_LIB = @RUBYLIB@
RUBY_LIBOPTS = @RUBYLINK@ @LIBS@ $(SYSLIBS)
ruby_static: $(SRCS)
$(SWIG) -ruby -lembed.i $(SWIGOPT) $(INTERFACE)
$(CC) $(CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCS) $(INCLUDE) \
$(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
ruby_static_cpp: $(SRCS)
$(SWIG) -c++ -ruby -lembed.i $(SWIGOPT) $(INTERFACE)
$(CXX) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDE) \
$(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
##################################################################
##### SWIG ######
##################################################################

View file

@ -1,6 +1,6 @@
SWIG Examples
The "perl5", "python", "tcl", "guile", "java", and "mzscheme"
The "perl5", "python", "tcl", "guile", "java", "mzscheme", and "ruby"
directories contain a very simple example. The "GIFPlot" contains a
more complicated example that illustrates some of SWIG's more advanced
capabilities.

View file

@ -43,6 +43,7 @@ language:
<li><a href="guile/index.html">Guile</a>
<li><a href="java/index.html">Java</a>
<li><a href="mzscheme/index.html">Mzscheme</a>
<li><a href="ruby/index.html">Ruby</a>
</ul>
<h2>Real Life</h2>

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../swig
SRCS =
TARGET = example
INTERFACE = example.i
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static
clean::
rm -f *_wrap* *.o *~ *.so myruby .~* core

View file

@ -0,0 +1,24 @@
/* File : example.i */
%module example
/* A few preprocessor macros */
#define ICONST 42
#define FCONST 2.1828
#define CCONST 'x'
#define SCONST "Hello World"
/* This should work just fine */
#define EXPR ICONST + 3*(FCONST)
/* This shouldn't do anything */
#define EXTERN extern
/* Neither should this (BAR isn't defined) */
#define FOO (ICONST + BAR)
/* The following statements also produce constants */
const int iconst = 37;
const double fconst = 3.14;

View file

@ -0,0 +1,66 @@
<html>
<head>
<title>SWIG:Examples:ruby:constants</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/ruby/constants/</tt>
<hr>
<H2>Wrapping C Constants</H2>
<tt>$Header$</tt><br>
<p>
When SWIG encounters C preprocessor macros and C declarations that look like constants,
it creates Ruby constants with an identical value. Click <a href="example.i">here</a>
to see a SWIG interface with some constant declarations in it.
<h2>Accessing Constants from Ruby</h2>
Click <a href="run.rb">here</a> to see a script that prints out the values
of the constants contained in the above file.
<h2>Key points</h2>
<ul>
<li>The values of preprocessor macros are converted into Ruby constants.
<li>Types are inferred by syntax (e.g., "3" is an integer and "3.5" is a float).
<li>Character constants such as 'x' are converted into Ruby strings.
<li>C string literals such as "Hello World" are converted into Ruby strings.
<li>Macros that are not fully defined are simply ignored. For example:
<blockquote>
<pre>
#define EXTERN extern
</pre>
</blockquote>
is ignored because SWIG has no idea what type of variable this would be.
<p>
<li>Expressions are allowed provided that all of their components are defined. Otherwise, the constant is ignored.
<li>Certain C declarations involving 'const' are also turned into Ruby constants.
<li>Constants that begin with lower case character are automatically capitalized.
For example:
<blockquote>
<pre>
const int iconst = 37;
</pre>
</blockquote>
is capitalized as <tt>Example::Iconst</tt> because Ruby constants name must begin
with upper case character.
<li>The constants that appear in a SWIG interface file do not have to appear in any sort
of matching C source file since the creation of a constant does not require linkage
to a stored value (i.e., a value held in a C global variable or memory location).
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,23 @@
# file: run.rb
require 'example'
print "ICONST = ", Example::ICONST, " (should be 42)\n"
print "FCONST = ", Example::FCONST, " (should be 2.1828)\n"
print "CCONST = ", Example::CCONST, " (should be 'x')\n"
print "SCONST = ", Example::SCONST, " (should be 'Hello World')\n"
print "EXPR = ", Example::EXPR, " (should be 48.5484)\n"
print "iconst = ", Example::Iconst, " (should be 37)\n"
print "fconst = ", Example::Fconst, " (should be 3.14)\n"
begin
print "EXTERN = ", Example::EXTERN, " (Arg! This shouldn't print anything)\n"
rescue NameError
print "EXTERN isn't defined (good)\n"
end
begin
print "FOO = ", Example::FOO, " (Arg! This shouldn't print anything)\n"
rescue NameError
print "FOO isn't defined (good)\n"
end

85
Examples/ruby/index.html Normal file
View file

@ -0,0 +1,85 @@
<head>
<title>SWIG:Examples:ruby</title>
</head>
<body bgcolor="#ffffff">
<H1>SWIG Ruby Examples</H1>
<tt>$Header$</tt><br>
<p>
The following examples illustrate the use of SWIG with Ruby.
<ul>
<li><a href="simple/index.html">simple</a>. A minimal example showing how SWIG can
be used to wrap a C function, a global variable, and a constant.
<li><a href="constants/index.html">constants</a>. This shows how preprocessor macros and
certain C declarations are turned into constants.
</ul>
<h2>Compilation Issues</h2>
<ul>
<li>To create a Ruby extension, SWIG is run with the following options:
<blockquote>
<pre>
% swig -ruby interface.i
</pre>
</blockquote>
<li>The compilation of examples is done using the file <tt>Example/Makefile</tt>. This
makefile performs a manual module compilation which is platform specific. Typically,
the steps look like this (Linux):
<blockquote>
<pre>
% swig -ruby interface.i
% gcc -fpic -c interface_wrap.c -I/usr/local/lib/ruby/1.4/i686-linux
% gcc -shared interface_wrap.o $(OBJS) -o interface.so
% ruby
require 'interface'
Interface.blah(...)
...
</pre>
</blockquote>
<li>The politically "correct" way to compile a Ruby extension is to follow the steps
described <tt>README.EXT</tt> in Ruby distribution:
<p>
<ol>
<li>Create a file called <tt>extconf.rb</tt> that looks like the following:
<blockquote>
<pre>
require 'mkmf'
create_makefile('interface')
</pre>
</blockquote>
<li>Type the following to build the extension:
<blockquote>
<pre>
% ruby extconf.rb
% make
</pre>
</blockquote>
</ol>
</ul>
<h2>Compatibility</h2>
The examples have been extensively tested on the following platforms:
<ul>
<li>Linux
</ul>
Your mileage may vary. If you experience a problem, please let us know by
sending a message to <a href="mailto:swig-dev@cs.uchicago.edu">swig-dev@cs.uchicago.edu</a>.
</body>
</html>

View file

@ -0,0 +1,18 @@
TOP = ../..
SWIG = $(TOP)/../swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static
clean::
rm -f *_wrap* *.o *~ *.so myruby .~* core

View file

@ -0,0 +1,18 @@
/* File : example.c */
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}

View file

@ -0,0 +1,5 @@
/* File : example.i */
%module example
extern int gcd(int x, int y);
extern double Foo;

View file

@ -0,0 +1,99 @@
<html>
<head>
<title>SWIG:Examples:ruby:simple</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/ruby/simple/</tt>
<hr>
<H2>Simple Ruby Example</H2>
<tt>$Header$</tt><br>
<p>
This example illustrates how you can hook Ruby to a very simple C program containing
a function and a global variable.
<h2>The C Code</h2>
Suppose you have the following C code:
<blockquote>
<pre>
/* File : example.c */
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
</pre>
</blockquote>
<h2>The SWIG interface</h2>
Here is a simple SWIG interface file:
<blockquote>
<pre>
/* File: example.i */
%module example
extern int gcd(int x, int y);
extern double Foo;
</pre>
</blockquote>
<h2>Compilation</h2>
<ol>
<li><tt>swig -ruby <a href="example.i">example.i</a></tt>
<p>
<li>Compile <tt><a href="example_wrap.c">example_wrap.c</a></tt> and <tt><a href="example.c">example.c</a></tt>
to create the extension <tt>example.so</tt>.
</ol>
<h2>Using the extension</h2>
Click <a href="run.rb">here</a> to see a script that calls our C functions from Ruby.
<h2>Key points</h2>
<ul>
<li>Use the <tt>require</tt> function to load your extension library from Ruby. For example:
<blockquote>
<pre>
require 'example'
</pre>
</blockquote>
<li>C functions work just like Ruby functions. For example:
<blockquote>
<pre>
g = Example.gcd(42,105)
</pre>
</blockquote>
<li>C global variables are accessed through module method. For example:
<blockquote>
<pre>
a = Example.Foo
</pre>
</blockquote>
</ul>
<hr>
</body>
</html>

View file

@ -0,0 +1,21 @@
# file: run.rb
require 'example'
# Call our gcd() function
x = 42
y = 105
g = Example.gcd(x,y)
printf "The gcd of %d and %d is %d\n",x,y,g
# Manipulate the Foo global variable
# Output its current value
print "Foo = ", Example.Foo, "\n"
# Change its value
Example.Foo = 3.1415926
# See if the change took effect
print "Foo = ", Example.Foo, "\n"

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);
}

View file

@ -174,6 +174,12 @@ install-lib:
echo "Installing Lib/mzscheme/$$i"; \
../../$(INSTALL_DATA) $$i $(SWIG_LIB)/mzscheme/$$i; \
done;
@$(MKINSTDIRS) $(SWIG_LIB)/ruby
@cd $(srcdir)/Lib/ruby; for i in *.i *.swg Makefile.swig extconf.rb; \
do \
echo "Installing Lib/ruby/$$i"; \
../../$(INSTALL_DATA) $$i $(SWIG_LIB)/ruby/$$i; \
done;
install-runtime:
@cd Runtime; $(MAKE) install

View file

@ -13,7 +13,7 @@ VPATH = @srcdir@
CC = @CC@
LIBTOOL = ../Tools/libtool
SWIGLIB = ../Lib
LIBS = libswigpl.la libswigpy.la libswigtcl8.la
LIBS = libswigpl.la libswigpy.la libswigtcl8.la libswigrb.la
LIB_DIR = $(exec_prefix)/lib
all:
@ -80,3 +80,20 @@ libswigpl.la:
cat $(srcdir)/$(PERL5_RUNTIME) >> libperl.c
$(LIBTOOL) $(CC) -c $(PERL5_INCLUDE) -DSWIG_GLOBAL -Dbool=char -Dexplicit= libperl.c
$(LIBTOOL) $(CC) -o libswigpl.la libperl.lo -rpath $(LIB_DIR) -avoid-version
# ----------------------------------------------------------------------
# Ruby run-time library
# ----------------------------------------------------------------------
RUBY_INCLUDE = @RUBYINCLUDE@
RUBY_RUNTIME = $(SWIGLIB)/ruby/ruby.swg
# Ruby shared
ruby: libswigrb.la
libswigrb.la:
cp $(srcdir)/$(RUBY_RUNTIME) librb.c
cat $(SWIGLIB)/ruby/rubydef.swg >> librb.c
$(LIBTOOL) $(CC) -c $(RUBY_INCLUDE) -DSWIG_GLOBAL librb.c
$(LIBTOOL) $(CC) -o libswigrb.la librb.lo -rpath $(LIB_DIR) -avoid-version

View file

@ -15,7 +15,7 @@ necho() {
# Script that attempts to produce different run-time libraries
TARGET='perl5 python tcl'
TARGET='perl5 python tcl ruby'
echo "Building the SWIG runtime libraries."
echo ""

View file

@ -13,8 +13,8 @@ AR = @AR@
RANLIB = @RANLIB@
TARGET = libmodules11.a
OBJS = swigmain.o tcl8.o perl5.o python.o pycpp.o guile.o java.o mzscheme.o
SRCS = swigmain.cxx tcl8.cxx perl5.cxx python.cxx pycpp.cxx guile.cxx java.cxx mzscheme.cxx
OBJS = swigmain.o tcl8.o perl5.o python.o pycpp.o guile.o java.o mzscheme.o ruby.o
SRCS = swigmain.cxx tcl8.cxx perl5.cxx python.cxx pycpp.cxx guile.cxx java.cxx mzscheme.cxx ruby.cxx
INCLUDE = -I$(srcdir)/../Include \
-I$(srcdir)/../SWIG1.1 \
-I$(srcdir)/../SWIG1.3 \

1300
Source/Modules1.1/ruby.cxx Normal file

File diff suppressed because it is too large Load diff

125
Source/Modules1.1/ruby.h Normal file
View file

@ -0,0 +1,125 @@
/********************************************************************
* Ruby module for SWIG
*
* $Header$
*
* Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
* Copyright (C) 2000 Information-technology Promotion Agency, Japan
*
* Masaki Fukushima
*
********************************************************************/
class RClass {
private:
String temp;
public:
String name; // class name (renamed)
String cname; // original C class/struct name
String vname; // variable name
String type;
String prefix;
String header;
String init;
String aliases;
String includes;
DOH *freemethods;
DOH *predmethods;
int destructor_defined;
RClass(void) {
freemethods = NewHash();
predmethods = NewHash();
destructor_defined = 0;
}
void set_name(char *cn, char *rn, char *valn) {
cname = cn;
name = valn;
vname << "c" << name;
prefix << (rn ? rn : cn) << "_";
}
char *strip(char *s) {
if (strncmp(s, prefix.get(), strlen(prefix.get())) != 0)
return s;
temp = s;
temp.replace(prefix.get(), "");
return temp.get();
}
};
class RUBY : public Language {
private:
char *module;
char *modvar;
char *feature;
int toplevel;
String other_extern;
String other_init;
char *import_file;
int current;
enum {
NO_CPP,
MEMBER_FUNC,
CONSTRUCTOR,
DESTRUCTOR,
MEMBER_VAR,
CLASS_CONST,
STATIC_FUNC,
STATIC_VAR
};
DOH *classes; // key=cname val=RClass
RClass *klass; // Currently processing class
DOH *special_methods; // Python style special method name table
virtual char *make_wrapper_name(char *cname);
virtual char *validate_const_name(char *name);
virtual char *ruby_typemap_lookup(char *, DataType *, char *, char *, char *, WrapperFunction * = 0);
virtual int to_VALUE(DataType *, char *, String&, int = 0);
virtual int from_VALUE(DataType *, char *, String&);
public:
RUBY();
// Virtual functions required by the SWIG parser
virtual void parse_args(int, char *argv[]);
virtual void parse();
virtual void create_function(char *, char *, DataType *, ParmList *);
virtual void link_variable(char *, char *, DataType *);
virtual void declare_const(char *, char *, DataType *, char *);
virtual void initialize(void);
virtual void headers(void);
virtual void close(void);
virtual void set_module(char *,char **);
virtual void create_command(char *, char *, int);
// C++ language extensions.
virtual void cpp_member_func(char *name, char *iname, DataType *t, ParmList *l);
virtual void cpp_constructor(char *name, char *iname, ParmList *l);
virtual void cpp_destructor(char *name, char *newname);
virtual void cpp_open_class(char *classname, char *rname, char *ctype, int strip);
virtual void cpp_close_class();
virtual void cpp_inherit(char **baseclass, int mode = INHERIT_ALL);
virtual void cpp_variable(char *name, char *iname, DataType *t);
virtual void cpp_static_func(char *name, char *iname, DataType *t, ParmList *l);
virtual void cpp_declare_const(char *name, char *iname, DataType *type, char *value);
virtual void cpp_static_var(char *name, char *iname, DataType *t);
// Declaration of a class, but not a full definition
virtual void cpp_class_decl(char *, char *, char *);
// Pragma directive
virtual void pragma(char *, char *, char *);
virtual void cpp_pragma(Pragma *);
// Import directive
virtual void import(char *filename);
};
/*
* Local Variables:
* c-basic-offset: 2
* End:
*/

View file

@ -32,6 +32,7 @@ static char cvsroot[] = "$Header$";
#include "python.h"
#include "guile.h"
#include "mzscheme.h"
#include "ruby.h"
#include <ctype.h>
@ -47,7 +48,8 @@ Target Language Options:\n\
-perl5 - Generate Perl5 wrappers.\n\
-java - Generate Java wrappers.\n\
-guile - Generate Guile wrappers.\n\
-mzscheme - Generate Mzscheme wrappers.\n";
-mzscheme - Generate Mzscheme wrappers.\n\
-ruby - Generate Ruby wrappers.\n";
//-----------------------------------------------------------------
// main()
@ -87,6 +89,9 @@ int main(int argc, char **argv) {
} else if (strcmp(argv[i],"-mzscheme") == 0) {
dl = new MZSCHEME;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-ruby") == 0) {
dl = new RUBY;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-help") == 0) {
fputs(usage,stderr);
Swig_mark_arg(i);

View file

@ -594,6 +594,71 @@ AC_SUBST(GUILEINCLUDE)
AC_SUBST(GUILELIB)
AC_SUBST(GUILELINK)
#----------------------------------------------------------------
# Look for Ruby
#----------------------------------------------------------------
RUBYBIN=nope
AC_ARG_WITH(ruby,[ --with-ruby=path Set location of Ruby executable],[ RUBYBIN="$withval"], [RUBYBIN=nope])
# First figure out what the name of Ruby is
if test "$RUBYBIN" = nope; then
AC_CHECK_PROGS(RUBY, ruby, nope)
else
RUBY="$RUBYBIN"
fi
AC_MSG_CHECKING(for Ruby header files)
if test "$RUBY" != nope; then
RUBYDIR=`($RUBY -rmkmf -e 'print $archdir') 2>/dev/null`
if test "$RUBYDIR" != ""; then
dirs="$RUBYDIR"
RUBYINCLUDE=none
for i in $dirs; do
if test -r $i/ruby.h; then
AC_MSG_RESULT($i)
RUBYINCLUDE="-I$i"
break;
fi
done
if test "$RUBYINCLUDE" = none; then
RUBYINCLUDE="-I$RUBYDIR"
AC_MSG_RESULT(could not locate ruby.h...using $RUBYINCLUDE)
fi
AC_MSG_CHECKING(for Ruby library)
RUBYLIB=none
for i in $dirs; do
if test -r $i/libruby.a; then
AC_MSG_RESULT($i)
RUBYLIB="$i"
break;
fi
done
if test "$RUBYLIB" = none; then
RUBYLIB="$RUBYDIR"
AC_MSG_RESULT(could not locate libruby.a...using $RUBYLIB)
fi
else
AC_MSG_RESULT(unable to determine ruby configuration)
RUBYINCLUDE="-I$RUBYDIR"
RUBYLIB="$RUBYDIR"
fi
RUBYLINK=`($RUBY -rrbconfig -e 'print Config::CONFIG[["RUBY_INSTALL_NAME"]]') 2>/dev/null`
RUBYLINK="-l$RUBYLINK"
RUBYLINK="$RUBYLINK `($RUBY -rrbconfig -e 'print Config::CONFIG[["LIBS"]]') 2>/dev/null`"
else
AC_MSG_RESULT(could not figure out how to run ruby)
RUBYINCLUDE="-I/usr/local/lib/ruby/1.4/arch"
RUBYLIB="-I/usr/local/lib/ruby/1.4/arch"
RUBYLINK="-lruby -lm"
fi
AC_SUBST(RUBYINCLUDE)
AC_SUBST(RUBYLIB)
AC_SUBST(RUBYLINK)
#----------------------------------------------------------------
# Miscellaneous