From patchwork Wed Oct 13 00:16:56 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicola Pero X-Patchwork-Id: 67633 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id C224AB6F11 for ; Wed, 13 Oct 2010 11:17:16 +1100 (EST) Received: (qmail 12446 invoked by alias); 13 Oct 2010 00:17:11 -0000 Received: (qmail 12432 invoked by uid 22791); 13 Oct 2010 00:17:07 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL, BAYES_00, SARE_SUB_ENC_UTF8, TW_BJ, TW_CP, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (140.186.70.10) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Oct 2010 00:17:00 +0000 Received: from eggs.gnu.org ([140.186.70.92]:46426) by fencepost.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1P5p1e-0002hu-Sm for gcc-patches@gnu.org; Tue, 12 Oct 2010 20:16:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P5p1d-0000ls-8Z for gcc-patches@gnu.org; Tue, 12 Oct 2010 20:16:58 -0400 Received: from smtp121.iad.emailsrvr.com ([207.97.245.121]:40724) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P5p1d-0000lW-4w for gcc-patches@gnu.org; Tue, 12 Oct 2010 20:16:57 -0400 Received: from relay22.relay.iad.mlsrvr.com (localhost [127.0.0.1]) by relay22.relay.iad.mlsrvr.com (SMTP Server) with ESMTP id ACF941B5403 for ; Tue, 12 Oct 2010 20:16:56 -0400 (EDT) Received: from dynamic4.wm-web.iad.mlsrvr.com (dynamic4.wm-web.iad.mlsrvr.com [192.168.2.153]) by relay22.relay.iad.mlsrvr.com (SMTP Server) with ESMTP id A84561B53C6 for ; Tue, 12 Oct 2010 20:16:56 -0400 (EDT) Received: from meta-innovation.com (localhost [127.0.0.1]) by dynamic4.wm-web.iad.mlsrvr.com (Postfix) with ESMTP id 846581D4A24C for ; Tue, 12 Oct 2010 20:16:56 -0400 (EDT) Received: by www2.webmail.us (Authenticated sender: nicola.pero@meta-innovation.com, from: nicola.pero@meta-innovation.com) with HTTP; Wed, 13 Oct 2010 02:16:56 +0200 (CEST) Date: Wed, 13 Oct 2010 02:16:56 +0200 (CEST) Subject: =?UTF-8?Q?libobjc=20-=20more=20modern=20Objective-C=20runtime=20API=20(6?= =?UTF-8?Q?)?= From: "Nicola Pero" To: "gcc-patches@gnu.org" MIME-Version: 1.0 X-Type: plain Message-ID: <1286929016.540310217@192.168.2.230> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Another batch. We're getting there. :-) Committed to trunk. Thanks 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. Index: encoding.c =================================================================== --- encoding.c (revision 165403) +++ encoding.c (working copy) @@ -39,6 +39,7 @@ see the files COPYING3 and COPYING.RUNTIME respect #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 *m } } */ - char * method_get_next_argument (arglist_t argframe, const char **type) { Index: methods.c =================================================================== --- methods.c (revision 165400) +++ methods.c (working copy) @@ -29,7 +29,8 @@ see the files COPYING3 and COPYING.RUNTIME respect #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 @@ see the files COPYING3 and COPYING.RUNTIME respect 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 @@ see the files COPYING3 and COPYING.RUNTIME respect return method->method_types; } -IMP method_getImplementation (struct objc_method * method) +IMP +method_getImplementation (struct objc_method * method) { if (method == NULL) return NULL; @@ -53,8 +56,17 @@ see the files COPYING3 and COPYING.RUNTIME respect 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; struct objc_method_list* method_list; Index: ChangeLog =================================================================== --- ChangeLog (revision 165403) +++ ChangeLog (working copy) @@ -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. Index: objc/runtime.h =================================================================== --- objc/runtime.h (revision 165400) +++ objc/runtime.h (working copy) @@ -479,6 +479,10 @@ objc_EXPORT IMP method_getImplementation (Method m 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,7 +504,49 @@ objc_EXPORT Method * class_copyMethodList (Class c 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. */ /* Return the protocol with name 'name', or nil if it the protocol is