diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6646ef8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +obj +*.o +*.app diff --git a/Examples/Gui/CurrencyConverter/fake.m b/Examples/Gui/CurrencyConverter/fake.m index 80959c3..16e1ffb 100644 --- a/Examples/Gui/CurrencyConverter/fake.m +++ b/Examples/Gui/CurrencyConverter/fake.m @@ -1,2 +1,2 @@ /* This is a dummy C file to keep GNUmakefile happy */ -main() {} +int main() {} diff --git a/Examples/Gui/FirstApp/FirstApp.rb b/Examples/Gui/FirstApp/FirstApp.rb index 3e12135..fc463d0 100644 --- a/Examples/Gui/FirstApp/FirstApp.rb +++ b/Examples/Gui/FirstApp/FirstApp.rb @@ -29,17 +29,17 @@ # You can drag all Foundation and AppKit Classes at once or .... require 'Foundation' -require 'AppKit' +# require 'AppKit' #... get only those you need one by one -#Rigs.import("NSApplication") -#Rigs.import("NSGraphicsContext") -#Rigs.import("NSWindow") -#Rigs.import("NSButton") -#Rigs.import("NSProcessInfo") -#Rigs.import("NSMenu") -#Rigs.import("NSSelector") -#Rigs.import("NSString") +Rigs.import("NSApplication") +Rigs.import("NSGraphicsContext") +Rigs.import("NSWindow") +Rigs.import("NSButton") +Rigs.import("NSProcessInfo") +Rigs.import("NSMenu") +Rigs.import("NSSelector") +Rigs.import("NSString") $STRING_AUTOCONVERT = true $SELECTOR_AUTOCONVERT = false @@ -111,8 +111,8 @@ def createWindow rect = NSRect.new(0, 0, 400, 200) @window = NSWindow.alloc - @window = @window.initWithContentRect_styleMask_backing_defer \ - (rect, styleMask, NSBackingStoreRetained, false) + @window = @window.initWithContentRect_styleMask_backing_defer( + rect, styleMask, NSBackingStoreRetained, false) @window.setTitle("Test window with one giant button!") @window.setContentView (button) diff --git a/Examples/Gui/FirstApp/fake.m b/Examples/Gui/FirstApp/fake.m index 80959c3..16e1ffb 100644 --- a/Examples/Gui/FirstApp/fake.m +++ b/Examples/Gui/FirstApp/fake.m @@ -1,2 +1,2 @@ /* This is a dummy C file to keep GNUmakefile happy */ -main() {} +int main() {} diff --git a/Ruby/rigs.rb b/Ruby/rigs.rb index 860a1f9..965e600 100644 --- a/Ruby/rigs.rb +++ b/Ruby/rigs.rb @@ -47,6 +47,26 @@ end +%w[ + NSCharacterConversionException + NSDestinationInvalidException + NSGenericException + NSInternalInconsistencyException + NSInvalidArgumentException + NSInvalidReceivePortException + NSInvalidSendPortException + NSMallocException + NSObjectInaccessibleException + NSObjectNotAvailableException + NSOldStyleException + NSPortReceiveException + NSPortSendException + NSPortTimeoutException + NSRangeException +].each do |exception_name| + Object.const_set(exception_name, Class.new(RuntimeError)) unless Object.const_defined?(exception_name) +end + diff --git a/Source/GNUmakefile b/Source/GNUmakefile index 82c1d25..ebd7c40 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -36,7 +36,11 @@ RUBY_ARCH_DIR := $(shell ruby -rrbconfig -e 'print RbConfig::CONFIG["archdir"]') RUBY_SITE_ARCH_DIR := $(shell ruby -rrbconfig -e 'print RbConfig::CONFIG["sitearchdir"]') -ADDITIONAL_INCLUDE_DIRS = -I$(RUBY_ARCH_DIR) +RUBY_HDR_DIR := $(shell ruby -rrbconfig -e 'print RbConfig::CONFIG["rubyhdrdir"]') + +RUBY_ARCH_HDR_DIR := $(shell ruby -rrbconfig -e 'print RbConfig::CONFIG["rubyarchhdrdir"]') + +ADDITIONAL_INCLUDE_DIRS = -I$(RUBY_HDR_DIR) -I$(RUBY_ARCH_HDR_DIR) -I$(RUBY_ARCH_DIR) ADDITIONAL_OBJCFLAGS = -Wall -g -DVERSION=\"$(VERSION)\" $(LIBRARY_NAME)_OBJC_FILES = $(wildcard *.m) diff --git a/Source/ObjcRuntimeUtilities.h b/Source/ObjcRuntimeUtilities.h index ac01a1a..534d1f1 100644 --- a/Source/ObjcRuntimeUtilities.h +++ b/Source/ObjcRuntimeUtilities.h @@ -26,9 +26,8 @@ #ifndef __ObjcRuntimeUtilities_h_GNUSTEP_RUBY_INCLUDE #define __ObjcRuntimeUtilities_h_GNUSTEP_RUBY_INCLUDE -#include -#include -#include +#import +#import /* * This code is by no means tidied to Java. @@ -85,50 +84,29 @@ BOOL ObjcUtilities_new_class (const char *name, const char *superclassName, Adding new methods to a class - Quick HOWTO: - A. alloc a MethodList using ObjcUtilities_alloc_method_list. - B. insert the methods you want to register in the MethodList using - ObjcUtilities_insert_method_in_list. - To get the objective-C runtime type for a method, you may want to use - ObjcUtilities_build_runtime_Objc_signature - C. register your method list with the objective-C runtime using - ObjcUtilities_register_method_list. + To get the Objective-C runtime type for a method, you may want to use + ObjcUtilities_build_runtime_Objc_signature before adding the method with + ObjcUtilities_add_method. */ /* - * ObjcUtilities_alloc_method_list: + * ObjcUtilities_add_method: * - * Allocate a MethodList capable of containing `count' methods. - * A pointer to the allocated list is returned. + * Add a method definition to a class. `class' is the class to modify, + * `name' is the selector name, `types' is the Objective-C run-time + * signature of the method, and `imp' is the implementation. * */ -MethodList *ObjcUtilities_alloc_method_list (int count); - -/* - * ObjcUtilities_insert_method_in_list: - * - * Insert a method definition in a MethodList. `ml' is a pointer to - * the MethodList. `index' is the index of the method to add. `name' - * is the name of the method; `types' is the objective-C run-time - * signature of the method (see below for a facility to create this - * automatically), `imp' is the IMP (ie, the actual implementation of - * the method). `imp' must be a pointer to a function taking the - * correct arguments and returning the correct type; cast it to an IMP - * then before calling this function. - */ - -void ObjcUtilities_insert_method_in_list (MethodList *ml, - int index, const char *name, - const char *types, IMP imp); +BOOL ObjcUtilities_add_method (Class class, const char *name, + const char *types, IMP imp); /* * ObjcUtilities_build_runtime_Objc_signature: * * This method creates a runtime objc signature which can be used * to describe type for a selector *on this machine* (you need this - * signature for example to insert a method description in a method list, - * using the ObjcUtilities_insert_method_in_list function above). + * signature for example to add a method to a class. * * It takes as argument a 'naive' objc signature, in the form of * a string obtained by concatenating the following strings: @@ -148,24 +126,10 @@ void ObjcUtilities_insert_method_in_list (MethodList *ml, * * On my machine, ObjcUtilities_build_runtime_Objc_signature ("i@:@") * returns "i12@0:4@8", which I can then use as selector type when - * creating entries in MethodList. + * adding a method to a class. * */ const char *ObjcUtilities_build_runtime_Objc_signature (const char *); -/* - * ObjcUtilities_register_method_list: - * - * Add the list `ml' of methods to an existing Class `class'. - * They are registered as instance methods. - * To add class methods, you simply need to pass the meta class - * [(Class)class->class_pointer] instead of the class. - * - * *Never* release or modify a method list after registering it with - * *the objective-C runtime. - */ - -void ObjcUtilities_register_method_list (Class class, MethodList *ml); - #endif /* __ObjcRuntimeUtilitis_h_GNUSTEP_RUBY_INCLUDE */ diff --git a/Source/ObjcRuntimeUtilities.m b/Source/ObjcRuntimeUtilities.m index d8a01e7..ecc78b0 100644 --- a/Source/ObjcRuntimeUtilities.m +++ b/Source/ObjcRuntimeUtilities.m @@ -39,189 +39,90 @@ * Objective-C runtime you are using. You can find this in the file * 'init.c' in the GNU objective-C runtime source. */ -#define OBJC_VERSION 8 - -#include "ObjcRuntimeUtilities.h" +#import "ObjcRuntimeUtilities.h" +#import #include -#ifndef objc_EXPORT -#if libobjc_ISDLL /* linking against DLL version of libobjc */ -# define objc_EXPORT extern __declspec(dllimport) -#else -# define objc_EXPORT extern -#endif -#endif - -BOOL ObjcUtilities_new_class (const char *name, - const char *superclassName, - int ivarNumber, ...) +BOOL ObjcUtilities_new_class(const char *name, + const char *superclassName, + int ivarNumber, ...) { - objc_EXPORT void __objc_exec_class (void *module); - objc_EXPORT void __objc_resolve_class_links (); - Module_t module; - Symtab_t symtab; - Class super_class; - Class new_class; - int ivarsize; - // - // Check that the name for the new class isn't already in use. - // - if (objc_lookup_class (name) != nil) - { - return NO; - } + NSValue *classPointer = nil; + NSArray *classes = nil; + NSMutableDictionary *ivarDictionary = [NSMutableDictionary dictionary]; + NSString *className = [NSString stringWithUTF8String: name]; + NSString *superClassName = [NSString stringWithUTF8String: superclassName]; - // - // Check that the superclass exists. - // - super_class = objc_lookup_class (superclassName); - if (super_class == nil) + if (objc_getClass (name) != Nil || objc_getClass (superclassName) == Nil) { return NO; } - - // - // Prepare a fake module containing only this class. - // - module = objc_calloc (1, sizeof (Module)); - module->version = OBJC_VERSION; - module->size = sizeof (Module); - module->name = objc_malloc (strlen (name) + 15); - strcpy ((char*)module->name, "GNUstep-Proxy-"); - strcat ((char*)module->name, name); - module->symtab = objc_calloc (1, sizeof (Symtab)); - symtab = module->symtab; - symtab->sel_ref_cnt = 0; - symtab->refs = 0; - symtab->cls_def_cnt = 1; // We are defining a single class. - symtab->cat_def_cnt = 0; // But no categories - // Allocate space for two classes (the class and its meta class) - symtab->defs[0] = objc_calloc (2, sizeof (struct objc_class)); - symtab->defs[1] = 0; // NULL terminate the list. - - // - // Build class structure. - // - - // Class - new_class = (Class)symtab->defs[0]; - - // NB: There is a trick here. - // The runtime system will look up the name in the following string, - // and replace it with a pointer to the actual superclass structure. - // This also means the type of pointer will change, that's why we - // need to force it with a (void *) - new_class->super_class = (void *)superclassName; - - new_class->name = objc_malloc (strlen (name) + 1); - strcpy ((char*)new_class->name, name); - new_class->version = 0; - new_class->info = _CLS_CLASS; - ivarsize = super_class->instance_size; - + // Build ivar dictionary.... if (ivarNumber > 0) { - // Prepare ivars va_list ap; - struct objc_ivar *ivar; - int size, i; - - size = sizeof (struct objc_ivar_list); - size += (ivarNumber - 1) * sizeof (struct objc_ivar); - - new_class->ivars = (struct objc_ivar_list*) objc_malloc (size); - new_class->ivars->ivar_count = ivarNumber; - - va_start (ap, ivarNumber); - - ivar = new_class->ivars->ivar_list; + int i = 0; + // Prepare ivars + va_start(ap, ivarNumber); for (i = 0; i < ivarNumber; i++) { - char *name = strdup (va_arg (ap, char *)); - char *type = strdup (va_arg (ap, char *)); - - int align; - - ivar->ivar_name = name; - ivar->ivar_type = type; - - align = objc_alignof_type (ivar->ivar_type); // pad to alignment - ivarsize = align * ((ivarsize + align - 1) /align); // ROUND - ivar->ivar_offset = ivarsize; - ivarsize += objc_sizeof_type (ivar->ivar_type); - ivar++; + const char *ivarNameCString = va_arg (ap, char *); + const char *ivarTypeCString = va_arg (ap, char *); + NSString *ivarName = [NSString stringWithUTF8String: ivarNameCString]; + NSString *ivarType = [NSString stringWithUTF8String: ivarTypeCString]; + + [ivarDictionary setObject: ivarType + forKey: ivarName]; } - va_end (ap); + va_end(ap); } - - new_class->instance_size = ivarsize; - - // Meta class - new_class->class_pointer = &new_class[1]; - new_class->class_pointer->super_class = (void *)superclassName; - new_class->class_pointer->name = new_class->name; - new_class->class_pointer->version = 0; - new_class->class_pointer->info = _CLS_META; - new_class->class_pointer->instance_size - = super_class->class_pointer->instance_size; - - // Insert our new class into the runtime. - __objc_exec_class (module); - __objc_resolve_class_links(); - - return YES; -} -MethodList *ObjcUtilities_alloc_method_list (int count) -{ - MethodList *ml; - int extra; + classPointer = GSObjCMakeClass(className, + superClassName, + ivarDictionary); - extra = (sizeof (struct objc_method)) * (count - 1); - ml = objc_calloc (1, sizeof(MethodList) + extra); - ml->method_count = count; - return ml; -} + if (classPointer == nil) + { + return NO; + } -void ObjcUtilities_insert_method_in_list (MethodList *ml, - int index, const char *name, - const char *types, IMP imp) -{ - Method *method; + classes = [NSArray arrayWithObject: classPointer]; + GSObjCAddClasses(classes); - method = &(ml->method_list[index]); - method->method_name = (void *)strdup (name); - method->method_types = strdup (types); - method->method_imp = imp; + return (objc_getClass (name) != Nil); } -const char *ObjcUtilities_build_runtime_Objc_signature (const char - *types) +BOOL ObjcUtilities_add_method(Class class, + const char *name, + const char *types, + IMP imp) { - NSMethodSignature *sig; + SEL selector; - sig = [NSMethodSignature signatureWithObjCTypes: types]; + selector = GSSelectorFromNameAndTypes(name, types); + if (selector == NULL) + { + selector = sel_registerName(name); + } -#if defined GNUSTEP_BASE_VERSION || defined(LIB_FOUNDATION_LIBRARY) - return [sig methodType]; -#else -# error "Don't know how to get method signature on this platform!" -#endif + return class_addMethod(class, selector, imp, types); } -void ObjcUtilities_register_method_list (Class class, MethodList *ml) +const char *ObjcUtilities_build_runtime_Objc_signature(const char *types) { - objc_EXPORT void class_add_method_list (Class class, MethodList_t list); - objc_EXPORT objc_mutex_t __objc_runtime_mutex; + NSMethodSignature *sig; - objc_mutex_lock (__objc_runtime_mutex); - class_add_method_list (class, ml); - objc_mutex_unlock (__objc_runtime_mutex); -} + sig = [NSMethodSignature signatureWithObjCTypes: types]; + if (sig == nil) + { + return NULL; + } + return types; +} diff --git a/Source/RIGSCore.h b/Source/RIGSCore.h index cde44ff..7d04bbf 100644 --- a/Source/RIGSCore.h +++ b/Source/RIGSCore.h @@ -32,11 +32,21 @@ // After inclusion of ruby.h undefine the "_" macro because // it is also defined in Foundation/NSBundle.h #include "ruby.h" +#ifndef STR2CSTR +static inline char *RIGSStringValueCStr(VALUE value) +{ + return (char *)StringValueCStr(value); +} +#define STR2CSTR(value) RIGSStringValueCStr(value) +#endif +#ifdef rb_argv +#undef rb_argv +#endif #undef _ #undef __ -char **ourargv; -int ourargc; +extern char **ourargv; +extern int ourargc; void rb_objc_release(id objc_object); void rb_objc_mark(VALUE rb_object); diff --git a/Source/RIGSCore.m b/Source/RIGSCore.m index a7be5d7..b289325 100644 --- a/Source/RIGSCore.m +++ b/Source/RIGSCore.m @@ -37,7 +37,10 @@ #ifdef GNUSTEP +#include +#include #include +#include #define ROUND(V, A) \ ({ typeof(V) __v=(V); typeof(A) __a=(A); \ @@ -116,6 +119,12 @@ If false then Ruby must use selector("...") and an NSSelector #define IS_NUMBER_AUTOCONVERT_ON() \ (numberAutoConvert == Qtrue) +static const char * +RIGSObjCSkipTypeQualifiers(const char *type) +{ + return objc_skip_type_qualifiers(type); +} + /* Define a couple of macros to get/set Ruby CStruct objects (CStruct class is the Ruby equivalent of the C structure */ @@ -176,7 +185,7 @@ If false then Ruby must use selector("...") and an NSSelector VALUE new_rb_object; // get the class from the objc_class class variable now - Class objc_class = (Class) NUM2UINT(rb_iv_get(rb_class, "@objc_class")); + Class objc_class = (Class) NUM2ULONG(rb_iv_get(rb_class, "@objc_class")); // This object is not released on purpose. The Ruby garbage collector // will take care of deallocating it by calling rb_objc_release() @@ -198,9 +207,11 @@ If false then Ruby must use selector("...") and an NSSelector BOOL ret = YES; Class objcClass; NSString *msg; + const char *originalType = type; VALUE rb_class_val; int idx = 0; BOOL inStruct = NO; + type = RIGSObjCSkipTypeQualifiers(type); // If Ruby gave the NIL value then bypass all the rest @@ -222,16 +233,17 @@ If false then Ruby must use selector("...") and an NSSelector do { - int align = objc_alignof_type(type); /* pad to alignment */ + const char *componentType = RIGSObjCSkipTypeQualifiers(type); + int align = objc_alignof_type(componentType); /* pad to alignment */ void *where; VALUE rb_val; offset = ROUND(offset, align); where = data + offset; - offset += objc_sizeof_type(type); + offset += objc_sizeof_type(componentType); NSDebugLog(@"Converting Ruby value (0x%lx, type 0x%02lx) to ObjC value of type '%c' at target address 0x%lx)", - rb_thing, TYPE(rb_thing),*type,where); + rb_thing, TYPE(rb_thing),*componentType,where); if (inStruct) { rb_val = RB_CSTRUCT_ENTRY(rb_thing,idx); @@ -241,7 +253,7 @@ If false then Ruby must use selector("...") and an NSSelector } // All other cases - switch (*type) { + switch (*componentType) { case _C_ID: case _C_CLASS: @@ -249,7 +261,7 @@ If false then Ruby must use selector("...") and an NSSelector switch (TYPE(rb_val)) { case T_DATA: - Data_Get_Struct(rb_val,id,* (id*)where); + *(id*)where = (id)DATA_PTR(rb_val); /* Automatic conversion from string -- see below _C_SEL case if ([ret class] == [NSSelector class]) { @@ -328,7 +340,7 @@ If false then Ruby must use selector("...") and an NSSelector // This is in case the selector is passed as an instance of NSSelector // which is a class the we have created id object; - Data_Get_Struct(rb_val,id,object); + object = (id)DATA_PTR(rb_val); if ([object isKindOfClass: [NSSelector class]]) { *(SEL*)where = [object getSEL]; } else { @@ -400,14 +412,28 @@ If false then Ruby must use selector("...") and an NSSelector case _C_LNG: if (TYPE(rb_val) == T_FIXNUM || TYPE(rb_val) == T_BIGNUM ) - *(long*)where = (long) NUM2INT(rb_val); + *(long*)where = NUM2LONG(rb_val); else ret = NO; break; case _C_ULNG: if (TYPE(rb_val) == T_FIXNUM || TYPE(rb_val) == T_BIGNUM ) - *(unsigned long*)where = (unsigned long) NUM2INT(rb_val); + *(unsigned long*)where = NUM2ULONG(rb_val); + else + ret = NO; + break; + + case _C_LNG_LNG: + if (TYPE(rb_val) == T_FIXNUM || TYPE(rb_val) == T_BIGNUM ) + *(long long*)where = NUM2LL(rb_val); + else + ret = NO; + break; + + case _C_ULNG_LNG: + if (TYPE(rb_val) == T_FIXNUM || TYPE(rb_val) == T_BIGNUM ) + *(unsigned long long*)where = NUM2ULL(rb_val); else ret = NO; break; @@ -450,13 +476,13 @@ If false then Ruby must use selector("...") and an NSSelector s = STR2CSTR(rb_val); l = strlen(s)+1; - d = [NSMutableData dataWithBytesNoCopy: s length: l]; + d = [NSMutableData dataWithBytes: s length: l]; *(char**)where = (char*)[d mutableBytes]; } else if (TYPE(rb_val) == T_DATA) { // I guess this is the right thing to do. Pass the // embedded ObjC as a blob - Data_Get_Struct(rb_val,char* ,* (char**)where); + *(char**)where = (char*)DATA_PTR(rb_val); } else { ret = NO; } @@ -473,7 +499,7 @@ If false then Ruby must use selector("...") and an NSSelector s = STR2CSTR(rb_val); l = strlen(s); - d = [NSMutableData dataWithBytesNoCopy: s length: l]; + d = [NSMutableData dataWithBytes: s length: l]; *(void**)where = (void*)[d mutableBytes]; } else if (TYPE(rb_val) == T_DATA) { @@ -493,7 +519,7 @@ If false then Ruby must use selector("...") and an NSSelector // The Ruby argument must be of type CStruct or a sub-class of it if (rb_obj_is_kind_of(rb_val, RB_CSTRUCT_CLASS) == Qtrue) { - if ( rb_objc_convert_to_objc(rb_val, where, 0, type) == NO) { + if ( rb_objc_convert_to_objc(rb_val, where, 0, componentType) == NO) { // if something went wrong in the conversion just return Qnil rb_val = Qnil; ret = NO; @@ -513,13 +539,13 @@ If false then Ruby must use selector("...") and an NSSelector } // skip the component we have just processed - type = objc_skip_typespec(type); + type = objc_skip_typespec(componentType); } while (inStruct && *type != _C_STRUCT_E); if (ret == NO) { /* raise exception - Don't know how to handle this type of argument */ - msg = [NSString stringWithFormat: @"Don't know how to convert Ruby type 0x%02x in ObjC type '%c'", TYPE(rb_thing), *type]; + msg = [NSString stringWithFormat: @"Don't know how to convert Ruby type 0x%02x in ObjC type '%s'", TYPE(rb_thing), originalType]; NSDebugLog(msg); rb_raise(rb_eTypeError, [msg cString]); } @@ -538,6 +564,7 @@ If false then Ruby must use selector("...") and an NSSelector NSSelector *selObj; BOOL inStruct = NO; VALUE end = Qnil; + type = RIGSObjCSkipTypeQualifiers(type); if (*type == _C_STRUCT_B) { @@ -558,17 +585,18 @@ If false then Ruby must use selector("...") and an NSSelector do { VALUE rb_val; - int align = objc_alignof_type (type); /* pad to alignment */ + const char *componentType = RIGSObjCSkipTypeQualifiers(type); + int align = objc_alignof_type (componentType); /* pad to alignment */ void *where; NSDebugLog(@"Converting ObjC value (0x%lx) of type '%c' to Ruby value", - *(id*)data, *type); + *(id*)data, *componentType); offset = ROUND(offset, align); where = data + offset; - offset += objc_sizeof_type(type); + offset += objc_sizeof_type(componentType); - switch (*type) + switch (*componentType) { case _C_ID: { id val = *(id*)where; @@ -601,11 +629,11 @@ If false then Ruby must use selector("...") and an NSSelector // to its type const char *tmptype = [val objCType]; int tmpsize = objc_sizeof_type(tmptype); - struct dummy { char val[tmpsize]; } block; + void *block = alloca(tmpsize); - [val getValue: (void *)&block]; + [val getValue: block]; - rb_objc_convert_to_rb(&block, 0, tmptype, &rb_val); + rb_objc_convert_to_rb(block, 0, tmptype, &rb_val); } else { @@ -684,7 +712,15 @@ object by calling rb_objc_release() break; case _C_ULNG: - rb_val = INT2FIX(*(unsigned long*)where); + rb_val = ULONG2NUM(*(unsigned long*)where); + break; + + case _C_LNG_LNG: + rb_val = LL2NUM(*(long long*)where); + break; + + case _C_ULNG_LNG: + rb_val = ULL2NUM(*(unsigned long long*)where); break; case _C_FLT: @@ -755,7 +791,7 @@ object by calling rb_objc_release() // We are attacking a new embedded structure in a structure - if ( rb_objc_convert_to_rb(where, 0, type, &rb_val) == NO) { + if ( rb_objc_convert_to_rb(where, 0, componentType, &rb_val) == NO) { // if something went wrong in the conversion just return Qnil rb_val = Qnil; ret = NO; @@ -765,7 +801,7 @@ object by calling rb_objc_release() break; default: - NSLog(@"Don't know how to convert ObjC type '%c' to Ruby VALUE",*type); + NSLog(@"Don't know how to convert ObjC type '%s' to Ruby VALUE", componentType); rb_val = Qnil; ret = NO; @@ -796,7 +832,7 @@ object by calling rb_objc_release() } // skip the type of the component we have just processed - type = (char*)objc_skip_typespec(type); + type = (char*)objc_skip_typespec(componentType); @@ -845,13 +881,13 @@ object by calling rb_objc_release() case T_DATA: NSDebugLog(@"Self Ruby value is 0x%lx (ObjC is at 0x%lx)",rb_self,DATA_PTR(rb_self)); - Data_Get_Struct(rb_self,id,rcv); + rcv = (id)DATA_PTR(rb_self); NSDebugLog(@"Self is an object of Class %@ (description is '%@')",NSStringFromClass([rcv class]),rcv); break; case T_CLASS: - rcv = (id) NUM2UINT(rb_iv_get(rb_self, "@objc_class")); + rcv = (id) NUM2ULONG(rb_iv_get(rb_self, "@objc_class")); NSDebugLog(@"Self is Class: %@", NSStringFromClass(rcv)); break; @@ -945,7 +981,7 @@ object by calling rb_objc_release() VALUE rb_objc_handler(int rb_argc, VALUE *rb_argv, VALUE rb_self) { - return rb_objc_send(rb_id2name(rb_frame_last_func()), rb_argc, rb_argv, rb_self); + return rb_objc_send((char *)rb_id2name(rb_frame_this_func()), rb_argc, rb_argv, rb_self); } VALUE @@ -956,7 +992,7 @@ object by calling rb_objc_release() VALUE rb_desc; // Invoke ObjC description method and always return a Ruby string - Data_Get_Struct(rb_self,id,rcv); + rcv = (id)DATA_PTR(rb_self); rb_desc = rb_str_new2([[rcv description] cString]); DESTROY(pool); @@ -967,7 +1003,7 @@ object by calling rb_objc_release() VALUE rb_objc_invoke(int rb_argc, VALUE *rb_argv, VALUE rb_self) { - char *method = rb_id2name(SYM2ID(rb_argv[0])); + char *method = (char *)rb_id2name(SYM2ID(rb_argv[0])); return rb_objc_send(method, rb_argc-1, rb_argv+1, rb_self); } @@ -975,7 +1011,7 @@ object by calling rb_objc_release() NSArray* class_method_selectors_for_class(Class class, BOOL use_super) { - Class meta_class = class_get_meta_class(class); + Class meta_class = object_getClass((id)class); return(method_selectors_for_class(meta_class, use_super)); } @@ -985,47 +1021,26 @@ object by calling rb_objc_release() return(method_selectors_for_class(class, use_super)); } -/* -This is to mimic a MACOSX function and have a single -method_selectors_for_class function for MACOSX and GNUstep -(see below) -*/ -static MethodList_t class_getNextMethodList( Class class, void ** iterator_ptr ) -{ - MethodList_t mlist; - - if (*iterator_ptr) { - mlist = ((MethodList_t) (*iterator_ptr) )->method_next; - } else { - mlist = class->methods; - } - - *iterator_ptr = (void *)mlist; - return mlist; - -} - NSArray* method_selectors_for_class(Class class, BOOL use_super) { - MethodList_t mlist; NSMutableSet *methodSet = [NSMutableSet new]; - int i; - void *iterator = NULL; + unsigned int i; while(class) { - - while( (mlist = class_getNextMethodList(class, &iterator)) != NULL) { - - for(i = 0; i < mlist->method_count; i++) { - SEL sel = mlist->method_list[i].method_name; - [methodSet addObject: NSStringFromSelector(sel)]; - //NSLog(@"method name %@",NSStringFromSelector(sel)); - } + Method *methods; + unsigned int methodCount; + + methods = class_copyMethodList(class, &methodCount); + for(i = 0; i < methodCount; i++) { + SEL sel = method_getName(methods[i]); + [methodSet addObject: NSStringFromSelector(sel)]; + //NSLog(@"method name %@",NSStringFromSelector(sel)); } + free(methods); if(use_super) - class = class->super_class; + class = class_getSuperclass(class); else class = NULL; } @@ -1042,7 +1057,7 @@ int rb_objc_register_instance_methods(Class objc_class, VALUE rb_class) int imth_cnt = 0; //Store the ObjcC Class id in the @@objc_class Ruby Class Variable - rb_iv_set(rb_class, "@objc_class", INT2NUM((int)objc_class)); + rb_iv_set(rb_class, "@objc_class", ULONG2NUM((unsigned long)objc_class)); /* Define all Ruby Instance methods for this Class */ allMthSels = method_selectors_for_class(objc_class, NO); @@ -1071,7 +1086,7 @@ int rb_objc_register_class_methods(Class objc_class, VALUE rb_class) NSEnumerator *mthEnum; NSString *mthSel; NSString *mthRubyName; - Class objc_meta_class = class_get_meta_class(objc_class); + Class objc_meta_class = object_getClass((id)objc_class); int cmth_cnt = 0; @@ -1424,11 +1439,11 @@ void _rb_objc_initialize_process_context(VALUE rb_argc, VALUE rb_argv) // Define the NSNotFound enum constant that is used all over the place // as a return value by Objective C methods - rb_define_global_const("NSNotFound", INT2FIX((int)NSNotFound)); - + rb_define_global_const("NSNotFound", LL2NUM((long long)NSNotFound)); + // Initialize Process Info and Main Bundle rb_argv = rb_gv_get("$*"); - rb_argc = INT2FIX(RARRAY(rb_argv)->len); + rb_argc = INT2FIX(RARRAY_LEN(rb_argv)); _rb_objc_initialize_process_context(rb_argc, rb_argv); diff --git a/Source/RIGSNSApplication.h b/Source/RIGSNSApplication.h index f6af08d..5ac6392 100644 --- a/Source/RIGSNSApplication.h +++ b/Source/RIGSNSApplication.h @@ -39,10 +39,7 @@ @end -typedef struct global_entry * global_entry_ptr; - VALUE _NSApplicationMainFromRuby(int arg_count, VALUE *arg_values, VALUE self); -VALUE _RIGS_get_NSApp (ID rb_id, VALUE *data, global_entry_ptr entry); -void _RIGS_set_NSApp (VALUE value, ID rb_id, VALUE *data, - global_entry_ptr entry); +VALUE _RIGS_get_NSApp (ID rb_id, VALUE *data); +void _RIGS_set_NSApp (VALUE value, ID rb_id, VALUE *data); #endif diff --git a/Source/RIGSNSApplication.m b/Source/RIGSNSApplication.m index e3b8da2..bb327e7 100644 --- a/Source/RIGSNSApplication.m +++ b/Source/RIGSNSApplication.m @@ -37,16 +37,16 @@ // Ruvy view of the NSApp global GNUstep variable static VALUE rb_NSApp = Qnil; -VALUE _RIGS_get_NSApp(ID rb_id, VALUE *data, global_entry_ptr entry) +VALUE _RIGS_get_NSApp(ID rb_id, VALUE *data) { DATA_PTR(rb_NSApp) = NSApp; return rb_NSApp; } -void _RIGS_set_NSApp(VALUE value, ID rb_id, VALUE *data, global_entry_ptr entry) +void _RIGS_set_NSApp(VALUE value, ID rb_id, VALUE *data) { - Data_Get_Struct(value, NSApplication, NSApp); + NSApp = (NSApplication *)DATA_PTR(value); DATA_PTR(rb_NSApp) = NSApp; NSDebugLog(@"Setting NSApp to 0x%lx", NSApp); diff --git a/Source/RIGSNSArray.m b/Source/RIGSNSArray.m index eb75339..9207063 100644 --- a/Source/RIGSNSArray.m +++ b/Source/RIGSNSArray.m @@ -65,7 +65,7 @@ + (id) arrayWithRubyArray: (RIGSWrapObject *) wrapped_ruby_array return nil; // Loop through the elements of the ruby array and generate a NSArray - count = RARRAY(ruby_array)->len; + count = RARRAY_LEN(ruby_array); gnustepObjects = malloc (sizeof (id) * count); if (gnustepObjects == NULL) { return nil; diff --git a/Source/RIGSProxyIMP.m b/Source/RIGSProxyIMP.m index 5564661..2bec97e 100644 --- a/Source/RIGSProxyIMP.m +++ b/Source/RIGSProxyIMP.m @@ -25,8 +25,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include -#include +#include +#include +#include +#include #include "RIGS.h" #include "RIGSCore.h" @@ -36,11 +38,124 @@ #include "RIGSWrapObject.h" #include "RIGSSelectorMapping.h" +static void +_RIGS_copy_objc_argument_from_varargs(va_list *ap, const char *type, void *dest) +{ + switch (*type) + { + case _C_ID: + { + id value = va_arg(*ap, id); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_CLASS: + { + Class value = va_arg(*ap, Class); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_SEL: + { + SEL value = va_arg(*ap, SEL); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_CHR: + { + char value = (char)va_arg(*ap, int); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_UCHR: + { + unsigned char value = (unsigned char)va_arg(*ap, int); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_SHT: + { + short value = (short)va_arg(*ap, int); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_USHT: + { + unsigned short value = (unsigned short)va_arg(*ap, int); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_INT: + { + int value = va_arg(*ap, int); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_UINT: + { + unsigned int value = va_arg(*ap, unsigned int); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_LNG: + { + long value = va_arg(*ap, long); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_ULNG: + { + unsigned long value = va_arg(*ap, unsigned long); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_LNG_LNG: + { + long long value = va_arg(*ap, long long); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_ULNG_LNG: + { + unsigned long long value = va_arg(*ap, unsigned long long); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_FLT: + { + float value = (float)va_arg(*ap, double); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_DBL: + { + double value = va_arg(*ap, double); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_CHARPTR: + { + char *value = va_arg(*ap, char *); + memcpy(dest, &value, sizeof(value)); + } + break; + case _C_PTR: + { + void *value = va_arg(*ap, void *); + memcpy(dest, &value, sizeof(value)); + } + break; + default: + memset(dest, 0, objc_sizeof_type(type)); + break; + } +} + #define COMMON_VAR_DECLARATION \ const char *type; \ const char *return_type; \ - Class class = (Class)(rcv->class_pointer); \ + Class class = object_getClass(rcv); \ const char *className; \ const char *rb_mth_name; \ int i; \ @@ -110,10 +225,10 @@ while (*type != '\0') { \ int size = objc_sizeof_type(type); \ { \ - struct dummy { char val[size]; } block; \ + void *block = alloca(size); \ int offset = 0; \ - block = va_arg(ap, struct dummy); \ - okydoky = rb_objc_convert_to_rb((void *) &block, offset, type, &rb_args[i]); \ + _RIGS_copy_objc_argument_from_varargs(&ap, type, block); \ + okydoky = rb_objc_convert_to_rb(block, offset, type, &rb_args[i]); \ } \ type = objc_skip_argspec (type); \ i++; } diff --git a/Source/RIGSProxySetup.m b/Source/RIGSProxySetup.m index a846c9b..22ab611 100644 --- a/Source/RIGSProxySetup.m +++ b/Source/RIGSProxySetup.m @@ -86,7 +86,6 @@ int _RIGS_ruby_method_arity(const char *rb_class_name, const char *rb_mth_name) Class _RIGS_register_ruby_class (VALUE rb_class) { CREATE_AUTORELEASE_POOL(pool); - MethodList *ml; int i; int count; VALUE listOption; @@ -117,7 +116,7 @@ Class _RIGS_register_ruby_class (VALUE rb_class) return nil; } - NSDebugLog (@"Registering Ruby class %s with the objective-C runtime", + NSDebugLog (@"Registering Ruby class %s with the Objective-C runtime", rb_class_name); // If this class has already been registered with ObjC then @@ -157,120 +156,124 @@ Class _RIGS_register_ruby_class (VALUE rb_class) listOption = INT2FIX(0); rb_mth_ary = rb_class_instance_methods(0,&listOption,rb_class); // number of instance methods in this class - count = RARRAY(rb_mth_ary)->len; + count = RARRAY_LEN(rb_mth_ary); NSDebugLog(@"This Ruby class has %d instance methods",count); // Prepare the instance methods list if (count > 0) { - - ml = ObjcUtilities_alloc_method_list (count); + for (i=0;i +#include #include #endif diff --git a/Testing/Base/NSArrayTest.rb b/Testing/Base/NSArrayTest.rb index 1fc190c..7f0ed79 100644 --- a/Testing/Base/NSArrayTest.rb +++ b/Testing/Base/NSArrayTest.rb @@ -204,7 +204,7 @@ def NSArrayTest.main puts "Now trying to clone () #{arrayOne}" arrayTwo = arrayOne.dup puts "Comparing the original array and its clone" - compare (arrayOne, arrayTwo, true) + compare(arrayOne, arrayTwo, true) puts # OK, then write it to a file and read it back. */ @@ -262,4 +262,3 @@ def NSArrayTest.main end NSArrayTest.main - diff --git a/Testing/Base/NSDictionaryTest.rb b/Testing/Base/NSDictionaryTest.rb index 1cb30fd..274d784 100644 --- a/Testing/Base/NSDictionaryTest.rb +++ b/Testing/Base/NSDictionaryTest.rb @@ -82,14 +82,14 @@ def NSDictionaryTest.main puts "Now testing removeObjectForKey ()" dictionaryOne = NSMutableDictionary.new - dictionaryOne.setObject_forKey ("value1", "key1") - if (!dictionaryOne.objectForKey ("key1").isEqual("value1")) + dictionaryOne.setObject_forKey("value1", "key1") + if (!dictionaryOne.objectForKey("key1").isEqual("value1")) puts "setObject_forKey didn't work" puts "==> test failed" exit 1 end - dictionaryOne.removeObjectForKey ("key1") - if (dictionaryOne.objectForKey ("key1") != nil) + dictionaryOne.removeObjectForKey("key1") + if (dictionaryOne.objectForKey("key1") != nil) puts "removeObjectForKey didn't work" puts "==> test failed" exit 1 @@ -108,7 +108,7 @@ def NSDictionaryTest.main GC.start dictionaryOne.removeObjectForKey("key1") - if (dictionaryOne.objectForKey ("key1") != nil) + if (dictionaryOne.objectForKey("key1") != nil) puts "removeObjectForKey didn't work" puts "==> test failed" exit 1 diff --git a/Testing/Gui/NSButtonTest.rb b/Testing/Gui/NSButtonTest.rb index 9994008..6b1b7b7 100644 --- a/Testing/Gui/NSButtonTest.rb +++ b/Testing/Gui/NSButtonTest.rb @@ -49,8 +49,8 @@ def applicationWillFinishLaunching (notification) styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask - @window.initWithContentRect_styleMask_backing_defer \ - (rect, styleMask, NSBackingStoreRetained, false) + @window.initWithContentRect_styleMask_backing_defer( + rect, styleMask, NSBackingStoreRetained, false) @window.setTitle("GNUstep") @window.setContentView (button) end diff --git a/Testing/Gui/NSButtonTest2.rb b/Testing/Gui/NSButtonTest2.rb index c6f60c9..c1f9668 100644 --- a/Testing/Gui/NSButtonTest2.rb +++ b/Testing/Gui/NSButtonTest2.rb @@ -55,8 +55,8 @@ def applicationWillFinishLaunching (notification) styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask - @window.initWithContentRect_styleMask_backing_defer \ - (rect, styleMask, NSBackingStoreRetained, false) + @window.initWithContentRect_styleMask_backing_defer( + rect, styleMask, NSBackingStoreRetained, false) @window.setTitle("GNUstep") @window.setContentView (button) end diff --git a/Testing/Gui/NSWindowTest.rb b/Testing/Gui/NSWindowTest.rb index e05aeb5..3c3e7f2 100644 --- a/Testing/Gui/NSWindowTest.rb +++ b/Testing/Gui/NSWindowTest.rb @@ -40,8 +40,8 @@ def applicationWillFinishLaunching (notification) styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask - @window.initWithContentRect_styleMask_backing_defer \ - (rect, styleMask, NSBackingStoreRetained, false) + @window.initWithContentRect_styleMask_backing_defer( + rect, styleMask, NSBackingStoreRetained, false) @window.setTitle("GNUstep GUI working from Ruby") end