diff options
author | Doug Evans <xdje42@gmail.com> | 2015-05-16 12:14:26 -0700 |
---|---|---|
committer | Doug Evans <xdje42@gmail.com> | 2015-05-16 12:14:26 -0700 |
commit | 37442ce10aaa2f84d245631d38e25ee47e5057aa (patch) | |
tree | f3ca51f86a4e0a5a4c58b571ea9b49986cff4311 /gdb/testsuite/gdb.guile | |
parent | d976bace1c68aed43311651c1033c23b3c983094 (diff) | |
download | gdb-37442ce10aaa2f84d245631d38e25ee47e5057aa.zip gdb-37442ce10aaa2f84d245631d38e25ee47e5057aa.tar.gz gdb-37442ce10aaa2f84d245631d38e25ee47e5057aa.tar.bz2 |
Add support for unbuffered and zero sized Guile ports.
gdb/ChangeLog
* NEWS: Mention support for unbuffered Guile memory ports.
* scm-ports.c (ioscm_memory_port): Update comments on end, size.
(ioscm_lseek_address): Improve overflow calculation.
(gdbscm_memory_port_fill_input): Add assert.
(gdbscm_memory_port_write): Handle unbuffered ports.
Handle large writes identical to Guile's fport_write.
(gdbscm_memory_port_seek): Fix seeking past end check.
(gdbscm_memory_port_close): Handle closing unbuffered port.
(ioscm_parse_mode_bits): Recognize "0" for unbuffered ports.
(ioscm_init_memory_port): Handle unbuffered ports.
(ioscm_reinit_memory_port): Ditto.
(ioscm_init_memory_port): Update size calculation.
(gdbscm_open_memory): Support zero sized ports.
gdb/testsuite/ChangeLog
* gdb.guile/scm-ports.c: New file.
* gdb.guile/scm-ports.exp: Add memory port tests.
gdb/doc/ChangeLog
* guile.texi (Memory Ports in Guile): Document support for unbuffered
memory ports.
Diffstat (limited to 'gdb/testsuite/gdb.guile')
-rw-r--r-- | gdb/testsuite/gdb.guile/scm-ports.c | 22 | ||||
-rw-r--r-- | gdb/testsuite/gdb.guile/scm-ports.exp | 136 |
2 files changed, 155 insertions, 3 deletions
diff --git a/gdb/testsuite/gdb.guile/scm-ports.c b/gdb/testsuite/gdb.guile/scm-ports.c new file mode 100644 index 0000000..b92fefb --- /dev/null +++ b/gdb/testsuite/gdb.guile/scm-ports.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 Free Software Foundation, Inc. + + This program 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. + + This program 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 <http://www.gnu.org/licenses/>. */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.guile/scm-ports.exp b/gdb/testsuite/gdb.guile/scm-ports.exp index 099f5e6..420f183 100644 --- a/gdb/testsuite/gdb.guile/scm-ports.exp +++ b/gdb/testsuite/gdb.guile/scm-ports.exp @@ -18,20 +18,150 @@ load_lib gdb-guile.exp -# Start with a fresh gdb. -gdb_exit -gdb_start +standard_testfile + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { + return +} # Skip all tests if Guile scripting is not enabled. if { [skip_guile_tests] } { continue } +if ![gdb_guile_runto_main] { + return +} + gdb_reinitialize_dir $srcdir/$subdir gdb_install_guile_utils gdb_install_guile_module +gdb_scm_test_silent_cmd "guile (use-modules (rnrs io ports) (rnrs bytevectors))" \ + "import (rnrs io ports) (rnrs bytevectors)" + gdb_test "guile (print (stdio-port? 42))" "= #f" gdb_test "guile (print (stdio-port? (%make-void-port \"r\")))" "= #f" gdb_test "guile (print (stdio-port? (input-port)))" "= #t" gdb_test "guile (print (stdio-port? (output-port)))" "= #t" gdb_test "guile (print (stdio-port? (error-port)))" "= #t" + +# Test memory port open/close. + +proc test_port { mode } { + with_test_prefix "basic $mode tests" { + gdb_test_no_output "guile (define my-port (open-memory #:mode \"$mode\"))" \ + "create memory port" + gdb_test "guile (print (memory-port? my-port))" "= #t" + switch -glob $mode { + "r+*" { + gdb_test "guile (print (input-port? my-port))" "= #t" + gdb_test "guile (print (output-port? my-port))" "= #t" + } + "r*" { + gdb_test "guile (print (input-port? my-port))" "= #t" + gdb_test "guile (print (output-port? my-port))" "= #f" + } + "w*" { + gdb_test "guile (print (input-port? my-port))" "= #f" + gdb_test "guile (print (output-port? my-port))" "= #t" + } + default { + error "bad test mode" + } + } + gdb_test "guile (print (port-closed? my-port))" "= #f" \ + "test port-closed? before it's closed" + gdb_test "guile (print (close-port my-port))" "= #t" + gdb_test "guile (print (port-closed? my-port))" "= #t" \ + "test port-closed? after it's closed" + } +} + +set port_variations { r w r+ rb wb r+b r0 w0 r+0 } +foreach variation $port_variations { + test_port $variation +} + +# Test read/write of memory ports. + +proc test_mem_port_rw { kind } { + if { "$kind" == "buffered" } { + set buffered 1 + } else { + set buffered 0 + } + with_test_prefix $kind { + if $buffered { + set mode "r+" + } else { + set mode "r+0" + } + gdb_test_no_output "guile (define rw-mem-port (open-memory #:mode \"$mode\"))" \ + "create r/w memory port" + gdb_test "guile (print rw-mem-port)" \ + "#<input-output: gdb:memory-port 0x0-0xf+>" + gdb_test_no_output "guile (define sp-reg (parse-and-eval \"\$sp\"))" \ + "get sp reg" + # Note: Only use $sp_reg for gdb_test result matching, don't use it in + # gdb commands. Otherwise transcript.N becomes unusable. + set sp_reg [get_integer_valueof "\$sp" 0] + gdb_test_no_output "guile (define byte-at-sp (parse-and-eval \"*(char*) \$sp\"))" \ + "save current value at sp" + # Pass the result of parse-and-eval through value-fetch-lazy!, + # otherwise the value gets left as a lazy reference to memory, which + # when re-evaluated after we flush the write will yield the newly + # written value. PR 18175 + gdb_test_no_output "guile (value-fetch-lazy! byte-at-sp)" \ + "un-lazyify byte-at-sp" + gdb_test "guile (print (seek rw-mem-port (value->integer sp-reg) SEEK_SET))" \ + "= $sp_reg" \ + "seek to \$sp" + gdb_test_no_output "guile (define old-value (value->integer byte-at-sp))" \ + "define old-value" + gdb_test_no_output "guile (define new-value (logxor old-value 1))" \ + "define new-value" + gdb_test "guile (print (put-bytevector rw-mem-port (make-bytevector 1 new-value)))" \ + "= #<unspecified>" + if $buffered { + # Value shouldn't be in memory yet. + gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") byte-at-sp))" \ + "= #t" \ + "test byte at sp, before flush" + gdb_test_no_output "guile (force-output rw-mem-port)" \ + "flush port" + } + # Value should be in memory now. + gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") byte-at-sp))" \ + "= #f" \ + "test byte at sp, after flush" + # Restore the value for cleanliness sake, and to verify close-port + # flushes the buffer. + gdb_test "guile (print (seek rw-mem-port (value->integer sp-reg) SEEK_SET))" \ + "= $sp_reg" \ + "seek to \$sp for restore" + gdb_test "guile (print (put-bytevector rw-mem-port (make-bytevector 1 old-value)))" \ + "= #<unspecified>" + gdb_test "guile (print (close-port rw-mem-port))" \ + "= #t" + gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") byte-at-sp))" \ + "= #t" \ + "test byte at sp, after close" + } +} + +test_mem_port_rw buffered +test_mem_port_rw unbuffered + +# Test zero-length memory ports. + +gdb_test_no_output "guile (define zero-mem-port (open-memory #:start 0 #:size 0 #:mode \"r+\"))" \ + "create zero length memory port" +gdb_test "guile (print (read-char zero-mem-port))" \ + "= #<eof>" +gdb_test "guile (print (write-char #\\a zero-mem-port))" \ + "ERROR: .*Out of range: writing beyond end of memory range.*Error while executing Scheme code." +gdb_test "guile (print (get-bytevector-n zero-mem-port 0))" \ + "= #vu8\\(\\)" +gdb_test "guile (print (put-bytevector zero-mem-port (make-bytevector 0)))" \ + "= #<unspecified>" +gdb_test "guile (print (close-port zero-mem-port))" "= #t" |