X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/f43fcb8535894f72761f717a792f91ac94364356..def9084602162fbc6081fadd247ad50a78ad0bce:/Console.cpp?ds=inline diff --git a/Console.cpp b/Console.cpp index dbb8baa..a7e0929 100644 --- a/Console.cpp +++ b/Console.cpp @@ -1,21 +1,21 @@ /* Cycript - Optimizing JavaScript Compiler/Runtime - * Copyright (C) 2009-2013 Jay Freeman (saurik) + * Copyright (C) 2009-2015 Jay Freeman (saurik) */ -/* GNU General Public License, Version 3 {{{ */ +/* GNU Affero General Public License, Version 3 {{{ */ /* - * Cycript is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation, either version 3 of the License, - * or (at your option) any later version. - * - * Cycript is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Cycript. If not, see . + * GNU Affero General Public License for more details. + + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . **/ /* }}} */ @@ -44,6 +44,8 @@ #endif #include +#include +#include #include #include @@ -58,10 +60,6 @@ #include #include -#include -#include -#include - #include #include "Display.hpp" @@ -87,7 +85,8 @@ static void sigint(int) { case Parsing: longjmp(ctrlc_, 1); case Running: - throw "*** Ctrl-C"; + CYCancel(); + return; case Sending: return; case Waiting: @@ -227,17 +226,20 @@ static CYExpression *ParseExpression(CYUTF8String code) { CYOptions options; CYContext context(options); - // XXX: this could be replaced with a CYStatement::Primitive() - if (CYExpress *express = dynamic_cast(driver.program_->statements_)) - return express->expression_->Primitive(context); + CYStatement *statement(driver.program_->statements_); + _assert(statement != NULL); + _assert(statement->next_ == NULL); - return NULL; + CYExpress *express(dynamic_cast(driver.program_->statements_)); + _assert(express != NULL); + + return express->expression_; } static int client_; static char **Complete(const char *word, int start, int end) { - rl_attempted_completion_over = TRUE; + rl_attempted_completion_over = ~0; CYLocalPool pool; @@ -295,7 +297,7 @@ static char **Complete(const char *word, int start, int end) { " var before = prefix.length;\n" " prefix += word;\n" " var entire = prefix.length;\n" - " for (name in object)\n" + " for (var name in object)\n" " if (name.substring(0, entire) == prefix)\n" " names.push(name.substr(before));\n" " return names;\n" @@ -316,8 +318,7 @@ static char **Complete(const char *word, int start, int end) { if (result == NULL) return NULL; - CYArray *array(dynamic_cast(result)); - + CYArray *array(dynamic_cast(result->Primitive(context))); if (array == NULL) { *out_ << '\n'; Output(false, json, out_); @@ -403,7 +404,8 @@ class History { ~History() { if (append_history$ != NULL) { - _syscall(close(_syscall(open(histfile_.c_str(), O_CREAT | O_WRONLY, 0600)))); + int fd(_syscall(open(histfile_.c_str(), O_CREAT | O_WRONLY, 0600))); + _syscall(close(fd)); _assert((*append_history$)(histlines_, histfile_.c_str()) == 0); } else { _assert(write_history(histfile_.c_str()) == 0); @@ -417,15 +419,18 @@ class History { }; static void Console(CYOptions &options) { - CYPool pool; - - passwd *passwd; - if (const char *username = getenv("LOGNAME")) - passwd = getpwnam(username); - else - passwd = getpwuid(getuid()); + std::string basedir; + if (const char *home = getenv("HOME")) + basedir = home; + else { + passwd *passwd; + if (const char *username = getenv("LOGNAME")) + passwd = getpwnam(username); + else + passwd = getpwuid(getuid()); + basedir = passwd->pw_dir; + } - std::string basedir(passwd->pw_dir); basedir += "/.cycript"; mkdir(basedir.c_str(), 0700); @@ -497,6 +502,14 @@ static void Console(CYOptions &options) { } else if (data == "debug") { debug = !debug; *out_ << "debug == " << (debug ? "true" : "false") << std::endl; + } else if (data == "destroy") { + CYDestroyContext(); + } else if (data == "gc") { + *out_ << "collecting... " << std::flush; + CYGarbageCollect(CYGetJSContext()); + *out_ << "done." << std::endl; + } else if (data == "exit") { + return; } else if (data == "expand") { expand = !expand; *out_ << "expand == " << (expand ? "true" : "false") << std::endl; @@ -541,9 +554,9 @@ static void Console(CYOptions &options) { if (parser.parse() != 0 || !driver.errors_.empty()) { for (CYDriver::Errors::const_iterator error(driver.errors_.begin()); error != driver.errors_.end(); ++error) { - cy::position begin(error->location_.begin); + CYPosition begin(error->location_.begin); if (begin.line != lines.size() || begin.column < lines.back().size() || error->warning_) { - cy::position end(error->location_.end); + CYPosition end(error->location_.end); if (begin.line != lines.size()) { std::cerr << " | "; @@ -596,16 +609,12 @@ static void Console(CYOptions &options) { } } -void InjectLibrary(pid_t pid); - -int Main(int argc, char const * const argv[], char const * const envp[]) { - _aprcall(apr_initialize()); - - apr_pool_t *pool; - apr_pool_create(&pool, NULL); +void InjectLibrary(pid_t, int, const char *[]); +int Main(int argc, char * const argv[], char const * const envp[]) { bool tty(isatty(STDIN_FILENO)); bool compile(false); + bool target(false); CYOptions options; append_history$ = (int (*)(int, const char *)) (dlsym(RTLD_DEFAULT, "append_history")); @@ -617,27 +626,35 @@ int Main(int argc, char const * const argv[], char const * const envp[]) { const char *host(NULL); const char *port(NULL); - apr_getopt_t *state; - _aprcall(apr_getopt_init(&state, pool, argc, argv)); + optind = 1; for (;;) { - char opt; - const char *arg; - - apr_status_t status(apr_getopt(state, - "cg:n:" + int option(getopt_long(argc, argv, + "c" + "g:" + "n:" #ifdef CY_ATTACH "p:" #endif "r:" "s" - , &opt, &arg)); + , (const struct option[]) { + {NULL, no_argument, NULL, 'c'}, + {NULL, required_argument, NULL, 'g'}, + {NULL, required_argument, NULL, 'n'}, +#ifdef CY_ATTACH + {NULL, required_argument, NULL, 'p'}, +#endif + {NULL, required_argument, NULL, 'r'}, + {NULL, no_argument, NULL, 's'}, + {0, 0, 0, 0}}, NULL)); - switch (status) { - case APR_EOF: + switch (option) { + case -1: goto getopt; - case APR_BADCH: - case APR_BADARG: + + case ':': + case '?': fprintf(stderr, "usage: cycript [-c]" #ifdef CY_ATTACH @@ -647,21 +664,30 @@ int Main(int argc, char const * const argv[], char const * const envp[]) { " [