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); } }
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; } }
unsigned int method_getNumberOfArguments (struct objc_method *method) { if (method == NULL) return 0; else { unsigned int i = 0; const char *type = method->method_types; while (*type) { type = objc_skip_argspec (type); i += 1; } if (i == 0) { /* This could only happen if method_types is invalid; in that case, return 0. */ return 0; } else { /* Remove the return type. */ return (i - 1); } } }
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); } }
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_get_nth_argument (struct objc_method* m, arglist_t argframe, int arg, const char **type) { const char* t = objc_skip_argspec (m->method_types); if (arg > method_get_number_of_arguments (m)) return 0; while (arg--) t = objc_skip_argspec (t); *type = t; t = objc_skip_typespec (t); if (*t == '+') return argframe->arg_regs + atoi (++t); else return argframe->arg_ptr + atoi (t); }
/* Return the number of arguments that the method MTH expects. Note that all methods need two implicit arguments `self' and `_cmd'. */ int method_get_number_of_arguments (struct objc_method* mth) { int i = 0; const char* type = mth->method_types; while (*type) { type = objc_skip_argspec (type); i += 1; } return i - 1; }
char * method_get_next_argument (arglist_t argframe, const char **type) { const char *t = objc_skip_argspec (*type); if (*t == '\0') return 0; *type = t; t = objc_skip_typespec (t); if (*t == '+') return argframe->arg_regs + atoi (++t); else return argframe->arg_ptr + atoi (t); }