commit 964890a98332fca6bbba757ba0953e1b87dfdddb
parent 867e8fb255e341505761bf9538f2d0d5a57201a7
Author: Oto Havle <havleoto@gmail.com>
Date: Tue, 29 Nov 2011 22:59:59 +0100
Added platform-dependent tty detection.
Diffstat:
7 files changed, 70 insertions(+), 8 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -104,10 +104,9 @@ mingw:
"MINGW_LDFLAGS=$(if $(USE_LIBFFI), $(MINGW_LIBFFI_LDFLAGS) -lffi.dll)" \
"MYLDFLAGS=-s" klisp.exe
#lisp_use_posix isn't used right now...
-# TEMP: rename read() and write() here to avoid name conflicts with foreign code
posix:
$(MAKE) all \
- "MYCFLAGS=-DKLISP_USE_POSIX $(if $(USE_LIBFFI),-DKUSE_LIBFFI=1 -Dread=klisp_read -Dwrite=klisp_write)" \
+ "MYCFLAGS=-DKLISP_USE_POSIX -D_POSIX_SOURCE $(if $(USE_LIBFFI),-DKUSE_LIBFFI=1)" \
"MYLIBS=$(if $(USE_LIBFFI), -rdynamic -ldl -lffi)"
# list targets that do not create files (but not all makes understand .PHONY)
diff --git a/src/klisp.c b/src/klisp.c
@@ -33,6 +33,7 @@
#include "kwrite.h"
#include "kerror.h"
#include "krepl.h"
+#include "ksystem.h"
#include "kghelpers.h" /* for do_return_value, do_pass_value and do_seq */
static const char *progname = KLISP_PROGNAME;
@@ -612,7 +613,7 @@ static void pmain(klisp_State *K)
if (has_i) {
dotty(K);
} else if (script == 0 && !has_e && !has_v) {
- if (true) {
+ if (ksystem_isatty(K, kcurr_input_port(K))) {
print_version();
dotty(K);
} else {
diff --git a/src/ksystem.c b/src/ksystem.c
@@ -35,7 +35,6 @@
#include <time.h>
-/* TEMP for now the best we can do is return the current second */
TValue ksystem_current_jiffy(klisp_State *K)
{
time_t now = time(NULL);
@@ -45,6 +44,7 @@ TValue ksystem_current_jiffy(klisp_State *K)
return KFALSE;
} else {
return kinteger_new_uint64(K, (uint64_t) now);
+ }
}
}
@@ -53,4 +53,15 @@ TValue ksystem_jiffies_per_second(klisp_State *K)
return i2tv(1);
}
-#endif
+#endif /* HAVE_PLATFORM_JIFFIES */
+
+#ifndef HAVE_PLATFORM_ISATTY
+
+bool ksystem_isatty(klisp_State *K, TValue port)
+{
+ UNUSED(K);
+ UNUSED(port);
+ return false;
+}
+
+#endif /* HAVE_PLATFORM_ISATTY */
diff --git a/src/ksystem.h b/src/ksystem.h
@@ -11,6 +11,7 @@
TValue ksystem_current_jiffy(klisp_State *K);
TValue ksystem_jiffies_per_second(klisp_State *K);
+bool ksystem_isatty(klisp_State *K, TValue port);
#endif
diff --git a/src/ksystem.posix.c b/src/ksystem.posix.c
@@ -4,15 +4,18 @@
** See Copyright Notice in klisp.h
*/
+#include <stdio.h>
#include <sys/time.h>
#include "kobject.h"
#include "kstate.h"
#include "kinteger.h"
+#include "kport.h"
#include "ksystem.h"
/* declare implemented functionality */
#define HAVE_PLATFORM_JIFFIES
+#define HAVE_PLATFORM_ISATTY
/* jiffies */
@@ -40,3 +43,11 @@ TValue ksystem_jiffies_per_second(klisp_State *K)
UNUSED(K);
return i2tv(1000000);
}
+
+/* isatty */
+
+bool ksystem_isatty(klisp_State *K, TValue port)
+{
+ return ttisfport(port) && kport_is_open(port)
+ && isatty(fileno(kfport_file(port)));
+}
diff --git a/src/ksystem.win32.c b/src/ksystem.win32.c
@@ -5,14 +5,17 @@
*/
#include <windows.h>
+#include <stdio.h>
#include "kobject.h"
#include "kstate.h"
#include "kinteger.h"
+#include "kport.h"
#include "ksystem.h"
/* declare implemented functionality */
#define HAVE_PLATFORM_JIFFIES
+#define HAVE_PLATFORM_ISATTY
/* jiffies */
@@ -29,3 +32,36 @@ TValue ksystem_jiffies_per_second(klisp_State *K)
QueryPerformanceFrequency(&li);
return kinteger_new_uint64(K, li.QuadPart);
}
+
+bool ksystem_isatty(klisp_State *K, TValue port)
+{
+ if (!ttisfport(port) || kport_is_closed(port))
+ return false;
+
+ /* get the underlying Windows File HANDLE */
+
+ int fd = _fileno(kfport_file(port));
+ if (fd == -1 || fd == -2)
+ return false;
+
+ HANDLE h = (HANDLE) _get_osfhandle(fd);
+ if (h == INVALID_HANDLE_VALUE)
+ return false;
+
+ /* Googling gives two unreliable ways to emulate isatty():
+ *
+ * 1) test if GetFileType() returns FILE_TYPE_CHAR
+ * - reports NUL special file as a terminal
+ *
+ * 2) test if GetConsoleMode() succeeds
+ * - does not work on output handles
+ * - does not work in plain wine (works in wineconsole)
+ * - probably won't work if Windows Console is replaced
+ * a terminal emulator
+ *
+ * TEMP: use GetConsoleMode()
+ */
+
+ DWORD mode;
+ return GetConsoleMode(h, &mode);
+}
diff --git a/src/tests/test-interpreter.sh b/src/tests/test-interpreter.sh
@@ -2,6 +2,10 @@
#
# Test of the stand-alone interpreter.
#
+# Does not work in MSYS shell on Windows because
+# of different handling of command line arguments.
+# TODO: Write similar test script for Windows cmd.exe or PowerShell.
+#
if [ $# -ne 1 ] ; then
echo "usage: test-interpreter.sh KLISP-EXECUTABLE" 1>&2
@@ -25,8 +29,7 @@ check_match()
expected="$1"
actual="$2"
- if expr match "$expected" '^/.*/$' >/dev/null ; then
- regexp=`expr substr "$expected" 2 $((${#expected} - 2))`
+ if regexp=`expr match "$expected" '/\(.*\)/$'` ; then
expr match "$actual" "$regexp" >/dev/null
else
test "$actual" = "$expected"
@@ -147,7 +150,7 @@ check_oi 'klisp> ' '' $KLISP -i
# option: -v
-check_o '/^klisp [0-9.]+ .*/' $KLISP -v
+check_o '/klisp [0-9.]+ .*/' $KLISP -v
# '--' on the command line