Patchwork =?UTF-8?Q?libobjc=20-=20more=20modern=20Objective-C=20runtime=20API=20(6?= =?UTF-8?Q?)?=

login
register
mail settings
Submitter Nicola Pero
Date Oct. 13, 2010, 12:16 a.m.
Message ID <1286929016.540310217@192.168.2.230>
Download mbox | patch
Permalink /patch/67633/
State New
Headers show

Comments

Nicola Pero - Oct. 13, 2010, 12:16 a.m.
Another batch.  We're getting there. :-)

Committed to trunk.

Thanks

2010-10-13  Nicola Pero  <nicola.pero@meta-innovation.com>

        * 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.

Patch

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 <stdlib.h>
 #include <ctype.h>
+#include <string.h>                    /* 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 <stdlib.h>                    /* 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  <nicola.pero@meta-innovation.com>
+
+	* 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  <nicola.pero@meta-innovation.com>
 
 	* 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