From ad49efbd54ff6652837998463068e426584e9208 Mon Sep 17 00:00:00 2001 From: Nicola Pero Date: Wed, 13 Oct 2010 00:15:43 +0000 Subject: [PATCH] In libobjc/: 2010-10-13 Nicola Pero In libobjc/: 2010-10-13 Nicola Pero * encoding.c (method_copyReturnType): New. (method_copyArgumentType): New. (method_getReturnType): New. (method_getArgumentType): New. * methods.c (method_getDescription): New. * objc/runtime.h (method_copyReturnType): New. (method_copyArgumentType): New. (method_getReturnType): New. (method_getArgumentType): New. (method_getDescription): New. From-SVN: r165404 --- libobjc/ChangeLog | 13 ++++ libobjc/encoding.c | 168 ++++++++++++++++++++++++++++++++++++++++- libobjc/methods.c | 20 ++++- libobjc/objc/runtime.h | 46 +++++++++++ 4 files changed, 242 insertions(+), 5 deletions(-) diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index a7910f7e5d4d..7d3af57c1efc 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,16 @@ +2010-10-13 Nicola Pero + + * encoding.c (method_copyReturnType): New. + (method_copyArgumentType): New. + (method_getReturnType): New. + (method_getArgumentType): New. + * methods.c (method_getDescription): New. + * objc/runtime.h (method_copyReturnType): New. + (method_copyArgumentType): New. + (method_getReturnType): New. + (method_getArgumentType): New. + (method_getDescription): New. + 2010-10-12 Nicola Pero * encoding.c: Tidied up comments. diff --git a/libobjc/encoding.c b/libobjc/encoding.c index e36e46494122..13647d7d47ce 100644 --- a/libobjc/encoding.c +++ b/libobjc/encoding.c @@ -39,6 +39,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "objc-private/module-abi-8.h" /* For struct objc_method */ #include #include +#include /* For memcpy. */ #undef MAX #define MAX(X, Y) \ @@ -769,6 +770,172 @@ objc_skip_argspec (const char *type) return type; } +char * +method_copyReturnType (struct objc_method *method) +{ + if (method == NULL) + return 0; + else + { + char *returnValue; + size_t returnValueSize; + + /* Determine returnValueSize. */ + { + /* Find the end of the first argument. We want to return the + first argument spec, plus 1 byte for the \0 at the end. */ + const char *type = method->method_types; + if (*type == '\0') + return NULL; + type = objc_skip_argspec (type); + returnValueSize = type - method->method_types + 1; + } + + /* Copy the first argument into returnValue. */ + returnValue = malloc (sizeof (char) * returnValueSize); + memcpy (returnValue, method->method_types, returnValueSize); + returnValue[returnValueSize - 1] = '\0'; + + return returnValue; + } +} + +char * +method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber) +{ + if (method == NULL) + return 0; + else + { + char *returnValue; + const char *returnValueStart; + size_t returnValueSize; + + /* Determine returnValueStart and returnValueSize. */ + { + const char *type = method->method_types; + + /* Skip the first argument (return type). */ + type = objc_skip_argspec (type); + + /* Now keep skipping arguments until we get to + argumentNumber. */ + while (argumentNumber > 0) + { + /* We are supposed to skip an argument, but the string is + finished. This means we were asked for a non-existing + argument. */ + if (*type == '\0') + return NULL; + + type = objc_skip_argspec (type); + argumentNumber--; + } + + /* If the argument does not exist, return NULL. */ + if (*type == '\0') + return NULL; + + returnValueStart = type; + type = objc_skip_argspec (type); + returnValueSize = type - returnValueStart + 1; + } + + /* Copy the argument into returnValue. */ + returnValue = malloc (sizeof (char) * returnValueSize); + memcpy (returnValue, returnValueStart, returnValueSize); + returnValue[returnValueSize - 1] = '\0'; + + return returnValue; + } +} + +void method_getReturnType (struct objc_method * method, char *returnValue, + size_t returnValueSize) +{ + if (returnValue == NULL || returnValueSize == 0) + return; + + /* Zero the string; we'll then write the argument type at the + beginning of it, if needed. */ + memset (returnValue, 0, returnValueSize); + + if (method == NULL) + return; + else + { + size_t argumentTypeSize; + + /* Determine argumentTypeSize. */ + { + /* Find the end of the first argument. We want to return the + first argument spec. */ + const char *type = method->method_types; + if (*type == '\0') + return; + type = objc_skip_argspec (type); + argumentTypeSize = type - method->method_types; + if (argumentTypeSize > returnValueSize) + argumentTypeSize = returnValueSize; + } + /* Copy the argument at the beginning of the string. */ + memcpy (returnValue, method->method_types, argumentTypeSize); + } +} + +void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber, + char *returnValue, size_t returnValueSize) +{ + if (returnValue == NULL || returnValueSize == 0) + return; + + /* Zero the string; we'll then write the argument type at the + beginning of it, if needed. */ + memset (returnValue, 0, returnValueSize); + + if (method == NULL) + return; + else + { + const char *returnValueStart; + size_t argumentTypeSize; + + /* Determine returnValueStart and argumentTypeSize. */ + { + const char *type = method->method_types; + + /* Skip the first argument (return type). */ + type = objc_skip_argspec (type); + + /* Now keep skipping arguments until we get to + argumentNumber. */ + while (argumentNumber > 0) + { + /* We are supposed to skip an argument, but the string is + finished. This means we were asked for a non-existing + argument. */ + if (*type == '\0') + return; + + type = objc_skip_argspec (type); + argumentNumber--; + } + + /* If the argument does not exist, it's game over. */ + if (*type == '\0') + return; + + returnValueStart = type; + type = objc_skip_argspec (type); + argumentTypeSize = type - returnValueStart; + if (argumentTypeSize > returnValueSize) + argumentTypeSize = returnValueSize; + } + /* Copy the argument at the beginning of the string. */ + memcpy (returnValue, returnValueStart, argumentTypeSize); + } +} + unsigned int method_getNumberOfArguments (struct objc_method *method) { @@ -835,7 +1002,6 @@ method_get_sizeof_arguments (struct objc_method *mth) } } */ - char * method_get_next_argument (arglist_t argframe, const char **type) { diff --git a/libobjc/methods.c b/libobjc/methods.c index c6236a100e7e..65939a6d5cd7 100644 --- a/libobjc/methods.c +++ b/libobjc/methods.c @@ -29,7 +29,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "objc-private/runtime.h" /* For __objc_runtime_mutex. */ #include /* For malloc. */ -SEL method_getName (struct objc_method * method) +SEL +method_getName (struct objc_method * method) { if (method == NULL) return NULL; @@ -37,7 +38,8 @@ SEL method_getName (struct objc_method * method) return method->method_name; } -const char * method_getTypeEncoding (struct objc_method * method) +const char * +method_getTypeEncoding (struct objc_method * method) { if (method == NULL) return NULL; @@ -45,7 +47,8 @@ const char * method_getTypeEncoding (struct objc_method * method) return method->method_types; } -IMP method_getImplementation (struct objc_method * method) +IMP +method_getImplementation (struct objc_method * method) { if (method == NULL) return NULL; @@ -53,7 +56,16 @@ IMP method_getImplementation (struct objc_method * method) return method->method_imp; } -struct objc_method ** class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods) +struct objc_method_description * +method_getDescription (struct objc_method * method) +{ + /* Note that the following returns NULL if method is NULL, which is + fine. */ + return (struct objc_method_description *)method; +} + +struct objc_method ** +class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods) { unsigned int count = 0; struct objc_method **returnValue = NULL; diff --git a/libobjc/objc/runtime.h b/libobjc/objc/runtime.h index a11d283586f7..43ef9b909845 100644 --- a/libobjc/objc/runtime.h +++ b/libobjc/objc/runtime.h @@ -479,6 +479,10 @@ objc_EXPORT IMP method_getImplementation (Method method); NULL. */ objc_EXPORT const char * method_getTypeEncoding (Method method); +/* Return a method description for the method. Return NULL if + 'method' is NULL. */ +objc_EXPORT struct objc_method_description * method_getDescription (Method method); + /* Return all the instance methods of the class. The return value of the function is a pointer to an area, allocated with malloc(), that contains all the instance methods of the class. It does not @@ -500,6 +504,48 @@ objc_EXPORT Method * class_copyMethodList (Class class_, unsigned int *numberOfR NULL. */ objc_EXPORT unsigned int method_getNumberOfArguments (Method method); +/* Return the string encoding for the return type of method 'method'. + The string is a standard NULL-terminated string in an area of + memory allocated with malloc(); you should free it with free() when + you finish using it. Return an empty string if method is NULL. */ +objc_EXPORT char * method_copyReturnType (Method method); + +/* Return the string encoding for the argument type of method + 'method', argument number 'argumentNumber' ('argumentNumber' is 0 + for self, 1 for _cmd, and 2 or more for the additional arguments if + any). The string is a standard NULL-terminated string in an area + of memory allocated with malloc(); you should free it with free() + when you finish using it. Return an empty string if method is NULL + or if 'argumentNumber' refers to a non-existing argument. */ +objc_EXPORT char * method_copyArgumentType (Method method, unsigned int argumentNumber); + +/* Return the string encoding for the return type of method 'method'. + The string is returned by copying it into the supplied + 'returnValue' string, which is of size 'returnValueSize'. No more + than 'returnValueSize' characters are copied; if the encoding is + smaller than 'returnValueSize', the rest of 'returnValue' is filled + with NULLs. If it is bigger, it is truncated (and would not be + NULL-terminated). You should supply a big enough + 'returnValueSize'. If the method is NULL, returnValue is set to a + string of NULLs. */ +objc_EXPORT void method_getReturnType (Method method, char *returnValue, + size_t returnValueSize); + +/* Return the string encoding for the argument type of method + 'method', argument number 'argumentNumber' ('argumentNumber' is 0 + for self, 1 for _cmd, and 2 or more for the additional arguments if + any). The string is returned by copying it into the supplied + 'returnValue' string, which is of size 'returnValueSize'. No more + than 'returnValueSize' characters are copied; if the encoding is + smaller than 'returnValueSize', the rest of 'returnValue' is filled + with NULLs. If it is bigger, it is truncated (and would not be + NULL-terminated). You should supply a big enough + 'returnValueSize'. If the method is NULL, returnValue is set to a + string of NULLs. */ +objc_EXPORT void method_getArgumentType (Method method, unsigned int argumentNumber, + char *returnValue, size_t returnValueSize); + + /** Implementation: the following functions are in protocols.c. */ -- 2.39.2