2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 /***********************************************************************
26 * Parsing of old-style type strings.
27 **********************************************************************/
29 #include "objc-private.h"
31 /***********************************************************************
35 **********************************************************************/
36 static int SubtypeUntil (const char * type,
40 const char * head = type;
45 if (!*type || (!level && (*type == end)))
46 return (int)(type - head);
50 case ']': case '}': case ')': level--; break;
51 case '[': case '{': case '(': level += 1; break;
57 _objc_fatal ("Object: SubtypeUntil: end of type encountered prematurely\n");
62 /***********************************************************************
64 **********************************************************************/
65 static const char * SkipFirstType (const char * type)
71 case 'O': /* bycopy */
76 case 'V': /* oneway */
77 case '^': /* pointers */
80 case '@': /* objects */
81 if (type[0] == '?') type++; /* Blocks */
86 while ((*type >= '0') && (*type <= '9'))
88 return type + SubtypeUntil (type, ']') + 1;
92 return type + SubtypeUntil (type, '}') + 1;
96 return type + SubtypeUntil (type, ')') + 1;
106 /***********************************************************************
107 * encoding_getNumberOfArguments.
108 **********************************************************************/
110 encoding_getNumberOfArguments(const char *typedesc)
114 // First, skip the return type
115 typedesc = SkipFirstType (typedesc);
117 // Next, skip stack size
118 while ((*typedesc >= '0') && (*typedesc <= '9'))
121 // Now, we have the arguments - count how many
125 // Traverse argument type
126 typedesc = SkipFirstType (typedesc);
128 // Skip GNU runtime's register parameter hint
129 if (*typedesc == '+') typedesc++;
131 // Traverse (possibly negative) argument offset
132 if (*typedesc == '-')
134 while ((*typedesc >= '0') && (*typedesc <= '9'))
137 // Made it past an argument
144 /***********************************************************************
145 * encoding_getSizeOfArguments.
146 **********************************************************************/
148 encoding_getSizeOfArguments(const char *typedesc)
152 // Get our starting points
155 // Skip the return type
156 typedesc = SkipFirstType (typedesc);
158 // Convert ASCII number string to integer
159 while ((*typedesc >= '0') && (*typedesc <= '9'))
160 stack_size = (stack_size * 10) + (*typedesc++ - '0');
166 /***********************************************************************
167 * encoding_getArgumentInfo.
168 **********************************************************************/
170 encoding_getArgumentInfo(const char *typedesc, unsigned int arg,
171 const char **type, int *offset)
175 bool offset_is_negative = NO;
177 // First, skip the return type
178 typedesc = SkipFirstType (typedesc);
180 // Next, skip stack size
181 while ((*typedesc >= '0') && (*typedesc <= '9'))
184 // Now, we have the arguments - position typedesc to the appropriate argument
185 while (*typedesc && nargs != arg)
188 // Skip argument type
189 typedesc = SkipFirstType (typedesc);
193 // Skip GNU runtime's register parameter hint
194 if (*typedesc == '+') typedesc++;
196 // Skip negative sign in offset
197 if (*typedesc == '-')
199 offset_is_negative = YES;
203 offset_is_negative = NO;
205 while ((*typedesc >= '0') && (*typedesc <= '9'))
206 self_offset = self_offset * 10 + (*typedesc++ - '0');
207 if (offset_is_negative)
208 self_offset = -(self_offset);
214 // Skip GNU runtime's register parameter hint
215 if (*typedesc == '+') typedesc++;
217 // Skip (possibly negative) argument offset
218 if (*typedesc == '-')
220 while ((*typedesc >= '0') && (*typedesc <= '9'))
232 typedesc = SkipFirstType (typedesc);
241 // Skip GNU register parameter hint
242 if (*typedesc == '+') typedesc++;
244 // Pick up (possibly negative) argument offset
245 if (*typedesc == '-')
247 offset_is_negative = YES;
251 offset_is_negative = NO;
253 while ((*typedesc >= '0') && (*typedesc <= '9'))
254 arg_offset = arg_offset * 10 + (*typedesc++ - '0');
255 if (offset_is_negative)
256 arg_offset = - arg_offset;
258 *offset = arg_offset - self_offset;
274 encoding_getReturnType(const char *t, char *dst, size_t dst_len)
281 strncpy(dst, "", dst_len);
285 end = SkipFirstType(t);
287 strncpy(dst, t, MIN(len, dst_len));
288 if (len < dst_len) memset(dst+len, 0, dst_len - len);
291 /***********************************************************************
292 * encoding_copyReturnType. Returns the method's return type string
294 **********************************************************************/
296 encoding_copyReturnType(const char *t)
304 end = SkipFirstType(t);
306 result = (char *)malloc(len + 1);
307 strncpy(result, t, len);
314 encoding_getArgumentType(const char *t, unsigned int index,
315 char *dst, size_t dst_len)
323 strncpy(dst, "", dst_len);
327 encoding_getArgumentInfo(t, index, &t, &offset);
330 strncpy(dst, "", dst_len);
334 end = SkipFirstType(t);
336 strncpy(dst, t, MIN(len, dst_len));
337 if (len < dst_len) memset(dst+len, 0, dst_len - len);
341 /***********************************************************************
342 * encoding_copyArgumentType. Returns a single argument's type string
343 * on the heap. Argument 0 is `self`; argument 1 is `_cmd`.
344 **********************************************************************/
346 encoding_copyArgumentType(const char *t, unsigned int index)
355 encoding_getArgumentInfo(t, index, &t, &offset);
359 end = SkipFirstType(t);
361 result = (char *)malloc(len + 1);
362 strncpy(result, t, len);