Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,37 @@
|
|||
# query.rb
|
||||
require 'fiddle'
|
||||
|
||||
# Look for a C variable named QueryPointer.
|
||||
# Raise an error if it is missing.
|
||||
c_var = Fiddle.dlopen(nil)['QueryPointer']
|
||||
|
||||
int = Fiddle::TYPE_INT
|
||||
voidp = Fiddle::TYPE_VOIDP
|
||||
sz_voidp = Fiddle::SIZEOF_VOIDP
|
||||
|
||||
# Implement the C function
|
||||
# int Query(void *data, size_t *length)
|
||||
# in Ruby code. Store it in a global constant in Ruby (named Query)
|
||||
# to protect it from Ruby's garbage collector.
|
||||
#
|
||||
Query = Fiddle::Closure::BlockCaller
|
||||
.new(int, [voidp, voidp]) do |datap, lengthp|
|
||||
message = "Here am I"
|
||||
|
||||
# We got datap and lengthp as Fiddle::Pointer objects.
|
||||
# Read length, assuming sizeof(size_t) == sizeof(void *).
|
||||
length = lengthp[0, sz_voidp].unpack('J').first
|
||||
|
||||
# Does the message fit in length bytes?
|
||||
if length < message.bytesize
|
||||
0 # failure
|
||||
else
|
||||
length = message.bytesize
|
||||
datap[0, length] = message # Copy the message.
|
||||
lengthp[0, sz_voidp] = [length].pack('J') # Update the length.
|
||||
1 # success
|
||||
end
|
||||
end
|
||||
|
||||
# Set the C variable to our Query.
|
||||
Fiddle::Pointer.new(c_var)[0, sz_voidp] = [Query.to_i].pack('J')
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/* query-rb.c */
|
||||
#include <stdlib.h>
|
||||
#include <ruby.h>
|
||||
|
||||
/*
|
||||
* QueryPointer() uses Ruby and may raise a Ruby error. Query() is a
|
||||
* C wrapper around QueryPointer() that loads Ruby, sets QueryPointer,
|
||||
* and protects against Ruby errors.
|
||||
*/
|
||||
int (*QueryPointer)(char *, size_t *) = NULL;
|
||||
|
||||
static int in_bad_exit = 0;
|
||||
|
||||
static void
|
||||
do_at_exit(void)
|
||||
{
|
||||
RUBY_INIT_STACK;
|
||||
|
||||
if (!in_bad_exit)
|
||||
ruby_cleanup(0);
|
||||
}
|
||||
|
||||
static void
|
||||
bad_exit(int state)
|
||||
{
|
||||
in_bad_exit = 1;
|
||||
ruby_stop(state); /* Clean up Ruby and exit the process. */
|
||||
}
|
||||
|
||||
static void
|
||||
require_query(void)
|
||||
{
|
||||
static int done = 0;
|
||||
int state;
|
||||
|
||||
if (done)
|
||||
return;
|
||||
done = 1;
|
||||
|
||||
ruby_init();
|
||||
atexit(do_at_exit);
|
||||
ruby_init_loadpath(); /* needed to require 'fiddle' */
|
||||
|
||||
/* Require query.rb in current directory. */
|
||||
rb_eval_string_protect("require_relative 'query'", &state);
|
||||
if (!state && !QueryPointer)
|
||||
rb_eval_string_protect("fail 'missing QueryPointer'", &state);
|
||||
if (state)
|
||||
bad_exit(state); /* Ruby will report the error. */
|
||||
}
|
||||
|
||||
struct args {
|
||||
char *data;
|
||||
size_t *length;
|
||||
int result;
|
||||
};
|
||||
|
||||
static VALUE
|
||||
Query1(VALUE v) {
|
||||
struct args *a = (struct args *)v;
|
||||
a->result = QueryPointer(a->data, a->length);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
int
|
||||
Query(char *data, size_t *length)
|
||||
{
|
||||
struct args a;
|
||||
int state;
|
||||
RUBY_INIT_STACK;
|
||||
|
||||
require_query();
|
||||
|
||||
/* Call QueryPointer(), protect against errors. */
|
||||
a.data = data;
|
||||
a.length = length;
|
||||
rb_protect(Query1, (VALUE)&a, &state);
|
||||
if (state)
|
||||
bad_exit(state);
|
||||
return a.result;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Rakefile
|
||||
|
||||
# To build and run:
|
||||
# $ rake
|
||||
# $ ./callruby
|
||||
|
||||
# Must link with cc -Wl,-E so query.c exports QueryPointer.
|
||||
CC = ENV.fetch('CC', 'cc')
|
||||
LDFLAGS = '-Wl,-E'
|
||||
CPPFLAGS = RbConfig.expand('-I$(rubyarchhdrdir) -I$(rubyhdrdir)')
|
||||
LIBS = RbConfig.expand('$(LIBRUBYARG) $(LIBS)')
|
||||
|
||||
task 'default' => 'callruby'
|
||||
|
||||
desc 'compiles callruby'
|
||||
file 'callruby' => %w[main.o query-rb.o] do |t|
|
||||
sh "#{CC} #{LDFLAGS} -o #{t.name} #{t.sources.join(' ')} #{LIBS}"
|
||||
end
|
||||
|
||||
rule '.o' => %w[.c] do |t|
|
||||
sh "#{CC} #{CPPFLAGS} -o #{t.name} -c #{t.source}"
|
||||
end
|
||||
|
||||
desc 'removes callruby and .o files'
|
||||
task 'clean' do
|
||||
rm_f %w[callruby main.o query-rb.o]
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue