summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--linenoise/linenoise.c41
-rw-r--r--linenoise/linenoise.h4
-rw-r--r--parser.c13
-rw-r--r--parser.h2
-rw-r--r--txr.c44
6 files changed, 59 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index 5e5b5eef..077870fa 100644
--- a/Makefile
+++ b/Makefile
@@ -56,6 +56,7 @@ OBJS += arith.o hash.o utf8.o filter.o eval.o parser.o rand.o combi.o sysif.o
OBJS += args.o lisplib.o cadr.o struct.o itypes.o buf.o jmp.o protsym.o ffi.o
OBJS += strudel.o vm.o chksum.o chksums/sha256.o chksums/crc32.o chksums/md5.o
OBJS += tree.o time.o
+OBJS += linenoise/linenoise.o
OBJS-$(debug_support) += debug.o
OBJS-$(have_syslog) += syslog.o
OBJS-$(have_glob) += glob.o
@@ -63,7 +64,6 @@ OBJS-$(have_ftw) += ftw.o
OBJS-$(have_posix_sigs) += signal.o
OBJS-$(have_sockets) += socket.o
OBJS-$(have_termios) += termios.o
-OBJS-$(have_termios) += linenoise/linenoise.o
EXTRA_OBJS-$(add_win_res) += win/txr.res
STDLIB_SRCS := $(wildcard stdlib/*.tl)
diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c
index 256553d4..7c945964 100644
--- a/linenoise/linenoise.c
+++ b/linenoise/linenoise.c
@@ -42,8 +42,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <termios.h>
-#include <unistd.h>
#include <stddef.h>
#include <wchar.h>
#include <stdlib.h>
@@ -52,13 +50,16 @@
#include <string.h>
#include <ctype.h>
#include <wctype.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
#include <signal.h>
#include <limits.h>
#include <assert.h>
#include <stdarg.h>
+#include <unistd.h>
#include "config.h"
+#if HAVE_TERMIOS
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
#if HAVE_POLL
#include <poll.h>
#endif
@@ -67,6 +68,7 @@
#include <sys/fcntl.h>
#include <io.h>
#endif
+#endif
#include "linenoise.h"
#ifdef __cplusplus
@@ -92,13 +94,17 @@ struct lino_state {
lino_t *next, *prev; /* Links for global list: must be first */
/* Lifetime enduring state */
+#if HAVE_TERMIOS
lino_compl_cb_t *completion_callback;
+#endif
void *cb_ctx; /* User context for completion callback */
lino_atom_cb_t *atom_callback;
void *ca_ctx; /* User context for atom callback */
lino_enter_cb_t *enter_callback;
void *ce_ctx; /* User context for enter callback */
+#if HAVE_TERMIOS
struct termios orig_termios; /* In order to restore at exit.*/
+#endif
#ifdef __CYGWIN__
int orig_imode, orig_omode;
#endif
@@ -162,10 +168,14 @@ enum key_action {
static lino_os_t lino_os;
static lino_t lino_list;
volatile sig_atomic_t lino_list_busy;
+#if HAVE_TERMIOS
static int atexit_registered = 0; /* Register atexit just 1 time. */
+#endif
#define nelem(array) (sizeof (array) / sizeof (array)[0])
+#if HAVE_TERMIOS
+
static int wcsnprintf(wchar_t *s, size_t nchar, const wchar_t *fmt, ...)
{
int ret;
@@ -178,6 +188,8 @@ static int wcsnprintf(wchar_t *s, size_t nchar, const wchar_t *fmt, ...)
return wcslen(s);
}
+#endif
+
/* ======================= Low level terminal handling ====================== */
/* Set if to use or not the multi line mode. */
@@ -225,6 +237,8 @@ void lino_set_enter_cb(lino_t *l, lino_enter_cb_t *cb, void *ctx)
l->ce_ctx = ctx;
}
+#if HAVE_TERMIOS
+
static void atexit_handler(void);
/* Raw mode: 1960 magic shit. */
@@ -2523,6 +2537,8 @@ static void sigwinch_handler(int sig)
}
#endif
+#endif
+
/* The main function of the linenoise library
* handles a non-TTY input file descriptor by opening
* a standard I/O stream on it and reading lines
@@ -2530,7 +2546,6 @@ static void sigwinch_handler(int sig)
* the edit function. */
wchar_t *linenoise(lino_t *ls, const wchar_t *prompt)
{
- int count;
int ifd = lino_os.fileno_fn(ls->tty_ifs);
if (ls->noninteractive || !isatty(ifd)) {
@@ -2589,6 +2604,8 @@ wchar_t *linenoise(lino_t *ls, const wchar_t *prompt)
return ret;
} else {
wchar_t *ret = 0;
+#if HAVE_TERMIOS
+ int count;
#ifdef SIGWINCH
static struct sigaction blank;
struct sigaction sa = blank, oa;
@@ -2614,6 +2631,7 @@ wchar_t *linenoise(lino_t *ls, const wchar_t *prompt)
#ifdef SIGWINCH
sigaction(SIGWINCH, &oa, 0);
#endif
+#endif
return ret;
}
}
@@ -2648,6 +2666,9 @@ lino_t *lino_make(mem_t *ifs, mem_t *ofs)
ls->tty_ofs = ofs;
link_into_list(&lino_list, ls);
+#if !HAVE_TERMIOS
+ ls->noninteractive = 1;
+#endif
}
return ls;
@@ -2677,9 +2698,13 @@ static void free_hist(lino_t *ls);
static void lino_cleanup(lino_t *ls)
{
+#if HAVE_TERMIOS
disable_raw_mode(ls);
+#endif
free_hist(ls);
+#if HAVE_TERMIOS
free_undo_stack(ls);
+#endif
lino_os.free_fn(ls->clip);
ls->clip = 0;
lino_os.free_fn(ls->result);
@@ -2729,6 +2754,8 @@ static void free_hist(lino_t *ls) {
}
}
+#if HAVE_TERMIOS
+
/* At exit we'll try to fix the terminal to the initial conditions. */
static void atexit_handler(void) {
lino_t *ls;
@@ -2737,6 +2764,8 @@ static void atexit_handler(void) {
lino_cleanup(ls);
}
+#endif
+
/* This is the API call to add a new entry in the linenoise history.
* It uses a fixed array of char pointers that are shifted (memmoved)
* when the history max length is reached in order to remove the older
@@ -2776,7 +2805,9 @@ int lino_hist_add(lino_t *ls, const wchar_t *line) {
}
ls->history[ls->history_len] = linecopy;
ls->history_len++;
+#if HAVE_TERMIOS
undo_renumber_hist_idx(ls, 1);
+#endif
return 1;
}
diff --git a/linenoise/linenoise.h b/linenoise/linenoise.h
index 7fef68d9..bc72eaa7 100644
--- a/linenoise/linenoise.h
+++ b/linenoise/linenoise.h
@@ -92,6 +92,8 @@ typedef struct lino_os {
wide_disp \
}
+#if HAVE_TERMIOS
+
typedef struct lino_completions {
size_t len;
wchar_t **cvec;
@@ -102,6 +104,8 @@ typedef void lino_compl_cb_t(const wchar_t *, lino_completions_t *, void *ctx);
void lino_set_completion_cb(lino_t *, lino_compl_cb_t *, void *ctx);
void lino_add_completion(lino_completions_t *, const wchar_t *);
+#endif
+
void lino_init(lino_os_t *);
lino_t *lino_make(mem_t *istream, mem_t *ostream);
lino_t *lino_copy(lino_t *);
diff --git a/parser.c b/parser.c
index bfbfa625..6df51fda 100644
--- a/parser.c
+++ b/parser.c
@@ -66,9 +66,7 @@
#include "vm.h"
#include "ffi.h"
#include "txr.h"
-#if HAVE_TERMIOS
#include "linenoise/linenoise.h"
-#endif
val parser_s, unique_s, circref_s;
val listener_hist_len_s, listener_multi_line_p_s, listener_sel_inclusive_p_s;
@@ -863,8 +861,6 @@ val txr_parse(val source_in, val error_stream,
return pi->syntax_tree;
}
-#if HAVE_TERMIOS
-
static void report_security_problem(val name)
{
val self = lit("listener");
@@ -928,6 +924,8 @@ static void load_rcfile(val name)
uw_catch_end;
}
+#if HAVE_TERMIOS
+
static val get_visible_syms(val package, int include_fallback)
{
val fblist;
@@ -1159,6 +1157,8 @@ static wchar_t *provide_atom(lino_t *l, const wchar_t *str, int n, void *ctx)
return out;
}
+#endif
+
static val repl_intr(val signo, val async_p)
{
(void) signo;
@@ -1520,8 +1520,11 @@ val repl(val bindings, val in_stream, val out_stream, val env)
reg_varl(result_hash_sym, result_hash);
+#if HAVE_TERMIOS
lino_set_completion_cb(ls, provide_completions, 0);
lino_set_atom_cb(ls, provide_atom, 0);
+#endif
+
lino_set_enter_cb(ls, is_balanced_line, 0);
lino_set_tempfile_suffix(ls, ".tl");
@@ -1680,8 +1683,6 @@ val repl(val bindings, val in_stream, val out_stream, val env)
return nil;
}
-#endif
-
val parser_errors(val parser)
{
val self = lit("parser-errors");
diff --git a/parser.h b/parser.h
index 3c99c1ba..9f14a7ad 100644
--- a/parser.h
+++ b/parser.h
@@ -138,9 +138,7 @@ val read_eval_stream(val self, val stream, val error_stream);
val read_compiled_file(val self, val stream, val error_stream);
val txr_parse(val source, val error_stream,
val error_return_val, val name_in);
-#if HAVE_TERMIOS
val repl(val bindings, val in_stream, val out_stream, val env);
-#endif
void parser_common_init(parser_t *);
void parser_cleanup(parser_t *);
val parser(val stream, val name, val lineno);
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;
}