Add MRI 1.8 Support #163
					 4 changed files with 210 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -32,7 +32,9 @@
 | 
			
		|||
#include "boost-hash.h"
 | 
			
		||||
 | 
			
		||||
#include <ruby.h>
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR > 1
 | 
			
		||||
| 
					
	
 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 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 
			
			
		 | 
			||||
#include <ruby/encoding.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +206,7 @@ RB_METHOD(mriP)
 | 
			
		|||
RB_METHOD(mkxpDataDirectory)
 | 
			
		||||
{
 | 
			
		||||
	RB_UNUSED_PARAM;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	const std::string &path = shState->config().customDataPath;
 | 
			
		||||
	const char *s = path.empty() ? "." : path.c_str();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -580,9 +582,15 @@ static void mriBindingExecute()
 | 
			
		|||
	 * stdio streams on some platforms (eg. Windows) */
 | 
			
		||||
	int argc = 0;
 | 
			
		||||
	char **argv = 0;
 | 
			
		||||
	ruby_sysinit(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR == 1
 | 
			
		||||
	ruby_init();
 | 
			
		||||
	//ruby_options(argc, argv);
 | 
			
		||||
#else
 | 
			
		||||
	ruby_sysinit(&argc, &argv);
 | 
			
		||||
	ruby_setup();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding()));
 | 
			
		||||
 | 
			
		||||
	Config &conf = shState->rtData().config;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,6 +90,9 @@ void raiseRbExc(const Exception &exc)
 | 
			
		|||
void
 | 
			
		||||
raiseDisposedAccess(VALUE self)
 | 
			
		||||
{
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR == 1
 | 
			
		||||
// FIXME: raiseDisposedAccess not implemented
 | 
			
		||||
#else
 | 
			
		||||
	const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name;
 | 
			
		||||
	char buf[32];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +100,7 @@ raiseDisposedAccess(VALUE self)
 | 
			
		|||
	buf[0] = tolower(buf[0]);
 | 
			
		||||
 | 
			
		||||
	rb_raise(getRbData()->exc[RGSS], "disposed %s", buf);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
| 
						 | 
				
			
			@ -319,3 +323,73 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
 | 
			
		|||
 | 
			
		||||
	return argI;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR == 1
 | 
			
		||||
// Functions providing Ruby 1.8 compatibililty
 | 
			
		||||
VALUE rb_sprintf(const char* fmt, ...) {
 | 
			
		||||
	va_list args;
 | 
			
		||||
	va_start(args, fmt);
 | 
			
		||||
	char buf[4096];
 | 
			
		||||
	int const result = vsnprintf(buf, sizeof(buf), fmt, args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
 | 
			
		||||
	return rb_str_new2(buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 v, const rb_data_type_t *) {
 | 
			
		||||
// FIXME: rb_check_typeddata not implemented
 | 
			
		||||
	return RTYPEDDATA_DATA(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NORETURN(void rb_error_arity(int, int, int)) {
 | 
			
		||||
	assert(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE rb_enc_str_new(const char* ch, long len, rb_encoding*) {
 | 
			
		||||
	return rb_str_new(ch, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
rb_encoding *rb_utf8_encoding(void) {
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rb_enc_set_default_external(VALUE encoding) {
 | 
			
		||||
	// no-op, assuming UTF-8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE rb_enc_from_encoding(rb_encoding *enc) {
 | 
			
		||||
	return Qnil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE rb_str_catf(VALUE, const char*, ...) {
 | 
			
		||||
	return Qnil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE rb_errinfo(void) {
 | 
			
		||||
	return ruby_errinfo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rb_typeddata_is_kind_of(VALUE, const rb_data_type_t *) {
 | 
			
		||||
	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) {
 | 
			
		||||
	return Qnil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rb_utf8_encindex(void) {
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
					
	
 missing newline at end missing newline at end 
			
			
		 | 
			||||
VALUE rb_hash_lookup2(VALUE, VALUE, VALUE) {
 | 
			
		||||
	return Qnil;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,9 +23,124 @@
 | 
			
		|||
#define BINDING_UTIL_H
 | 
			
		||||
 | 
			
		||||
#include <ruby.h>
 | 
			
		||||
#include <ruby/version.h>
 | 
			
		||||
 | 
			
		||||
#include "exception.h"
 | 
			
		||||
 | 
			
		||||
// Ruby 1.8 and Ruby 2.x use different version macros
 | 
			
		||||
#ifndef RUBY_API_VERSION_MAJOR
 | 
			
		||||
#define RUBY_API_VERSION_MAJOR RUBY_VERSION_MAJOR
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR == 1
 | 
			
		||||
// 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 OBJ_INIT_COPY(obj, orig) \
 | 
			
		||||
    ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
 | 
			
		||||
 | 
			
		||||
#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 PRIsVALUE "s"
 | 
			
		||||
#define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
 | 
			
		||||
#define RB_OBJ_STRING(obj) StringValueCStr(obj)
 | 
			
		||||
 | 
			
		||||
#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))
 | 
			
		||||
 | 
			
		||||
NORETURN(void rb_error_arity(int, int, int));
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
enum RbException
 | 
			
		||||
{
 | 
			
		||||
	RGSS = 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +181,6 @@ raiseRbExc(const Exception &exc);
 | 
			
		|||
	extern rb_data_type_t Klass##Type
 | 
			
		||||
 | 
			
		||||
/* 2.1 has added a new field (flags) to rb_data_type_t */
 | 
			
		||||
#include <ruby/version.h>
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1
 | 
			
		||||
/* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */
 | 
			
		||||
#define DEF_TYPE_FLAGS 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,9 @@
 | 
			
		|||
#include "filesystem.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR > 1
 | 
			
		||||
#include "ruby/encoding.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "ruby/intern.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +132,6 @@ kernelLoadDataInt(const char *filename, bool rubyExc)
 | 
			
		|||
	VALUE port = fileIntForPath(filename, rubyExc);
 | 
			
		||||
 | 
			
		||||
	VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal"));
 | 
			
		||||
 | 
			
		||||
	// FIXME need to catch exceptions here with begin rescue
 | 
			
		||||
	VALUE result = rb_funcall2(marsh, rb_intern("load"), 1, &port);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -195,14 +196,21 @@ RB_METHOD(_marshalLoad)
 | 
			
		|||
	rb_get_args(argc, argv, "o|o", &port, &proc RB_ARG_END);
 | 
			
		||||
 | 
			
		||||
	VALUE utf8Proc;
 | 
			
		||||
	// FIXME: Not implemented for Ruby 1.8
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR > 1
 | 
			
		||||
	if (NIL_P(proc))
 | 
			
		||||
		utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(stringForceUTF8), Qnil);
 | 
			
		||||
	else
 | 
			
		||||
		utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(customProc), proc);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal"));
 | 
			
		||||
 | 
			
		||||
#if RUBY_API_VERSION_MAJOR > 1
 | 
			
		||||
	VALUE v[] = { port, utf8Proc };
 | 
			
		||||
#else
 | 
			
		||||
	VALUE v[] = { port, proc };
 | 
			
		||||
#endif
 | 
			
		||||
	return rb_funcall2(marsh, rb_intern("_mkxp_load_alias"), ARRAY_SIZE(v), v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -214,6 +222,8 @@ fileIntBindingInit()
 | 
			
		|||
 | 
			
		||||
	_rb_define_method(klass, "read", fileIntRead);
 | 
			
		||||
	_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, "close", fileIntClose);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	
If this defined by a ruby header, or do we define it?