aboutsummaryrefslogtreecommitdiff
path: root/libobjc
diff options
context:
space:
mode:
Diffstat (limited to 'libobjc')
-rw-r--r--libobjc/ChangeLog10
-rw-r--r--libobjc/objc/runtime.h45
-rw-r--r--libobjc/selector.c99
3 files changed, 146 insertions, 8 deletions
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 78112bd..e028b58 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,5 +1,15 @@
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,
class_copyProtocolList): Updated documentation.
diff --git a/libobjc/objc/runtime.h b/libobjc/objc/runtime.h
index 7ad46dc..18fc872 100644
--- a/libobjc/objc/runtime.h
+++ b/libobjc/objc/runtime.h
@@ -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. */
diff --git a/libobjc/selector.c b/libobjc/selector.c
index 4fd213b..f8a7f14 100644
--- a/libobjc/selector.c
+++ b/libobjc/selector.c
@@ -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. */