]>
git.saurik.com Git - cycript.git/blob - sig/parse.cpp
5 #include "minimal/stdlib.h"
7 #include <apr-1/apr_strings.h>
11 #include "sig/parse.hpp"
15 void (*sig_aggregate
)(apr_pool_t
*pool
, enum Primitive primitive
, const char *name
, struct Signature
*signature
, const char *types
) = NULL
;
17 /* XXX: I really screwed up this time */
18 void *prealloc_(apr_pool_t
*pool
, void *odata
, size_t osize
, size_t nsize
) {
19 void *ndata
= apr_palloc(pool
, nsize
);
20 memcpy(ndata
, odata
, osize
);
24 void sig_parse_signature(apr_pool_t
*pool
, struct Signature
*signature
, const char **name
, char eos
) {
25 _assert(*name
!= NULL
);
27 bool named
= **name
== '"';
29 signature
->elements
= NULL
;
38 signature
->elements
= (struct Element
*) prealloc_(pool
, signature
->elements
, signature
->count
* sizeof(struct Element
), (signature
->count
+ 1) * sizeof(struct Element
));
39 _assert(signature
->elements
!= NULL
);
41 struct Element
*element
= &signature
->elements
[signature
->count
++];
46 char *quote
= strchr(++*name
, '"');
47 element
->name
= apr_pstrmemdup(pool
, *name
, quote
- *name
);
51 element
->type
= sig_parse_type(pool
, name
, eos
, named
);
53 if (**name
< '0' || **name
> '9')
54 element
->offset
= _not(size_t);
59 element
->offset
= element
->offset
* 10 + (*(*name
)++ - '0');
60 while (**name
>= '0' && **name
<= '9');
65 struct Type
*sig_parse_type(apr_pool_t
*pool
, const char **name
, char eos
, bool named
) {
66 char next
= *(*name
)++;
70 struct Type
*type
= (struct Type
*) apr_palloc(pool
, sizeof(struct Type
));
71 _assert(type
!= NULL
);
72 memset(type
, 0, sizeof(struct Type
));
76 case '#': type
->primitive
= typename_P
; break;
79 type
->primitive
= union_P
;
83 case '*': type
->primitive
= string_P
; break;
84 case ':': type
->primitive
= selector_P
; break;
88 char *quote
= strchr(*name
+ 1, '"');
89 if (!named
|| quote
[1] == eos
|| quote
[1] == '"') {
90 type
->name
= apr_pstrmemdup(pool
, *name
+ 1, quote
- *name
- 1);
95 type
->primitive
= object_P
;
98 case 'B': type
->primitive
= boolean_P
; break;
99 case 'C': type
->primitive
= uchar_P
; break;
100 case 'I': type
->primitive
= uint_P
; break;
101 case 'L': type
->primitive
= ulong_P
; break;
102 case 'Q': type
->primitive
= ulonglong_P
; break;
103 case 'S': type
->primitive
= ushort_P
; break;
106 type
->primitive
= array_P
;
107 type
->data
.data
.size
= strtoul(*name
, (char **) name
, 10);
108 type
->data
.data
.type
= sig_parse_type(pool
, name
, eos
, false);
110 printf("']' != \"%s\"\n", *name
);
117 type
->primitive
= pointer_P
;
119 type
->data
.data
.type
= NULL
;
121 } else if (**name
== '"') {
122 type
->data
.data
.type
= NULL
;
124 type
->data
.data
.type
= sig_parse_type(pool
, name
, eos
, named
);
129 type
->primitive
= bit_P
;
130 type
->data
.data
.size
= strtoul(*name
, (char **) name
, 10);
133 case 'c': type
->primitive
= char_P
; break;
134 case 'd': type
->primitive
= double_P
; break;
135 case 'f': type
->primitive
= float_P
; break;
136 case 'i': type
->primitive
= int_P
; break;
137 case 'l': type
->primitive
= long_P
; break;
138 case 'q': type
->primitive
= longlong_P
; break;
139 case 's': type
->primitive
= short_P
; break;
140 case 'v': type
->primitive
= void_P
; break;
143 type
->primitive
= struct_P
;
149 const char *begin
= *name
;
150 do next
= *(*name
)++;
155 size_t length
= *name
- begin
- 1;
156 if (strncmp(begin
, "?", length
) != 0)
157 type
->name
= (char *) apr_pstrmemdup(pool
, begin
, length
);
165 const char *temp
= *name
;
166 sig_parse_signature(pool
, &type
->data
.signature
, name
, end
);
167 types
= (char *) apr_pstrmemdup(pool
, temp
, *name
- temp
- 1);
170 if (type
->name
!= NULL
&& sig_aggregate
!= NULL
) {
171 char *angle
= strchr(type
->name
, '<');
173 (*sig_aggregate
)(pool
, type
->primitive
, type
->name
, &type
->data
.signature
, types
);
175 angle
= (char *) apr_pstrmemdup(pool
, type
->name
, angle
- type
->name
);
176 (*sig_aggregate
)(pool
, type
->primitive
, angle
, &type
->data
.signature
, types
);
181 case 'N': type
->flags
|= JOC_TYPE_INOUT
; goto next
;
182 case 'n': type
->flags
|= JOC_TYPE_IN
; goto next
;
183 case 'O': type
->flags
|= JOC_TYPE_BYCOPY
; goto next
;
184 case 'o': type
->flags
|= JOC_TYPE_OUT
; goto next
;
185 case 'R': type
->flags
|= JOC_TYPE_BYREF
; goto next
;
186 case 'r': type
->flags
|= JOC_TYPE_CONST
; goto next
;
187 case 'V': type
->flags
|= JOC_TYPE_ONEWAY
; goto next
;
195 printf("invalid type character: '%c' {%s}\n", next
, *name
- 10);
202 void Parse(apr_pool_t
*pool
, struct Signature
*signature
, const char *name
) {
203 const char *temp
= name
;
204 sig_parse_signature(pool
, signature
, &temp
, '\0');
205 _assert(temp
[-1] == '\0');
208 const char *sig_unparse_signature(apr_pool_t
*pool
, struct Signature
*signature
) {
209 const char *value
= "";
212 for (offset
= 0; offset
!= signature
->count
; ++offset
) {
213 const char *type
= sig_unparse_type(pool
, signature
->elements
[offset
].type
);
214 value
= apr_pstrcat(pool
, value
, type
, NULL
);
220 const char *sig_unparse_type(apr_pool_t
*pool
, struct Type
*type
) {
223 else switch (type
->primitive
) {
224 case typename_P
: return "#";
225 case union_P
: return apr_psprintf(pool
, "(%s)", sig_unparse_signature(pool
, &type
->data
.signature
));
226 case string_P
: return "*";
227 case selector_P
: return ":";
228 case object_P
: return type
->name
== NULL
? "@" : apr_psprintf(pool
, "@\"%s\"", type
->name
);
229 case boolean_P
: return "B";
230 case uchar_P
: return "C";
231 case uint_P
: return "I";
232 case ulong_P
: return "L";
233 case ulonglong_P
: return "Q";
234 case ushort_P
: return "S";
237 const char *value
= sig_unparse_type(pool
, type
->data
.data
.type
);
238 return apr_psprintf(pool
, "[%lu%s]", type
->data
.data
.size
, value
);
241 case pointer_P
: return apr_psprintf(pool
, "^%s", type
->data
.data
.type
== NULL
? "" : sig_unparse_type(pool
, type
->data
.data
.type
));
242 case bit_P
: return apr_psprintf(pool
, "b%zu", type
->data
.data
.size
);
243 case char_P
: return "c";
244 case double_P
: return "d";
245 case float_P
: return "f";
246 case int_P
: return "i";
247 case long_P
: return "l";
248 case longlong_P
: return "q";
249 case short_P
: return "s";
250 case void_P
: return "v";
251 case struct_P
: return apr_psprintf(pool
, "{%s=%s}", type
->name
== NULL
? "?" : type
->name
, sig_unparse_signature(pool
, &type
->data
.signature
));