gash/gash/compat/textual-ports.scm

97 lines
3.0 KiB
Scheme

;;; Gash -- Guile As SHell
;;; Copyright © 2019, 2022 Timothy Sample <samplet@ngyro.com>
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Gash.
;;;
;;; Gash 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.
;;;
;;; Gash 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 Gash. If not, see <http://www.gnu.org/licenses/>.
(define-module (gash compat textual-ports)
#:use-module (gash compat))
;;; Commentary:
;;;
;;; This module provides is a very simple Guile 2.0 shim for
;;; '(ice-9 textual-ports)'.
;;;
;;; Code:
(if-guile-version-below (2 2 0)
(begin
(use-modules (rnrs io ports))
(re-export get-char
get-line
get-string-all
put-char
lookahead-char)
(define-public (unget-char port char)
(unread-char char port)))
(begin
(use-modules (ice-9 textual-ports))
(re-export get-char
get-line
get-string-all
lookahead-char
put-char
unget-char)))
(when-mes
(export make-soft-port
get-char
unget-char
lookahead-char
get-string-all)
(define-record-type <soft-input-port>
(make-soft-input-port thunk buffer)
soft-input-port?
(thunk soft-input-port-thunk)
(buffer soft-input-port-buffer set-soft-input-port-buffer!))
(define (make-soft-port pv modes)
(unless (equal? modes "r")
(error "Soft ports must have mode \"r\""))
(make-soft-input-port (vector-ref pv 3) '()))
(define (push-soft-input-port-buffer! sip char)
(let ((buffer (soft-input-port-buffer sip)))
(set-soft-input-port-buffer! sip (cons char buffer))))
(define (pop-soft-input-port-buffer! sip)
(let* ((buffer (soft-input-port-buffer sip))
(result (car buffer)))
(set-soft-input-port-buffer! sip (cdr buffer))
result))
(define (get-char port)
(if (soft-input-port? port)
(let ((thunk (soft-input-port-thunk port))
(buffer (soft-input-port-buffer port)))
(if (null? buffer)
(thunk)
(pop-soft-input-port-buffer! port)))
(with-input-from-port port read-char)))
(define (unget-char port char)
(if (soft-input-port? port)
(push-soft-input-port-buffer! port char)
(with-input-from-port port (lambda () (unread-char char)))))
(define (lookahead-char port)
(let ((result (get-char port)))
(unget-char port result)
result))
(define get-string-all read-string))