+ done:
+ *out << std::endl;
+}
+
+static void Run(int client, bool syntax, const char *data, size_t size, std::ostream *out = NULL, bool expand = false) {
+ CYPool pool;
+ Output(syntax, Run(pool, client, CYUTF8String(data, size)), out, expand);
+}
+
+static void Run(int client, bool syntax, std::string &code, std::ostream *out = NULL, bool expand = false) {
+ Run(client, syntax, code.c_str(), code.size(), out, expand);
+}
+
+int (*append_history$)(int, const char *);
+
+static std::string command_;
+
+static int client_;
+
+static CYUTF8String Run(CYPool &pool, const std::string &code) {
+ return Run(pool, client_, code);
+}
+
+static char **Complete(const char *word, int start, int end) {
+ rl_attempted_completion_over = ~0;
+ std::string line(rl_line_buffer, start);
+ return CYComplete(word, command_ + line, &Run);
+}
+
+// need char *, not const char *
+static char name_[] = "cycript";
+static char break_[] = " \t\n\"\\'`@><=;|&{(" ")}" ".:[]";
+
+class History {
+ private:
+ std::string histfile_;
+ size_t histlines_;
+
+ public:
+ History(std::string histfile) :
+ histfile_(histfile),
+ histlines_(0)
+ {
+ read_history(histfile_.c_str());
+ }
+
+ ~History() {
+ if (append_history$ != NULL) {
+ 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);
+ }
+ }
+
+ void operator +=(const std::string &command) {
+ add_history(command.c_str());
+ ++histlines_;
+ }
+};
+
+static void Console(CYOptions &options) {
+ 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;
+ }
+
+ basedir += "/.cycript";
+ mkdir(basedir.c_str(), 0700);
+
+ rl_initialize();
+ rl_readline_name = name_;
+
+ History history(basedir + "/history");