From 4aaf96f5aaab5c249c3c8ea6d24ee6683bca6f10 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 20 Aug 2021 05:47:57 -0700 Subject: listener: unbundle from termios. This commit fixes the conceptual issue that when there is no termios support (HAVE_TERMIOS is absent/false), then there is no listener at all, even though the listener supports plain mode that doesn't require termios. * Makefile (linenoise/linenoise.o): Link in unconditionally, not subject to have_termios. * linenoise.c: Include termios-related header only if HAVE_TERMIOS. (struct lino_state): Define the completion_callback and orig_termios members only if HAVE_TERMIOS. (wcnsprintf, atexit_handler, enable_raw_mode, disable_raw_mode, get_cursor_position, get_columns, lino_clear_screen, refresh_line, handle_resize, generate_beep, delete_undo, free_undo_stack, record_undo, record_triv_undo, remove_noop_undo, restore_undo, undo_subst_hist_idx, undo_renumber_hist_idx, free_completions, sync_data_to_buf, compare_completions, complete_line, lino_set_completion_cb, lino_add_completion, next_hist_match, copy_display_params, history_search, ab_init, ab_append, ab_free, sync_data_to_buf, copy_display_params, refresh_singleline, col_offset_in_str, refresh_multiline, refresh_line, move_cursor_multiline, move_cursor, scan_match_rev, scan_rev, scan_match_fwd, scan_fwd, find_nearest_paren, usec_delay, paren_jump, flash, yank, yank_by_ptr, update_sel, clear_sel, yank_sel, delete_sel, edit_insert, edit_insert_str, edit_move_left, edit_move_right, edit_move_home, edit_move_sol, edit_move_end, edit_move_eol, edit_move_matching_paren, edit_history_next, edit_delete, edit_backspace, edit_delete_prev_all, edit_delete_to_eol, edit_delete_prev_word, edit_delete_line, tr, char, edit_in_editor, edit, sigwinch_handler): Functions defined only if HAVE_TERMIOS. (struct abuf, struct row_values): Struct types defined only if HAVE_TERMIOS. (screen_rows): Defined only if HAVE_TERMIOS. (linenoise): Support only noninteractive read loop unless HAVE_TERMIOS. (lino_make): If HAVE_TERMIOS is false, then set the noninteractive flag, so the linenoise function enters the plain-mode loop. (lino_cleanup, lino_hist_add): Add #ifdefs to avoid calling nonexistent functions when HAVE_TERMIOS is false. * linenoise/linenoise.h (struct lino_completions, lino_compl_cb_t): Define these types only if HAVE_TERMIOS. (lino_set_completion_cb, lino_add_completion): Declare only if HAVE_TERMIOS. * parser.c: Include linenoise/linenoise.h unconditionally. (report_security_problem, load_rcfile, repl_intr, read_eval_ret_last, get_home_path, repl_warning, is_balanced_line, hist_save): Now define regardless of HAVE_TERMIOS. (repl): Define regardless of HAVE_TERMIOS, but don't set completion or atom callback if HAVE_TERMIOS is false. * parser.h (repl): Declare unconditionally, not subject to HAVE_TERMIOS. * txr.c (if_termios): New macro. (opt_noninteractive): Initialize to 1 if HAVE_TERMIOS is false. (help): Text about entering into listener mode is always present now, even in a build withou HAVE_TERMIOS. (banner): Function is always defined. If we don't HAVE_TERMIOS, then the unused string literal that will never be printed is replaced by nil. (hint): Function removed. (txr_main): Blocks conditional on HAVE_TERMIOS that either call banner and go to the repl, or else call hint and exit, are reduced to unconditionally calling banner and going to the repl. All #if HAVE_TERMIOS blocks are similarly replaced with just the HAVE_TERMIOS case. --- txr.c | 44 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) (limited to 'txr.c') diff --git a/txr.c b/txr.c index 20c1a2ef..a7b4f9db 100644 --- a/txr.c +++ b/txr.c @@ -63,6 +63,12 @@ #endif #include "txr.h" +#if HAVE_TERMIOS +#define if_termios(THEN, ELSE) (THEN) +#else +#define if_termios(THEN, ELSE) (ELSE) +#endif + const wchli_t *version = wli(TXR_VER); #ifdef TXR_BUILD_ID const wchli_t *build_id = wli(TXR_BUILD_ID); @@ -70,7 +76,7 @@ const wchli_t *build_id = wli(TXR_BUILD_ID); wchar_t *progname; static const char *progname_u8; static val prog_path = nil, sysroot_path = nil; -int opt_noninteractive; +int opt_noninteractive = if_termios(0, 1); int opt_noprofile; int opt_compat; int opt_dbg_expansion; @@ -87,10 +93,8 @@ static void help(void) "\n" " ~a [ options ] script-file { argument }*\n" "\n" -#if HAVE_TERMIOS "If no arguments are present, TXR will enter into interactive listener mode.\n" "\n" -#endif "The script-file or data-file arguments may be specified as -, in which case\n" "standard input is used. All data-file arguments which begin with a !\n" "character are treated as command pipes. Those which begin with a $\n" @@ -182,7 +186,6 @@ static void help(void) format(std_output, text, static_str(version), prog_string, nao); } -#if HAVE_TERMIOS static void banner(val self) { if (!isatty(c_int(stream_fd(std_input), self))) @@ -192,18 +195,12 @@ static void banner(val self) if3(opt_noninteractive, lit("This is the TXR Lisp plain mode listener of TXR ~a.\n" "Quit with :quit or Ctrl-D on an empty line.\n"), - lit("This is the TXR Lisp interactive listener of TXR ~a.\n" - "Quit with :quit or Ctrl-D on an empty line. " - "Ctrl-X ? for cheatsheet.\n")), + if_termios(lit("This is the TXR Lisp interactive " + "listener of TXR ~a.\n" + "Quit with :quit or Ctrl-D on an empty line. " + "Ctrl-X ? for cheatsheet.\n"), nil)), static_str(version), nao); } -#else -static void hint(void) -{ - format(std_error, lit("~a: incorrect arguments: try --help\n"), - prog_string, nao); -} -#endif static val check_hash_bang(val stream, val args, int *occurs) { @@ -577,13 +574,8 @@ int txr_main(int argc, char **argv) arg_list = list(string_utf8(alt_args), nao); } else if (argc <= 1) { drop_privilege(); -#if HAVE_TERMIOS banner(self); goto repl; -#else - hint(); - return EXIT_FAILURE; -#endif } for (ref_arg_list = arg_list, arg = upop(&arg_list, &arg_undo); @@ -1047,15 +1039,8 @@ int txr_main(int argc, char **argv) break; case 'i': drop_privilege(); -#if HAVE_TERMIOS enter_repl = t; break; -#else - format(std_error, - lit("~a: option ~a requires a platform with termios\n"), - prog_string, arg, nao); - return EXIT_FAILURE; -#endif case 'd': drop_privilege(); #if CONFIG_DEBUG_SUPPORT @@ -1111,13 +1096,8 @@ int txr_main(int argc, char **argv) goto repl; if (evaled) return EXIT_SUCCESS; -#if HAVE_TERMIOS banner(self); goto repl; -#else - hint(); - return EXIT_FAILURE; -#endif } drop_privilege(); @@ -1199,7 +1179,6 @@ int txr_main(int argc, char **argv) } repl: -#if HAVE_TERMIOS if (compat_val) format(std_output, lit("Note: operating in TXR ~a compatibility mode " @@ -1211,6 +1190,5 @@ repl: opt_compat && opt_compat <= 190 ? user_package : public_package); env_vbind(dyn_env, load_recursive_s, nil); repl(bindings, std_input, std_output, nil); -#endif return 0; } -- cgit v1.2.3