diff --git a/interface.c b/interface.c index e9d06c1..8bf80df 100644 --- a/interface.c +++ b/interface.c @@ -85,7 +85,7 @@ char *line_ptr; int in_chat_mode; tgl_peer_id_t chat_mode_id; - +extern int readline_disabled; int is_same_word (const char *s, size_t l, const char *word) { return s && word && strlen (word) == l && !memcmp (s, word, l); @@ -276,10 +276,12 @@ char *complete_none (const char *text UU, int state UU) { void set_prompt (const char *s) { + if (readline_disabled) { return; } rl_set_prompt (s); } void update_prompt (void) { + if (readline_disabled) { return; } print_start (); set_prompt (get_default_prompt ()); if (readline_active) { @@ -1065,6 +1067,7 @@ void interpreter (char *line UU) { static char stat_buf[1 << 15]; tgl_print_stat (stat_buf, (1 << 15) - 1); printf ("%s\n", stat_buf); + fflush (stdout); } else if (IS_WORD ("msg")) { GET_PEER; int t; @@ -1578,6 +1581,7 @@ char *saved_line; int prompt_was; void print_start (void) { if (in_readline) { return; } + if (readline_disabled) { return; } assert (!prompt_was); if (readline_active) { saved_point = rl_point; @@ -1602,6 +1606,10 @@ void print_start (void) { void print_end (void) { if (in_readline) { return; } + if (readline_disabled) { + fflush (stdout); + return; + } assert (prompt_was); if (readline_active) { set_prompt (get_default_prompt ()); @@ -1631,12 +1639,17 @@ void logprintf (const char *format, ...) { x = 1; print_start (); } - printf (COLOR_GREY " *** "); + if (!disable_colors) { + printf (COLOR_GREY); + } + printf (" *** "); va_list ap; va_start (ap, format); vfprintf (stdout, format, ap); va_end (ap); - printf (COLOR_NORMAL); + if (!disable_colors) { + printf (COLOR_NORMAL); + } if (x) { print_end (); } @@ -2051,6 +2064,7 @@ void play_sound (void) { } void set_interface_callbacks (void) { + if (readline_disabled) { return; } readline_active = 1; rl_callback_handler_install (get_default_prompt (), interpreter); //rl_attempted_completion_function = (void *) complete_text; diff --git a/loop.c b/loop.c index 79c4abc..32eda8f 100644 --- a/loop.c +++ b/loop.c @@ -53,6 +53,7 @@ #include "binlog.h" int verbosity; +extern int readline_disabled; int binlog_read; extern char *default_username; @@ -69,35 +70,103 @@ extern int sync_from_start; void got_it (char *line, int len); void write_state_file (void); -static void stdin_read_callback (evutil_socket_t fd, short what, void *arg) { - if (((long)arg) & 1) { - rl_callback_read_char (); +static char *line_buffer; +static int line_buffer_size; +static int line_buffer_pos; +static int delete_stdin_event; + +static void stdin_read_callback_all (int arg, short what, struct event *self) { + if (!readline_disabled) { + if (((long)arg) & 1) { + rl_callback_read_char (); + } else { + char *line = 0; + size_t len = 0; + assert (getline (&line, &len, stdin) >= 0); + got_it (line, strlen (line)); + } } else { - char *line = 0; - size_t len = 0; - assert (getline (&line, &len, stdin) >= 0); - got_it (line, strlen (line)); + while (1) { + if (line_buffer_pos == line_buffer_size) { + line_buffer = realloc (line_buffer, line_buffer_size * 2 + 100); + line_buffer_size = line_buffer_size * 2 + 100; + assert (line_buffer); + } + int r = read (0, line_buffer + line_buffer_pos, line_buffer_size - line_buffer_pos); + //logprintf ("r = %d, size = %d, pos = %d, what = 0x%x, fd = %d\n", r, line_buffer_size, line_buffer_pos, (int)what, fd); + if (r < 0) { + perror ("read"); + break; + } + if (r == 0) { + //struct event *ev = event_base_get_running_event (tgl_state.ev_base); + //event_del (ev); + //event_del (self); + + delete_stdin_event = 1; + break; + } + line_buffer_pos += r; + + while (1) { + int p = 0; + while (p < line_buffer_pos && line_buffer[p] != '\n') { p ++; } + if (p < line_buffer_pos) { + if (((long)arg) & 1) { + line_buffer[p] = 0; + interpreter (line_buffer); + } else { + got_it (line_buffer, p + 1); + } + memmove (line_buffer, line_buffer + p + 1, line_buffer_pos - p - 1); + line_buffer_pos -= (p + 1); + } else { + break; + } + } + } } } + +static void stdin_read_callback_char (evutil_socket_t fd, short what, void *arg) { + stdin_read_callback_all (1, what, arg); +} + +static void stdin_read_callback_line (evutil_socket_t fd, short what, void *arg) { + stdin_read_callback_all (2, what, arg); +} + void net_loop (int flags, int (*is_end)(void)) { + delete_stdin_event = 0; if (verbosity) { logprintf ("Starting netloop\n"); } struct event *ev = 0; if (flags & 3) { - ev = event_new (tgl_state.ev_base, 0, EV_READ | EV_PERSIST, stdin_read_callback, (void *)(long)flags); + if (flags & 1) { + ev = event_new (tgl_state.ev_base, 0, EV_READ | EV_PERSIST, stdin_read_callback_char, 0); + } else { + ev = event_new (tgl_state.ev_base, 0, EV_READ | EV_PERSIST, stdin_read_callback_line, 0); + } event_add (ev, 0); } while (!is_end || !is_end ()) { event_base_loop (tgl_state.ev_base, EVLOOP_ONCE); + if (ev && delete_stdin_event) { + event_free (ev); + ev = 0; + } + #ifdef USE_LUA lua_do_all (); #endif if (safe_quit && !tgl_state.active_queries) { printf ("All done. Exit\n"); - rl_callback_handler_remove (); + if (!readline_disabled) { + rl_callback_handler_remove (); + } exit (0); } write_state_file (); diff --git a/main.c b/main.c index 6d21fe9..f7b19f7 100644 --- a/main.c +++ b/main.c @@ -93,6 +93,7 @@ int sync_from_start; int allow_weak_random; char *lua_file; int disable_colors; +int readline_disabled; void set_default_username (const char *s) { if (default_username) { @@ -394,6 +395,7 @@ void usage (void) { #endif printf (" -W send dialog_list query and wait for answer before reading input\n"); printf (" -C disable color output\n"); + printf (" -R disable readline\n"); exit (1); } @@ -411,7 +413,7 @@ int wait_dialog_list; void args_parse (int argc, char **argv) { int opt = 0; - while ((opt = getopt (argc, argv, "u:hk:vNl:fEwWC" + while ((opt = getopt (argc, argv, "u:hk:vNl:fEwWCR" #ifdef HAVE_LIBCONFIG "c:p:" #else @@ -453,20 +455,9 @@ void args_parse (int argc, char **argv) { case 'l': log_level = atoi (optarg); break; - //case 'R': - // register_mode = 1; - // break; case 'f': sync_from_start = 1; break; - //case 'L': - // if (log_net_file) { - // usage (); - // } - // log_net_file = tstrdup (optarg); - // log_net_f = fopen (log_net_file, "a"); - // assert (log_net_f); - // break; case 'E': disable_auto_accept = 1; break; @@ -484,6 +475,9 @@ void args_parse (int argc, char **argv) { case 'C': disable_colors ++; break; + case 'R': + readline_disabled ++; + break; case 'h': default: usage ();