In libobjc/: 2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>

In libobjc/:
2010-12-24  Nicola Pero  <nicola.pero@meta-innovation.com>

	* objc/runtime.h (sel_getType): Renamed to sel_getTypeEncoding to
	be consistent with method_getTypeEncoding and
	ivar_getTypeEncoding.
	(sel_copyTypedSelectorList, sel_getTypedSelector): New.
	* selector.c (sel_getType): Renamed to sel_getTypeEncoding.
	(sel_copyTypedSelectorList, sel_getTypedSelector): New.
	(sel_get_type): Updated call to sel_getType.
	
In gcc/testsuite/:
2010-12-24  Nicola Pero  <nicola.pero@meta-innovation.com>

	* objc.dg/gnu-api-2-sel.m: Updated for renaming of sel_getType to
	sel_getTypeEncoding.  Test that sel_getTypeEncoding returns NULL
	when called with a NULL argument.  Added test for
	sel_copyTypedSelectorList and sel_getTypedSelector.
	* obj-c++.dg/gnu-api-2-sel.mm: Same changes.

From-SVN: r168229
This commit is contained in:
Nicola Pero 2010-12-24 17:00:19 +00:00 committed by Nicola Pero
parent e66d38fe05
commit 5750872c61
6 changed files with 285 additions and 15 deletions

View File

@ -1,3 +1,11 @@
2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/gnu-api-2-sel.m: Updated for renaming of sel_getType to
sel_getTypeEncoding. Test that sel_getTypeEncoding returns NULL
when called with a NULL argument. Added test for
sel_copyTypedSelectorList and sel_getTypedSelector.
* obj-c++.dg/gnu-api-2-sel.mm: Same changes.
2010-12-24 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/opt13_pkg.ad[sb]: Fix line ending.

View File

@ -35,11 +35,13 @@
{ id variable_ivar; }
- (void) setVariable: (id)value;
- (id) variable;
- (void) method;
@end
@implementation MySubClass
- (void) setVariable: (id)value { variable_ivar = value; }
- (id) variable { return variable_ivar; }
- (void) method { return; }
@end
@ -47,6 +49,30 @@ int main ()
{
/* Functions are tested in alphabetical order. */
std::cout << "Testing sel_copyTypedSelectorList ()...\n";
{
unsigned int count;
SEL * list = sel_copyTypedSelectorList ("method", &count);
/* There should only be two, since 'method' is referenced twice,
once with types and once without (in this very test). */
if (count != 2)
abort ();
/* Check that both selectors are not-NULL, and have the correct
name. We use @selector() here, which wouldn't really be
needed, just to register a second, untyped selector with name
'method'. */
if (std::strcmp (sel_getName (list[0]), sel_getName (@selector (method))) != 0)
abort ();
if (std::strcmp (sel_getName (list[1]), sel_getName (@selector (method))) != 0)
abort ();
if (list[2] != NULL)
abort ();
}
std::cout << "Testing sel_getName () ...\n";
{
if (std::strcmp (sel_getName (@selector (variable)), "variable") != 0)
@ -56,14 +82,50 @@ int main ()
abort ();
}
std::cout << "Testing sel_getType () ...\n";
std::cout << "Testing sel_getTypeEncoding () ...\n";
{
/* Get a selector from a real class, so it has interesting
types. */
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
@selector (variable));
if (std::strcmp (sel_getType (method_getName (method)), method_getTypeEncoding (method)) != 0)
if (std::strcmp (sel_getTypeEncoding (method_getName (method)),
method_getTypeEncoding (method)) != 0)
abort ();
if (sel_getTypeEncoding (NULL) != NULL)
abort ();
}
std::cout << "Testing sel_getTypedSelector () ...\n";
{
/* First try with a selector where we know that a typed one has
been registered. */
SEL selector = sel_getTypedSelector ("variable");
if (selector == NULL)
abort ();
if (sel_getTypeEncoding (selector) == NULL)
abort ();
/* Now try a selector which was never registered. */
selector = sel_getTypedSelector ("not_registered");
if (selector != NULL)
abort ();
/* Now try registering a selector with no types. The following
line is just a way to have an unused '@selector()' expression
without the compiler complaining. */
if (@selector (registered_with_no_types) == NULL)
abort ();
/* Try getting it. Nothing should be returned because it is
untyped. */
selector = sel_getTypedSelector ("registered_with_no_types");
if (selector != NULL)
abort ();
}
@ -91,11 +153,11 @@ int main ()
(objc_getClass ("MySubClass"),
@selector (variable)));
SEL selector = sel_registerTypedName ("aMethod", types);
if (std::strcmp (sel_getName (selector), "aMethod") != 0)
abort ();
if (std::strcmp (sel_getType (selector), types) != 0)
if (std::strcmp (sel_getTypeEncoding (selector), types) != 0)
abort ();
}

View File

@ -35,11 +35,13 @@
{ id variable_ivar; }
- (void) setVariable: (id)value;
- (id) variable;
- (void) method;
@end
@implementation MySubClass
- (void) setVariable: (id)value { variable_ivar = value; }
- (id) variable { return variable_ivar; }
- (void) method { return; }
@end
@ -47,6 +49,30 @@ int main(int argc, void **args)
{
/* Functions are tested in alphabetical order. */
printf ("Testing sel_copyTypedSelectorList ()...\n");
{
unsigned int count;
SEL * list = sel_copyTypedSelectorList ("method", &count);
/* There should only be two, since 'method' is referenced twice,
once with types and once without (in this very test). */
if (count != 2)
abort ();
/* Check that both selectors are not-NULL, and have the correct
name. We use @selector() here, which wouldn't really be
needed, just to register a second, untyped selector with name
'method'. */
if (strcmp (sel_getName (list[0]), sel_getName (@selector (method))) != 0)
abort ();
if (strcmp (sel_getName (list[1]), sel_getName (@selector (method))) != 0)
abort ();
if (list[2] != NULL)
abort ();
}
printf ("Testing sel_getName () ...\n");
{
if (strcmp (sel_getName (@selector (variable)), "variable") != 0)
@ -56,14 +82,50 @@ int main(int argc, void **args)
abort ();
}
printf ("Testing sel_getType () ...\n");
printf ("Testing sel_getTypeEncoding () ...\n");
{
/* Get a selector from a real class, so it has interesting
types. */
Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
@selector (variable));
if (strcmp (sel_getType (method_getName (method)), method_getTypeEncoding (method)) != 0)
if (strcmp (sel_getTypeEncoding (method_getName (method)),
method_getTypeEncoding (method)) != 0)
abort ();
if (sel_getTypeEncoding (NULL) != NULL)
abort ();
}
printf ("Testing sel_getTypedSelector () ...\n");
{
/* First try with a selector where we know that a typed one has
been registered. */
SEL selector = sel_getTypedSelector ("variable");
if (selector == NULL)
abort ();
if (sel_getTypeEncoding (selector) == NULL)
abort ();
/* Now try a selector which was never registered. */
selector = sel_getTypedSelector ("not_registered");
if (selector != NULL)
abort ();
/* Now try registering a selector with no types. The following
line is just a way to have an unused '@selector()' expression
without the compiler complaining. */
if (@selector (registered_with_no_types) == NULL)
abort ();
/* Try getting it. Nothing should be returned because it is
untyped. */
selector = sel_getTypedSelector ("registered_with_no_types");
if (selector != NULL)
abort ();
}
@ -95,7 +157,7 @@ int main(int argc, void **args)
if (strcmp (sel_getName (selector), "aMethod") != 0)
abort ();
if (strcmp (sel_getType (selector), types) != 0)
if (strcmp (sel_getTypeEncoding (selector), types) != 0)
abort ();
}

View File

@ -1,3 +1,13 @@
2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>
* objc/runtime.h (sel_getType): Renamed to sel_getTypeEncoding to
be consistent with method_getTypeEncoding and
ivar_getTypeEncoding.
(sel_copyTypedSelectorList, sel_getTypedSelector): New.
* selector.c (sel_getType): Renamed to sel_getTypeEncoding.
(sel_copyTypedSelectorList, sel_getTypedSelector): New.
(sel_get_type): Updated call to sel_getType.
2010-12-24 Nicola Pero <nicola.pero@meta-innovation.com>
* objc/runtime.h (class_conformsToProtocol,

View File

@ -175,12 +175,13 @@ object_getClass (id object)
"<null selector>". */
objc_EXPORT const char *sel_getName (SEL selector);
/* Return the type of a given selector.
/* Return the type of a given selector. Return NULL if selector is
NULL.
Compatibility Note: the Apple/NeXT runtime has untyped selectors,
so it does not have this function, which is specific to the GNU
Runtime. */
objc_EXPORT const char *sel_getType (SEL selector);
objc_EXPORT const char *sel_getTypeEncoding (SEL selector);
/* This is the same as sel_registerName (). Please use
sel_registerName () instead. */
@ -188,11 +189,16 @@ objc_EXPORT SEL sel_getUid (const char *name);
/* Register a selector with a given name (but unspecified types). If
you know the types, it is better to call sel_registerTypedName().
If a selector with this name already exists, it is returned. */
If a selector with this name and no types already exists, it is
returned. Note that this function should really be called
'objc_registerSelector'. */
objc_EXPORT SEL sel_registerName (const char *name);
/* Register a selector with a given name and types. If a selector
with this name and types already exists, it is returned.
with this name and types already exists, it is returned. Note that
this function should really be called 'objc_registerTypedSelector',
and it's called 'sel_registerTypedName' only for consistency with
'sel_registerName'.
Compatibility Note: the Apple/NeXT runtime has untyped selectors,
so it does not have this function, which is specific to the GNU
@ -203,6 +209,37 @@ objc_EXPORT SEL sel_registerTypedName (const char *name, const char *type);
if not. */
objc_EXPORT BOOL sel_isEqual (SEL first_selector, SEL second_selector);
/* Return all the selectors with the supplied name. In the GNU
runtime, selectors are typed and there may be multiple selectors
with the same name but a different type. The return value of the
function is a pointer to an area, allocated with malloc(), that
contains all the selectors with the supplier name known to the
runtime. The list is terminated by NULL. Optionally, if you pass
a non-NULL 'numberOfReturnedSelectors' pointer, the unsigned int
that it points to will be filled with the number of selectors
returned.
Compatibility Note: the Apple/NeXT runtime has untyped selectors,
so it does not have this function, which is specific to the GNU
Runtime. */
objc_EXPORT SEL * sel_copyTypedSelectorList (const char *name,
unsigned int *numberOfReturnedSelectors);
/* Return a selector with name 'name' and a non-zero type encoding, if
any such selector is registered with the runtime. If there is no
such selector, NULL is returned.
This is useful if you have the name of the selector, and would
really like to get a selector for it that includes the type
encoding. Unfortunately, if the program contains multiple selector
with the same name but different types, sel_getTypedSelector
returns a random one of them, which may not be the right one.
Compatibility Note: the Apple/NeXT runtime has untyped selectors,
so it does not have this function, which is specific to the GNU
Runtime. */
objc_EXPORT SEL sel_getTypedSelector (const char *name);
/** Implementation: the following functions are in objects.c. */

View File

@ -31,6 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "objc-private/runtime.h"
#include "objc-private/sarray.h"
#include "objc-private/selector.h"
#include <stdlib.h> /* For malloc. */
/* Initial selector hash table size. Value doesn't matter much. */
#define SELECTOR_HASH_SIZE 128
@ -250,7 +251,11 @@ sel_types_match (const char *t1, const char *t2)
return NO;
}
/* Return selector representing name. */
/* Return selector representing name. In the Modern API, you'd
normally use sel_registerTypedName() for this, which does the same
but would register the selector with the runtime if not registered
yet (if you only want to check for selectors without registering,
use sel_copyTypedSelectorList()). */
SEL
sel_get_typed_uid (const char *name, const char *types)
{
@ -290,7 +295,8 @@ sel_get_typed_uid (const char *name, const char *types)
}
/* Return selector representing name; prefer a selector with non-NULL
type. */
type. In the Modern API, sel_getTypedSelector() is similar but
returns NULL if a typed selector couldn't be found. */
SEL
sel_get_any_typed_uid (const char *name)
{
@ -347,6 +353,91 @@ sel_get_any_uid (const char *name)
return (SEL) l->head;
}
SEL
sel_getTypedSelector (const char *name)
{
sidx i;
objc_mutex_lock (__objc_runtime_mutex);
/* Look for a typed selector. */
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
if (i != 0)
{
struct objc_list *l;
for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
l; l = l->tail)
{
SEL s = (SEL) l->head;
if (s->sel_types)
{
objc_mutex_unlock (__objc_runtime_mutex);
return s;
}
}
}
/* No typed selector found. Return NULL. */
objc_mutex_unlock (__objc_runtime_mutex);
return 0;
}
SEL *
sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
{
unsigned int count = 0;
SEL *returnValue = NULL;
sidx i;
if (name == NULL)
{
if (numberOfReturnedSelectors)
*numberOfReturnedSelectors = 0;
return NULL;
}
objc_mutex_lock (__objc_runtime_mutex);
/* Count how many selectors we have. */
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
if (i != 0)
{
struct objc_list *selector_list = NULL;
selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
/* Count how many selectors we have. */
{
struct objc_list *l;
for (l = selector_list; l; l = l->tail)
count++;
}
if (count != 0)
{
/* Allocate enough memory to hold them. */
returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
/* Copy the selectors. */
{
unsigned int j;
for (j = 0; j < count; j++)
{
returnValue[j] = (SEL)(selector_list->head);
selector_list = selector_list->tail;
}
returnValue[j] = NULL;
}
}
}
objc_mutex_unlock (__objc_runtime_mutex);
if (numberOfReturnedSelectors)
*numberOfReturnedSelectors = count;
return returnValue;
}
/* Get the name of a selector. If the selector is unknown, the empty
string "" is returned. */
const char *sel_getName (SEL selector)
@ -382,7 +473,7 @@ sel_is_mapped (SEL selector)
return ((idx > 0) && (idx <= __objc_selector_max_index));
}
const char *sel_getType (SEL selector)
const char *sel_getTypeEncoding (SEL selector)
{
if (selector)
return selector->sel_types;
@ -393,7 +484,7 @@ const char *sel_getType (SEL selector)
/* Traditional GNU Objective-C Runtime API. */
const char *sel_get_type (SEL selector)
{
return sel_getType (selector);
return sel_getTypeEncoding (selector);
}
/* The uninstalled dispatch table. */