From f35eb7269743a0433a2bcf21acac6f6b956d34fe Mon Sep 17 00:00:00 2001 From: David Thompson Date: Mon, 13 Sep 2021 08:18:57 -0400 Subject: Add readline bindings. --- Makefile.am | 1 + chickadee/config.scm.in | 2 ++ chickadee/readline.scm | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 11 ++++++ guix.scm | 4 ++- 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 chickadee/readline.scm diff --git a/Makefile.am b/Makefile.am index 806157f..5164774 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,7 @@ SOURCES = \ chickadee/array-list.scm \ chickadee/queue.scm \ chickadee/freetype.scm \ + chickadee/readline.scm \ chickadee/math.scm \ chickadee/math/vector.scm \ chickadee/math/bezier.scm \ diff --git a/chickadee/config.scm.in b/chickadee/config.scm.in index d540231..81b0f3e 100644 --- a/chickadee/config.scm.in +++ b/chickadee/config.scm.in @@ -31,6 +31,7 @@ %libvorbisfile %libmpg123 %libfreetype + %libreadline scope-datadir)) ;; Try to link against multiple library possibilities, such as the @@ -55,6 +56,7 @@ (define %libvorbisfile '("@VORBIS_LIBDIR@/libvorbisfile" "libvorbisfile")) (define %libmpg123 '("@MPG123_LIBDIR@/libmpg123" "libmpg123")) (define %libfreetype '("@FREETYPE_LIBDIR@/libfreetype" "libfreetype")) +(define %libreadline '("@READLINE_LIBDIR@/libreadline" "libreadline")) (define (scope-datadir file) "Append the Chickadee data directory to FILE." diff --git a/chickadee/readline.scm b/chickadee/readline.scm new file mode 100644 index 0000000..ff370e8 --- /dev/null +++ b/chickadee/readline.scm @@ -0,0 +1,91 @@ +;;; Chickadee Game Toolkit +;;; Copyright © 2021 David Thompson +;;; +;;; Chickadee is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published +;;; by the Free Software Foundation, either version 3 of the License, +;;; or (at your option) any later version. +;;; +;;; Chickadee is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; . + +;;; Commentary +;; +;; GNU readline bindings for use with the Chickadee REPL. The +;; guile-readline C extension is not compatible with the alternative, +;; callback-based readline interface so here comes the FFI to the +;; rescue. +;; +;;; Code: + +(define-module (chickadee readline) + #:use-module (chickadee config) + #:use-module (system foreign) + #:export (bind-readline-variable + install-readline-handler + remove-readline-handler + readline-read-char + add-readline-history)) + +;;; +;;; Setup +;;; + +(define libreadline (dynamic-link* %libreadline)) + +(define (readline-func return-type function-name arg-types) + (pointer->procedure return-type + (dynamic-func function-name libreadline) + arg-types)) + +(define-syntax-rule (define-foreign name return-type func-name arg-types) + (define name + (readline-func return-type func-name arg-types))) + +;;; +;;; Variables +;;; + +(define-foreign rl-variable-bind void "rl_variable_bind" '(* *)) + +(define (bind-readline-variable name value) + (rl-variable-bind (string->pointer name) (string->pointer value))) + +;;; +;;; Callbacks +;;; + +(define-foreign rl-callback-handler-install void "rl_callback_handler_install" '(* *)) +(define-foreign rl-callback-handler-remove void "rl_callback_handler_remove" '()) +(define-foreign rl-callback-read-char void "rl_callback_read_char" '()) +(define-foreign rl-callback-sigcleanup void "rl_callback_sigcleanup" '()) + +(define (install-readline-handler prompt proc) + (let ((proc-ptr (procedure->pointer void + (lambda (ptr) + (proc (if (null-pointer? ptr) + "" + (pointer->string ptr)))) + '(*)))) + (rl-callback-handler-install (string->pointer prompt) proc-ptr))) + +(define (remove-readline-handler) + (rl-callback-handler-remove)) + +(define (readline-read-char) + (rl-callback-read-char)) + +;;; +;;; History +;;; + +(define-foreign add-history void "add_history" '(*)) + +(define (add-readline-history line) + (add-history (string->pointer line))) diff --git a/configure.ac b/configure.ac index aa53707..699e3b6 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,7 @@ AC_PATH_PROG([GUILE], [guile]) AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([pre-inst-env], [chmod +x pre-inst-env]) AC_CONFIG_FILES([test-env], [chmod +x test-env]) +AC_CONFIG_FILES([scripts/chickadee], [chmod +x scripts/chickadee]) AC_CONFIG_FILES([chickadee/config.scm]) # Prepare a version of $datadir that does not contain references to @@ -64,4 +65,14 @@ AS_IF([test "FREETYPE_LIBDIR" = "x"], [ ]) AC_SUBST([FREETYPE_LIBDIR]) +PKG_CHECK_MODULES([readline], [readline]) +PKG_CHECK_VAR([READLINE_LIBDIR], [readline], [libdir]) +AC_MSG_CHECKING([readline library path]) +AS_IF([test "x$READLINE_LIBDIR" = "x"], [ + AC_MSG_FAILURE([Unable to identify readline lib path.]) +], [ + AC_MSG_RESULT([$READLINE_LIBDIR]) +]) +AC_SUBST([READLINE_LIBDIR]) + AC_OUTPUT diff --git a/guix.scm b/guix.scm index 7d0bda7..5d3ddf3 100644 --- a/guix.scm +++ b/guix.scm @@ -48,6 +48,7 @@ (gnu packages autotools) (gnu packages fontutils) (gnu packages pkg-config) + (gnu packages readline) (gnu packages texinfo) (gnu packages guile) (gnu packages gl) @@ -153,7 +154,8 @@ SDL2 C shared library via the foreign function interface.") ("guile" ,target-guile) ("libvorbis" ,libvorbis) ("mpg123" ,mpg123) - ("openal" ,openal))) + ("openal" ,openal) + ("readline" ,readline))) (propagated-inputs `(("guile-opengl" ,guile3.0-opengl) ("guile-sdl2" ,guile-sdl2))) -- cgit v1.2.3