From: Jay Freeman (saurik) Date: Sat, 17 Oct 2009 01:39:17 +0000 (+0000) Subject: Improved lexical syntax errors and added not-isatty detection for selecting the parse... X-Git-Tag: v0.9.432~333 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/48e3be8aedf3d63652b4d0c6167992164f2d0623?ds=sidebyside Improved lexical syntax errors and added not-isatty detection for selecting the parser algorithm. --- diff --git a/Console.cpp b/Console.cpp index 25f624e..468a6d3 100644 --- a/Console.cpp +++ b/Console.cpp @@ -72,7 +72,7 @@ static void sigint(int) { longjmp(ctrlc_, 1); } -void Run(int socket, const char *data, size_t size, FILE *fout, bool expand = false) { +void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expand = false) { CYPool pool; const char *json; @@ -120,7 +120,7 @@ void Run(int socket, const char *data, size_t size, FILE *fout, bool expand = fa } } -void Run(int socket, std::string &code, FILE *fout, bool expand = false) { +void Run(int socket, std::string &code, FILE *fout = NULL, bool expand = false) { Run(socket, code.c_str(), code.size(), fout, expand); } @@ -199,20 +199,24 @@ static void Console(int socket) { cy::position begin(error->location_.begin); if (begin.line != lines.size() || begin.column - 1 != lines.back().size()) { cy::position end(error->location_.end); + if (begin.line != lines.size()) { std::cerr << " | "; std::cerr << lines[begin.line - 1] << std::endl; } + std::cerr << " | "; for (size_t i(0); i != begin.column - 1; ++i) std::cerr << '.'; - if (begin.line != end.line) + if (begin.line != end.line || begin.column == end.column) std::cerr << '^'; else for (size_t i(0), e(end.column - begin.column); i != e; ++i) std::cerr << '^'; std::cerr << std::endl; + std::cerr << " | "; std::cerr << error->message_ << std::endl; + add_history(command.c_str()); goto restart; } @@ -267,6 +271,7 @@ 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)); for (;;) switch (getopt(argc, argv, "p:")) { @@ -304,6 +309,11 @@ int main(int argc, char *argv[]) { script = NULL; } + if (script == NULL && !tty && pid != _not(pid_t)) { + fprintf(stderr, "non-terminal attaching to remove console\n"); + return 1; + } + int socket; if (pid == _not(pid_t)) @@ -319,27 +329,36 @@ int main(int argc, char *argv[]) { _syscall(connect(socket, reinterpret_cast(&address), SUN_LEN(&address))); } - if (script == NULL) + if (script == NULL && tty) Console(socket); else { - CYDriver driver(script); + CYDriver driver(script ?: ""); cy::parser parser(driver); - size_t size; - char *start(reinterpret_cast(Map(script, &size))); - char *end(start + size); + char *start, *end; - if (size >= 2 && start[0] == '#' && start[1] == '!') { - start += 2; + if (script == NULL) { + start = NULL; + end = NULL; - if (void *line = memchr(start, '\n', end - start)) - start = reinterpret_cast(line); - else - start = end; - } + driver.file_ = stdin; + } else { + size_t size; + start = reinterpret_cast(Map(script, &size)); + end = start + size; + + if (size >= 2 && start[0] == '#' && start[1] == '!') { + start += 2; - driver.data_ = start; - driver.size_ = end - start; + if (void *line = memchr(start, '\n', end - start)) + start = reinterpret_cast(line); + else + start = end; + } + + driver.data_ = start; + driver.size_ = end - start; + } if (parser.parse() != 0 || !driver.errors_.empty()) { for (CYDriver::Errors::const_iterator i(driver.errors_.begin()); i != driver.errors_.end(); ++i) @@ -351,7 +370,7 @@ int main(int argc, char *argv[]) { std::ostringstream str; driver.source_->Show(str); std::string code(str.str()); - Run(socket, code, stdout); + Run(socket, code); } } diff --git a/Cycript.l b/Cycript.l index 43c9285..2ab8f0c 100644 --- a/Cycript.l +++ b/Cycript.l @@ -35,7 +35,10 @@ int H(char c) { } #define YY_INPUT(data, value, size) { \ - if (yyextra->size_ == 0) \ + if (yyextra->file_ != NULL) { \ + size_t copy(fread(data, 1, size, yyextra->file_)); \ + value = copy == 0 ? YY_NULL : copy; \ + } else if (yyextra->size_ == 0) \ value = YY_NULL; \ else { \ size_t copy(std::min(size, yyextra->size_)); \ @@ -231,7 +234,7 @@ Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4} [ \t] L <> L yyterminate(); -. { +. L { CYDriver::Error error; error.location_ = *yylloc; error.message_ = "syntax error, unknown token"; diff --git a/Library.mm b/Library.mm index 2c22bb1..c9fea30 100644 --- a/Library.mm +++ b/Library.mm @@ -2769,6 +2769,7 @@ CYDriver::CYDriver(const std::string &filename) : state_(CYClear), data_(NULL), size_(0), + file_(NULL), filename_(filename), source_(NULL) { diff --git a/Parser.hpp b/Parser.hpp index 88a4b13..8e6a59d 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -159,6 +159,7 @@ class CYDriver { const char *data_; size_t size_; + FILE *file_; std::string filename_;