]> git.saurik.com Git - cycript.git/blobdiff - sig/parse.cpp
Added cyrver to make clean, fixed GC protection for CYJS*, implemented array comprehe...
[cycript.git] / sig / parse.cpp
index a786039d789ddf3ab175fbba7a6e1e594cf1a5fb..2f007de986ba67abc9d3c1f43e047162bca0b8fc 100644 (file)
@@ -1,3 +1,42 @@
+/* Cycript - Remove Execution Server and Disassembler
+ * Copyright (C) 2009  Jay Freeman (saurik)
+*/
+
+/* Modified BSD License {{{ */
+/*
+ *        Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer in the documentation
+ *    and/or other materials provided with the
+ *    distribution.
+ * 3. The name of the author may not be used to endorse
+ *    or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* }}} */
+
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
 
 namespace sig {
 
-void (*sig_aggregate)(apr_pool_t *pool, enum Primitive primitive, const char *name, struct Signature *signature, const char *types) = NULL;
-
-void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos);
-struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named);
+void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos, Callback callback);
+struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, Callback callback);
 
 
 /* XXX: I really screwed up this time */
@@ -25,10 +62,11 @@ void *prealloc_(apr_pool_t *pool, void *odata, size_t osize, size_t nsize) {
     return ndata;
 }
 
-void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos) {
+void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos, Callback callback) {
     _assert(*name != NULL);
 
-    bool named = **name == '"';
+    // XXX: this is just a stupid check :(
+    bool named(**name == '"');
 
     signature->elements = NULL;
     signature->count = 0;
@@ -52,7 +90,7 @@ void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, ch
             *name = quote + 1;
         }
 
-        element->type = Parse_(pool, name, eos, named);
+        element->type = Parse_(pool, name, eos, named, callback);
 
         if (**name < '0' || **name > '9')
             element->offset = _not(size_t);
@@ -66,7 +104,7 @@ void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, ch
     }
 }
 
-struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) {
+struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, Callback callback) {
     char next = *(*name)++;
     if (next == '?')
         return NULL;
@@ -80,7 +118,10 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) {
         case '#': type->primitive = typename_P; break;
 
         case '(':
-            type->primitive = union_P;
+            if (type->data.signature.count < 2)
+                type->primitive = struct_P;
+            else
+                type->primitive = union_P;
             next = ')';
         goto aggregate;
 
@@ -109,7 +150,7 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) {
         case '[':
             type->primitive = array_P;
             type->data.data.size = strtoul(*name, (char **) name, 10);
-            type->data.data.type = Parse_(pool, name, eos, false);
+            type->data.data.type = Parse_(pool, name, eos, false, callback);
             if (**name != ']') {
                 printf("']' != \"%s\"\n", *name);
                 _assert(false);
@@ -119,13 +160,13 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) {
 
         case '^':
             type->primitive = pointer_P;
-            if (**name == 'v') {
-                type->data.data.type = NULL;
-                ++*name;
-            } else if (**name == '"') {
+            if (**name == '"') {
                 type->data.data.type = NULL;
             } else {
-                type->data.data.type = Parse_(pool, name, eos, named);
+                type->data.data.type = Parse_(pool, name, eos, named, callback);
+                sig::Type *&target(type->data.data.type);
+                if (target != NULL && target->primitive == void_P)
+                    target = NULL;
             }
         break;
 
@@ -162,24 +203,19 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) {
             else
                 type->name = NULL;
 
+            // XXX: this types thing is a throwback to JocStrap
+
             char *types;
-            if (next != '=')
+            if (next != '=') {
                 types = NULL;
-            else {
-                const char *temp = *name;
-                Parse_(pool, &type->data.signature, name, end);
+            else {
+                const char *temp(*name);
+                Parse_(pool, &type->data.signature, name, end, callback);
                 types = (char *) apr_pstrmemdup(pool, temp, *name - temp - 1);
             }
 
-            if (type->name != NULL && sig_aggregate != NULL) {
-                char *angle = strchr(type->name, '<');
-                if (angle == NULL)
-                    (*sig_aggregate)(pool, type->primitive, type->name, &type->data.signature, types);
-                else {
-                    angle = (char *) apr_pstrmemdup(pool, type->name, angle - type->name);
-                    (*sig_aggregate)(pool, type->primitive, angle, &type->data.signature, types);
-                }
-            }
+            if (callback != NULL)
+                (*callback)(pool, type->name, types, type);
         } break;
 
         case 'N': type->flags |= JOC_TYPE_INOUT; goto next;
@@ -203,9 +239,9 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named) {
     return type;
 }
 
-void Parse(apr_pool_t *pool, struct Signature *signature, const char *name) {
+void Parse(apr_pool_t *pool, struct Signature *signature, const char *name, Callback callback) {
     const char *temp = name;
-    Parse_(pool, signature, &temp, '\0');
+    Parse_(pool, signature, &temp, '\0', callback);
     _assert(temp[-1] == '\0');
 }