-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2015 Jay Freeman (saurik)
+/* Cycript - The Truly Universal Scripting Language
+ * Copyright (C) 2009-2016 Jay Freeman (saurik)
*/
/* GNU Affero General Public License, Version 3 {{{ */
case Parsing:
longjmp(ctrlc_, 1);
case Running:
+#ifndef __ANDROID__
CYCancel();
+#endif
return;
case Sending:
return;
if (*character == '\x01') *character = '\n';
}
- ~History() {
+ ~History() { try {
for (HIST_ENTRY *history((history_set_pos(0), current_history())); history; history = next_history())
for (char *character(history->line); *character; ++character)
if (*character == '\n') *character = '\x01';
} else {
_assert(write_history(histfile_.c_str()) == 0);
}
- }
+ } catch (const CYException &error) {
+ CYPool pool;
+ std::cout << error.PoolCString(pool) << std::endl;
+ } }
void operator +=(std::string command) {
add_history(command.c_str());
return NULL;
}
+static void _lblcall(int (*command)(int, int), int count, int key) {
+ int last(_rl_last_c_pos);
+ // rl_rubout crashes in _rl_erase_at_end_of_line if _rl_last_c_pos != 0
+ if (command == &rl_rubout)
+ _rl_last_c_pos = 0;
+ for (int i(0); i != count; ++i)
+ if (command(1, key) != 0)
+ _assert(false);
+ _rl_last_c_pos = last;
+}
+
static int CYConsoleKeyReturn(int count, int key) {
if (rl_point != rl_end) {
- if (memchr(rl_line_buffer, '\n', rl_end) == NULL)
- return rl_newline(count, key);
+ if (memchr(rl_line_buffer, '\n', rl_end) == NULL) {
+ _lblcall(&rl_newline, count, key);
+ return 0;
+ }
insert:
char *before(CYmemrchr(rl_line_buffer, '\n', rl_point));
int adjust(rl_line_buffer + space - 1 - before);
if (space == rl_point && adjust != 0)
- rl_rubout(adjust, '\b');
+ _lblcall(&rl_rubout, adjust, '\b');
- rl_insert(count, '\n');
+ _lblcall(&rl_insert, count, '\n');
if (adjust != 0)
- rl_insert(adjust, ' ');
+ _lblcall(&rl_insert, adjust, ' ');
return 0;
}
done = true;
}
- if (done)
- return rl_newline(count, key);
+ if (done) {
+ _lblcall(&rl_newline, count, key);
+ return 0;
+ }
// XXX: this was the most obvious fix, but is seriously dumb
goto insert;
}
static int CYConsoleKeyUp(int count, int key) {
- while (count-- != 0) {
+ for (; count != 0; --count) {
char *after(CYmemrchr(rl_line_buffer, '\n', rl_point));
if (after == NULL) {
if (int value = rl_get_previous_history(1, key))
}
static int CYConsoleKeyDown(int count, int key) {
- while (count-- != 0) {
+ for (; count != 0; --count) {
char *after(static_cast<char *>(memchr(rl_line_buffer + rl_point, '\n', rl_end - rl_point)));
if (after == NULL) {
int where(where_history());
}
static int CYConsoleKeyBack(int count, int key) {
- while (count-- != 0) {
+ for (; count != 0; --count) {
+ if (rl_point == 0)
+ return 1;
+
char *before(CYmemrchr(rl_line_buffer, '\n', rl_point));
- if (before == NULL)
- return rl_rubout(count, key);
+ if (before == NULL) {
+ int adjust(std::min(count, rl_point));
+ _lblcall(&rl_rubout, adjust, key);
+ count -= adjust - 1;
+ continue;
+ }
int start(before + 1 - rl_line_buffer);
if (start == rl_point) rubout: {
- rl_rubout(1, key);
+ _lblcall(&rl_rubout, 1, key);
continue;
}
for (int i(start); i != rl_point; ++i)
if (rl_line_buffer[i] != ' ')
goto rubout;
- rl_rubout((rl_point - start) % 4 ?: 4, key);
+ _lblcall(&rl_rubout, (rl_point - start) % 4 ?: 4, key);
}
return 0;
for (int i(start); i != rl_point; ++i)
if (rl_line_buffer[i] != ' ')
goto complete;
- return rl_insert(4 - (rl_point - start) % 4, ' ');
+ _lblcall(&rl_insert, 4 - (rl_point - start) % 4, ' ');
+ return 0;
}
static void CYConsoleRemapBind(Keymap map, rl_command_func_t *from, rl_command_func_t *to) {
CYConsoleRemapKeys(vi_movement_keymap);
}
+static void CYOutputRun(const std::string &code, bool expand = false) {
+ CYPool pool;
+ Output(Run(pool, client_, code), &std::cout, expand);
+}
+
static void Console(CYOptions &options) {
std::string basedir;
+#ifdef __ANDROID__
+ basedir = "/data/local/tmp";
+#else
if (const char *home = getenv("HOME"))
basedir = home;
else {
passwd = getpwuid(getuid());
basedir = passwd->pw_dir;
}
+#endif
basedir += "/.cycript";
mkdir(basedir.c_str(), 0700);
rl_completer_word_break_characters = break_;
rl_attempted_completion_function = &Complete;
- rl_redisplay_function = CYDisplayUpdate;
- rl_prep_term_function = CYConsolePrepTerm;
+ if (cur_term != NULL) {
+ rl_redisplay_function = CYDisplayUpdate;
+ rl_prep_term_function = CYConsolePrepTerm;
+ }
+
+ CYOutputRun("");
struct sigaction action;
sigemptyset(&action.sa_mask);
std::cout << std::endl;
}
- CYPool pool;
- Output(Run(pool, client_, code), &std::cout, expand);
+ CYOutputRun(code, expand);
}
}
}
} file(address.sun_path);
- _syscall(bind(server, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
+ _syscall(bind(server, reinterpret_cast<sockaddr *>(&address), sizeof(address)));
_syscall(chmod(address.sun_path, 0777));
_syscall(listen(server, 1));
return 0;
}
-int main(int argc, char * const argv[], char const * const envp[]) {
+_visible int main(int argc, char * const argv[], char const * const envp[]) {
try {
return Main(argc, argv, envp);
} catch (const CYException &error) {