mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-09 15:50:59 +00:00
384 lines
9.9 KiB
Objective-C
384 lines
9.9 KiB
Objective-C
#import "Testing.h"
|
|
#import <Foundation/NSAutoreleasePool.h>
|
|
#import <Foundation/NSMethodSignature.h>
|
|
#import <Foundation/NSRunLoop.h>
|
|
#import <Foundation/NSConnection.h>
|
|
#import <Foundation/NSException.h>
|
|
#import <Foundation/NSDebug.h>
|
|
|
|
#if GNUSTEP
|
|
#import <GNUstepBase/GSObjCRuntime.h>
|
|
|
|
|
|
#define SRV_NAME @"nsmethodsignaturetest"
|
|
|
|
struct _MyLargeStruct
|
|
{
|
|
double first;
|
|
double second;
|
|
};
|
|
typedef struct _MyLargeStruct MyLargeStruct;
|
|
|
|
struct _MySmallStruct
|
|
{
|
|
char first;
|
|
};
|
|
typedef struct _MySmallStruct MySmallStruct;
|
|
|
|
/*------------------------------------*/
|
|
@interface MyClass : NSObject
|
|
- (void) void_void;
|
|
- (id)id_void;
|
|
|
|
- (char)char_void;
|
|
- (unsigned char)uchar_void;
|
|
- (signed char)schar_void;
|
|
|
|
- (short)short_void;
|
|
- (unsigned short)ushort_void;
|
|
- (signed short)sshort_void;
|
|
|
|
- (int)int_void;
|
|
- (unsigned int)uint_void;
|
|
- (signed int)sint_void;
|
|
|
|
- (long)long_void;
|
|
- (unsigned long)ulong_void;
|
|
- (signed long)slong_void;
|
|
|
|
- (float)float_void;
|
|
- (double)double_void;
|
|
|
|
- (MyLargeStruct)largeStruct_void;
|
|
- (MySmallStruct)smallStruct_void;
|
|
|
|
|
|
|
|
- (void) void_id: (id)_id;
|
|
|
|
- (void) void_char: (char)_char;
|
|
- (void) void_uchar: (unsigned char)_char;
|
|
- (void) void_schar: (signed char)_char;
|
|
|
|
- (void) void_short: (short)_short;
|
|
- (void) void_ushort: (unsigned short)_short;
|
|
- (void) void_sshort: (signed short)_short;
|
|
|
|
- (void) void_int: (int)_int;
|
|
- (void) void_uint: (unsigned int)_int;
|
|
- (void) void_sint: (signed int)_int;
|
|
|
|
- (void) void_long: (long)_long;
|
|
- (void) void_ulong: (unsigned long)_long;
|
|
- (void) void_slong: (signed long)_long;
|
|
|
|
- (void) void_float: (float)_float;
|
|
- (void) void_double: (double)_double;
|
|
|
|
- (void) void_largeStruct: (MyLargeStruct)_str;
|
|
- (void) void_smallStruct: (MySmallStruct)_str;
|
|
|
|
- (void) void_float: (float)_float double:(double)_double;
|
|
- (void) void_double: (double)_double float:(float)_float;
|
|
|
|
- (MyLargeStruct)largeStruct_id: (id)_id
|
|
char: (char)_char
|
|
short: (short)_short
|
|
int: (int)_int
|
|
long: (long)_long
|
|
float: (float)_float
|
|
double: (double)_double
|
|
largeStruct: (MyLargeStruct)_lstr
|
|
smallStruct: (MySmallStruct)_sstr;
|
|
- (MySmallStruct)smallStruct_id: (id)_id
|
|
uchar: (unsigned char)_uchar
|
|
ushort: (unsigned short)_ushort
|
|
uint: (unsigned int)_uint
|
|
ulong: (unsigned long)_ulong
|
|
float: (float)_float
|
|
double: (double)_double
|
|
largeStruct: (MyLargeStruct)_lstr
|
|
smallStruct: (MySmallStruct)_sstr;
|
|
|
|
- (const char *)runtimeSignatureForSelector: (SEL)selector;
|
|
@end
|
|
|
|
@implementation MyClass
|
|
- (void) void_void {}
|
|
- (id) id_void { return 0; }
|
|
|
|
- (char) char_void { return 0; }
|
|
- (unsigned char) uchar_void { return 0; }
|
|
- (signed char) schar_void { return 0; }
|
|
|
|
- (short) short_void { return 0; }
|
|
- (unsigned short) ushort_void { return 0; }
|
|
- (signed short) sshort_void { return 0; }
|
|
|
|
- (int) int_void { return 0; }
|
|
- (unsigned int) uint_void { return 0; }
|
|
- (signed int) sint_void { return 0; }
|
|
|
|
- (long) long_void { return 0; }
|
|
- (unsigned long) ulong_void { return 0; }
|
|
- (signed long) slong_void { return 0; }
|
|
|
|
- (float) float_void { return 0; }
|
|
- (double) double_void { return 0; }
|
|
|
|
- (MyLargeStruct) largeStruct_void { MyLargeStruct str; return str; }
|
|
- (MySmallStruct) smallStruct_void { MySmallStruct str; return str; }
|
|
|
|
|
|
|
|
- (void) void_id: (id)_id {}
|
|
|
|
- (void) void_char: (char)_char {}
|
|
- (void) void_uchar: (unsigned char)_char {}
|
|
- (void) void_schar: (signed char)_char {}
|
|
|
|
- (void) void_short: (short)_short {}
|
|
- (void) void_ushort: (unsigned short)_short {}
|
|
- (void) void_sshort: (signed short)_short {}
|
|
|
|
- (void) void_int: (int)_int {}
|
|
- (void) void_uint: (unsigned int)_int {}
|
|
- (void) void_sint: (signed int)_int {}
|
|
|
|
- (void) void_long: (long)_long {}
|
|
- (void) void_ulong: (unsigned long)_long {}
|
|
- (void) void_slong: (signed long)_long {}
|
|
|
|
- (void) void_float: (float)_float {}
|
|
- (void) void_double: (double)_double {}
|
|
|
|
- (void) void_largeStruct: (MyLargeStruct)_str {}
|
|
- (void) void_smallStruct: (MySmallStruct)_str {}
|
|
|
|
- (void) void_float: (float)_float double:(double)_double {}
|
|
- (void) void_double: (double)_double float:(float)_float {}
|
|
|
|
|
|
- (MyLargeStruct) largeStruct_id: (id)_id
|
|
char: (char)_char
|
|
short: (short)_short
|
|
int: (int)_int
|
|
long: (long)_long
|
|
float: (float)_float
|
|
double: (double)_double
|
|
largeStruct: (MyLargeStruct)_lstr
|
|
smallStruct: (MySmallStruct)_sstr { return _lstr; }
|
|
|
|
- (MySmallStruct) smallStruct_id: (id)_id
|
|
uchar: (unsigned char)_uchar
|
|
ushort: (unsigned short)_ushort
|
|
uint: (unsigned int)_uint
|
|
ulong: (unsigned long)_ulong
|
|
float: (float)_float
|
|
double: (double)_double
|
|
largeStruct: (MyLargeStruct)_lstr
|
|
smallStruct: (MySmallStruct)_sstr { return _sstr; }
|
|
|
|
- (const char *) runtimeSignatureForSelector: (SEL)selector
|
|
{
|
|
GSMethod meth = GSGetMethod(object_getClass(self), selector, YES, YES);
|
|
return method_getTypeEncoding (meth);
|
|
}
|
|
|
|
@end
|
|
|
|
/*------------------------------------*/
|
|
|
|
|
|
/*
|
|
This test is useful if the nsmethodsignatureserver is running which
|
|
was compiled with either a different GNUstep-base version or a different
|
|
version of gcc. It the server isn't found the test is skipped.
|
|
*/
|
|
void
|
|
test_compare_server_signature(void)
|
|
{
|
|
id objct = AUTORELEASE([MyClass new]);
|
|
id proxy = [NSConnection rootProxyForConnectionWithRegisteredName: SRV_NAME
|
|
host: nil];
|
|
if (proxy)
|
|
{
|
|
const char *rmtSig;
|
|
const char *lclSig;
|
|
const char *msg;
|
|
|
|
#define TEST_SEL(SELNAME) { \
|
|
BOOL ok; \
|
|
lclSig = [objct runtimeSignatureForSelector: @selector(SELNAME)]; \
|
|
rmtSig = [proxy runtimeSignatureForSelector: @selector(SELNAME)]; \
|
|
msg = [[NSString stringWithFormat: @"runtime: sel:%s\nlcl:%s\nrmt:%s", \
|
|
GSNameFromSelector(@selector(SELNAME)), lclSig, rmtSig] UTF8String]; \
|
|
ok = GSSelectorTypesMatch(lclSig, rmtSig); \
|
|
PASS(ok, "%s", msg) \
|
|
}
|
|
|
|
TEST_SEL(void_void);
|
|
TEST_SEL(id_void);
|
|
TEST_SEL(char_void);
|
|
TEST_SEL(uchar_void);
|
|
TEST_SEL(schar_void);
|
|
TEST_SEL(short_void);
|
|
TEST_SEL(ushort_void);
|
|
TEST_SEL(sshort_void);
|
|
TEST_SEL(int_void);
|
|
TEST_SEL(uint_void);
|
|
TEST_SEL(sint_void);
|
|
TEST_SEL(long_void);
|
|
TEST_SEL(ulong_void);
|
|
TEST_SEL(slong_void);
|
|
TEST_SEL(float_void);
|
|
TEST_SEL(double_void);
|
|
TEST_SEL(largeStruct_void);
|
|
TEST_SEL(smallStruct_void);
|
|
|
|
TEST_SEL(void_id:);
|
|
TEST_SEL(void_char:);
|
|
TEST_SEL(void_uchar:);
|
|
TEST_SEL(void_schar:);
|
|
TEST_SEL(void_short:);
|
|
TEST_SEL(void_ushort:);
|
|
TEST_SEL(void_sshort:);
|
|
TEST_SEL(void_int:);
|
|
TEST_SEL(void_uint:);
|
|
TEST_SEL(void_sint:);
|
|
TEST_SEL(void_long:);
|
|
TEST_SEL(void_ulong:);
|
|
TEST_SEL(void_slong:);
|
|
TEST_SEL(void_float:);
|
|
TEST_SEL(void_double:);
|
|
TEST_SEL(void_largeStruct:);
|
|
TEST_SEL(void_smallStruct:);
|
|
TEST_SEL(void_float:double:);
|
|
TEST_SEL(void_double:float:);
|
|
TEST_SEL(largeStruct_id:char:short:int:long:float:double:largeStruct:smallStruct:);
|
|
TEST_SEL(smallStruct_id:uchar:ushort:uint:ulong:float:double:largeStruct:smallStruct:);
|
|
|
|
}
|
|
else
|
|
{
|
|
NSLog(@"Skipping test_compare_server_signature: proxy not found.");
|
|
}
|
|
}
|
|
|
|
void
|
|
test_GSSelectorTypesMatch(void)
|
|
{
|
|
const char *pairs[][2] = { {"@@::", "@12@0:4:8"},
|
|
{"@@::", "@12@+0:+4:+8"},
|
|
{"@@::", "@12@-0:-4:-8"},
|
|
{"@12@0:4:8", "@@::"},
|
|
{"@12@+0:+4:+8", "@@::"},
|
|
{"@12@-0:-4:-8", "@@::"},
|
|
|
|
{"@12@0:4:8", "@12@+0:+4:+8"},
|
|
{"@12@0:4:8", "@12@-0:-4:-8"},
|
|
{"@12@+0:+4:+8", "@12@0:4:8"},
|
|
{"@12@-0:-4:-8", "@12@0:4:8"},
|
|
|
|
{"@12@0:4:8", "@16@+4:+8:+12"},
|
|
{"@12@0:4:8", "@16@-4:-8:-12"},
|
|
{"@12@+0:+4:+8", "@16@4:8:12"},
|
|
{"@12@-0:-4:-8", "@16@4:8:12"},
|
|
|
|
/* NB Use of a backslash in a ? ? = sequence below is to prevent the sequence
|
|
* from being interpreted as a trigraph by the compiler/preprocessor.
|
|
*/
|
|
{"{_MyLargeStruct2={_MyLargeStruct=dd}dd}@:",
|
|
"{?\?={?\?=dd}dd}16@0:4"},
|
|
|
|
{"{_MyLargeStruct=dd}56@+8:+12@+16c+23s+26i+28l24f28d32{_MyLargeStruct=dd}40{_MySmallStruct=c}44",
|
|
"{_MyLargeStruct=dd}46@+8:+12@+16c+17s+16i+20l+24f+28d24{_MyLargeStruct=dd}32{_MySmallStruct=c}45"},
|
|
{"{_MyLargeStruct=dd}56@+8:+12@+16c+23s+26i+28l24f28d32{_MyLargeStruct=dd}40{_MySmallStruct=c}44",
|
|
"{?\?=dd}46@+8:+12@+16c+17s+16i+20l+24f+28d24{?\?=dd}32{?\?=c}45"},
|
|
{0, 0} };
|
|
unsigned int i = 0;
|
|
|
|
while (pairs[i][0])
|
|
{
|
|
const char *s;
|
|
BOOL ok;
|
|
|
|
s = [[NSString stringWithFormat: @"pair %d matches:\n%s\n%s",
|
|
i, pairs[i][0], pairs[i][1]] UTF8String];
|
|
ok = GSSelectorTypesMatch(pairs[i][0], pairs[i][1]);
|
|
PASS(ok, "%s", s)
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void
|
|
run_server(void)
|
|
{
|
|
id obj = [MyClass new];
|
|
NSConnection *conn = [NSConnection defaultConnection];
|
|
|
|
[conn setRootObject: obj];
|
|
if ([conn registerName: SRV_NAME] == NO)
|
|
{
|
|
NSLog(@"Failed to register name: " SRV_NAME );
|
|
abort();
|
|
}
|
|
[[NSRunLoop currentRunLoop] run];
|
|
}
|
|
#endif
|
|
|
|
@interface SimpleClass : NSObject
|
|
- (const char *) sel1;
|
|
@end
|
|
|
|
@implementation SimpleClass
|
|
- (const char *) sel1
|
|
{
|
|
return "";
|
|
}
|
|
@end
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
NSAutoreleasePool *pool;
|
|
pool = [[NSAutoreleasePool alloc] init];
|
|
const char *e;
|
|
id o;
|
|
id s;
|
|
|
|
o = [SimpleClass new];
|
|
s = [o methodSignatureForSelector: @selector(sel1)];
|
|
e = @encode(const char*);
|
|
PASS(strcmp(e, "r*") == 0, "@encode(const char*) makes 'r*' type encoding")
|
|
PASS(strcmp([s methodReturnType], "r*") == 0,
|
|
"sel1 return type is 'r*'")
|
|
|
|
#if GNUSTEP
|
|
if ([[[[NSProcessInfo processInfo] arguments] lastObject] isEqual: @"srv"])
|
|
{
|
|
run_server();
|
|
abort();
|
|
}
|
|
|
|
NS_DURING
|
|
{
|
|
test_compare_server_signature();
|
|
test_GSSelectorTypesMatch();
|
|
}
|
|
NS_HANDLER
|
|
{
|
|
NSLog(@"MethodSignature Test Failed:");
|
|
NSLog(@"%@ %@ %@",
|
|
[localException name],
|
|
[localException reason],
|
|
[localException userInfo]);
|
|
}
|
|
NS_ENDHANDLER
|
|
#endif
|
|
|
|
[pool release];
|
|
|
|
exit(0);
|
|
}
|
|
|