X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/ea2d184cbcdf25cfa51727f175356fe2ee211136..e52c39bcd7a4d9cdd6084fb0b982b4bd51c5d94f:/sig/parse.cpp diff --git a/sig/parse.cpp b/sig/parse.cpp index cf628a8..7fc663f 100644 --- a/sig/parse.cpp +++ b/sig/parse.cpp @@ -1,18 +1,55 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include "minimal/stdlib.h" - -#include - -#include - +/* Cycript - Inlining/Optimizing JavaScript Compiler + * 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. +*/ +/* }}} */ + +#include #include "sig/parse.hpp" +#include "Error.hpp" + +#include +#include +#include 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, 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 */ void *prealloc_(apr_pool_t *pool, void *odata, size_t osize, size_t nsize) { @@ -21,10 +58,11 @@ void *prealloc_(apr_pool_t *pool, void *odata, size_t osize, size_t nsize) { return ndata; } -void sig_parse_signature(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; @@ -43,12 +81,12 @@ void sig_parse_signature(apr_pool_t *pool, struct Signature *signature, const ch 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->type = sig_parse_type(pool, name, eos, named); + element->type = Parse_(pool, name, eos, named, callback); if (**name < '0' || **name > '9') element->offset = _not(size_t); @@ -62,7 +100,7 @@ void sig_parse_signature(apr_pool_t *pool, struct Signature *signature, const ch } } -struct Type *sig_parse_type(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; @@ -76,7 +114,10 @@ struct Type *sig_parse_type(apr_pool_t *pool, const char **name, char eos, bool 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; @@ -85,7 +126,7 @@ struct Type *sig_parse_type(apr_pool_t *pool, const char **name, char eos, bool case '@': if (**name == '"') { - char *quote = strchr(*name + 1, '"'); + 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; @@ -105,7 +146,7 @@ struct Type *sig_parse_type(apr_pool_t *pool, const char **name, char eos, bool case '[': type->primitive = array_P; type->data.data.size = strtoul(*name, (char **) name, 10); - type->data.data.type = sig_parse_type(pool, name, eos, false); + type->data.data.type = Parse_(pool, name, eos, false, callback); if (**name != ']') { printf("']' != \"%s\"\n", *name); _assert(false); @@ -115,13 +156,13 @@ struct Type *sig_parse_type(apr_pool_t *pool, const char **name, char eos, bool 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 = sig_parse_type(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; @@ -158,24 +199,10 @@ struct Type *sig_parse_type(apr_pool_t *pool, const char **name, char eos, bool else type->name = NULL; - char *types; - if (next != '=') - types = NULL; - else { - const char *temp = *name; - sig_parse_signature(pool, &type->data.signature, name, end); - types = (char *) apr_pstrmemdup(pool, temp, *name - temp - 1); - } + // XXX: this types thing is a throwback to JocStrap - 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 (next == '=') + Parse_(pool, &type->data.signature, name, end, callback); } break; case 'N': type->flags |= JOC_TYPE_INOUT; goto next; @@ -196,33 +223,36 @@ struct Type *sig_parse_type(apr_pool_t *pool, const char **name, char eos, bool _assert(false); } + if (callback != NULL) + (*callback)(pool, type); + 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; - sig_parse_signature(pool, signature, &temp, '\0'); + Parse_(pool, signature, &temp, '\0', callback); _assert(temp[-1] == '\0'); } -const char *sig_unparse_signature(apr_pool_t *pool, struct Signature *signature) { +const char *Unparse(apr_pool_t *pool, struct Signature *signature) { const char *value = ""; size_t offset; for (offset = 0; offset != signature->count; ++offset) { - const char *type = sig_unparse_type(pool, signature->elements[offset].type); + const char *type = Unparse(pool, signature->elements[offset].type); value = apr_pstrcat(pool, value, type, NULL); } return value; } -const char *sig_unparse_type(apr_pool_t *pool, struct Type *type) { +const char *Unparse(apr_pool_t *pool, struct Type *type) { if (type == NULL) return "?"; else switch (type->primitive) { case typename_P: return "#"; - case union_P: return apr_psprintf(pool, "(%s)", sig_unparse_signature(pool, &type->data.signature)); + case union_P: return apr_psprintf(pool, "(%s)", Unparse(pool, &type->data.signature)); case string_P: return "*"; case selector_P: return ":"; case object_P: return type->name == NULL ? "@" : apr_psprintf(pool, "@\"%s\"", type->name); @@ -234,12 +264,12 @@ const char *sig_unparse_type(apr_pool_t *pool, struct Type *type) { case ushort_P: return "S"; case array_P: { - const char *value = sig_unparse_type(pool, type->data.data.type); - return apr_psprintf(pool, "[%lu%s]", type->data.data.size, value); + const char *value = Unparse(pool, type->data.data.type); + return apr_psprintf(pool, "[%"APR_SIZE_T_FMT"%s]", type->data.data.size, value); } break; - case pointer_P: return apr_psprintf(pool, "^%s", type->data.data.type == NULL ? "" : sig_unparse_type(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"; @@ -248,7 +278,7 @@ const char *sig_unparse_type(apr_pool_t *pool, struct Type *type) { case longlong_P: return "q"; case short_P: return "s"; case void_P: return "v"; - case struct_P: return apr_psprintf(pool, "{%s=%s}", type->name == NULL ? "?" : type->name, sig_unparse_signature(pool, &type->data.signature)); + case struct_P: return apr_psprintf(pool, "{%s=%s}", type->name == NULL ? "?" : type->name, Unparse(pool, &type->data.signature)); } _assert(false);