]>
git.saurik.com Git - cycript.git/blob - sig/parse.cpp
a786039d789ddf3ab175fbba7a6e1e594cf1a5fb
   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 void Parse_(apr_pool_t 
*pool
, struct Signature 
*signature
, const char **name
, char eos
); 
  18 struct Type 
*Parse_(apr_pool_t 
*pool
, const char **name
, char eos
, bool named
); 
  21 /* XXX: I really screwed up this time */ 
  22 void *prealloc_(apr_pool_t 
*pool
, void *odata
, size_t osize
, size_t nsize
) { 
  23     void *ndata 
= apr_palloc(pool
, nsize
); 
  24     memcpy(ndata
, odata
, osize
); 
  28 void Parse_(apr_pool_t 
*pool
, struct Signature 
*signature
, const char **name
, char eos
) { 
  29     _assert(*name 
!= NULL
); 
  31     bool named 
= **name 
== '"'; 
  33     signature
->elements 
= NULL
; 
  42         signature
->elements 
= (struct Element 
*) prealloc_(pool
, signature
->elements
, signature
->count 
* sizeof(struct Element
), (signature
->count 
+ 1) * sizeof(struct Element
)); 
  43         _assert(signature
->elements 
!= NULL
); 
  45         struct Element 
*element 
= &signature
->elements
[signature
->count
++]; 
  50             char *quote 
= strchr(++*name
, '"'); 
  51             element
->name 
= apr_pstrmemdup(pool
, *name
, quote 
- *name
); 
  55         element
->type 
= Parse_(pool
, name
, eos
, named
); 
  57         if (**name 
< '0' || **name 
> '9') 
  58             element
->offset 
= _not(size_t); 
  63                 element
->offset 
= element
->offset 
* 10 + (*(*name
)++ - '0'); 
  64             while (**name 
>= '0' && **name 
<= '9'); 
  69 struct Type 
*Parse_(apr_pool_t 
*pool
, const char **name
, char eos
, bool named
) { 
  70     char next 
= *(*name
)++; 
  74     struct Type 
*type 
= (struct Type 
*) apr_palloc(pool
, sizeof(struct Type
)); 
  75     _assert(type 
!= NULL
); 
  76     memset(type
, 0, sizeof(struct Type
)); 
  80         case '#': type
->primitive 
= typename_P
; break; 
  83             type
->primitive 
= union_P
; 
  87         case '*': type
->primitive 
= string_P
; break; 
  88         case ':': type
->primitive 
= selector_P
; break; 
  92                 char *quote 
= strchr(*name 
+ 1, '"'); 
  93                 if (!named 
|| quote
[1] == eos 
|| quote
[1] == '"') { 
  94                     type
->name 
= apr_pstrmemdup(pool
, *name 
+ 1, quote 
- *name 
- 1); 
  99             type
->primitive 
= object_P
; 
 102         case 'B': type
->primitive 
= boolean_P
; break; 
 103         case 'C': type
->primitive 
= uchar_P
; break; 
 104         case 'I': type
->primitive 
= uint_P
; break; 
 105         case 'L': type
->primitive 
= ulong_P
; break; 
 106         case 'Q': type
->primitive 
= ulonglong_P
; break; 
 107         case 'S': type
->primitive 
= ushort_P
; break; 
 110             type
->primitive 
= array_P
; 
 111             type
->data
.data
.size 
= strtoul(*name
, (char **) name
, 10); 
 112             type
->data
.data
.type 
= Parse_(pool
, name
, eos
, false); 
 114                 printf("']' != \"%s\"\n", *name
); 
 121             type
->primitive 
= pointer_P
; 
 123                 type
->data
.data
.type 
= NULL
; 
 125             } else if (**name 
== '"') { 
 126                 type
->data
.data
.type 
= NULL
; 
 128                 type
->data
.data
.type 
= Parse_(pool
, name
, eos
, named
); 
 133             type
->primitive 
= bit_P
; 
 134             type
->data
.data
.size 
= strtoul(*name
, (char **) name
, 10); 
 137         case 'c': type
->primitive 
= char_P
; break; 
 138         case 'd': type
->primitive 
= double_P
; break; 
 139         case 'f': type
->primitive 
= float_P
; break; 
 140         case 'i': type
->primitive 
= int_P
; break; 
 141         case 'l': type
->primitive 
= long_P
; break; 
 142         case 'q': type
->primitive 
= longlong_P
; break; 
 143         case 's': type
->primitive 
= short_P
; break; 
 144         case 'v': type
->primitive 
= void_P
; break; 
 147             type
->primitive 
= struct_P
; 
 153             const char *begin 
= *name
; 
 154             do next 
= *(*name
)++; 
 159             size_t length 
= *name 
- begin 
- 1; 
 160             if (strncmp(begin
, "?", length
) != 0) 
 161                 type
->name 
= (char *) apr_pstrmemdup(pool
, begin
, length
); 
 169                 const char *temp 
= *name
; 
 170                 Parse_(pool
, &type
->data
.signature
, name
, end
); 
 171                 types 
= (char *) apr_pstrmemdup(pool
, temp
, *name 
- temp 
- 1); 
 174             if (type
->name 
!= NULL 
&& sig_aggregate 
!= NULL
) { 
 175                 char *angle 
= strchr(type
->name
, '<'); 
 177                     (*sig_aggregate
)(pool
, type
->primitive
, type
->name
, &type
->data
.signature
, types
); 
 179                     angle 
= (char *) apr_pstrmemdup(pool
, type
->name
, angle 
- type
->name
); 
 180                     (*sig_aggregate
)(pool
, type
->primitive
, angle
, &type
->data
.signature
, types
); 
 185         case 'N': type
->flags 
|= JOC_TYPE_INOUT
; goto next
; 
 186         case 'n': type
->flags 
|= JOC_TYPE_IN
; goto next
; 
 187         case 'O': type
->flags 
|= JOC_TYPE_BYCOPY
; goto next
; 
 188         case 'o': type
->flags 
|= JOC_TYPE_OUT
; goto next
; 
 189         case 'R': type
->flags 
|= JOC_TYPE_BYREF
; goto next
; 
 190         case 'r': type
->flags 
|= JOC_TYPE_CONST
; goto next
; 
 191         case 'V': type
->flags 
|= JOC_TYPE_ONEWAY
; goto next
; 
 199             printf("invalid type character: '%c' {%s}\n", next
, *name 
- 10); 
 206 void Parse(apr_pool_t 
*pool
, struct Signature 
*signature
, const char *name
) { 
 207     const char *temp 
= name
; 
 208     Parse_(pool
, signature
, &temp
, '\0'); 
 209     _assert(temp
[-1] == '\0'); 
 212 const char *Unparse(apr_pool_t 
*pool
, struct Signature 
*signature
) { 
 213     const char *value 
= ""; 
 216     for (offset 
= 0; offset 
!= signature
->count
; ++offset
) { 
 217         const char *type 
= Unparse(pool
, signature
->elements
[offset
].type
); 
 218         value 
= apr_pstrcat(pool
, value
, type
, NULL
); 
 224 const char *Unparse(apr_pool_t 
*pool
, struct Type 
*type
) { 
 227     else switch (type
->primitive
) { 
 228         case typename_P
: return "#"; 
 229         case union_P
: return apr_psprintf(pool
, "(%s)", Unparse(pool
, &type
->data
.signature
)); 
 230         case string_P
: return "*"; 
 231         case selector_P
: return ":"; 
 232         case object_P
: return type
->name 
== NULL 
? "@" : apr_psprintf(pool
, "@\"%s\"", type
->name
); 
 233         case boolean_P
: return "B"; 
 234         case uchar_P
: return "C"; 
 235         case uint_P
: return "I"; 
 236         case ulong_P
: return "L"; 
 237         case ulonglong_P
: return "Q"; 
 238         case ushort_P
: return "S"; 
 241             const char *value 
= Unparse(pool
, type
->data
.data
.type
); 
 242             return apr_psprintf(pool
, "[%lu%s]", type
->data
.data
.size
, value
); 
 245         case pointer_P
: return apr_psprintf(pool
, "^%s", type
->data
.data
.type 
== NULL 
? "" : Unparse(pool
, type
->data
.data
.type
)); 
 246         case bit_P
: return apr_psprintf(pool
, "b%zu", type
->data
.data
.size
); 
 247         case char_P
: return "c"; 
 248         case double_P
: return "d"; 
 249         case float_P
: return "f"; 
 250         case int_P
: return "i"; 
 251         case long_P
: return "l"; 
 252         case longlong_P
: return "q"; 
 253         case short_P
: return "s"; 
 254         case void_P
: return "v"; 
 255         case struct_P
: return apr_psprintf(pool
, "{%s=%s}", type
->name 
== NULL 
? "?" : type
->name
, Unparse(pool
, &type
->data
.signature
));