X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/48e3be8aedf3d63652b4d0c6167992164f2d0623..e818f0e07214ed24416c7aedf63d2972e42b9ca4:/Console.cpp diff --git a/Console.cpp b/Console.cpp index 468a6d3..c377db2 100644 --- a/Console.cpp +++ b/Console.cpp @@ -66,10 +66,43 @@ #include #include +static volatile enum { + Working, + Parsing, + Running, + Sending, + Waiting, +} mode_; + static jmp_buf ctrlc_; static void sigint(int) { - longjmp(ctrlc_, 1); + switch (mode_) { + case Working: + return; + case Parsing: + longjmp(ctrlc_, 1); + case Running: + throw "*** Ctrl-C"; + case Sending: + return; + case Waiting: + return; + } +} + +#if YYDEBUG +static bool bison_; +#endif +static bool strict_; + +void Setup(CYDriver &driver, cy::parser &parser) { +#if YYDEBUG + if (bison_) + parser.set_debug_level(1); +#endif + if (strict_) + driver.strict_ = true; } void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expand = false) { @@ -77,12 +110,16 @@ void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expa const char *json; if (socket == -1) { + mode_ = Running; json = CYExecute(pool, data); + mode_ = Working; if (json != NULL) size = strlen(json); } else { + mode_ = Sending; CYSendAll(socket, &size, sizeof(size)); CYSendAll(socket, data, size); + mode_ = Waiting; CYRecvAll(socket, &size, sizeof(size)); if (size == _not(size_t)) json = NULL; @@ -92,6 +129,7 @@ void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expa temp[size] = '\0'; json = temp; } + mode_ = Working; } if (json != NULL && fout != NULL) { @@ -147,13 +185,16 @@ static void Console(int socket) { const char *prompt("cy# "); if (setjmp(ctrlc_) != 0) { + mode_ = Working; fputs("\n", fout); fflush(fout); goto restart; } read: + mode_ = Parsing; char *line(readline(prompt)); + mode_ = Working; if (line == NULL) break; @@ -179,8 +220,17 @@ static void Console(int socket) { } } - lines.push_back(line); command += line; + + char *begin(line), *end(line + strlen(line)); + while (char *nl = reinterpret_cast(memchr(begin, '\n', end - begin))) { + *nl = '\0'; + lines.push_back(begin); + begin = nl + 1; + } + + lines.push_back(begin); + free(line); std::string code; @@ -190,6 +240,7 @@ static void Console(int socket) { else { CYDriver driver(""); cy::parser parser(driver); + Setup(driver, parser); driver.data_ = command.c_str(); driver.size_ = command.size(); @@ -197,7 +248,7 @@ static void Console(int socket) { 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); - if (begin.line != lines.size() || begin.column - 1 != lines.back().size()) { + if (begin.line != lines.size() || begin.column - 1 != lines.back().size() || error->warning_) { cy::position end(error->location_.end); if (begin.line != lines.size()) { @@ -229,14 +280,15 @@ static void Console(int socket) { goto read; } - if (driver.source_ == NULL) + if (driver.program_ == NULL) goto restart; if (socket != -1) code = command; else { std::ostringstream str; - driver.source_->Show(str); + CYOutput out(str); + driver.program_->Multiple(out); code = str.str(); } } @@ -273,14 +325,31 @@ static void *Map(const char *path, size_t *psize) { int main(int argc, char *argv[]) { bool tty(isatty(STDIN_FILENO)); pid_t pid(_not(pid_t)); + bool compile(false); - for (;;) switch (getopt(argc, argv, "p:")) { + for (;;) switch (getopt(argc, argv, "cg:p:s")) { case -1: goto getopt; case '?': - fprintf(stderr, "usage: cycript [-p ] [