klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

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:
Msrc/Makefile | 3+--
Msrc/klisp.c | 3++-
Msrc/ksystem.c | 15+++++++++++++--
Msrc/ksystem.h | 1+
Msrc/ksystem.posix.c | 11+++++++++++
Msrc/ksystem.win32.c | 36++++++++++++++++++++++++++++++++++++
Msrc/tests/test-interpreter.sh | 9++++++---
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