Use a dummy space to handle the lower-right corner.
[cycript.git] / sig / parse.cpp
index 18f0668f4e094d50c8a4964248790f74adef52d5..51782d2f98f0175c6dffcb22a42e1a75093bc240 100644 (file)
@@ -1,53 +1,31 @@
-/* Cycript - Remove Execution Server and Disassembler
- * Copyright (C) 2009  Jay Freeman (saurik)
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2012  Jay Freeman (saurik)
 */
 
 */
 
-/* Modified BSD License {{{ */
+/* GNU Lesser General Public License, Version 3 {{{ */
 /*
 /*
- *        Redistribution and use in source and binary
- * forms, with or without modification, are permitted
- * provided that the following conditions are met:
+ * Cycript is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
  *
  *
- * 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.
+ * Cycript is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
  *
  *
- * 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.
-*/
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Cycript.  If not, see <http://www.gnu.org/licenses/>.
+**/
 /* }}} */
 
 /* }}} */
 
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include "minimal/stdlib.h"
-
-#include <apr-1/apr_strings.h>
-
-#include <string.h>
-
+#include <apr_strings.h>
 #include "sig/parse.hpp"
 #include "sig/parse.hpp"
+#include "Error.hpp"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
 
 namespace sig {
 
 
 namespace sig {
 
@@ -85,7 +63,7 @@ void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, ch
         if (**name != '"')
             element->name = NULL;
         else {
         if (**name != '"')
             element->name = NULL;
         else {
-            char *quote = strchr(++*name, '"');
+            const char *quote = strchr(++*name, '"');
             element->name = apr_pstrmemdup(pool, *name, quote - *name);
             *name = quote + 1;
         }
             element->name = apr_pstrmemdup(pool, *name, quote - *name);
             *name = quote + 1;
         }
@@ -128,17 +106,25 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, C
         case '*': type->primitive = string_P; break;
         case ':': type->primitive = selector_P; break;
 
         case '*': type->primitive = string_P; break;
         case ':': type->primitive = selector_P; break;
 
-        case '@':
-            if (**name == '"') {
-                char *quote = strchr(*name + 1, '"');
-                if (!named || quote[1] == eos || quote[1] == '"') {
-                    type->name = apr_pstrmemdup(pool, *name + 1, quote - *name - 1);
-                    *name = quote + 1;
+        case '@': {
+            char next(**name);
+
+            if (next == '?') {
+                type->primitive = block_P;
+                ++*name;
+            } else {
+                type->primitive = object_P;
+
+                if (next == '"') {
+                    const char *quote = strchr(*name + 1, '"');
+                    if (!named || quote[1] == eos || quote[1] == '"') {
+                        type->name = apr_pstrmemdup(pool, *name + 1, quote - *name - 1);
+                        *name = quote + 1;
+                    }
                 }
             }
 
                 }
             }
 
-            type->primitive = object_P;
-        break;
+        } break;
 
         case 'B': type->primitive = boolean_P; break;
         case 'C': type->primitive = uchar_P; break;
 
         case 'B': type->primitive = boolean_P; break;
         case 'C': type->primitive = uchar_P; break;
@@ -164,8 +150,9 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, C
                 type->data.data.type = NULL;
             } else {
                 type->data.data.type = Parse_(pool, name, eos, named, callback);
                 type->data.data.type = NULL;
             } else {
                 type->data.data.type = Parse_(pool, name, eos, named, callback);
-                if (type->data.data.type->primitive == void_P)
-                    type->data.data.type = NULL;
+                sig::Type *&target(type->data.data.type);
+                if (target != NULL && target->primitive == void_P)
+                    target = NULL;
             }
         break;
 
             }
         break;
 
@@ -204,17 +191,8 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, C
 
             // XXX: this types thing is a throwback to JocStrap
 
 
             // XXX: this types thing is a throwback to JocStrap
 
-            char *types;
-            if (next != '=') {
-                types = NULL;
-            } else {
-                const char *temp(*name);
+            if (next == '=')
                 Parse_(pool, &type->data.signature, name, end, callback);
                 Parse_(pool, &type->data.signature, name, end, callback);
-                types = (char *) apr_pstrmemdup(pool, temp, *name - temp - 1);
-            }
-
-            if (callback != NULL)
-                (*callback)(pool, type->name, types, type);
         } break;
 
         case 'N': type->flags |= JOC_TYPE_INOUT; goto next;
         } break;
 
         case 'N': type->flags |= JOC_TYPE_INOUT; goto next;
@@ -235,6 +213,9 @@ struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, C
             _assert(false);
     }
 
             _assert(false);
     }
 
+    if (callback != NULL)
+        (*callback)(pool, type);
+
     return type;
 }
 
     return type;
 }
 
@@ -264,6 +245,7 @@ const char *Unparse(apr_pool_t *pool, struct Type *type) {
         case union_P: return apr_psprintf(pool, "(%s)", Unparse(pool, &type->data.signature));
         case string_P: return "*";
         case selector_P: return ":";
         case union_P: return apr_psprintf(pool, "(%s)", Unparse(pool, &type->data.signature));
         case string_P: return "*";
         case selector_P: return ":";
+        case block_P: return "@?";
         case object_P: return type->name == NULL ? "@" : apr_psprintf(pool, "@\"%s\"", type->name);
         case boolean_P: return "B";
         case uchar_P: return "C";
         case object_P: return type->name == NULL ? "@" : apr_psprintf(pool, "@\"%s\"", type->name);
         case boolean_P: return "B";
         case uchar_P: return "C";
@@ -274,11 +256,11 @@ const char *Unparse(apr_pool_t *pool, struct Type *type) {
 
         case array_P: {
             const char *value = Unparse(pool, type->data.data.type);
 
         case array_P: {
             const char *value = Unparse(pool, type->data.data.type);
-            return apr_psprintf(pool, "[%lu%s]", type->data.data.size, value);
+            return apr_psprintf(pool, "[%"APR_SIZE_T_FMT"%s]", type->data.data.size, value);
         } break;
 
         } break;
 
-        case pointer_P: return apr_psprintf(pool, "^%s", type->data.data.type == NULL ? "" : Unparse(pool, type->data.data.type));
-        case bit_P: return apr_psprintf(pool, "b%zu", type->data.data.size);
+        case pointer_P: return apr_psprintf(pool, "^%s", type->data.data.type == NULL ? "v" : Unparse(pool, type->data.data.type));
+        case bit_P: return apr_psprintf(pool, "b%"APR_SIZE_T_FMT"", type->data.data.size);
         case char_P: return "c";
         case double_P: return "d";
         case float_P: return "f";
         case char_P: return "c";
         case double_P: return "d";
         case float_P: return "f";