2010-01-23 16:21:13 +01:00
|
|
|
|
;;;; structs.test --- Structures. -*- mode: scheme; coding: utf-8; -*-
|
|
|
|
|
|
;;;; Ludovic Courtès <ludo@gnu.org>, 2006-06-12.
|
2006-06-13 07:56:41 +00:00
|
|
|
|
;;;;
|
2010-01-23 16:21:13 +01:00
|
|
|
|
;;;; Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
|
2006-06-13 07:56:41 +00:00
|
|
|
|
;;;;
|
2009-06-17 00:22:09 +01:00
|
|
|
|
;;;; This library is free software; you can redistribute it and/or
|
|
|
|
|
|
;;;; modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
|
;;;; License as published by the Free Software Foundation; either
|
|
|
|
|
|
;;;; version 3 of the License, or (at your option) any later version.
|
|
|
|
|
|
;;;;
|
|
|
|
|
|
;;;; This library is distributed in the hope that it will be useful,
|
2006-06-13 07:56:41 +00:00
|
|
|
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2009-06-17 00:22:09 +01:00
|
|
|
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
;;;; Lesser General Public License for more details.
|
|
|
|
|
|
;;;;
|
|
|
|
|
|
;;;; You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
;;;; License along with this library; if not, write to the Free Software
|
|
|
|
|
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2006-06-13 07:56:41 +00:00
|
|
|
|
|
2007-01-19 08:53:33 +00:00
|
|
|
|
(define-module (test-suite test-structs)
|
|
|
|
|
|
:use-module (test-suite lib))
|
2006-06-13 07:56:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Struct example taken from the reference manual (by Tom Lord).
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define ball-root (make-vtable-vtable "pr" 0))
|
|
|
|
|
|
|
|
|
|
|
|
(define (make-ball-type ball-color)
|
|
|
|
|
|
(make-struct ball-root 0
|
|
|
|
|
|
(make-struct-layout "pw")
|
|
|
|
|
|
(lambda (ball port)
|
|
|
|
|
|
(format port "#<a ~A ball owned by ~A>"
|
|
|
|
|
|
(color ball)
|
|
|
|
|
|
(owner ball)))
|
|
|
|
|
|
ball-color))
|
|
|
|
|
|
|
|
|
|
|
|
(define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user))
|
|
|
|
|
|
(define (owner ball) (struct-ref ball 0))
|
|
|
|
|
|
(define (set-owner! ball owner) (struct-set! ball 0 owner))
|
|
|
|
|
|
|
|
|
|
|
|
(define red (make-ball-type 'red))
|
|
|
|
|
|
(define green (make-ball-type 'green))
|
|
|
|
|
|
|
|
|
|
|
|
(define (make-ball type owner) (make-struct type 0 owner))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Test suite.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "low-level struct procedures"
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "constructors"
|
|
|
|
|
|
(and (struct-vtable? ball-root)
|
|
|
|
|
|
(struct-vtable? red)
|
|
|
|
|
|
(struct-vtable? green)))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "vtables"
|
|
|
|
|
|
(and (eq? (struct-vtable red) ball-root)
|
|
|
|
|
|
(eq? (struct-vtable green) ball-root)
|
|
|
|
|
|
(eq? (struct-vtable (make-ball red "Bob")) red)
|
|
|
|
|
|
|
|
|
|
|
|
;; end of the vtable tower
|
|
|
|
|
|
(eq? (struct-vtable ball-root) ball-root)))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if-exception "write-access denied"
|
|
|
|
|
|
exception:struct-set!-denied
|
|
|
|
|
|
|
|
|
|
|
|
;; The first field of instances of BALL-ROOT is read-only.
|
|
|
|
|
|
(struct-set! red vtable-offset-user "blue"))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "write-access granted"
|
|
|
|
|
|
(set-owner! (make-ball red "Bob") "Fred")
|
|
|
|
|
|
#t)
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "struct-set!"
|
|
|
|
|
|
(let ((ball (make-ball green "Bob")))
|
|
|
|
|
|
(set-owner! ball "Bill")
|
2010-01-23 16:21:13 +01:00
|
|
|
|
(string=? (owner ball) "Bill")))
|
2006-06-13 07:56:41 +00:00
|
|
|
|
|
2010-01-23 16:21:13 +01:00
|
|
|
|
(pass-if "struct-ref"
|
|
|
|
|
|
(let ((ball (make-ball red "Alice")))
|
|
|
|
|
|
(equal? (struct-ref ball 0) "Alice")))
|
2007-01-19 08:53:33 +00:00
|
|
|
|
|
2010-01-23 16:21:13 +01:00
|
|
|
|
(pass-if "struct-set!"
|
|
|
|
|
|
(let* ((v (make-vtable "pw"))
|
|
|
|
|
|
(s (make-struct v 0))
|
|
|
|
|
|
(r (struct-set! s 0 'a)))
|
|
|
|
|
|
(eq? r
|
|
|
|
|
|
(struct-ref s 0)
|
|
|
|
|
|
'a)))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if-exception "struct-ref out-of-range"
|
|
|
|
|
|
exception:out-of-range
|
|
|
|
|
|
(let* ((v (make-vtable "prpr"))
|
|
|
|
|
|
(s (make-struct v 0 'a 'b)))
|
|
|
|
|
|
(struct-ref s 2)))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if-exception "struct-set! out-of-range"
|
|
|
|
|
|
exception:out-of-range
|
|
|
|
|
|
(let* ((v (make-vtable "pwpw"))
|
|
|
|
|
|
(s (make-struct v 0 'a 'b)))
|
|
|
|
|
|
(struct-set! s 2 'c))))
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-01-19 08:53:33 +00:00
|
|
|
|
(with-test-prefix "equal?"
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "simple structs"
|
2009-11-03 22:26:46 +01:00
|
|
|
|
(let* ((vtable (make-vtable "pr"))
|
2007-01-19 08:53:33 +00:00
|
|
|
|
(s1 (make-struct vtable 0 "hello"))
|
|
|
|
|
|
(s2 (make-struct vtable 0 "hello")))
|
|
|
|
|
|
(equal? s1 s2)))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "more complex structs"
|
2006-06-13 07:56:41 +00:00
|
|
|
|
(let ((first (make-ball red (string-copy "Bob")))
|
2007-01-19 08:53:33 +00:00
|
|
|
|
(second (make-ball red (string-copy "Bob"))))
|
2006-06-13 07:56:41 +00:00
|
|
|
|
(equal? first second)))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "not-equal?"
|
2007-01-19 08:53:33 +00:00
|
|
|
|
(not (or (equal? (make-ball red "Bob") (make-ball green "Bob"))
|
2006-06-13 07:56:41 +00:00
|
|
|
|
(equal? (make-ball red "Bob") (make-ball red "Bill"))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-07 23:00:22 +00:00
|
|
|
|
;;
|
|
|
|
|
|
;; make-struct
|
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
|
|
(define exception:bad-tail
|
|
|
|
|
|
(cons 'misc-error "tail array not allowed unless"))
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "make-struct"
|
|
|
|
|
|
|
|
|
|
|
|
;; in guile 1.8.1 and earlier, this caused an error throw out of an
|
|
|
|
|
|
;; SCM_CRITICAL_SECTION_START / SCM_CRITICAL_SECTION_END, which abort()ed
|
|
|
|
|
|
;; the program
|
|
|
|
|
|
;;
|
|
|
|
|
|
(pass-if-exception "wrong type for `u' field" exception:wrong-type-arg
|
|
|
|
|
|
(let* ((vv (make-vtable-vtable "" 0))
|
|
|
|
|
|
(v (make-struct vv 0 (make-struct-layout "uw"))))
|
|
|
|
|
|
(make-struct v 0 'x)))
|
|
|
|
|
|
|
|
|
|
|
|
;; In guile 1.8.1 and earlier, and 1.6.8 and earlier, there was no check
|
|
|
|
|
|
;; on a tail array being created without an R/W/O type for it. This left
|
|
|
|
|
|
;; it uninitialized by scm_struct_init(), resulting in garbage getting
|
|
|
|
|
|
;; into an SCM when struct-ref read it (and attempting to print a garbage
|
|
|
|
|
|
;; SCM can cause a segv).
|
|
|
|
|
|
;;
|
|
|
|
|
|
(pass-if-exception "no R/W/O for tail array" exception:bad-tail
|
|
|
|
|
|
(let* ((vv (make-vtable-vtable "" 0))
|
|
|
|
|
|
(v (make-struct vv 0 (make-struct-layout "pw"))))
|
|
|
|
|
|
(make-struct v 123 'x))))
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
|
;; make-vtable
|
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
|
|
(with-test-prefix "make-vtable"
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "without printer"
|
|
|
|
|
|
(let* ((vtable (make-vtable "pwpr"))
|
|
|
|
|
|
(struct (make-struct vtable 0 'x 'y)))
|
|
|
|
|
|
(and (eq? 'x (struct-ref struct 0))
|
|
|
|
|
|
(eq? 'y (struct-ref struct 1)))))
|
|
|
|
|
|
|
|
|
|
|
|
(pass-if "with printer"
|
|
|
|
|
|
(let ()
|
|
|
|
|
|
(define (print struct port)
|
|
|
|
|
|
(display "hello" port))
|
|
|
|
|
|
|
|
|
|
|
|
(let* ((vtable (make-vtable "pwpr" print))
|
|
|
|
|
|
(struct (make-struct vtable 0 'x 'y))
|
|
|
|
|
|
(str (call-with-output-string
|
|
|
|
|
|
(lambda (port)
|
|
|
|
|
|
(display struct port)))))
|
|
|
|
|
|
(equal? str "hello")))))
|