;; lookahead-char (import (rnrs)) ;R6RS (import (rnrs io ports)) ;R6RS ;; peek-char (import (rnrs)) ;R6RS (import (rnrs io simple)) ;R6RS (import (scheme r5rs)) ;R7RS (import (scheme base)) ;R7RS
(lookahead-char textual-input-port) ;R6RS (peek-char) (peek-char textual-input-port)
This procedure blocks as necessary until a character is available, or the data that are available cannot be the prefix of any valid encoding, or an end of file is reached.
If a complete character is available before the next end of file, this procedure returns that character.
If an end of file is reached before any data are read, this procedure returns the end-of-file object.
If textual-input-port is omitted, it defaults to the value returned by current-input-port(3scm).
;; This demonstrates one way to parse /etc/passwd
;; using peek-char.
(import (scheme base) (scheme file) (scheme write))
(define (get-string-until-chars p terminators)
(let lp ((chars '()))
(let ((c (peek-char p)))
(cond ((or (eof-object? c)
(memv c terminators))
;; Take the characters we found up until
;; the terminator and return them as
;; a string.
(list->string (reverse chars)))
(else
(lp (cons (read-char p) chars)))))))
(define (get-record p)
(let lp ((fields '()))
(let* ((field (get-string-until-chars p '(#\: #\newline)))
(terminator (read-char p)))
(cond ((and (eof-object? terminator) (null? fields))
;; Returns the end-of-file object
terminator)
((or (eof-object? terminator)
(eqv? terminator #\newline))
;; The record was terminated with or
;; without a newline.
(reverse (cons field fields)))
(else
;; Save the field from the record.
(lp (cons field fields)))))))
(call-with-input-file "/etc/passwd"
(lambda (p)
;; Read records from the port and write them as lists to standard
;; output until the end of the file.
(let lp ()
(let ((record (get-record p)))
(unless (eof-object? record)
(write record)
(newline)
(lp))))))
;; The R7RS program above prints something like this:
;;
;; ("root" "x" "0" "0" "root" "/root" "/bin/bash")
;; ("daemon" "x" "1" "1" "daemon" "/usr/sbin" "/usr/sbin/nologin")
;; ("bin" "x" "2" "2" "bin" "/bin" "/usr/sbin/nologin")
;; ...
https://github.com/schemedoc/manpages/.