1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-29 22:40:34 +02:00

Close accumulating output ports after use

* module/ice-9/ports.scm (call-with-port): New procedure, from r7rs.
  (call-with-input-file, call-with-output-file): Refactor to use
  call-with-port.
  (call-with-output-string): Close the string after normal exit.
* module/scheme/base.scm (scheme): Re-export call-with-port from base.
This commit is contained in:
Andy Wingo 2021-01-12 11:45:39 +01:00
parent a20ef7e769
commit 9fecf20fcf
2 changed files with 25 additions and 30 deletions

View file

@ -1,5 +1,5 @@
;;; Ports ;;; Ports
;;; Copyright (C) 2016, 2019 Free Software Foundation, Inc. ;;; Copyright (C) 2016,2019,2021 Free Software Foundation, Inc.
;;; ;;;
;;; This library is free software: you can redistribute it and/or modify ;;; This library is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU Lesser General Public License as ;;; it under the terms of the GNU Lesser General Public License as
@ -107,6 +107,7 @@
open-input-file open-input-file
open-output-file open-output-file
open-io-file open-io-file
call-with-port
call-with-input-file call-with-input-file
call-with-output-file call-with-output-file
with-input-from-port with-input-from-port
@ -425,6 +426,15 @@ file with the given name already exists, the effect is unspecified."
"Open file with name STR for both input and output." "Open file with name STR for both input and output."
(open-file str OPEN_BOTH)) (open-file str OPEN_BOTH))
(define (call-with-port port proc)
"Call @var{proc}, passing it @var{port} and closing @var{port} upon exit of
@var{proc}. Return the return values of @var{proc}."
(call-with-values
(lambda () (proc port))
(lambda vals
(close-port port)
(apply values vals))))
(define* (call-with-input-file (define* (call-with-input-file
file proc #:key (binary #f) (encoding #f) (guess-encoding #f)) file proc #:key (binary #f) (encoding #f) (guess-encoding #f))
"PROC should be a procedure of one argument, and FILE should be a "PROC should be a procedure of one argument, and FILE should be a
@ -441,11 +451,7 @@ never again be used for a read or write operation."
#:binary binary #:binary binary
#:encoding encoding #:encoding encoding
#:guess-encoding guess-encoding))) #:guess-encoding guess-encoding)))
(call-with-values (call-with-port p proc)))
(lambda () (proc p))
(lambda vals
(close-input-port p)
(apply values vals)))))
(define* (call-with-output-file file proc #:key (binary #f) (encoding #f)) (define* (call-with-output-file file proc #:key (binary #f) (encoding #f))
"PROC should be a procedure of one argument, and FILE should be a "PROC should be a procedure of one argument, and FILE should be a
@ -459,11 +465,7 @@ If the procedure does not return, then the port will not be closed
automatically unless it is possible to prove that the port will automatically unless it is possible to prove that the port will
never again be used for a read or write operation." never again be used for a read or write operation."
(let ((p (open-output-file file #:binary binary #:encoding encoding))) (let ((p (open-output-file file #:binary binary #:encoding encoding)))
(call-with-values (call-with-port p proc)))
(lambda () (proc p))
(lambda vals
(close-output-port p)
(apply values vals)))))
(define (with-input-from-port port thunk) (define (with-input-from-port port thunk)
(parameterize ((current-input-port port)) (parameterize ((current-input-port port))
@ -525,9 +527,9 @@ procedures, their behavior is implementation dependent."
#:encoding encoding)) #:encoding encoding))
(define (call-with-input-string string proc) (define (call-with-input-string string proc)
"Calls the one-argument procedure @var{proc} with a newly created "Call the one-argument procedure @var{proc} with a newly created input
input port from which @var{string}'s contents may be read. The value port from which @var{string}'s contents may be read. All values yielded
yielded by the @var{proc} is returned." by the @var{proc} are returned."
(proc (open-input-string string))) (proc (open-input-string string)))
(define (with-input-from-string string thunk) (define (with-input-from-string string thunk)
@ -543,12 +545,14 @@ procedures, their behavior is implementation dependent."
(lambda (p) (with-input-from-port p thunk)))) (lambda (p) (with-input-from-port p thunk))))
(define (call-with-output-string proc) (define (call-with-output-string proc)
"Calls the one-argument procedure @var{proc} with a newly created output "Call the one-argument procedure @var{proc} with a newly created
port. When the function returns, the string composed of the characters output port. When the function returns, port is closed and the string
written into the port is returned." composed of the characters written into the port is returned."
(let ((port (open-output-string))) (let ((port (open-output-string)))
(proc port) (proc port)
(get-output-string port))) (let ((res (get-output-string port)))
(close-port port)
res)))
(define (with-output-to-string thunk) (define (with-output-to-string thunk)
"Calls THUNK and returns its output as a string." "Calls THUNK and returns its output as a string."

View file

@ -1,5 +1,5 @@
;;; R7RS compatibility libraries ;;; R7RS compatibility libraries
;;; Copyright (C) 2019-2020 Free Software Foundation, Inc. ;;; Copyright (C) 2019-2021 Free Software Foundation, Inc.
;;; ;;;
;;; This library is free software: you can redistribute it and/or modify ;;; This library is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU Lesser General Public License as ;;; it under the terms of the GNU Lesser General Public License as
@ -34,6 +34,7 @@
#:use-module (srfi srfi-11) #:use-module (srfi srfi-11)
#:use-module (ice-9 exceptions) #:use-module (ice-9 exceptions)
#:use-module ((srfi srfi-34) #:select (guard)) #:use-module ((srfi srfi-34) #:select (guard))
#:use-module (ice-9 ports)
#:use-module (ice-9 textual-ports) #:use-module (ice-9 textual-ports)
#:use-module (ice-9 binary-ports) #:use-module (ice-9 binary-ports)
#:use-module (rnrs bytevectors) #:use-module (rnrs bytevectors)
@ -65,7 +66,6 @@
square square
(r7:expt . expt) (r7:expt . expt)
boolean=? symbol=? boolean=? symbol=?
call-with-port
features features
input-port-open? output-port-open?) input-port-open? output-port-open?)
#:re-export #:re-export
@ -75,7 +75,7 @@
boolean? boolean?
bytevector-length bytevector-length
bytevector-u8-ref bytevector-u8-set! bytevector? caar cadr bytevector-u8-ref bytevector-u8-set! bytevector? caar cadr
call-with-current-continuation call-with-values call-with-current-continuation call-with-port call-with-values
call/cc car case cdar cddr cdr ceiling char->integer char-ready? call/cc car case cdar cddr cdr ceiling char->integer char-ready?
char<=? char<? char=? char>=? char>? char? close-input-port char<=? char<? char=? char>=? char>? char? close-input-port
close-output-port close-port complex? cond cons close-output-port close-port complex? cond cons
@ -565,15 +565,6 @@ defaults to 0 and SEND defaults to the length of SOURCE."
(exact->inexact (expt x y)) (exact->inexact (expt x y))
(expt x y))) (expt x y)))
(define (call-with-port port proc)
"Call @var{proc}, passing it @var{port} and closing @var{port} upon exit of
@var{proc}. Return the return values of @var{proc}."
(call-with-values
(lambda () (proc port))
(lambda vals
(close-port port)
(apply values vals))))
(define (features) (define (features)
(append (append
(case (native-endianness) (case (native-endianness)