Add MRI 1.8 Support #163
|
@ -32,7 +32,9 @@
|
||||||
#include "boost-hash.h"
|
#include "boost-hash.h"
|
||||||
|
|
||||||
#include <ruby.h>
|
#include <ruby.h>
|
||||||
|
#ifndef RUBY_LEGACY_VERSION
|
||||||
|
|||||||
#include <ruby/encoding.h>
|
#include <ruby/encoding.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -580,9 +582,14 @@ static void mriBindingExecute()
|
||||||
* stdio streams on some platforms (eg. Windows) */
|
* stdio streams on some platforms (eg. Windows) */
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
char **argv = 0;
|
char **argv = 0;
|
||||||
ruby_sysinit(&argc, &argv);
|
|
||||||
|
|
||||||
|
#if RUBY_API_VERSION_MAJOR == 1
|
||||||
|
ruby_init();
|
||||||
|
#else
|
||||||
|
ruby_sysinit(&argc, &argv);
|
||||||
ruby_setup();
|
ruby_setup();
|
||||||
|
#endif
|
||||||
|
|
||||||
rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding()));
|
rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding()));
|
||||||
|
|
||||||
Config &conf = shState->rtData().config;
|
Config &conf = shState->rtData().config;
|
||||||
|
|
|
@ -90,7 +90,11 @@ void raiseRbExc(const Exception &exc)
|
||||||
void
|
void
|
||||||
raiseDisposedAccess(VALUE self)
|
raiseDisposedAccess(VALUE self)
|
||||||
{
|
{
|
||||||
|
#ifdef RUBY_LEGACY_VERSION
|
||||||
|
const char *klassName = rb_class2name(self);
|
||||||
|
#else
|
||||||
const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name;
|
const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name;
|
||||||
|
#endif
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
strncpy(buf, klassName, sizeof(buf));
|
strncpy(buf, klassName, sizeof(buf));
|
||||||
|
@ -319,3 +323,122 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
|
||||||
|
|
||||||
return argI;
|
return argI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RUBY_API_VERSION_MAJOR == 1
|
||||||
|
NORETURN(void rb_error_arity(int, int, int))
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RUBY_API_VERSION_MINOR == 8
|
||||||
|
/*
|
||||||
|
Functions providing Ruby 1.8 compatibililty.
|
||||||
|
All encoding related functions return dummy values because mkxp only uses them
|
||||||
|
to retrieve the UTF-8 encoding.
|
||||||
|
*/
|
||||||
|
VALUE rb_sprintf_vararg(const char* fmt, va_list args) {
|
||||||
|
char buf[4096];
|
||||||
|
int result = vsnprintf(buf, sizeof(buf), fmt, args);
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
buf[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return rb_str_new2(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_sprintf(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
VALUE val = rb_sprintf_vararg(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *rbType)
|
||||||
|
{
|
||||||
|
return rb_data_object_alloc(klass, 0, rbType->function.dmark, rbType->function.dfree);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *rb_check_typeddata(VALUE value, const rb_data_type_t* typed)
|
||||||
|
{
|
||||||
|
// FIXME: Won't work because rb_typeddata_is_kind_of is not implemented
|
||||||
|
if (!rb_typeddata_is_kind_of(value, typed)) {
|
||||||
|
rb_raise(getRbData()->exc[RGSS],
|
||||||
|
"wrong data type %s (expected %s)", rb_class2name(value), typed->wrap_struct_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RTYPEDDATA_DATA(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_enc_str_new(const char* ch, long len, rb_encoding*)
|
||||||
|
{
|
||||||
|
// Encoding is ignored
|
||||||
|
return rb_str_new(ch, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_encoding *rb_utf8_encoding(void)
|
||||||
|
{
|
||||||
|
// not relevant
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rb_enc_set_default_external(VALUE)
|
||||||
|
{
|
||||||
|
// not relevant
|
||||||
missing newline at end missing newline at end
|
|||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_enc_from_encoding(rb_encoding*)
|
||||||
|
{
|
||||||
|
// not relevant
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_str_catf(VALUE value, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
VALUE second = rb_sprintf_vararg(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return rb_str_concat(value, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_errinfo(void)
|
||||||
|
{
|
||||||
|
return ruby_errinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rb_typeddata_is_kind_of(VALUE value, const rb_data_type_t* typed)
|
||||||
|
{
|
||||||
|
// FIXME: rb_typeddata_is_kind_of not implemented
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_file_open_str(VALUE filename, const char* mode)
|
||||||
|
{
|
||||||
|
return rb_file_open(RB_OBJ_STRING(filename), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_enc_associate_index(VALUE, int)
|
||||||
|
{
|
||||||
|
// not relevant
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rb_utf8_encindex(void)
|
||||||
|
{
|
||||||
|
// not relevant
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
|
||||||
|
{
|
||||||
|
VALUE v = rb_hash_lookup(hash, key);
|
||||||
|
return (v == Qnil) ? def : v;
|
||||||
|
}
|
||||||
|
#endif // RUBY_API_VERSION_MINOR == 8
|
||||||
|
#endif // RUBY_API_VERSION_MAJOR == 1
|
||||||
|
|
|
@ -23,9 +23,131 @@
|
||||||
#define BINDING_UTIL_H
|
#define BINDING_UTIL_H
|
||||||
|
|
||||||
#include <ruby.h>
|
#include <ruby.h>
|
||||||
|
#include <ruby/version.h>
|
||||||
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
|
// Ruby 1.8 and Ruby 1.9+ use different version macros
|
||||||
|
#ifndef RUBY_API_VERSION_MAJOR
|
||||||
|
#define RUBY_API_VERSION_MAJOR RUBY_VERSION_MAJOR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RUBY_API_VERSION_MINOR
|
||||||
|
#define RUBY_API_VERSION_MINOR RUBY_VERSION_MINOR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RUBY_API_VERSION_MAJOR == 1
|
||||||
|
#define PRIsVALUE "s"
|
||||||
|
#define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
|
||||||
|
#define RB_OBJ_STRING(obj) StringValueCStr(obj)
|
||||||
|
|
||||||
|
NORETURN(void rb_error_arity(int, int, int));
|
||||||
|
|
||||||
|
#define OBJ_INIT_COPY(obj, orig) \
|
||||||
|
((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
|
||||||
|
#if RUBY_API_VERSION_MINOR == 8
|
||||||
|
// Makes version checks easier
|
||||||
|
#define RUBY_LEGACY_VERSION
|
||||||
|
// Functions and macros providing Ruby 1.8 compatibililty
|
||||||
|
#define FLONUM_P(x) 0
|
||||||
|
|
||||||
|
#define RB_FLOAT_TYPE_P(obj) (FLONUM_P(obj) || (!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == T_FLOAT))
|
||||||
|
|
||||||
|
#define RB_TYPE_P(obj, type) ( \
|
||||||
|
((type) == T_FIXNUM) ? FIXNUM_P(obj) : \
|
||||||
|
((type) == T_TRUE) ? ((obj) == Qtrue) : \
|
||||||
|
((type) == T_FALSE) ? ((obj) == Qfalse) : \
|
||||||
|
((type) == T_NIL) ? ((obj) == Qnil) : \
|
||||||
|
((type) == T_UNDEF) ? ((obj) == Qundef) : \
|
||||||
|
((type) == T_SYMBOL) ? SYMBOL_P(obj) : \
|
||||||
|
((type) == T_FLOAT) ? RB_FLOAT_TYPE_P(obj) : \
|
||||||
|
(!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == (type)))
|
||||||
|
|
||||||
|
#define RUBY_T_ARRAY T_ARRAY
|
||||||
|
#define RUBY_T_STRING T_STRING
|
||||||
|
#define RUBY_T_FLOAT T_FLOAT
|
||||||
|
#define RUBY_T_FIXNUM T_FIXNUM
|
||||||
|
#define RUBY_T_TRUE T_TRUE
|
||||||
|
#define RUBY_T_FALSE T_FALSE
|
||||||
|
#define RUBY_T_NIL T_NIL
|
||||||
|
|
||||||
|
#define rb_str_new_cstr rb_str_new2
|
||||||
|
|
||||||
|
#define RUBY_DEFAULT_FREE ((RUBY_DATA_FUNC)-1)
|
||||||
|
#define RUBY_NEVER_FREE ((RUBY_DATA_FUNC)0)
|
||||||
|
#define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE
|
||||||
|
#define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE
|
||||||
|
|
||||||
|
#define RTYPEDDATA_DATA DATA_PTR
|
||||||
|
|
||||||
|
#define RFLOAT_VALUE(d) RFLOAT(d)->value
|
||||||
|
|
||||||
|
#define ENCODING_INLINE_MAX 127
|
||||||
|
#define ENCODING_SHIFT (FL_USHIFT+10)
|
||||||
|
#define ENCODING_MASK (((VALUE)ENCODING_INLINE_MAX)<<ENCODING_SHIFT) /* FL_USER10|FL_USER11|FL_USER12|FL_USER13|FL_USER14|FL_USER15|FL_USER16 */
|
||||||
|
|
||||||
|
#define ENCODING_SET_INLINED(obj,i) do {\
|
||||||
|
RBASIC(obj)->flags &= ~ENCODING_MASK;\
|
||||||
|
RBASIC(obj)->flags |= (VALUE)(i) << ENCODING_SHIFT;\
|
||||||
|
} while (0)
|
||||||
|
#define ENCODING_SET(obj,i) rb_enc_set_index((obj), (i))
|
||||||
|
|
||||||
|
#define ENCODING_GET_INLINED(obj) (int)((RBASIC(obj)->flags & ENCODING_MASK)>>ENCODING_SHIFT)
|
||||||
|
#define ENCODING_GET(obj) \
|
||||||
|
(ENCODING_GET_INLINED(obj) != ENCODING_INLINE_MAX ? \
|
||||||
|
ENCODING_GET_INLINED(obj) : \
|
||||||
|
rb_enc_get_index(obj))
|
||||||
|
|
||||||
|
#define ENCODING_IS_ASCII8BIT(obj) (ENCODING_GET_INLINED(obj) == 0)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *wrap_struct_name;
|
||||||
|
struct {
|
||||||
|
void (*dmark)(void*);
|
||||||
|
void (*dfree)(void*);
|
||||||
|
size_t (*dsize)(const void *);
|
||||||
|
void *reserved[2];
|
||||||
|
} function;
|
||||||
|
const char *parent;
|
||||||
|
void *data;
|
||||||
|
VALUE flags;
|
||||||
|
} rb_data_type_t;
|
||||||
|
|
||||||
|
VALUE rb_sprintf(const char* fmt, ...);
|
||||||
|
|
||||||
|
VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *);
|
||||||
|
|
||||||
|
void *rb_check_typeddata(VALUE, const rb_data_type_t *);
|
||||||
|
|
||||||
|
#define Check_TypedStruct(v,t) rb_check_typeddata((VALUE)(v),(t))
|
||||||
|
|
||||||
|
typedef void rb_encoding;
|
||||||
|
|
||||||
|
VALUE rb_enc_str_new(const char*, long, rb_encoding*);
|
||||||
|
|
||||||
|
rb_encoding *rb_utf8_encoding(void);
|
||||||
|
|
||||||
|
void rb_enc_set_default_external(VALUE encoding);
|
||||||
|
|
||||||
|
VALUE rb_enc_from_encoding(rb_encoding *enc);
|
||||||
|
|
||||||
|
VALUE rb_str_catf(VALUE, const char*, ...);
|
||||||
|
|
||||||
|
VALUE rb_errinfo(void);
|
||||||
|
|
||||||
|
int rb_typeddata_is_kind_of(VALUE, const rb_data_type_t *);
|
||||||
|
|
||||||
|
VALUE rb_file_open_str(VALUE, const char*);
|
||||||
|
|
||||||
|
VALUE rb_enc_associate_index(VALUE, int);
|
||||||
|
|
||||||
|
int rb_utf8_encindex(void);
|
||||||
|
|
||||||
|
VALUE rb_hash_lookup2(VALUE, VALUE, VALUE);
|
||||||
|
|
||||||
|
#endif // RUBY_API_VERSION_MINOR == 8
|
||||||
|
#endif // RUBY_API_VERSION_MAJOR == 1
|
||||||
|
|
||||||
enum RbException
|
enum RbException
|
||||||
{
|
{
|
||||||
RGSS = 0,
|
RGSS = 0,
|
||||||
|
@ -66,8 +188,7 @@ raiseRbExc(const Exception &exc);
|
||||||
extern rb_data_type_t Klass##Type
|
extern rb_data_type_t Klass##Type
|
||||||
|
|
||||||
/* 2.1 has added a new field (flags) to rb_data_type_t */
|
/* 2.1 has added a new field (flags) to rb_data_type_t */
|
||||||
#include <ruby/version.h>
|
#if RUBY_API_VERSION_MAJOR > 1 && RUBY_API_VERSION_MINOR > 0
|
||||||
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1
|
|
||||||
/* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */
|
/* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */
|
||||||
#define DEF_TYPE_FLAGS 0
|
#define DEF_TYPE_FLAGS 0
|
||||||
#else
|
#else
|
||||||
|
@ -383,5 +504,4 @@ rb_check_argc(int actual, int expected)
|
||||||
_rb_define_method(klass, prop_name_s "=", Klass##Set##PropName); \
|
_rb_define_method(klass, prop_name_s "=", Klass##Set##PropName); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // BINDING_UTIL_H
|
#endif // BINDING_UTIL_H
|
||||||
|
|
|
@ -25,7 +25,9 @@
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#ifndef RUBY_LEGACY_VERSION
|
||||||
#include "ruby/encoding.h"
|
#include "ruby/encoding.h"
|
||||||
|
#endif
|
||||||
#include "ruby/intern.h"
|
#include "ruby/intern.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -195,14 +197,21 @@ RB_METHOD(_marshalLoad)
|
||||||
rb_get_args(argc, argv, "o|o", &port, &proc RB_ARG_END);
|
rb_get_args(argc, argv, "o|o", &port, &proc RB_ARG_END);
|
||||||
|
|
||||||
VALUE utf8Proc;
|
VALUE utf8Proc;
|
||||||
|
// FIXME: Not implemented for Ruby 1.8
|
||||||
|
#ifndef RUBY_LEGACY_VERSION
|
||||||
if (NIL_P(proc))
|
if (NIL_P(proc))
|
||||||
utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(stringForceUTF8), Qnil);
|
utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(stringForceUTF8), Qnil);
|
||||||
else
|
else
|
||||||
utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(customProc), proc);
|
utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(customProc), proc);
|
||||||
|
#endif
|
||||||
|
|
||||||
VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal"));
|
VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal"));
|
||||||
|
|
||||||
|
#ifndef RUBY_LEGACY_VERSION
|
||||||
VALUE v[] = { port, utf8Proc };
|
VALUE v[] = { port, utf8Proc };
|
||||||
|
#else
|
||||||
|
VALUE v[] = { port, proc };
|
||||||
|
#endif
|
||||||
return rb_funcall2(marsh, rb_intern("_mkxp_load_alias"), ARRAY_SIZE(v), v);
|
return rb_funcall2(marsh, rb_intern("_mkxp_load_alias"), ARRAY_SIZE(v), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +223,8 @@ fileIntBindingInit()
|
||||||
|
|
||||||
_rb_define_method(klass, "read", fileIntRead);
|
_rb_define_method(klass, "read", fileIntRead);
|
||||||
_rb_define_method(klass, "getbyte", fileIntGetByte);
|
_rb_define_method(klass, "getbyte", fileIntGetByte);
|
||||||
|
// Used by Ruby 1.8 Marshaller
|
||||||
|
_rb_define_method(klass, "getc", fileIntGetByte);
|
||||||
_rb_define_method(klass, "binmode", fileIntBinmode);
|
_rb_define_method(klass, "binmode", fileIntBinmode);
|
||||||
_rb_define_method(klass, "close", fileIntClose);
|
_rb_define_method(klass, "close", fileIntClose);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
If this defined by a ruby header, or do we define it?
I define it. Problem is that checking for 1.8 vs. 1.9 is ugly to write so I introduced a new macro for 1.8 only. You can suggest a better macro name :D