From bb74d6f83920d0efa3cd9a1529f2a2baaaab8a5d Mon Sep 17 00:00:00 2001 From: CaS Date: Wed, 27 Nov 2002 12:52:29 +0000 Subject: [PATCH] Tidy more GNUstep extensions. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@15137 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 7 + Headers/gnustep/base/GSObjCRuntime.h | 308 +++++++ Headers/gnustep/base/NSObjCRuntime.h | 265 +----- Source/Additions/GCArray.m | 6 +- Source/Additions/GCDictionary.m | 6 +- Source/Additions/GNUmakefile | 1 + Source/Additions/GSObjCRuntime.m | 1276 ++++++++++++++++++++++++++ Source/GNUmakefile | 1 + Source/GSArray.m | 4 +- Source/GSCountedSet.m | 1 - Source/GSDictionary.m | 4 +- Source/GSFormat.m | 2 - Source/GSSet.m | 4 +- Source/GSString.m | 4 +- Source/NSArray.m | 1 - Source/NSCalendarDate.m | 4 +- Source/NSCoder.m | 1 - Source/NSCountedSet.m | 1 - Source/NSData.m | 4 +- Source/NSDate.m | 4 +- Source/NSDictionary.m | 1 - Source/NSObjCRuntime.m | 782 ---------------- Source/NSSet.m | 1 - Source/NSString.m | 2 - Source/NSURL.m | 1 - Source/NSURLHandle.m | 1 - 26 files changed, 1614 insertions(+), 1078 deletions(-) create mode 100644 Headers/gnustep/base/GSObjCRuntime.h create mode 100644 Source/Additions/GSObjCRuntime.m diff --git a/ChangeLog b/ChangeLog index 107b3c8f7..98147dcc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-11-27 Richard Frith-Macdonald + + * Source/Additions/GSObjCRuntime.m: New file with GNUstep extensions + from NSObjCRuntime, plus renamed behavior functions, plus a few other + runtime manipulation functions. EXPERIMENTAL + * Headers/gnustep/base/GSObjCRuntime.h: declarations for above. + 2002-11-26 Richard Frith-Macdonald * Source/Additions/GCObject.m: Attempt to make garbage collecting diff --git a/Headers/gnustep/base/GSObjCRuntime.h b/Headers/gnustep/base/GSObjCRuntime.h new file mode 100644 index 000000000..a2acc60eb --- /dev/null +++ b/Headers/gnustep/base/GSObjCRuntime.h @@ -0,0 +1,308 @@ +/** Interface to ObjC runtime for GNUStep + Copyright (C) 1995, 1997, 2000, 2002 Free Software Foundation, Inc. + + Written by: Andrew Kachites McCallum + Date: 1995 + Written by: Richard Frith-Macdonald + Date: 2002 + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + + AutogsdocSource: Additions/NSObjCRuntime.m + + */ + +#ifndef __GSObjCRuntime_h_GNUSTEP_BASE_INCLUDE +#define __GSObjCRuntime_h_GNUSTEP_BASE_INCLUDE + +#include +#include +#include + +#ifdef GNUSTEP_WITH_DLL + +#if BUILD_libgnustep_base_DLL +# define GS_EXPORT __declspec(dllexport) +# define GS_DECLARE __declspec(dllexport) +#else +# define GS_EXPORT extern __declspec(dllimport) +# define GS_DECLARE __declspec(dllimport) +#endif + +#else /* GNUSTEP_WITH[OUT]_DLL */ + +# define GS_EXPORT extern +# define GS_DECLARE + +#endif + +@class NSArray; +@class NSDictionary; +@class NSObject; +@class NSString; +@class NSValue; + +#ifndef YES +#define YES 1 +#endif +#ifndef NO +#define NO 0 +#endif +#ifndef nil +#define nil 0 +#endif + +#define FOUNDATION_EXPORT +#define FOUNDATION_STATIC_INLINE static inline + +#ifndef NO_GNUSTEP +/* + * Functions for accessing instance variables directly - + * We can copy an ivar into arbitrary data, + * Get the type encoding for a named ivar, + * and copy a value into an ivar. + */ +GS_EXPORT BOOL GSFindInstanceVariable(id obj, const char *name, + const char **type, unsigned int *size, int *offset); +GS_EXPORT void GSGetVariable(id obj, int offset, unsigned int size, void *data); +GS_EXPORT void GSSetVariable(id obj, int offset, unsigned int size, + const void *data); + +GS_EXPORT void GSObjCAddClassBehavior(Class receiver, Class behavior); + +GS_EXPORT NSValue* +GSObjCMakeClass(NSString *name, NSString *superName, NSDictionary *iVars); +GS_EXPORT void GSObjCAddClasses(NSArray *classes); + + + + +/* + * Functions for key-value encoding ... they access values in an object + * either by selector or directly, but do so using NSNumber for the + * scalar types of data. + */ +GS_EXPORT id GSGetValue(NSObject *self, NSString *key, SEL sel, + const char *type, unsigned size, int offset); +GS_EXPORT void GSSetValue(NSObject *self, NSString *key, id val, SEL sel, + const char *type, unsigned size, int offset); + +#include + +/* + * GSObjCClass() return the class of an instance. + * The argument to this function must NOT be nil. + */ +FOUNDATION_STATIC_INLINE Class +GSObjCClass(id obj) +{ + return obj->class_pointer; +} + +/* + * GSObjCIsInstance() tests to see if an id is an instance. + * The argument to this function must NOT be nil. + */ +FOUNDATION_STATIC_INLINE BOOL +GSObjCIsInstance(id obj) +{ + return CLS_ISCLASS(obj->class_pointer); +} + +/* + * GSObjCIsKindOf() tests to see if a class inherits from another class + * The argument to this function must NOT be nil. + */ +FOUNDATION_STATIC_INLINE BOOL +GSObjCIsKindOf(Class this, Class other) +{ + while (this != Nil) + { + if (this == other) + { + return YES; + } + this = class_get_super_class(this); + } + return NO; +} + +/** ## deprecated ## + */ +FOUNDATION_STATIC_INLINE const char* +GSObjCName(Class this) +{ + return class_get_class_name(this); +} + +/** ## deprecated ## + */ +FOUNDATION_STATIC_INLINE const char* +GSObjCSelectorName(SEL this) +{ + if (this == 0) + return 0; + return sel_get_name(this); +} + +/** ## deprecated ## + */ +FOUNDATION_STATIC_INLINE const char* +GSObjCSelectorTypes(SEL this) +{ + return sel_get_type(this); +} + +/** + * Given a class name, return the corresponding class or + * a nul pointer if the class cannot be found.
+ * If the argument is nil, return a nul pointer. + */ +FOUNDATION_STATIC_INLINE Class +GSClassFromName(const char *name) +{ + if (name == 0) + return 0; + return objc_lookup_class(name); +} + +/** + * Return the name of the supplied class, or a nul pointer if no class + * was supplied. + */ +FOUNDATION_STATIC_INLINE const char* +GSNameFromClass(Class this) +{ + if (this == 0) + return 0; + return class_get_class_name(this); +} + +/** + * Return the name of the supplied selector, or a nul pointer if no selector + * was supplied. + */ +FOUNDATION_STATIC_INLINE const char* +GSNameFromSelector(SEL this) +{ + if (this == 0) + return 0; + return sel_get_name(this); +} + +/** + * Return a selector matching the specified name, or nil if no name is + * supplied. The returned selector could be any one with the name.
+ * If no selector exists, returns nil. + */ +FOUNDATION_STATIC_INLINE SEL +GSSelectorFromName(const char *name) +{ + if (name == 0) + { + return 0; + } + else + { + return sel_get_any_uid(name); + } +} + +/** + * Return the selector for the specified name and types. Returns a nul + * pointer if the name is nul. Uses any available selector if the types + * argument is nul.
+ * Creates a new selector if necessary. + */ +FOUNDATION_STATIC_INLINE SEL +GSSelectorFromNameAndTypes(const char *name, const char *types) +{ + if (name == 0) + { + return 0; + } + else + { + SEL s; + + if (types == 0) + { + s = sel_get_any_typed_uid(name); + } + else + { + s = sel_get_typed_uid(name, types); + } + if (s == 0) + { + if (types == 0) + { + s = sel_register_name(name); + } + else + { + s = sel_register_typed_name(name, types); + } + } + return s; + } + +} + +/** + * Return the type information from the specified selector. + * May return a nul pointer if the selector was a nul pointer or if it + * was not typed. + */ +FOUNDATION_STATIC_INLINE const char* +GSTypesFromSelector(SEL this) +{ + if (this == 0) + return 0; + return sel_get_type(this); +} + + +FOUNDATION_STATIC_INLINE Class +GSObjCSuper(Class this) +{ + return class_get_super_class(this); +} + +FOUNDATION_STATIC_INLINE int +GSObjCVersion(Class this) +{ + return class_get_version(this); +} + +/* + * Return the zone in which an object belongs, without using the zone method + */ +#include +GS_EXPORT NSZone *GSObjCZone(NSObject *obj); + +/* + * Quickly return autoreleased data. + */ +void *_fastMallocBuffer(unsigned size); + +/* Getting a system error message on a variety of systems */ +GS_EXPORT const char *GSLastErrorStr(long error_id); + +#endif + +#endif /* __GSObjCRuntime_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/gnustep/base/NSObjCRuntime.h b/Headers/gnustep/base/NSObjCRuntime.h index ed777c3b6..d8e69f738 100644 --- a/Headers/gnustep/base/NSObjCRuntime.h +++ b/Headers/gnustep/base/NSObjCRuntime.h @@ -28,29 +28,7 @@ #ifndef __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE #define __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE -#include -#include -#include - -#ifdef GNUSTEP_WITH_DLL - -#if BUILD_libgnustep_base_DLL -# define GS_EXPORT __declspec(dllexport) -# define GS_DECLARE __declspec(dllexport) -#else -# define GS_EXPORT extern __declspec(dllimport) -# define GS_DECLARE __declspec(dllimport) -#endif - -#else /* GNUSTEP_WITH[OUT]_DLL */ - -# define GS_EXPORT extern -# define GS_DECLARE - -#endif - -@class NSObject; -@class NSString; +#include GS_EXPORT NSString *NSStringFromSelector(SEL aSelector); GS_EXPORT SEL NSSelectorFromString(NSString *aSelectorName); @@ -85,245 +63,4 @@ GS_EXPORT void NSLogv (NSString *format, va_list args); #define nil 0 #endif -#define FOUNDATION_EXPORT -#define FOUNDATION_STATIC_INLINE static inline - -#ifndef NO_GNUSTEP -/* - * Functions for accessing instance variables directly - - * We can copy an ivar into arbitrary data, - * Get the type encoding for a named ivar, - * and copy a value into an ivar. - */ -GS_EXPORT BOOL GSFindInstanceVariable(id obj, const char *name, - const char **type, unsigned int *size, int *offset); -GS_EXPORT void GSGetVariable(id obj, int offset, unsigned int size, void *data); -GS_EXPORT void GSSetVariable(id obj, int offset, unsigned int size, - const void *data); - -/* - * Functions for key-value encoding ... they access values in an object - * either by selector or directly, but do so using NSNumber for the - * scalar types of data. - */ -GS_EXPORT id GSGetValue(NSObject *self, NSString *key, SEL sel, - const char *type, unsigned size, int offset); -GS_EXPORT void GSSetValue(NSObject *self, NSString *key, id val, SEL sel, - const char *type, unsigned size, int offset); - -/* - * The following three functions are deprecated and will be removed in future - */ -GS_EXPORT BOOL GSInstanceVariableInfo(id obj, NSString *iVarName, - const char **type, unsigned *size, unsigned *offset); -GS_EXPORT BOOL GSGetInstanceVariable(id obj, NSString *name, void* data); -GS_EXPORT BOOL GSSetInstanceVariable(id obj, NSString *name, const void* data); - -#include - -/* - * GSObjCClass() return the class of an instance. - * The argument to this function must NOT be nil. - */ -FOUNDATION_STATIC_INLINE Class -GSObjCClass(id obj) -{ - return obj->class_pointer; -} - -/* - * GSObjCIsInstance() tests to see if an id is an instance. - * The argument to this function must NOT be nil. - */ -FOUNDATION_STATIC_INLINE BOOL -GSObjCIsInstance(id obj) -{ - return CLS_ISCLASS(obj->class_pointer); -} - -/* - * GSObjCIsKindOf() tests to see if a class inherits from another class - * The argument to this function must NOT be nil. - */ -FOUNDATION_STATIC_INLINE BOOL -GSObjCIsKindOf(Class this, Class other) -{ - while (this != Nil) - { - if (this == other) - { - return YES; - } - this = class_get_super_class(this); - } - return NO; -} - -/** ## deprecated ## - */ -FOUNDATION_STATIC_INLINE const char* -GSObjCName(Class this) -{ - return class_get_class_name(this); -} - -/** ## deprecated ## - */ -FOUNDATION_STATIC_INLINE const char* -GSObjCSelectorName(SEL this) -{ - if (this == 0) - return 0; - return sel_get_name(this); -} - -/** ## deprecated ## - */ -FOUNDATION_STATIC_INLINE const char* -GSObjCSelectorTypes(SEL this) -{ - return sel_get_type(this); -} - - - - -/** - * Given a class name, return the corresponding class or - * a nul pointer if the class cannot be found.
- * If the argument is nil, return a nul pointer. - */ -FOUNDATION_STATIC_INLINE Class -GSClassFromName(const char *name) -{ - if (name == 0) - return 0; - return objc_lookup_class(name); -} - -/** - * Return the name of the supplied class, or a nul pointer if no class - * was supplied. - */ -FOUNDATION_STATIC_INLINE const char* -GSNameFromClass(Class this) -{ - if (this == 0) - return 0; - return class_get_class_name(this); -} - -/** - * Return the name of the supplied selector, or a nul pointer if no selector - * was supplied. - */ -FOUNDATION_STATIC_INLINE const char* -GSNameFromSelector(SEL this) -{ - if (this == 0) - return 0; - return sel_get_name(this); -} - -/** - * Return a selector matching the specified name, or nil if no name is - * supplied. The returned selector could be any one with the name.
- * If no selector exists, returns nil. - */ -FOUNDATION_STATIC_INLINE SEL -GSSelectorFromName(const char *name) -{ - if (name == 0) - { - return 0; - } - else - { - return sel_get_any_uid(name); - } -} - -/** - * Return the selector for the specified name and types. Returns a nul - * pointer if the name is nul. Uses any available selector if the types - * argument is nul.
- * Creates a new selector if necessary. - */ -FOUNDATION_STATIC_INLINE SEL -GSSelectorFromNameAndTypes(const char *name, const char *types) -{ - if (name == 0) - { - return 0; - } - else - { - SEL s; - - if (types == 0) - { - s = sel_get_any_typed_uid(name); - } - else - { - s = sel_get_typed_uid(name, types); - } - if (s == 0) - { - if (types == 0) - { - s = sel_register_name(name); - } - else - { - s = sel_register_typed_name(name, types); - } - } - return s; - } - -} - -/** - * Return the type information from the specified selector. - * May return a nul pointer if the selector was a nul pointer or if it - * was not typed. - */ -FOUNDATION_STATIC_INLINE const char* -GSTypesFromSelector(SEL this) -{ - if (this == 0) - return 0; - return sel_get_type(this); -} - - -FOUNDATION_STATIC_INLINE Class -GSObjCSuper(Class this) -{ - return class_get_super_class(this); -} - -FOUNDATION_STATIC_INLINE int -GSObjCVersion(Class this) -{ - return class_get_version(this); -} - -/* - * Return the zone in which an object belongs, without using the zone method - */ -#include -GS_EXPORT NSZone *GSObjCZone(NSObject *obj); - -/* - * Quickly return autoreleased data. - */ -void *_fastMallocBuffer(unsigned size); - -/* Getting a system error message on a variety of systems */ -GS_EXPORT const char *GSLastErrorStr(long error_id); - -#endif - #endif /* __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Source/Additions/GCArray.m b/Source/Additions/GCArray.m index a55982b7c..3e844adbe 100644 --- a/Source/Additions/GCArray.m +++ b/Source/Additions/GCArray.m @@ -27,7 +27,7 @@ #include #include -#include +#include #include @implementation GCArray @@ -39,7 +39,7 @@ static Class gcClass = 0; if (gcClass == 0) { gcClass = [GCObject class]; - behavior_class_add_class(self, gcClass); + GSObjCAddClassBehavior(self, gcClass); } } @@ -210,7 +210,7 @@ static Class gcClass = 0; if (beenHere == NO) { beenHere = YES; - behavior_class_add_class(self, [GCArray class]); + GSObjCAddClassBehavior(self, [GCArray class]); } } diff --git a/Source/Additions/GCDictionary.m b/Source/Additions/GCDictionary.m index 2a33fd0ac..8ec78fe28 100644 --- a/Source/Additions/GCDictionary.m +++ b/Source/Additions/GCDictionary.m @@ -26,7 +26,7 @@ #include #include -#include +#include #include typedef struct { @@ -148,7 +148,7 @@ static Class gcClass = 0; if (gcClass == 0) { gcClass = [GCObject class]; - behavior_class_add_class(self, gcClass); + GSObjCAddClassBehavior(self, gcClass); } } @@ -350,7 +350,7 @@ static Class gcClass = 0; if (beenHere == NO) { beenHere = YES; - behavior_class_add_class(self, [GCDictionary class]); + GSObjCAddClassBehavior(self, [GCDictionary class]); } } diff --git a/Source/Additions/GNUmakefile b/Source/Additions/GNUmakefile index 6d5c95b77..009ceacd1 100644 --- a/Source/Additions/GNUmakefile +++ b/Source/Additions/GNUmakefile @@ -31,6 +31,7 @@ include $(GNUSTEP_MAKEFILES)/common.make SUBPROJECT_NAME=Additions Additions_OBJC_FILES =\ + GSObjCRuntime.m \ GCObject.m \ GCArray.m \ GCDictionary.m \ diff --git a/Source/Additions/GSObjCRuntime.m b/Source/Additions/GSObjCRuntime.m new file mode 100644 index 000000000..aa336cde5 --- /dev/null +++ b/Source/Additions/GSObjCRuntime.m @@ -0,0 +1,1276 @@ +/** Implementation of ObjC runtime additions for GNUStep + Copyright (C) 1995-2002 Free Software Foundation, Inc. + + Written by: Andrew Kachites McCallum + Date: Aug 1995 + Written by: Richard Frith-Macdonald + Date: Nov 2002 + Written by: Manuel Guesdon + Date: Nov 2002 + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + + GSObjCRuntime function and macro reference + $Date$ $Revision$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * This function is used to locate information about the instance + * variable of obj called name. It returns YES if the variable + * was found, NO otherwise. If it returns YES, then the values + * pointed to by type, size, and offset will be set (except where + * they are null pointers). + */ +BOOL +GSFindInstanceVariable(id obj, const char *name, + const char **type, unsigned int *size, int *offset) +{ + Class class; + struct objc_ivar_list *ivars; + struct objc_ivar *ivar = 0; + + class = [obj class]; + while (class != nil && ivar == 0) + { + ivars = class->ivars; + class = class->super_class; + if (ivars != 0) + { + int i; + + for (i = 0; i < ivars->ivar_count; i++) + { + if (strcmp(ivars->ivar_list[i].ivar_name, name) == 0) + { + ivar = &ivars->ivar_list[i]; + break; + } + } + } + } + if (ivar == 0) + { + return NO; + } + + if (type) + *type = ivar->ivar_type; + if (size) + *size = objc_sizeof_type(ivar->ivar_type); + if (offset) + *offset = ivar->ivar_offset; + return YES; +} + +/** + * This function performs no checking ... you should use it only where + * you are providing information from a call to GSFindInstanceVariable() + * and you know that the data area provided is the correct size. + */ +void +GSGetVariable(id obj, int offset, unsigned int size, void *data) +{ + memcpy(data, ((void*)obj) + offset, size); +} + +/** + * This function performs no checking ... you should use it only where + * you are providing information from a call to GSFindInstanceVariable() + * and you know that the data area provided is the correct size. + */ +void +GSSetVariable(id obj, int offset, unsigned int size, const void *data) +{ + memcpy(((void*)obj) + offset, data, size); +} + +/* + * NOTE - OBJC_VERSION needs to be defined to be the version of the + * 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 + +/** references: +http://www.macdevcenter.com/pub/a/mac/2002/05/31/runtime_parttwo.html?page=1 +http://developer.apple.com/techpubs/macosx/Cocoa/ObjectiveC/9objc_runtime_reference/_Adding_Classes.html +http://developer.apple.com/techpubs/macosx/Cocoa/ObjectiveC/9objc_runtime_reference/_Class_Defi__Structures.html +ObjcRuntimeUtilities.m by Nicola Pero +**/ + +/** + *

Create a Class structure for use by the ObjectiveC runtime and return + * an NSValue object pointing to it. The class will not be added to the + * runtime (you must do that later using the GSObjCAddClasses() function). + *

+ *

The iVars dictionary lists the instance variable names and their types. + *

+ */ +NSValue* +GSObjCMakeClass(NSString *name, NSString *superName, NSDictionary *iVars) +{ + Class newClass; + Class classSuperClass; + const char *classNameCString; + const char *superClassNameCString; + Class newMetaClass; + Class rootClass; + unsigned int iVarSize; + char *tmp; + + NSCAssert(name, @"no name"); + NSCAssert(superName, @"no superName"); + + classSuperClass = NSClassFromString(superName); + + NSCAssert1(classSuperClass, @"No class named %@",superName); + NSCAssert1(!NSClassFromString(name), @"A class %@ already exists", name); + + classNameCString = [name cString]; + tmp = objc_malloc(strlen(classNameCString) + 1); + strcpy(tmp, classNameCString); + classNameCString = tmp; + + superClassNameCString = [superName cString]; + tmp = objc_malloc(strlen(superClassNameCString) + 1); + strcpy(tmp, superClassNameCString); + superClassNameCString = tmp; + + rootClass = classSuperClass; + while (rootClass->super_class != 0) + { + rootClass = rootClass->super_class; + } + + /* + * Create new class and meta class structure storage + * + * From Nicola: 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 cast it. + */ + newMetaClass = objc_malloc(sizeof(struct objc_class)); + memset(newMetaClass, 0, sizeof(struct objc_class)); + newMetaClass->class_pointer = rootClass->class_pointer; // Points to root + newMetaClass->super_class = (Class)superClassNameCString; + newMetaClass->name = classNameCString; + newMetaClass->version = 0; + newMetaClass->info = _CLS_META; // this is a Meta Class + + + newClass = objc_malloc(sizeof(struct objc_class)); + memset(newClass, 0, sizeof(struct objc_class)); + newClass->class_pointer = newMetaClass; // Points to the class's meta class. + newClass->super_class = (Class)superClassNameCString; + newClass->name = classNameCString; + newClass->version = 0; + newClass->info = _CLS_CLASS; // this is a Class + + // work on instances variables + iVarSize = classSuperClass->instance_size; // super class ivar size + if ([iVars count] > 0) + { + unsigned int iVarsStructsSize; + struct objc_ivar *ivar = NULL; + unsigned int iVarsCount = [iVars count]; + NSEnumerator *enumerator = [iVars keyEnumerator]; + NSString *key; + + // ivars list is 1 objc_ivar_list followed by (iVarsCount-1) ivar_list + iVarsStructsSize = sizeof(struct objc_ivar_list) + + (iVarsCount-1)*sizeof(struct objc_ivar); + + // Allocate for all ivars + newClass->ivars = (struct objc_ivar_list*)objc_malloc(iVarsStructsSize); + memset(newClass->ivars, 0, iVarsStructsSize); + + // Set ivars count + newClass->ivars->ivar_count = iVarsCount; + + // initialize each ivar + ivar = newClass->ivars->ivar_list; // 1st one + while ((key = [enumerator nextObject]) != nil) + { + const char *iVarName = [key cString]; + const char *iVarType = [[iVars objectForKey: key] cString]; + + tmp = objc_malloc(strlen(iVarName) + 1); + strcpy(tmp, iVarName); + ivar->ivar_name = tmp; + tmp = objc_malloc(strlen(iVarType) + 1); + strcpy(tmp, iVarType); + ivar->ivar_type = tmp; + + // align the ivar (i.e. put it on the first aligned address + iVarSize = objc_aligned_size(ivar->ivar_type); + ivar->ivar_offset = iVarSize; + iVarSize += objc_sizeof_type(ivar->ivar_type); // add the ivar size + ivar = ivar + 1; + } + } + + /* + * Size in bytes of the class. The sum of the class definition + * and all super class definitions. + */ + newClass->instance_size = iVarSize; + + // Meta Class instance size is superclass instance size. + newMetaClass->instance_size = classSuperClass->class_pointer->instance_size; + + return [NSValue valueWithPointer: newClass]; +} + +/** + * The classes argument is an array of NSValue objects containing pointers + * to classes previously created by the GSObjCMakeClass() function. + */ +void +GSObjCAddClasses(NSArray *classes) +{ + void __objc_exec_class (Module_t module); + void __objc_resolve_class_links (); + Module_t module; + Symtab_t symtab; + unsigned int numClasses = [classes count]; + unsigned int i; + Class c; + + NSCAssert(numClasses > 0, @"No classes (array is NULL)"); + + c = (Class)[[classes objectAtIndex: 0] pointerValue]; + + // Prepare a fake module containing only the new classes + module = objc_calloc (1, sizeof (Module)); + module->version = OBJC_VERSION; + module->size = sizeof (Module); + module->name = objc_malloc (strlen(c->name) + 15); + strcpy ((char*)module->name, "GNUstep-Proxy-"); + strcat ((char*)module->name, c->name); + module->symtab = objc_malloc(sizeof(Symtab) + numClasses * sizeof(void *)); + + symtab = module->symtab; + symtab->sel_ref_cnt = 0; + symtab->refs = 0; + symtab->cls_def_cnt = numClasses; // We are defining numClasses classes. + symtab->cat_def_cnt = 0; // But no categories + + for (i = 0; i < numClasses; i++) + { + symtab->defs[i] = (Class)[[classes objectAtIndex: i] pointerValue]; + } + symtab->defs[numClasses] = NULL; //null terminated list + + // Insert our new class into the runtime. + __objc_exec_class (module); + __objc_resolve_class_links(); +} + + + +static int behavior_debug = 0; + +void +GSObjCBehaviorDebug(int i) +{ + behavior_debug = i; +} + +#if NeXT_RUNTIME + +static struct objc_method *search_for_method_in_list (Class class, SEL op); + +void +GSObjCAddMethods (Class class, struct objc_method_list *methods) +{ + static SEL initialize_sel = 0; + struct objc_method_list *mlist; + + if (!initialize_sel) + initialize_sel = sel_register_name ("initialize"); + + /* Add methods to class->dtable and class->methods */ + mlist = methods; + { + int counter; + struct objc_method_list *new_list; + + counter = mlist->method_count ? mlist->method_count - 1 : 1; + + /* This is a little wasteful of memory, since not necessarily + all methods will go in here. */ + new_list = (struct objc_method_list *) + objc_malloc (sizeof(struct objc_method_list) + + sizeof(struct objc_method[counter+1])); + new_list->method_count = 0; + + while (counter >= 0) + { + struct objc_method *method = &(mlist->method_list[counter]); + + if (behavior_debug) + { + fprintf(stderr, " processing method [%s] ... ", + sel_get_name(method->method_name)); + } + + if (!search_for_method_in_list(class,method->method_name) + && !sel_eq(method->method_name, initialize_sel)) + { + /* As long as the method isn't defined in the CLASS, + put the BEHAVIOR method in there. Thus, behavior + methods override the superclasses' methods. */ + new_list->method_list[new_list->method_count] = *method; + (new_list->method_count)++; + if (behavior_debug) + { + fprintf(stderr, "added.\n"); + } + } + else if (behavior_debug) + { + fprintf(stderr, "ignored.\n"); + } + counter -= 1; + } + if (new_list->method_count) + { + class_add_method_list(class, new_list); + } + else + { + OBJC_FREE(new_list); + } + } +} + +/* Search for the named method's method structure. Return a pointer + to the method's method structure if found. NULL otherwise. */ +static struct objc_method * +search_for_method_in_list (Class class, SEL op) +{ + void *iterator = 0; + struct objc_method_list *method_list; + + if (! sel_is_mapped (op)) + return NULL; + + /* If not found then we'll search the list. */ + while ( (method_list = class_nextMethodList(class, &iterator)) ) + { + int i; + + /* Search the method list. */ + for (i = 0; i < method_list->method_count; ++i) + { + struct objc_method *method = &method_list->method_list[i]; + + if (method->method_name) + { + if (sel_eq(method->method_name, op)) + return method; + } + } + } + + return NULL; +} + +#else /* GNU runtime */ + +/* + * The following two functions are implemented in the GNU objc runtime + */ +extern Method_t search_for_method_in_list(MethodList_t list, SEL op); +extern void class_add_method_list(Class, MethodList_t); + +void +GSObjCAddMethods (Class class, struct objc_method_list *methods) +{ + static SEL initialize_sel = 0; + struct objc_method_list *mlist; + + if (initialize_sel == 0) + { + initialize_sel = sel_register_name ("initialize"); + } + + /* Add methods to class->dtable and class->methods */ + for (mlist = methods; mlist; mlist = mlist->method_next) + { + int counter; + struct objc_method_list *new_list; + + counter = mlist->method_count ? mlist->method_count - 1 : 1; + + /* This is a little wasteful of memory, since not necessarily + all methods will go in here. */ + new_list = (struct objc_method_list *) + objc_malloc (sizeof(struct objc_method_list) + + sizeof(struct objc_method[counter+1])); + new_list->method_count = 0; + new_list->method_next = NULL; + + while (counter >= 0) + { + struct objc_method *method = &(mlist->method_list[counter]); + const char *name = sel_get_name(method->method_name); + + if (behavior_debug) + { + fprintf(stderr, " processing method [%s] ... ", name); + } + if (!search_for_method_in_list(class->methods, method->method_name) + && !sel_eq(method->method_name, initialize_sel)) + { + /* As long as the method isn't defined in the CLASS, + put the BEHAVIOR method in there. Thus, behavior + methods override the superclasses' methods. */ + new_list->method_list[new_list->method_count] = *method; + /* + * HACK ... the GNU runtime implementation of + * class_add_method_list() expects the method names to be + * C-strings rather than selectors ... so we must allow + * for that. + */ + new_list->method_list[new_list->method_count].method_name + = (SEL)name; + (new_list->method_count)++; + if (behavior_debug) + { + fprintf(stderr, "added.\n"); + } + } + else if (behavior_debug) + { + fprintf(stderr, "ignored.\n"); + } + counter -= 1; + } + if (new_list->method_count) + { + class_add_method_list(class, new_list); + } + else + { + OBJC_FREE(new_list); + } + } +} + +#endif /* NeXT runtime */ + +/** + *

A Behavior can be seen as a "Protocol with an implementation" or a + * "Class without any instance variables". A key feature of behaviors + * is that they give a degree of multiple inheritance. + *

+ *

Behavior methods, when added to a class, override the class's + * superclass methods, but not the class's methods. + *

+ *

It's not the case that a class adding behaviors from another class + * must have "no instance vars". The receiver class just has to have the + * same layout as the behavior class (optionally with some additional + * ivars after those of the behavior class). + *

+ *

This function provides Behaviors without adding any new syntax to + * the Objective C language. Simply define a class with the methods you + * want to add, then call this function with that class as the behavior + * argument. + *

+ *

This function should be called in the +initialize method of the receiver. + *

+ *

If you add several behaviors to a class, be aware that the order of + * the additions is significant. + *

+ */ +void +GSObjCAddClassBehavior(Class receiver, Class behavior) +{ + Class behavior_super_class = GSObjCSuper(behavior); + + NSCAssert(CLS_ISCLASS(receiver), NSInvalidArgumentException); + NSCAssert(CLS_ISCLASS(behavior), NSInvalidArgumentException); + +#if NeXT_RUNTIME + if (receiver->instance_size < behavior->instance_size) + { + /* We can allow this since we're pretty sure NXConstantString is + not subclassed. */ + if (receiver == [NXConstantString class]) + { + receiver->instance_size = behavior->instance_size; + } + else + NSCAssert2(receiver->instance_size >= behavior->instance_size, + @"Trying to add behavior (%s) with instance size larger than class (%s)", + class_get_class_name(behavior), class_get_class_name(receiver)); + } +#else + /* If necessary, increase instance_size of CLASS. */ + if (receiver->instance_size < behavior->instance_size) + { + NSCAssert(!receiver->subclass_list, + @"The behavior-addition code wants to increase the\n" + @"instance size of a class, but it cannot because you\n" + @"have subclassed the class. There are two solutions:\n" + @"(1) Don't subclass it; (2) Add placeholder instance\n" + @"variables to the class, so the behavior-addition code\n" + @"will not have to increase the instance size\n"); + receiver->instance_size = behavior->instance_size; + } +#endif + + if (behavior_debug) + { + fprintf(stderr, "Adding behavior to class %s\n", receiver->name); + } + + /* Add instance methods */ + if (behavior_debug) + { + fprintf(stderr, "Adding instance methods from %s\n", behavior->name); + } +#if NeXT_RUNTIME + { + void *iterator = 0; + struct objc_method_list *method_list; + + method_list = class_nextMethodList(behavior, &iterator); + while (method_list != 0) + { + GSObjCAddMethods (receiver, method_list); + method_list = class_nextMethodList(behavior, &iterator); + } + } +#else + GSObjCAddMethods (receiver, behavior->methods); +#endif + + /* Add class methods */ + if (behavior_debug) + { + fprintf(stderr, "Adding class methods from %s\n", + behavior->class_pointer->name); + } +#if NeXT_RUNTIME + { + void *iterator = 0; + struct objc_method_list *method_list; + + method_list = class_nextMethodList(behavior->class_pointer, &iterator); + while (method_list != 0) + { + GSObjCAddMethods (class->class_pointer, method_list); + method_list = class_nextMethodList(behavior->class_pointer, &iterator); + } + } +#else + GSObjCAddMethods (receiver->class_pointer, behavior->class_pointer->methods); +#endif + + /* Add behavior's superclass, if not already there. */ + if (!GSObjCIsKindOf(receiver, behavior_super_class)) + { + GSObjCAddClassBehavior (receiver, behavior_super_class); + } +} + + + + +#include +#include +/** + * This is used internally by the key-value coding methods, to get a + * value from an object either via an accessor method (if sel is + * supplied), or via direct access (if type, size, and offset are + * supplied).
+ * Automatic conversion between NSNumber and C scalar types is performed.
+ * If type is null and can't be determined from the selector, the + * [NSObject-handleQueryWithUnboundKey:] method is called to try + * to get a value. + */ +id +GSGetValue(NSObject *self, NSString *key, SEL sel, + const char *type, unsigned size, int offset) +{ + if (sel != 0) + { + NSMethodSignature *sig = [self methodSignatureForSelector: sel]; + + if ([sig numberOfArguments] != 2) + { + [NSException raise: NSInvalidArgumentException + format: @"key-value get method has wrong number of args"]; + } + type = [sig methodReturnType]; + } + if (type == NULL) + { + return [self handleQueryWithUnboundKey: key]; + } + else + { + id val = nil; + + switch (*type) + { + case _C_ID: + case _C_CLASS: + { + id v; + + if (sel == 0) + { + v = *(id *)((char *)self + offset); + } + else + { + id (*imp)(id, SEL) = + (id (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = v; + } + break; + + case _C_CHR: + { + signed char v; + + if (sel == 0) + { + v = *(char *)((char *)self + offset); + } + else + { + signed char (*imp)(id, SEL) = + (signed char (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithChar: v]; + } + break; + + case _C_UCHR: + { + unsigned char v; + + if (sel == 0) + { + v = *(unsigned char *)((char *)self + offset); + } + else + { + unsigned char (*imp)(id, SEL) = + (unsigned char (*)(id, SEL))[self methodForSelector: + sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithUnsignedChar: v]; + } + break; + + case _C_SHT: + { + short v; + + if (sel == 0) + { + v = *(short *)((char *)self + offset); + } + else + { + short (*imp)(id, SEL) = + (short (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithShort: v]; + } + break; + + case _C_USHT: + { + unsigned short v; + + if (sel == 0) + { + v = *(unsigned short *)((char *)self + offset); + } + else + { + unsigned short (*imp)(id, SEL) = + (unsigned short (*)(id, SEL))[self methodForSelector: + sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithUnsignedShort: v]; + } + break; + + case _C_INT: + { + int v; + + if (sel == 0) + { + v = *(int *)((char *)self + offset); + } + else + { + int (*imp)(id, SEL) = + (int (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithInt: v]; + } + break; + + case _C_UINT: + { + unsigned int v; + + if (sel == 0) + { + v = *(unsigned int *)((char *)self + offset); + } + else + { + unsigned int (*imp)(id, SEL) = + (unsigned int (*)(id, SEL))[self methodForSelector: + sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithUnsignedInt: v]; + } + break; + + case _C_LNG: + { + long v; + + if (sel == 0) + { + v = *(long *)((char *)self + offset); + } + else + { + long (*imp)(id, SEL) = + (long (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithLong: v]; + } + break; + + case _C_ULNG: + { + unsigned long v; + + if (sel == 0) + { + v = *(unsigned long *)((char *)self + offset); + } + else + { + unsigned long (*imp)(id, SEL) = + (unsigned long (*)(id, SEL))[self methodForSelector: + sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithUnsignedLong: v]; + } + break; + +#ifdef _C_LNG_LNG + case _C_LNG_LNG: + { + long long v; + + if (sel == 0) + { + v = *(long long *)((char *)self + offset); + } + else + { + long long (*imp)(id, SEL) = + (long long (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithLongLong: v]; + } + break; +#endif + +#ifdef _C_ULNG_LNG + case _C_ULNG_LNG: + { + unsigned long long v; + + if (sel == 0) + { + v = *(unsigned long long *)((char *)self + offset); + } + else + { + unsigned long long (*imp)(id, SEL) = + (unsigned long long (*)(id, SEL))[self + methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithUnsignedLongLong: v]; + } + break; +#endif + + case _C_FLT: + { + float v; + + if (sel == 0) + { + v = *(float *)((char *)self + offset); + } + else + { + float (*imp)(id, SEL) = + (float (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithFloat: v]; + } + break; + + case _C_DBL: + { + double v; + + if (sel == 0) + { + v = *(double *)((char *)self + offset); + } + else + { + double (*imp)(id, SEL) = + (double (*)(id, SEL))[self methodForSelector: sel]; + + v = (*imp)(self, sel); + } + val = [NSNumber numberWithDouble: v]; + } + break; + + case _C_VOID: + { + void (*imp)(id, SEL) = + (void (*)(id, SEL))[self methodForSelector: sel]; + + (*imp)(self, sel); + } + val = nil; + break; + + default: + [NSException raise: NSInvalidArgumentException + format: @"key-value get method has unsupported type"]; + } + return val; + } +} + +/** + * This is used internally by the key-value coding methods, to set a + * value in an object either via an accessor method (if sel is + * supplied), or via direct access (if type, size, and offset are + * supplied).
+ * Automatic conversion between NSNumber and C scalar types is performed.
+ * If type is null and can't be determined from the selector, the + * [NSObject-handleTakeValue:forUnboundKey:] method is called to try + * to set a value. + */ +void +GSSetValue(NSObject *self, NSString *key, id val, SEL sel, + const char *type, unsigned size, int offset) +{ + if (sel != 0) + { + NSMethodSignature *sig = [self methodSignatureForSelector: sel]; + + if ([sig numberOfArguments] != 3) + { + [NSException raise: NSInvalidArgumentException + format: @"key-value set method has wrong number of args"]; + } + type = [sig getArgumentTypeAtIndex: 2]; + } + if (type == NULL) + { + [self handleTakeValue: val forUnboundKey: key]; + } + else + { + switch (*type) + { + case _C_ID: + case _C_CLASS: + { + id v = val; + + if (sel == 0) + { + id *ptr = (id *)((char *)self + offset); + + [*ptr autorelease]; + *ptr = [v retain]; + } + else + { + void (*imp)(id, SEL, id) = + (void (*)(id, SEL, id))[self methodForSelector: sel]; + + (*imp)(self, sel, val); + } + } + break; + + case _C_CHR: + { + char v = [val charValue]; + + if (sel == 0) + { + char *ptr = (char *)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, char) = + (void (*)(id, SEL, char))[self methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_UCHR: + { + unsigned char v = [val unsignedCharValue]; + + if (sel == 0) + { + unsigned char *ptr = (unsigned char*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, unsigned char) = + (void (*)(id, SEL, unsigned char))[self methodForSelector: + sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_SHT: + { + short v = [val shortValue]; + + if (sel == 0) + { + short *ptr = (short*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, short) = + (void (*)(id, SEL, short))[self methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_USHT: + { + unsigned short v = [val unsignedShortValue]; + + if (sel == 0) + { + unsigned short *ptr; + + ptr = (unsigned short*)((char *)self + offset); + *ptr = v; + } + else + { + void (*imp)(id, SEL, unsigned short) = + (void (*)(id, SEL, unsigned short))[self methodForSelector: + sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_INT: + { + int v = [val intValue]; + + if (sel == 0) + { + int *ptr = (int*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, int) = + (void (*)(id, SEL, int))[self methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_UINT: + { + unsigned int v = [val unsignedIntValue]; + + if (sel == 0) + { + unsigned int *ptr = (unsigned int*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, unsigned int) = + (void (*)(id, SEL, unsigned int))[self methodForSelector: + sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_LNG: + { + long v = [val longValue]; + + if (sel == 0) + { + long *ptr = (long*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, long) = + (void (*)(id, SEL, long))[self methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_ULNG: + { + unsigned long v = [val unsignedLongValue]; + + if (sel == 0) + { + unsigned long *ptr = (unsigned long*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, unsigned long) = + (void (*)(id, SEL, unsigned long))[self methodForSelector: + sel]; + + (*imp)(self, sel, v); + } + } + break; + +#ifdef _C_LNG_LNG + case _C_LNG_LNG: + { + long long v = [val longLongValue]; + + if (sel == 0) + { + long long *ptr = (long long*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, long long) = + (void (*)(id, SEL, long long))[self methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; +#endif + +#ifdef _C_ULNG_LNG + case _C_ULNG_LNG: + { + unsigned long long v = [val unsignedLongLongValue]; + + if (sel == 0) + { + unsigned long long *ptr = (unsigned long long*)((char*)self + + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, unsigned long long) = + (void (*)(id, SEL, unsigned long long))[self + methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; +#endif + + case _C_FLT: + { + float v = [val floatValue]; + + if (sel == 0) + { + float *ptr = (float*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, float) = + (void (*)(id, SEL, float))[self methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; + + case _C_DBL: + { + double v = [val doubleValue]; + + if (sel == 0) + { + double *ptr = (double*)((char *)self + offset); + + *ptr = v; + } + else + { + void (*imp)(id, SEL, double) = + (void (*)(id, SEL, double))[self methodForSelector: sel]; + + (*imp)(self, sel, v); + } + } + break; + + default: + [NSException raise: NSInvalidArgumentException + format: @"key-value set method has unsupported type"]; + } + } +} + + + +/* Getting a system error message on a variety of systems */ +#ifdef __MINGW__ +LPTSTR GetErrorMsg(DWORD msgId) +{ + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, msgId, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&lpMsgBuf, 0, NULL); + + return (LPTSTR)lpMsgBuf; +} +#else +#ifndef HAVE_STRERROR +const char* +strerror(int eno) +{ + extern char* sys_errlist[]; + extern int sys_nerr; + + if (eno < 0 || eno >= sys_nerr) + { + return("unknown error number"); + } + return(sys_errlist[eno]); +} +#endif +#endif /* __MINGW__ */ + +const char * +GSLastErrorStr(long error_id) +{ +#ifdef __MINGW__ + return GetErrorMsg(GetLastError()); +#else + return strerror(error_id); +#endif +} diff --git a/Source/GNUmakefile b/Source/GNUmakefile index cae3ed5c7..b216c5353 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -119,6 +119,7 @@ DistributedObjects.h \ GCObject.h \ GSFileHandle.h \ GSLocale.h \ +GSObjCRuntime.h \ GSUnion.h \ GSIArray.h \ GSIMap.h \ diff --git a/Source/GSArray.m b/Source/GSArray.m index f6856680b..b3b449297 100644 --- a/Source/GSArray.m +++ b/Source/GSArray.m @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -327,7 +327,7 @@ static SEL eqSel; if (self == [GSMutableArray class]) { [self setVersion: 1]; - behavior_class_add_class(self, [GSArray class]); + GSObjCAddClassBehavior(self, [GSArray class]); } } diff --git a/Source/GSCountedSet.m b/Source/GSCountedSet.m index 790825bb1..54a777be0 100644 --- a/Source/GSCountedSet.m +++ b/Source/GSCountedSet.m @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/Source/GSDictionary.m b/Source/GSDictionary.m index b5ea34a19..f1afb8910 100644 --- a/Source/GSDictionary.m +++ b/Source/GSDictionary.m @@ -31,7 +31,7 @@ #include #include -#include +#include /* * The 'Fastmap' stuff provides an inline implementation of a mapping @@ -273,7 +273,7 @@ static SEL objSel; { if (self == [GSMutableDictionary class]) { - behavior_class_add_class(self, [GSDictionary class]); + GSObjCAddClassBehavior(self, [GSDictionary class]); } } diff --git a/Source/GSFormat.m b/Source/GSFormat.m index 661a3de8b..54dcb6153 100644 --- a/Source/GSFormat.m +++ b/Source/GSFormat.m @@ -98,8 +98,6 @@ typedef unsigned long long uintmax_t; #endif #endif -#include - #include struct printf_info diff --git a/Source/GSSet.m b/Source/GSSet.m index eae3aa8c6..0aaabe06a 100644 --- a/Source/GSSet.m +++ b/Source/GSSet.m @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -458,7 +458,7 @@ static Class mutableSetClass; { if (self == [GSMutableSet class]) { - behavior_class_add_class(self, [GSSet class]); + GSObjCAddClassBehavior(self, [GSSet class]); } } diff --git a/Source/GSString.m b/Source/GSString.m index 2dca428b1..b0fc6b330 100644 --- a/Source/GSString.m +++ b/Source/GSString.m @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include "GSPrivate.h" @@ -3608,7 +3608,7 @@ transmute(ivars self, NSString *aString) { if (self == [NXConstantString class]) { - behavior_class_add_class(self, [GSCString class]); + GSObjCAddClassBehavior(self, [GSCString class]); NSConstantStringClass = self; } } diff --git a/Source/NSArray.m b/Source/NSArray.m index 294b90a8e..7765ccbe7 100644 --- a/Source/NSArray.m +++ b/Source/NSArray.m @@ -30,7 +30,6 @@ */ #include -#include #include #include #include diff --git a/Source/NSCalendarDate.m b/Source/NSCalendarDate.m index 08dec3eef..70a4571b8 100644 --- a/Source/NSCalendarDate.m +++ b/Source/NSCalendarDate.m @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include @@ -302,7 +302,7 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day, absAbrIMP = (NSString* (*)(id,SEL,id)) [absClass instanceMethodForSelector: abrSEL]; - behavior_class_add_class(self, [NSGDate class]); + GSObjCAddClassBehavior(self, [NSGDate class]); } } diff --git a/Source/NSCoder.m b/Source/NSCoder.m index 6788397f9..da20055f0 100644 --- a/Source/NSCoder.m +++ b/Source/NSCoder.m @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/Source/NSCountedSet.m b/Source/NSCountedSet.m index ae64cee7c..0a303554e 100644 --- a/Source/NSCountedSet.m +++ b/Source/NSCountedSet.m @@ -25,7 +25,6 @@ */ #include -#include #include #include #include diff --git a/Source/NSData.m b/Source/NSData.m index 7f95a4fa5..427f7f54e 100644 --- a/Source/NSData.m +++ b/Source/NSData.m @@ -65,7 +65,7 @@ */ #include -#include +#include #include #include #include @@ -2878,7 +2878,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) { if (self == [NSMutableDataMalloc class]) { - behavior_class_add_class(self, [NSDataMalloc class]); + GSObjCAddClassBehavior(self, [NSDataMalloc class]); } } diff --git a/Source/NSDate.m b/Source/NSDate.m index bae509b1c..774dcebd4 100644 --- a/Source/NSDate.m +++ b/Source/NSDate.m @@ -41,7 +41,7 @@ #include #include #include -#include +#include #ifdef HAVE_SYS_TIME_H #include #endif @@ -1346,7 +1346,7 @@ GSTimeNow(void) if (self == [GSDateSingle class]) { [self setVersion: 1]; - behavior_class_add_class(self, [NSGDate class]); + GSObjCAddClassBehavior(self, [NSGDate class]); } } diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 1d03da898..1798a7b41 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -26,7 +26,6 @@ */ #include -#include #include #include #include diff --git a/Source/NSObjCRuntime.m b/Source/NSObjCRuntime.m index 6716686c4..0e9d3b655 100644 --- a/Source/NSObjCRuntime.m +++ b/Source/NSObjCRuntime.m @@ -76,785 +76,3 @@ NSGetSizeAndAlignment(const char *typePtr, unsigned *sizep, unsigned *alignp) return typePtr; } -/** - * This function is used to locate information about the instance - * variable of obj called name. It returns YES if the variable - * was found, NO otherwise. If it returns YES, then the values - * pointed to by type, size, and offset will be set (except where - * they are null pointers). - */ -BOOL -GSFindInstanceVariable(id obj, const char *name, - const char **type, unsigned int *size, int *offset) -{ - Class class; - struct objc_ivar_list *ivars; - struct objc_ivar *ivar = 0; - - class = [obj class]; - while (class != nil && ivar == 0) - { - ivars = class->ivars; - class = class->super_class; - if (ivars != 0) - { - int i; - - for (i = 0; i < ivars->ivar_count; i++) - { - if (strcmp(ivars->ivar_list[i].ivar_name, name) == 0) - { - ivar = &ivars->ivar_list[i]; - break; - } - } - } - } - if (ivar == 0) - { - return NO; - } - - if (type) - *type = ivar->ivar_type; - if (size) - *size = objc_sizeof_type(ivar->ivar_type); - if (offset) - *offset = ivar->ivar_offset; - return YES; -} - -/** - * This function performs no checking ... you should use it only where - * you are providing information from a call to GSFindInstanceVariable() - * and you know that the data area provided is the correct size. - */ -void -GSGetVariable(id obj, int offset, unsigned int size, void *data) -{ - memcpy(data, ((void*)obj) + offset, size); -} - -/** - * This function performs no checking ... you should use it only where - * you are providing information from a call to GSFindInstanceVariable() - * and you know that the data area provided is the correct size. - */ -void -GSSetVariable(id obj, int offset, unsigned int size, const void *data) -{ - memcpy(((void*)obj) + offset, data, size); -} - -/** ## deprecated ## - */ -BOOL -GSInstanceVariableInfo(id obj, NSString *iVarName, - const char **type, unsigned *size, unsigned *offset) -{ - const char *name = [iVarName UTF8String]; - - return GSFindInstanceVariable(obj, name, type, size, offset); -} - -/** ## deprecated ## - */ -BOOL -GSGetInstanceVariable(id obj, NSString *name, void *data) -{ - const char *cName = [name UTF8String]; - int offset; - unsigned int size; - - if (GSFindInstanceVariable(obj, cName, 0, &size, &offset) == YES) - { - GSGetVariable(obj, offset, size, data); - return YES; - } - return NO; -} - -/** ## deprecated ## - */ -BOOL -GSSetInstanceVariable(id obj, NSString *name, const void *data) -{ - const char *cName = [name UTF8String]; - int offset; - unsigned int size; - - if (GSFindInstanceVariable(obj, cName, 0, &size, &offset) == YES) - { - GSSetVariable(obj, offset, size, data); - return YES; - } - return NO; -} - -#include -#include -/** - * This is used internally by the key-value coding methods, to get a - * value from an object either via an accessor method (if sel is - * supplied), or via direct access (if type, size, and offset are - * supplied).
- * Automatic conversion between NSNumber and C scalar types is performed.
- * If type is null and can't be determined from the selector, the - * [NSObject-handleQueryWithUnboundKey:] method is called to try - * to get a value. - */ -id -GSGetValue(NSObject *self, NSString *key, SEL sel, - const char *type, unsigned size, int offset) -{ - if (sel != 0) - { - NSMethodSignature *sig = [self methodSignatureForSelector: sel]; - - if ([sig numberOfArguments] != 2) - { - [NSException raise: NSInvalidArgumentException - format: @"key-value get method has wrong number of args"]; - } - type = [sig methodReturnType]; - } - if (type == NULL) - { - return [self handleQueryWithUnboundKey: key]; - } - else - { - id val = nil; - - switch (*type) - { - case _C_ID: - case _C_CLASS: - { - id v; - - if (sel == 0) - { - v = *(id *)((char *)self + offset); - } - else - { - id (*imp)(id, SEL) = - (id (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = v; - } - break; - - case _C_CHR: - { - signed char v; - - if (sel == 0) - { - v = *(char *)((char *)self + offset); - } - else - { - signed char (*imp)(id, SEL) = - (signed char (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithChar: v]; - } - break; - - case _C_UCHR: - { - unsigned char v; - - if (sel == 0) - { - v = *(unsigned char *)((char *)self + offset); - } - else - { - unsigned char (*imp)(id, SEL) = - (unsigned char (*)(id, SEL))[self methodForSelector: - sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithUnsignedChar: v]; - } - break; - - case _C_SHT: - { - short v; - - if (sel == 0) - { - v = *(short *)((char *)self + offset); - } - else - { - short (*imp)(id, SEL) = - (short (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithShort: v]; - } - break; - - case _C_USHT: - { - unsigned short v; - - if (sel == 0) - { - v = *(unsigned short *)((char *)self + offset); - } - else - { - unsigned short (*imp)(id, SEL) = - (unsigned short (*)(id, SEL))[self methodForSelector: - sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithUnsignedShort: v]; - } - break; - - case _C_INT: - { - int v; - - if (sel == 0) - { - v = *(int *)((char *)self + offset); - } - else - { - int (*imp)(id, SEL) = - (int (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithInt: v]; - } - break; - - case _C_UINT: - { - unsigned int v; - - if (sel == 0) - { - v = *(unsigned int *)((char *)self + offset); - } - else - { - unsigned int (*imp)(id, SEL) = - (unsigned int (*)(id, SEL))[self methodForSelector: - sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithUnsignedInt: v]; - } - break; - - case _C_LNG: - { - long v; - - if (sel == 0) - { - v = *(long *)((char *)self + offset); - } - else - { - long (*imp)(id, SEL) = - (long (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithLong: v]; - } - break; - - case _C_ULNG: - { - unsigned long v; - - if (sel == 0) - { - v = *(unsigned long *)((char *)self + offset); - } - else - { - unsigned long (*imp)(id, SEL) = - (unsigned long (*)(id, SEL))[self methodForSelector: - sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithUnsignedLong: v]; - } - break; - -#ifdef _C_LNG_LNG - case _C_LNG_LNG: - { - long long v; - - if (sel == 0) - { - v = *(long long *)((char *)self + offset); - } - else - { - long long (*imp)(id, SEL) = - (long long (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithLongLong: v]; - } - break; -#endif - -#ifdef _C_ULNG_LNG - case _C_ULNG_LNG: - { - unsigned long long v; - - if (sel == 0) - { - v = *(unsigned long long *)((char *)self + offset); - } - else - { - unsigned long long (*imp)(id, SEL) = - (unsigned long long (*)(id, SEL))[self - methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithUnsignedLongLong: v]; - } - break; -#endif - - case _C_FLT: - { - float v; - - if (sel == 0) - { - v = *(float *)((char *)self + offset); - } - else - { - float (*imp)(id, SEL) = - (float (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithFloat: v]; - } - break; - - case _C_DBL: - { - double v; - - if (sel == 0) - { - v = *(double *)((char *)self + offset); - } - else - { - double (*imp)(id, SEL) = - (double (*)(id, SEL))[self methodForSelector: sel]; - - v = (*imp)(self, sel); - } - val = [NSNumber numberWithDouble: v]; - } - break; - - case _C_VOID: - { - void (*imp)(id, SEL) = - (void (*)(id, SEL))[self methodForSelector: sel]; - - (*imp)(self, sel); - } - val = nil; - break; - - default: - [NSException raise: NSInvalidArgumentException - format: @"key-value get method has unsupported type"]; - } - return val; - } -} - -/** - * This is used internally by the key-value coding methods, to set a - * value in an object either via an accessor method (if sel is - * supplied), or via direct access (if type, size, and offset are - * supplied).
- * Automatic conversion between NSNumber and C scalar types is performed.
- * If type is null and can't be determined from the selector, the - * [NSObject-handleTakeValue:forUnboundKey:] method is called to try - * to set a value. - */ -void -GSSetValue(NSObject *self, NSString *key, id val, SEL sel, - const char *type, unsigned size, int offset) -{ - if (sel != 0) - { - NSMethodSignature *sig = [self methodSignatureForSelector: sel]; - - if ([sig numberOfArguments] != 3) - { - [NSException raise: NSInvalidArgumentException - format: @"key-value set method has wrong number of args"]; - } - type = [sig getArgumentTypeAtIndex: 2]; - } - if (type == NULL) - { - [self handleTakeValue: val forUnboundKey: key]; - } - else - { - switch (*type) - { - case _C_ID: - case _C_CLASS: - { - id v = val; - - if (sel == 0) - { - id *ptr = (id *)((char *)self + offset); - - [*ptr autorelease]; - *ptr = [v retain]; - } - else - { - void (*imp)(id, SEL, id) = - (void (*)(id, SEL, id))[self methodForSelector: sel]; - - (*imp)(self, sel, val); - } - } - break; - - case _C_CHR: - { - char v = [val charValue]; - - if (sel == 0) - { - char *ptr = (char *)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, char) = - (void (*)(id, SEL, char))[self methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_UCHR: - { - unsigned char v = [val unsignedCharValue]; - - if (sel == 0) - { - unsigned char *ptr = (unsigned char*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, unsigned char) = - (void (*)(id, SEL, unsigned char))[self methodForSelector: - sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_SHT: - { - short v = [val shortValue]; - - if (sel == 0) - { - short *ptr = (short*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, short) = - (void (*)(id, SEL, short))[self methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_USHT: - { - unsigned short v = [val unsignedShortValue]; - - if (sel == 0) - { - unsigned short *ptr; - - ptr = (unsigned short*)((char *)self + offset); - *ptr = v; - } - else - { - void (*imp)(id, SEL, unsigned short) = - (void (*)(id, SEL, unsigned short))[self methodForSelector: - sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_INT: - { - int v = [val intValue]; - - if (sel == 0) - { - int *ptr = (int*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, int) = - (void (*)(id, SEL, int))[self methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_UINT: - { - unsigned int v = [val unsignedIntValue]; - - if (sel == 0) - { - unsigned int *ptr = (unsigned int*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, unsigned int) = - (void (*)(id, SEL, unsigned int))[self methodForSelector: - sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_LNG: - { - long v = [val longValue]; - - if (sel == 0) - { - long *ptr = (long*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, long) = - (void (*)(id, SEL, long))[self methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_ULNG: - { - unsigned long v = [val unsignedLongValue]; - - if (sel == 0) - { - unsigned long *ptr = (unsigned long*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, unsigned long) = - (void (*)(id, SEL, unsigned long))[self methodForSelector: - sel]; - - (*imp)(self, sel, v); - } - } - break; - -#ifdef _C_LNG_LNG - case _C_LNG_LNG: - { - long long v = [val longLongValue]; - - if (sel == 0) - { - long long *ptr = (long long*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, long long) = - (void (*)(id, SEL, long long))[self methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; -#endif - -#ifdef _C_ULNG_LNG - case _C_ULNG_LNG: - { - unsigned long long v = [val unsignedLongLongValue]; - - if (sel == 0) - { - unsigned long long *ptr = (unsigned long long*)((char*)self + - offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, unsigned long long) = - (void (*)(id, SEL, unsigned long long))[self - methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; -#endif - - case _C_FLT: - { - float v = [val floatValue]; - - if (sel == 0) - { - float *ptr = (float*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, float) = - (void (*)(id, SEL, float))[self methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; - - case _C_DBL: - { - double v = [val doubleValue]; - - if (sel == 0) - { - double *ptr = (double*)((char *)self + offset); - - *ptr = v; - } - else - { - void (*imp)(id, SEL, double) = - (void (*)(id, SEL, double))[self methodForSelector: sel]; - - (*imp)(self, sel, v); - } - } - break; - - default: - [NSException raise: NSInvalidArgumentException - format: @"key-value set method has unsupported type"]; - } - } -} - - -/* Getting a system error message on a variety of systems */ -#ifdef __MINGW__ -LPTSTR GetErrorMsg(DWORD msgId) -{ - LPVOID lpMsgBuf; - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, msgId, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR)&lpMsgBuf, 0, NULL); - - return (LPTSTR)lpMsgBuf; -} -#else -#ifndef HAVE_STRERROR -const char* -strerror(int eno) -{ - extern char* sys_errlist[]; - extern int sys_nerr; - - if (eno < 0 || eno >= sys_nerr) - { - return("unknown error number"); - } - return(sys_errlist[eno]); -} -#endif -#endif /* __MINGW__ */ - -const char *GSLastErrorStr(long error_id) -{ -#ifdef __MINGW__ - return GetErrorMsg(GetLastError()); -#else - return strerror(error_id); -#endif -} diff --git a/Source/NSSet.m b/Source/NSSet.m index 9849b724a..84d573453 100644 --- a/Source/NSSet.m +++ b/Source/NSSet.m @@ -25,7 +25,6 @@ */ #include -#include #include #include #include diff --git a/Source/NSString.m b/Source/NSString.m index 7efe2e752..612978e37 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -76,8 +76,6 @@ #include #include -#include - #include #include "GSPrivate.h" diff --git a/Source/NSURL.m b/Source/NSURL.m index 25cfc9106..c63274f11 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -36,7 +36,6 @@ function may be incorrect * Some functions are not implemented */ #include -#include #include #include #include diff --git a/Source/NSURLHandle.m b/Source/NSURLHandle.m index 4a0b4e6e8..a34c9dde4 100644 --- a/Source/NSURLHandle.m +++ b/Source/NSURLHandle.m @@ -27,7 +27,6 @@ */ #include -#include #include #include #include