aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
authorDoug Evans <xdje42@gmail.com>2014-02-09 19:40:01 -0800
committerDoug Evans <xdje42@gmail.com>2014-02-09 19:40:01 -0800
commited3ef33944c39d9a3cea72b9a7cef3c20f0e3461 (patch)
tree4e67d95b8ea65bb36a9cade5e37df2ad6289052e /gdb/testsuite
parent7026a7c16ee82d39e84823f8cc3097a9a940ddb2 (diff)
downloadgdb-ed3ef33944c39d9a3cea72b9a7cef3c20f0e3461.zip
gdb-ed3ef33944c39d9a3cea72b9a7cef3c20f0e3461.tar.gz
gdb-ed3ef33944c39d9a3cea72b9a7cef3c20f0e3461.tar.bz2
Add Guile as an extension language.
* NEWS: Mention Guile scripting. * Makefile.in (SUBDIR_GUILE_OBS): New variable. (SUBDIR_GUILE_SRCS, SUBDIR_GUILE_DEPS): New variables (SUBDIR_GUILE_LDFLAGS, SUBDIR_GUILE_CFLAGS): New variables. (INTERNAL_CPPFLAGS): Add GUILE_CPPFLAGS. (CLIBS): Add GUILE_LIBS. (install-guile): New rule. (guile.o): New rule. (scm-arch.o, scm-auto-load.o, scm-block.o): New rules. (scm-breakpoint.o, scm-disasm.o, scm-exception.o): New rules. (scm-frame.o, scm-iterator.o, scm-lazy-string.o): New rules. (scm-math.o, scm-objfile.o, scm-ports.o): New rules. (scm-pretty-print.o, scm-safe-call.o, scm-gsmob.o): New rules. (scm-string.o, scm-symbol.o, scm-symtab.o): New rules. (scm-type.o, scm-utils.o, scm-value.o): New rules. * configure.ac: New option --with-guile. * configure: Regenerate. * config.in: Regenerate. * auto-load.c: Remove #include "python/python.h". Add #include "gdb/section-scripts.h". (source_section_scripts): Handle Guile scripts. (_initialize_auto_load): Add name of Guile objfile script to scripts-directory help text. * breakpoint.c (condition_command): Tweak comment to include Scheme. * breakpoint.h (gdbscm_breakpoint_object): Add forward decl. (struct breakpoint): New member scm_bp_object. * defs.h (enum command_control_type): New value guile_control. * cli/cli-cmds.c: Remove #include "python/python.h". Add #include "extension.h". (show_user): Update comment. (_initialize_cli_cmds): Update help text for "show user". Update help text for max-user-call-depth. * cli/cli-script.c: Remove #include "python/python.h". Add #include "extension.h". (multi_line_command_p): Add guile_control. (print_command_lines): Handle guile_control. (execute_control_command, recurse_read_control_structure): Ditto. (process_next_line): Recognize "guile" commands. * disasm.c (gdb_disassemble_info): Make non-static. * disasm.h: #include "dis-asm.h". (struct gdbarch): Add forward decl. (gdb_disassemble_info): Declare. * extension.c: #include "guile/guile.h". (extension_languages): Add guile. (get_ext_lang_defn): Handle EXT_LANG_GDB. * extension.h (enum extension_language): New value EXT_LANG_GUILE. * gdbtypes.c (get_unsigned_type_max): New function. (get_signed_type_minmax): New function. * gdbtypes.h (get_unsigned_type_max): Declare. (get_signed_type_minmax): Declare. * guile/README: New file. * guile/guile-internal.h: New file. * guile/guile.c: New file. * guile/guile.h: New file. * guile/scm-arch.c: New file. * guile/scm-auto-load.c: New file. * guile/scm-block.c: New file. * guile/scm-breakpoint.c: New file. * guile/scm-disasm.c: New file. * guile/scm-exception.c: New file. * guile/scm-frame.c: New file. * guile/scm-gsmob.c: New file. * guile/scm-iterator.c: New file. * guile/scm-lazy-string.c: New file. * guile/scm-math.c: New file. * guile/scm-objfile.c: New file. * guile/scm-ports.c: New file. * guile/scm-pretty-print.c: New file. * guile/scm-safe-call.c: New file. * guile/scm-string.c: New file. * guile/scm-symbol.c: New file. * guile/scm-symtab.c: New file. * guile/scm-type.c: New file. * guile/scm-utils.c: New file. * guile/scm-value.c: New file. * guile/lib/gdb.scm: New file. * guile/lib/gdb/boot.scm: New file. * guile/lib/gdb/experimental.scm: New file. * guile/lib/gdb/init.scm: New file. * guile/lib/gdb/iterator.scm: New file. * guile/lib/gdb/printing.scm: New file. * guile/lib/gdb/types.scm: New file. * data-directory/Makefile.in (GUILE_SRCDIR): New variable. (VPATH): Add $(GUILE_SRCDIR). (GUILE_DIR): New variable. (GUILE_INSTALL_DIR, GUILE_FILES): New variables. (all): Add stamp-guile dependency. (stamp-guile): New rule. (clean-guile, install-guile, uninstall-guile): New rules. (install-only): Add install-guile dependency. (uninstall): Add uninstall-guile dependency. (clean): Add clean-guile dependency. doc/ * Makefile.in (GDB_DOC_FILES): Add guile.texi. * gdb.texinfo (Auto-loading): Add set/show auto-load guile-scripts. (Extending GDB): New menu entries Guile, Multiple Extension Languages. (Guile docs): Include guile.texi. (objfile-gdbdotext file): Add objfile-gdb.scm. (dotdebug_gdb_scripts section): Mention Guile scripts. (Multiple Extension Languages): New node. * guile.texi: New file. testsuite/ * configure.ac (AC_OUTPUT): Add gdb.guile. * configure: Regenerate. * lib/gdb-guile.exp: New file. * lib/gdb.exp (get_target_charset): New function. * gdb.base/help.exp: Update expected output from "apropos apropos". * gdb.guile/Makefile.in: New file. * gdb.guile/guile.exp: New file. * gdb.guile/scm-arch.c: New file. * gdb.guile/scm-arch.exp: New file. * gdb.guile/scm-block.c: New file. * gdb.guile/scm-block.exp: New file. * gdb.guile/scm-breakpoint.c: New file. * gdb.guile/scm-breakpoint.exp: New file. * gdb.guile/scm-disasm.c: New file. * gdb.guile/scm-disasm.exp: New file. * gdb.guile/scm-equal.c: New file. * gdb.guile/scm-equal.exp: New file. * gdb.guile/scm-error.exp: New file. * gdb.guile/scm-error.scm: New file. * gdb.guile/scm-frame-args.c: New file. * gdb.guile/scm-frame-args.exp: New file. * gdb.guile/scm-frame-args.scm: New file. * gdb.guile/scm-frame-inline.c: New file. * gdb.guile/scm-frame-inline.exp: New file. * gdb.guile/scm-frame.c: New file. * gdb.guile/scm-frame.exp: New file. * gdb.guile/scm-generics.exp: New file. * gdb.guile/scm-gsmob.exp: New file. * gdb.guile/scm-iterator.c: New file. * gdb.guile/scm-iterator.exp: New file. * gdb.guile/scm-math.c: New file. * gdb.guile/scm-math.exp: New file. * gdb.guile/scm-objfile-script-gdb.in: New file. * gdb.guile/scm-objfile-script.c: New file. * gdb.guile/scm-objfile-script.exp: New file. * gdb.guile/scm-objfile.c: New file. * gdb.guile/scm-objfile.exp: New file. * gdb.guile/scm-ports.exp: New file. * gdb.guile/scm-pretty-print.c: New file. * gdb.guile/scm-pretty-print.exp: New file. * gdb.guile/scm-pretty-print.scm: New file. * gdb.guile/scm-section-script.c: New file. * gdb.guile/scm-section-script.exp: New file. * gdb.guile/scm-section-script.scm: New file. * gdb.guile/scm-symbol.c: New file. * gdb.guile/scm-symbol.exp: New file. * gdb.guile/scm-symtab-2.c: New file. * gdb.guile/scm-symtab.c: New file. * gdb.guile/scm-symtab.exp: New file. * gdb.guile/scm-type.c: New file. * gdb.guile/scm-type.exp: New file. * gdb.guile/scm-value-cc.cc: New file. * gdb.guile/scm-value-cc.exp: New file. * gdb.guile/scm-value.c: New file. * gdb.guile/scm-value.exp: New file. * gdb.guile/source2.scm: New file. * gdb.guile/types-module.cc: New file. * gdb.guile/types-module.exp: New file.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/ChangeLog61
-rwxr-xr-xgdb/testsuite/configure3
-rw-r--r--gdb/testsuite/configure.ac2
-rw-r--r--gdb/testsuite/gdb.base/help.exp2
-rw-r--r--gdb/testsuite/gdb.guile/Makefile.in17
-rw-r--r--gdb/testsuite/gdb.guile/guile.exp77
-rw-r--r--gdb/testsuite/gdb.guile/scm-arch.c22
-rw-r--r--gdb/testsuite/gdb.guile/scm-arch.exp33
-rw-r--r--gdb/testsuite/gdb.guile/scm-block.c38
-rw-r--r--gdb/testsuite/gdb.guile/scm-block.exp107
-rw-r--r--gdb/testsuite/gdb.guile/scm-breakpoint.c44
-rw-r--r--gdb/testsuite/gdb.guile/scm-breakpoint.exp438
-rw-r--r--gdb/testsuite/gdb.guile/scm-disasm.c22
-rw-r--r--gdb/testsuite/gdb.guile/scm-disasm.exp133
-rw-r--r--gdb/testsuite/gdb.guile/scm-equal.c24
-rw-r--r--gdb/testsuite/gdb.guile/scm-equal.exp55
-rw-r--r--gdb/testsuite/gdb.guile/scm-error-1.scm19
-rw-r--r--gdb/testsuite/gdb.guile/scm-error-2.scm30
-rw-r--r--gdb/testsuite/gdb.guile/scm-error.exp117
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame-args.c60
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame-args.exp76
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame-args.scm69
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame-inline.c43
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame-inline.exp43
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame.c30
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame.exp122
-rw-r--r--gdb/testsuite/gdb.guile/scm-generics.exp42
-rw-r--r--gdb/testsuite/gdb.guile/scm-gsmob.exp70
-rw-r--r--gdb/testsuite/gdb.guile/scm-iterator.c28
-rw-r--r--gdb/testsuite/gdb.guile/scm-iterator.exp62
-rw-r--r--gdb/testsuite/gdb.guile/scm-math.c30
-rw-r--r--gdb/testsuite/gdb.guile/scm-math.exp309
-rw-r--r--gdb/testsuite/gdb.guile/scm-objfile-script-gdb.in55
-rw-r--r--gdb/testsuite/gdb.guile/scm-objfile-script.c39
-rw-r--r--gdb/testsuite/gdb.guile/scm-objfile-script.exp57
-rw-r--r--gdb/testsuite/gdb.guile/scm-objfile.c23
-rw-r--r--gdb/testsuite/gdb.guile/scm-objfile.exp57
-rw-r--r--gdb/testsuite/gdb.guile/scm-ports.exp37
-rw-r--r--gdb/testsuite/gdb.guile/scm-pretty-print.c353
-rw-r--r--gdb/testsuite/gdb.guile/scm-pretty-print.exp148
-rw-r--r--gdb/testsuite/gdb.guile/scm-pretty-print.scm301
-rw-r--r--gdb/testsuite/gdb.guile/scm-section-script.c55
-rw-r--r--gdb/testsuite/gdb.guile/scm-section-script.exp80
-rw-r--r--gdb/testsuite/gdb.guile/scm-section-script.scm55
-rw-r--r--gdb/testsuite/gdb.guile/scm-symbol.c69
-rw-r--r--gdb/testsuite/gdb.guile/scm-symbol.exp196
-rw-r--r--gdb/testsuite/gdb.guile/scm-symtab-2.c28
-rw-r--r--gdb/testsuite/gdb.guile/scm-symtab.c45
-rw-r--r--gdb/testsuite/gdb.guile/scm-symtab.exp142
-rw-r--r--gdb/testsuite/gdb.guile/scm-type.c77
-rw-r--r--gdb/testsuite/gdb.guile/scm-type.exp299
-rw-r--r--gdb/testsuite/gdb.guile/scm-value-cc.cc39
-rw-r--r--gdb/testsuite/gdb.guile/scm-value-cc.exp57
-rw-r--r--gdb/testsuite/gdb.guile/scm-value.c101
-rw-r--r--gdb/testsuite/gdb.guile/scm-value.exp449
-rw-r--r--gdb/testsuite/gdb.guile/source2.scm19
-rw-r--r--gdb/testsuite/gdb.guile/types-module.cc38
-rw-r--r--gdb/testsuite/gdb.guile/types-module.exp50
-rw-r--r--gdb/testsuite/lib/gdb-guile.exp127
-rw-r--r--gdb/testsuite/lib/gdb.exp17
60 files changed, 5238 insertions, 3 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 8b9ec44..da1348b 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,64 @@
+2014-02-10 Doug Evans <xdje42@gmail.com>
+
+ * configure.ac (AC_OUTPUT): Add gdb.guile.
+ * configure: Regenerate.
+ * lib/gdb-guile.exp: New file.
+ * lib/gdb.exp (get_target_charset): New function.
+ * gdb.base/help.exp: Update expected output from "apropos apropos".
+ * gdb.guile/Makefile.in: New file.
+ * gdb.guile/guile.exp: New file.
+ * gdb.guile/scm-arch.c: New file.
+ * gdb.guile/scm-arch.exp: New file.
+ * gdb.guile/scm-block.c: New file.
+ * gdb.guile/scm-block.exp: New file.
+ * gdb.guile/scm-breakpoint.c: New file.
+ * gdb.guile/scm-breakpoint.exp: New file.
+ * gdb.guile/scm-disasm.c: New file.
+ * gdb.guile/scm-disasm.exp: New file.
+ * gdb.guile/scm-equal.c: New file.
+ * gdb.guile/scm-equal.exp: New file.
+ * gdb.guile/scm-error.exp: New file.
+ * gdb.guile/scm-error.scm: New file.
+ * gdb.guile/scm-frame-args.c: New file.
+ * gdb.guile/scm-frame-args.exp: New file.
+ * gdb.guile/scm-frame-args.scm: New file.
+ * gdb.guile/scm-frame-inline.c: New file.
+ * gdb.guile/scm-frame-inline.exp: New file.
+ * gdb.guile/scm-frame.c: New file.
+ * gdb.guile/scm-frame.exp: New file.
+ * gdb.guile/scm-generics.exp: New file.
+ * gdb.guile/scm-gsmob.exp: New file.
+ * gdb.guile/scm-iterator.c: New file.
+ * gdb.guile/scm-iterator.exp: New file.
+ * gdb.guile/scm-math.c: New file.
+ * gdb.guile/scm-math.exp: New file.
+ * gdb.guile/scm-objfile-script-gdb.in: New file.
+ * gdb.guile/scm-objfile-script.c: New file.
+ * gdb.guile/scm-objfile-script.exp: New file.
+ * gdb.guile/scm-objfile.c: New file.
+ * gdb.guile/scm-objfile.exp: New file.
+ * gdb.guile/scm-ports.exp: New file.
+ * gdb.guile/scm-pretty-print.c: New file.
+ * gdb.guile/scm-pretty-print.exp: New file.
+ * gdb.guile/scm-pretty-print.scm: New file.
+ * gdb.guile/scm-section-script.c: New file.
+ * gdb.guile/scm-section-script.exp: New file.
+ * gdb.guile/scm-section-script.scm: New file.
+ * gdb.guile/scm-symbol.c: New file.
+ * gdb.guile/scm-symbol.exp: New file.
+ * gdb.guile/scm-symtab-2.c: New file.
+ * gdb.guile/scm-symtab.c: New file.
+ * gdb.guile/scm-symtab.exp: New file.
+ * gdb.guile/scm-type.c: New file.
+ * gdb.guile/scm-type.exp: New file.
+ * gdb.guile/scm-value-cc.cc: New file.
+ * gdb.guile/scm-value-cc.exp: New file.
+ * gdb.guile/scm-value.c: New file.
+ * gdb.guile/scm-value.exp: New file.
+ * gdb.guile/source2.scm: New file.
+ * gdb.guile/types-module.cc: New file.
+ * gdb.guile/types-module.exp: New file.
+
2014-02-10 Yao Qi <yao@codesourcery.com>
PR testsuite/16543
diff --git a/gdb/testsuite/configure b/gdb/testsuite/configure
index aa08add..4bf6121 100755
--- a/gdb/testsuite/configure
+++ b/gdb/testsuite/configure
@@ -3448,7 +3448,7 @@ done
-ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.btrace/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.dlang/Makefile gdb.fortran/Makefile gdb.gdb/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.perf/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
+ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.btrace/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.dlang/Makefile gdb.fortran/Makefile gdb.gdb/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.guile/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.perf/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -4170,6 +4170,7 @@ do
"gdb.hp/gdb.aCC/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.aCC/Makefile" ;;
"gdb.hp/gdb.compat/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.compat/Makefile" ;;
"gdb.hp/gdb.defects/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.defects/Makefile" ;;
+ "gdb.guile/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.guile/Makefile" ;;
"gdb.linespec/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.linespec/Makefile" ;;
"gdb.mi/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.mi/Makefile" ;;
"gdb.modula2/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.modula2/Makefile" ;;
diff --git a/gdb/testsuite/configure.ac b/gdb/testsuite/configure.ac
index b6640bd..fb084d4 100644
--- a/gdb/testsuite/configure.ac
+++ b/gdb/testsuite/configure.ac
@@ -95,7 +95,7 @@ AC_OUTPUT([Makefile \
gdb.server/Makefile gdb.java/Makefile \
gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile \
gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile \
- gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile \
+ gdb.hp/gdb.defects/Makefile gdb.guile/Makefile gdb.linespec/Makefile \
gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile \
gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile \
gdb.perf/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile \
diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp
index c55eaf6..c4032a5 100644
--- a/gdb/testsuite/gdb.base/help.exp
+++ b/gdb/testsuite/gdb.base/help.exp
@@ -124,4 +124,4 @@ gdb_test "apropos \\\(print\[\^ bsiedf\\\".-\]\\\)" "handle -- Specify how to ha
# test apropos >1 word string
gdb_test "apropos handle signal" "handle -- Specify how to handle signals"
# test apropos apropos
-gdb_test "apropos apropos" "apropos -- Search for commands matching a REGEXP"
+gdb_test "apropos apropos" "apropos -- Search for commands matching a REGEXP.*"
diff --git a/gdb/testsuite/gdb.guile/Makefile.in b/gdb/testsuite/gdb.guile/Makefile.in
new file mode 100644
index 0000000..37f9cb0
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/Makefile.in
@@ -0,0 +1,17 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES =
+
+MISCELLANEOUS =
+
+all info install-info dvi install uninstall installcheck check:
+ @echo "Nothing to be done for $@..."
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f *.dwo *.dwp
+ -rm -f core $(EXECUTABLES) $(MISCELLANEOUS)
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log gdb.log gdb.sum
diff --git a/gdb/testsuite/gdb.guile/guile.exp b/gdb/testsuite/gdb.guile/guile.exp
new file mode 100644
index 0000000..2a171fe
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/guile.exp
@@ -0,0 +1,77 @@
+# Copyright (C) 2008-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests basic Guile features.
+
+load_lib gdb-guile.exp
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Do this instead of the skip_guile_check.
+# We want to do some tests when Guile is not present.
+gdb_test_multiple "guile (display 23) (newline)" "verify guile support" {
+ -re "Undefined command.*$gdb_prompt $" {
+ unsupported "Guile not supported."
+ return
+ }
+ -re "not supported.*$gdb_prompt $" {
+ unsupported "guile support is disabled"
+
+ # If Guile is not supported, verify that sourcing a guile script
+ # causes an error.
+ gdb_test "source $srcdir/$subdir/source2.scm" \
+ "Error in sourced command file:.*" \
+ "source source2.scm when guile disabled"
+ return
+ }
+ -re "$gdb_prompt $" {}
+}
+
+gdb_install_guile_utils
+gdb_install_guile_module
+
+gdb_test_multiline "multi-line guile command" \
+ "guile" "" \
+ "(print 23)" "" \
+ "end" "= 23"
+
+gdb_test_multiline "show guile command" \
+ "define zzq" "Type commands for definition of .* just \"end\"\\.*" \
+ "guile" "" \
+ "(print 23)" "" \
+ "end" "" \
+ "end" "" \
+ "show user zzq" "User command \"zzq\":.* guile.*\\(print 23\\).* end"
+
+gdb_test "source $srcdir/$subdir/source2.scm" "yes" "source source2.scm"
+
+gdb_test "source -s source2.scm" "yes" "source -s source2.scm"
+
+gdb_test "guile (print (current-objfile))" "= #f"
+gdb_test "guile (print (objfiles))" "= \\(\\)"
+
+gdb_test_no_output \
+ {guile (define x (execute "printf \"%d\", 23" #:to-string #t))}
+gdb_test "guile (print x)" "= 23"
+
+gdb_test_no_output "guile (define a (execute \"help\" #:to-string #t))" \
+ "collect help from uiout"
+
+gdb_test "guile (print a)" "= .*aliases -- Aliases of other commands.*" \
+ "verify help to uiout"
diff --git a/gdb/testsuite/gdb.guile/scm-arch.c b/gdb/testsuite/gdb.guile/scm-arch.c
new file mode 100644
index 0000000..6c0ef92
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-arch.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2014 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-arch.exp b/gdb/testsuite/gdb.guile/scm-arch.exp
new file mode 100644
index 0000000..1fcf615
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-arch.exp
@@ -0,0 +1,33 @@
+# Copyright 2014 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/>.
+
+load_lib gdb-guile.exp
+
+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_scm_test_silent_cmd "guile (define frame (selected-frame))" "get frame"
+gdb_scm_test_silent_cmd "guile (define arch (frame-arch frame))" "get arch"
+gdb_scm_test_silent_cmd "guile (define pc (frame-pc frame))" "get pc"
diff --git a/gdb/testsuite/gdb.guile/scm-block.c b/gdb/testsuite/gdb.guile/scm-block.c
new file mode 100644
index 0000000..69c37d0
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-block.c
@@ -0,0 +1,38 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2014 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 block_func (void)
+{
+ int i = 0;
+ {
+ double i = 1.0;
+ double f = 2.0;
+ {
+ const char *i = "stuff";
+ const char *f = "foo";
+ const char *b = "bar";
+ return 0; /* Block break here. */
+ }
+ }
+}
+
+
+int main (int argc, char *argv[])
+{
+ block_func ();
+ return 0; /* Break at end. */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-block.exp b/gdb/testsuite/gdb.guile/scm-block.exp
new file mode 100644
index 0000000..32d109a
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-block.exp
@@ -0,0 +1,107 @@
+# Copyright (C) 2010-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the mechanism exposing blocks to Guile.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_breakpoint [gdb_get_line_number "Block break here."]
+gdb_continue_to_breakpoint "Block break here."
+
+# Test initial innermost block.
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \
+ "Get frame inner"
+gdb_scm_test_silent_cmd "guile (define block (frame-block frame))" \
+ "Get block inner"
+gdb_test "guile (print block)" "#<gdb:block $hex-$hex>" \
+ "Check block not #f"
+gdb_test "guile (print (block-function block))" \
+ "#f" "First anonymous block"
+gdb_test "guile (print (block-start block))" \
+ "${decimal}" "Check start not #f"
+gdb_test "guile (print (block-end block))" \
+ "${decimal}" "Check end not #f"
+
+# Test eq?.
+gdb_test "guile (print (eq? (frame-block frame) (frame-block frame)))" \
+ "= #t" "Check eq? on same block"
+gdb_test "guile (print (eq? block (block-global-block block)))" \
+ "= #f" "Check eq? on different blocks"
+
+# Test global/static blocks.
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \
+ "Get frame for global/static"
+gdb_scm_test_silent_cmd "guile (define block (frame-block frame))" \
+ "Get block for global/static"
+gdb_test "guile (print (block-global? block))" \
+ "#f" "Not a global block"
+gdb_test "guile (print (block-static? block))" \
+ "#f" "Not a static block"
+gdb_scm_test_silent_cmd "guile (define gblock (block-global-block block))" \
+ "Get global block"
+gdb_scm_test_silent_cmd "guile (define sblock (block-static-block block))" \
+ "Get static block"
+gdb_test "guile (print (block-global? gblock))" \
+ "#t" "Is the global block"
+gdb_test "guile (print (block-static? sblock))" \
+ "#t" "Is the static block"
+
+# Move up superblock(s) until we reach function block_func.
+gdb_test_no_output "guile (set! block (block-superblock block))" \
+ "Get superblock"
+gdb_test "guile (print (block-function block))" \
+ "#f" "Second anonymous block"
+gdb_test_no_output "guile (set! block (block-superblock block))" \
+ "Get superblock 2"
+gdb_test "guile (print (block-function block))" \
+ "block_func" "Print superblock 2 function"
+
+# Switch frames, then test for main block.
+gdb_test "up" ".*"
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \
+ "Get frame 2"
+gdb_scm_test_silent_cmd "guile (define block (frame-block frame))" \
+ "Get frame 2's block"
+gdb_test "guile (print block)" "#<gdb:block main $hex-$hex>" \
+ "Check Frame 2's block not #f"
+gdb_test "guile (print (block-function block))" \
+ "main" "main block"
+
+# Test block-valid?. This must always be the last test in this
+# testcase as it unloads the object file.
+delete_breakpoints
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \
+ "Get frame for valid?"
+gdb_scm_test_silent_cmd "guile (define block (frame-block frame))" \
+ "Get frame block for valid?"
+gdb_test "guile (print (block-valid? block))" \
+ "#t" "Check block validity"
+gdb_unload
+gdb_test "guile (print (block-valid? block))" \
+ "#f" "Check block validity after unload"
diff --git a/gdb/testsuite/gdb.guile/scm-breakpoint.c b/gdb/testsuite/gdb.guile/scm-breakpoint.c
new file mode 100644
index 0000000..c8dc7f7
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-breakpoint.c
@@ -0,0 +1,44 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2014 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 result = 0;
+
+int multiply (int i)
+{
+ return i * i;
+}
+
+int add (int i)
+{
+ return i + i;
+}
+
+
+int main (int argc, char *argv[])
+{
+ int foo = 5;
+ int bar = 42;
+ int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ result += multiply (foo); /* Break at multiply. */
+ result += add (bar); /* Break at add. */
+ }
+
+ return 0; /* Break at end. */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-breakpoint.exp b/gdb/testsuite/gdb.guile/scm-breakpoint.exp
new file mode 100644
index 0000000..b25d4e0
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-breakpoint.exp
@@ -0,0 +1,438 @@
+# Copyright (C) 2010-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the mechanism exposing breakpoints to Guile.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+proc test_bkpt_basic { } {
+ global srcfile testfile hex decimal
+
+ with_test_prefix "test_bkpt_basic" {
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ # Initially there should be one breakpoint: main.
+
+ gdb_scm_test_silent_cmd "guile (define blist (breakpoints))" \
+ "get breakpoint list 1"
+ gdb_test "guile (print (car blist))" \
+ "<gdb:breakpoint #1 BP_BREAKPOINT enabled noisy hit:1 ignore:0 @main>" \
+ "check main breakpoint"
+ gdb_test "guile (print (breakpoint-location (car blist)))" \
+ "main" "check main breakpoint location"
+
+ set mult_line [gdb_get_line_number "Break at multiply."]
+ gdb_breakpoint ${mult_line}
+ gdb_continue_to_breakpoint "Break at multiply."
+
+ # Check that the Guile breakpoint code noted the addition of a
+ # breakpoint "behind the scenes".
+ gdb_scm_test_silent_cmd "guile (define blist (breakpoints))" \
+ "get breakpoint list 2"
+ gdb_scm_test_silent_cmd "guile (define mult-bkpt (cadr blist))" \
+ "get multiply breakpoint"
+ gdb_test "guile (print (length blist))" \
+ "= 2" "check for two breakpoints"
+ gdb_test "guile (print mult-bkpt)" \
+ "= #<gdb:breakpoint #2 BP_BREAKPOINT enabled noisy hit:1 ignore:0 @.*scm-breakpoint.c:$mult_line>" \
+ "check multiply breakpoint"
+ gdb_test "guile (print (breakpoint-location mult-bkpt))" \
+ "scm-breakpoint\.c:${mult_line}*" \
+ "check multiply breakpoint location"
+
+ # Check hit and ignore counts.
+ gdb_test "guile (print (breakpoint-hit-count mult-bkpt))" \
+ "= 1" "check multiply breakpoint hit count"
+ gdb_scm_test_silent_cmd "guile (set-breakpoint-ignore-count! mult-bkpt 4)" \
+ "set multiply breakpoint ignore count"
+ gdb_continue_to_breakpoint "Break at multiply."
+ gdb_test "guile (print (breakpoint-hit-count mult-bkpt))" \
+ "= 6" "check multiply breakpoint hit count 2"
+ gdb_test "print result" \
+ " = 545" "check expected variable result after 6 iterations"
+
+ # Test breakpoint is enabled and disabled correctly.
+ gdb_breakpoint [gdb_get_line_number "Break at add."]
+ gdb_continue_to_breakpoint "Break at add."
+ gdb_test "guile (print (breakpoint-enabled? mult-bkpt))" \
+ "= #t" "check multiply breakpoint enabled"
+ gdb_scm_test_silent_cmd "guile (set-breakpoint-enabled! mult-bkpt #f)" \
+ "set multiply breakpoint disabled"
+ gdb_continue_to_breakpoint "Break at add."
+ gdb_scm_test_silent_cmd "guile (set-breakpoint-enabled! mult-bkpt #t)" \
+ "set multiply breakpoint enabled"
+ gdb_continue_to_breakpoint "Break at multiply."
+
+ # Test other getters and setters.
+ gdb_scm_test_silent_cmd "guile (define blist (breakpoints))" \
+ "get breakpoint list 3"
+ gdb_test "guile (print (breakpoint-thread mult-bkpt))" \
+ "= #f" "check breakpoint thread"
+ gdb_test "guile (print (= (breakpoint-type mult-bkpt) BP_BREAKPOINT))" \
+ "= #t" "check breakpoint type"
+ gdb_test "guile (print (map breakpoint-number blist))" \
+ "= \\(1 2 3\\)" "check breakpoint numbers"
+ }
+}
+
+proc test_bkpt_deletion { } {
+ global srcfile testfile hex decimal
+
+ with_test_prefix test_bkpt_deletion {
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ # Test breakpoints are deleted correctly.
+ set deltst_location [gdb_get_line_number "Break at multiply."]
+ set end_location [gdb_get_line_number "Break at end."]
+ gdb_scm_test_silent_cmd "guile (define dp1 (create-breakpoint! \"$deltst_location\"))" \
+ "create deltst breakpoint"
+ gdb_breakpoint [gdb_get_line_number "Break at end."]
+ gdb_scm_test_silent_cmd "guile (define del-list (breakpoints))" \
+ "get breakpoint list 4"
+ gdb_test "guile (print (length del-list))" \
+ "= 3" "number of breakpoints before delete"
+ gdb_continue_to_breakpoint "Break at multiply." \
+ ".*/$srcfile:$deltst_location.*"
+ gdb_scm_test_silent_cmd "guile (breakpoint-delete! dp1)" \
+ "delete breakpoint"
+ gdb_test "guile (print (breakpoint-number dp1))" \
+ "ERROR: .*: Invalid object: <gdb:breakpoint> in position 1: #<gdb:breakpoint #2>.*" \
+ "check breakpoint invalidated"
+ gdb_scm_test_silent_cmd "guile (set! del-list (breakpoints))" \
+ "get breakpoint list 5"
+ gdb_test "guile (print (length del-list))" \
+ "= 2" "number of breakpoints after delete"
+ gdb_continue_to_breakpoint "Break at end." ".*/$srcfile:$end_location.*"
+ }
+}
+
+proc test_bkpt_cond_and_cmds { } {
+ global srcfile testfile hex decimal
+
+ with_test_prefix test_bkpt_cond_and_cmds {
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ # Test conditional setting.
+ set bp_location1 [gdb_get_line_number "Break at multiply."]
+ gdb_scm_test_silent_cmd "guile (define bp1 (create-breakpoint! \"$bp_location1\"))" \
+ "create multiply breakpoint"
+ gdb_continue_to_breakpoint "Break at multiply."
+ gdb_scm_test_silent_cmd "guile (set-breakpoint-condition! bp1 \"i == 5\")" \
+ "set condition"
+ gdb_test "guile (print (breakpoint-condition bp1))" \
+ "= i == 5" "test condition has been set"
+ gdb_continue_to_breakpoint "Break at multiply."
+ gdb_test "print i" \
+ "5" "test conditional breakpoint stopped after five iterations"
+ gdb_scm_test_silent_cmd "guile (set-breakpoint-condition! bp1 #f)" \
+ "clear condition"
+ gdb_test "guile (print (breakpoint-condition bp1))" \
+ "= #f" "test condition has been removed"
+ gdb_continue_to_breakpoint "Break at multiply."
+ gdb_test "print i" "6" "test breakpoint stopped after six iterations"
+
+ # Test commands.
+ gdb_breakpoint [gdb_get_line_number "Break at add."]
+ set test {commands $bpnum}
+ gdb_test_multiple $test $test { -re "\r\n>$" { pass $test } }
+ set test {print "Command for breakpoint has been executed."}
+ gdb_test_multiple $test $test { -re "\r\n>$" { pass $test } }
+ set test {print result}
+ gdb_test_multiple $test $test { -re "\r\n>$" { pass $test } }
+ gdb_test "end"
+
+ gdb_scm_test_silent_cmd "guile (define blist (breakpoints))" \
+ "get breakpoint list 6"
+ gdb_test "guile (print (breakpoint-commands (list-ref blist (- (length blist) 1))))" \
+ "print \"Command for breakpoint has been executed.\".*print result"
+ }
+}
+
+proc test_bkpt_invisible { } {
+ global srcfile testfile hex decimal
+
+ with_test_prefix test_bkpt_invisible {
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ # Test invisible breakpoints.
+ delete_breakpoints
+ set ibp_location [gdb_get_line_number "Break at multiply."]
+ gdb_scm_test_silent_cmd "guile (define vbp (create-breakpoint! \"$ibp_location\" #:internal #f))" \
+ "create visible breakpoint"
+ gdb_scm_test_silent_cmd "guile (define vbp (car (breakpoints)))" \
+ "get visible breakpoint"
+ gdb_test "guile (print vbp)" \
+ "= #<gdb:breakpoint #2 BP_BREAKPOINT enabled noisy hit:0 ignore:0 @.*scm-breakpoint.c:$ibp_location>" \
+ "check visible bp obj exists"
+ gdb_test "guile (print (breakpoint-location vbp))" \
+ "scm-breakpoint\.c:$ibp_location*" "check visible breakpoint location"
+ gdb_test "guile (print (breakpoint-visible? vbp))" \
+ "= #t" "check breakpoint visibility"
+ gdb_test "info breakpoints" \
+ "scm-breakpoint\.c:$ibp_location.*" \
+ "check info breakpoints shows visible breakpoints"
+ delete_breakpoints
+ gdb_scm_test_silent_cmd "guile (define ibp (create-breakpoint! \"$ibp_location\" #:internal #t))" \
+ "create invisible breakpoint"
+ gdb_test "guile (print ibp)" \
+ "= #<gdb:breakpoint #-$decimal BP_BREAKPOINT enabled noisy hit:0 ignore:0 @.*scm-breakpoint.c:$ibp_location>" \
+ "check invisible bp obj exists"
+ gdb_test "guile (print (breakpoint-location ibp))" \
+ "scm-breakpoint\.c:$ibp_location*" "check invisible breakpoint location"
+ gdb_test "guile (print (breakpoint-visible? ibp))" \
+ "= #f" "check breakpoint invisibility"
+ gdb_test "info breakpoints" \
+ "No breakpoints or watchpoints.*" \
+ "check info breakpoints does not show invisible breakpoints"
+ gdb_test "maint info breakpoints" \
+ "scm-breakpoint\.c:$ibp_location.*" \
+ "check maint info breakpoints shows invisible breakpoints"
+ }
+}
+
+proc test_watchpoints { } {
+ global srcfile testfile hex decimal
+
+ with_test_prefix test_watchpoints {
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ # Disable hardware watchpoints if necessary.
+ if [target_info exists gdb,no_hardware_watchpoints] {
+ gdb_test_no_output "set can-use-hw-watchpoints 0" ""
+ }
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ gdb_scm_test_silent_cmd "guile (define wp1 (create-breakpoint! \"result\" #:type BP_WATCHPOINT #:wp-class WP_WRITE))" \
+ "create watchpoint"
+ gdb_test "continue" \
+ ".*\[Ww\]atchpoint.*result.*Old value = 0.*New value = 25.*main.*" \
+ "test watchpoint write"
+ }
+}
+
+proc test_bkpt_internal { } {
+ global srcfile testfile hex decimal
+
+ with_test_prefix test_bkpt_internal {
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ # Disable hardware watchpoints if necessary.
+ if [target_info exists gdb,no_hardware_watchpoints] {
+ gdb_test_no_output "set can-use-hw-watchpoints 0" ""
+ }
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ delete_breakpoints
+
+ gdb_scm_test_silent_cmd "guile (define wp1 (create-breakpoint! \"result\" #:type BP_WATCHPOINT #:wp-class WP_WRITE #:internal #t))" \
+ "create invisible watchpoint"
+ gdb_test "info breakpoints" \
+ "No breakpoints or watchpoints.*" \
+ "check info breakpoints does not show invisible watchpoint"
+ gdb_test "maint info breakpoints" \
+ ".*watchpoint.*result.*" \
+ "check maint info breakpoints shows invisible watchpoint"
+ gdb_test "continue" \
+ ".*\[Ww\]atchpoint.*result.*Old value = 0.*New value = 25.*" \
+ "test invisible watchpoint write"
+ }
+}
+
+proc test_bkpt_eval_funcs { } {
+ global srcfile testfile hex decimal
+
+ with_test_prefix test_bkpt_eval_funcs {
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ # Disable hardware watchpoints if necessary.
+ if [target_info exists gdb,no_hardware_watchpoints] {
+ gdb_test_no_output "set can-use-hw-watchpoints 0" ""
+ }
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ delete_breakpoints
+
+ gdb_test_multiline "data collection breakpoint 1" \
+ "guile" "" \
+ "(define (make-bp-data) (cons 0 0))" "" \
+ "(define bp-data-count car)" "" \
+ "(define set-bp-data-count! set-car!)" "" \
+ "(define bp-data-inf-i cdr)" "" \
+ "(define set-bp-data-inf-i! set-cdr!)" "" \
+ "(define (bp-eval-count bkpt) (bp-data-count (gsmob-property bkpt 'bp-data)))" "" \
+ "(define (bp-eval-inf-i bkpt) (bp-data-inf-i (gsmob-property bkpt 'bp-data)))" "" \
+ "(define (make-bp-eval location)" "" \
+ " (let ((bp (create-breakpoint! location)))" "" \
+ " (set-gsmob-property! bp 'bp-data (make-bp-data))" "" \
+ " (set-breakpoint-stop! bp" "" \
+ " (lambda (bkpt)" "" \
+ " (let ((data (gsmob-property bkpt 'bp-data))" "" \
+ " (inf-i (parse-and-eval \"i\")))" "" \
+ " (set-bp-data-count! data (+ (bp-data-count data) 1))" "" \
+ " (set-bp-data-inf-i! data inf-i)" "" \
+ " (value=? inf-i 3))))" "" \
+ " bp))" "" \
+ "end" ""
+
+ gdb_test_multiline "data collection breakpoint 2" \
+ "guile" "" \
+ "(define (make-bp-also-eval location)" "" \
+ " (let ((bp (create-breakpoint! location)))" "" \
+ " (set-gsmob-property! bp 'bp-data (make-bp-data))" "" \
+ " (set-breakpoint-stop! bp" "" \
+ " (lambda (bkpt)" "" \
+ " (let* ((data (gsmob-property bkpt 'bp-data))" "" \
+ " (count (+ (bp-data-count data) 1)))" "" \
+ " (set-bp-data-count! data count)" "" \
+ " (= count 9))))" "" \
+ " bp))" "" \
+ "end" ""
+
+ gdb_test_multiline "data collection breakpoint 3" \
+ "guile" "" \
+ "(define (make-bp-basic location)" "" \
+ " (let ((bp (create-breakpoint! location)))" "" \
+ " (set-gsmob-property! bp 'bp-data (make-bp-data))" "" \
+ " bp))" "" \
+ "end" ""
+
+ set bp_location2 [gdb_get_line_number "Break at multiply."]
+ set end_location [gdb_get_line_number "Break at end."]
+ gdb_scm_test_silent_cmd "guile (define eval-bp1 (make-bp-eval \"$bp_location2\"))" \
+ "create eval-bp1 breakpoint"
+ gdb_scm_test_silent_cmd "guile (define also-eval-bp1 (make-bp-also-eval \"$bp_location2\"))" \
+ "create also-eval-bp1 breakpoint"
+ gdb_scm_test_silent_cmd "guile (define never-eval-bp1 (make-bp-also-eval \"$end_location\"))" \
+ "create never-eval-bp1 breakpoint"
+ gdb_continue_to_breakpoint "Break at multiply." ".*/$srcfile:$bp_location2.*"
+ gdb_test "print i" "3" "check inferior value matches guile accounting"
+ gdb_test "guile (print (bp-eval-inf-i eval-bp1))" \
+ "= 3" "check guile accounting matches inferior"
+ gdb_test "guile (print (bp-eval-count also-eval-bp1))" \
+ "= 4" \
+ "check non firing same-location breakpoint eval function was also called at each stop 1"
+ gdb_test "guile (print (bp-eval-count eval-bp1))" \
+ "= 4" \
+ "check non firing same-location breakpoint eval function was also called at each stop 2"
+
+ # Check we cannot assign a condition to a breakpoint with a stop-func,
+ # and cannot assign a stop-func to a breakpoint with a condition.
+
+ delete_breakpoints
+ set cond_bp [gdb_get_line_number "Break at multiply."]
+ gdb_scm_test_silent_cmd "guile (define eval-bp1 (make-bp-eval \"$cond_bp\"))" \
+ "create eval-bp1 breakpoint 2"
+ set test_cond {cond $bpnum}
+ gdb_test "$test_cond \"foo==3\"" \
+ "Only one stop condition allowed.*"
+ gdb_scm_test_silent_cmd "guile (define eval-bp2 (make-bp-basic \"$cond_bp\"))" \
+ "create basic breakpoint"
+ gdb_scm_test_silent_cmd "guile (set-breakpoint-condition! eval-bp2 \"1==1\")" \
+ "set a condition"
+ gdb_test_multiline "construct an eval function" \
+ "guile" "" \
+ "(define (stop-func bkpt)" "" \
+ " return #t)" "" \
+ "end" ""
+ gdb_test "guile (set-breakpoint-stop! eval-bp2 stop-func)" \
+ "Only one stop condition allowed.*"
+
+ # Check that stop-func is run when location has normal bp.
+
+ delete_breakpoints
+ gdb_breakpoint [gdb_get_line_number "Break at multiply."]
+ gdb_scm_test_silent_cmd "guile (define check-eval (make-bp-eval \"$bp_location2\"))" \
+ "create check-eval breakpoint"
+ gdb_test "guile (print (bp-eval-count check-eval))" \
+ "= 0" \
+ "test that evaluate function has not been yet executed (ie count = 0)"
+ gdb_continue_to_breakpoint "Break at multiply." ".*/$srcfile:$bp_location2.*"
+ gdb_test "guile (print (bp-eval-count check-eval))" \
+ "= 1" \
+ "test that evaluate function is run when location also has normal bp"
+
+ # Test watchpoints with stop-func.
+
+ gdb_test_multiline "watchpoint stop func" \
+ "guile" "" \
+ "(define (make-wp-eval location)" "" \
+ " (let ((wp (create-breakpoint! location #:type BP_WATCHPOINT #:wp-class WP_WRITE)))" "" \
+ " (set-breakpoint-stop! wp" "" \
+ " (lambda (bkpt)" "" \
+ " (let ((result (parse-and-eval \"result\")))" "" \
+ " (value=? result 788))))" "" \
+ " wp))" "" \
+ "end" ""
+
+ delete_breakpoints
+ gdb_scm_test_silent_cmd "guile (define wp1 (make-wp-eval \"result\"))" \
+ "create watchpoint"
+ gdb_test "continue" ".*\[Ww\]atchpoint.*result.*Old value =.*New value = 788.*" \
+ "test watchpoint write"
+
+ # Misc final tests.
+
+ gdb_test "guile (print (bp-eval-count never-eval-bp1))" \
+ "= 0" \
+ "check that this unrelated breakpoints eval function was never called"
+ }
+}
+
+test_bkpt_basic
+test_bkpt_deletion
+test_bkpt_cond_and_cmds
+test_bkpt_invisible
+test_watchpoints
+test_bkpt_internal
+test_bkpt_eval_funcs
diff --git a/gdb/testsuite/gdb.guile/scm-disasm.c b/gdb/testsuite/gdb.guile/scm-disasm.c
new file mode 100644
index 0000000..6c0ef92
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-disasm.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2014 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-disasm.exp b/gdb/testsuite/gdb.guile/scm-disasm.exp
new file mode 100644
index 0000000..5a1dae3
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-disasm.exp
@@ -0,0 +1,133 @@
+# Copyright 2014 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/>.
+
+load_lib gdb-guile.exp
+
+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
+}
+
+# Disassemble one instruction at pc and verify the result.
+
+proc test_disassemble_1 { name address extra_args } {
+ with_test_prefix $name {
+ gdb_scm_test_silent_cmd "guile (define insn-list (arch-disassemble arch $address $extra_args #:size 1 #:count 1))" \
+ "disassemble"
+
+ gdb_test "guile (print (length insn-list))" \
+ "= 1" "test number of instructions"
+ gdb_scm_test_silent_cmd "guile (define insn (car insn-list))" \
+ "get instruction"
+
+ # Verify all the fields are present.
+ gdb_test "guile (print (->bool (assq-ref insn 'address)))" \
+ "= #t" "test key address"
+ gdb_test "guile (print (->bool (assq-ref insn 'asm)))" \
+ "= #t" "test key asm"
+ gdb_test "guile (print (->bool (assq-ref insn 'length)))" \
+ "= #t" "test key length"
+
+ # Verify the correct address is used.
+ gdb_test "guile (print (= $address (assq-ref insn 'address)))" \
+ "= #t" "verify correct address"
+ }
+}
+
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" "get frame"
+gdb_scm_test_silent_cmd "guile (define arch (frame-arch frame))" "get arch"
+gdb_scm_test_silent_cmd "guile (define pc (frame-pc frame))" "get pc"
+
+gdb_test "guile (print (arch-disassemble arch pc #:size 0))" \
+ "= \\(\\)" "disassemble, zero size"
+gdb_test "guile (print (arch-disassemble arch pc #:count 0))" \
+ "= \\(\\)" "disassemble, zero count"
+
+gdb_scm_test_silent_cmd "guile (define insn-list1 (arch-disassemble arch pc #:size 1 #:count 1))" \
+ "disassemble"
+gdb_scm_test_silent_cmd "guile (define insn-list2 (arch-disassemble arch pc #:size 1))" \
+ "disassemble, no count"
+gdb_scm_test_silent_cmd "guile (define insn-list3 (arch-disassemble arch pc #:count 1))" \
+ "disassemble, no end"
+gdb_scm_test_silent_cmd "guile (define insn-list4 (arch-disassemble arch pc))" \
+ "disassemble, no end no count"
+
+gdb_test "guile (print (length insn-list1))" \
+ "= 1" "test number of instructions 1"
+gdb_test "guile (print (length insn-list2))" \
+ "= 1" "test number of instructions 2"
+gdb_test "guile (print (length insn-list3))" \
+ "= 1" "test number of instructions 3"
+gdb_test "guile (print (length insn-list4))" \
+ "= 1" "test number of instructions 4"
+
+test_disassemble_1 "basic" "pc" ""
+
+# Negative test
+gdb_test "guile (arch-disassemble arch 0 #:size 1)" \
+ "ERROR: Cannot access memory at address 0x.*" "test bad memory access"
+
+# Test disassembly through a port.
+
+gdb_scm_test_silent_cmd "guile (define mem (open-memory))" \
+ "open memory port"
+
+test_disassemble_1 "memory-port" "pc" "#:port mem"
+
+gdb_scm_test_silent_cmd "guile (define insn-list-mem (arch-disassemble arch pc #:port mem #:size 1 #:count 1))" \
+ "disassemble via memory port"
+
+# Test memory error reading from port.
+
+gdb_scm_test_silent_cmd "guile (define mem1 (open-memory #:start pc #:size 4))" \
+ "open restricted range memory port"
+
+# The x86 disassembler tries to be clever and will print "byte 0x42" if
+# there is insufficient memory for the entire instruction.
+# So we pass "#:count 5" to ensure the disassembler tries to read beyond
+# the end of the memory range.
+gdb_test "guile (arch-disassemble arch pc #:port mem1 #:count 5 #:offset pc)" \
+ "ERROR: Cannot access memory at address 0x.*" \
+ "test bad memory access from port"
+
+# Test disassembly of a bytevector.
+
+gdb_scm_test_silent_cmd "guile (use-modules (rnrs io ports))" \
+ "import (rnrs io ports)"
+
+# First fetch the length of the instruction at $pc.
+gdb_scm_test_silent_cmd "guile (define insn-list-for-bv (arch-disassemble arch pc))" \
+ "get insn for bytevector"
+gdb_test_no_output "guile (define insn-length (assq-ref (car insn-list-for-bv) 'length))" \
+ "get insn length for bytevector"
+
+# Read the insn into a bytevector.
+gdb_test_no_output "guile (define insn-bv (get-bytevector-n (open-memory #:start pc #:size insn-length) insn-length))" \
+ "read insn into bytevector"
+
+# Disassemble the bytevector.
+gdb_scm_test_silent_cmd "guile (define insn-list-from-bv (arch-disassemble arch pc #:port (open-bytevector-input-port insn-bv) #:offset pc))" \
+ "disassemble bytevector"
+
+gdb_test "guile (print (equal? insn-list-for-bv insn-list-from-bv))" \
+ "= #t" "verify bytevector disassembly"
diff --git a/gdb/testsuite/gdb.guile/scm-equal.c b/gdb/testsuite/gdb.guile/scm-equal.c
new file mode 100644
index 0000000..108c9be
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-equal.c
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2014 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 x;
+
+int
+main (void)
+{
+ return x;
+}
diff --git a/gdb/testsuite/gdb.guile/scm-equal.exp b/gdb/testsuite/gdb.guile/scm-equal.exp
new file mode 100644
index 0000000..ae23aa8
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-equal.exp
@@ -0,0 +1,55 @@
+# Copyright 2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests equal? for the various gsmobs.
+
+load_lib gdb-guile.exp
+
+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_scm_test_silent_cmd "guile (define frame (selected-frame))" "get frame"
+gdb_scm_test_silent_cmd "guile (define arch (frame-arch frame))" "get arch"
+
+gdb_test "guile (print (equal? (selected-frame) (newest-frame)))" \
+ "= #t" "equal? frame"
+gdb_test "guile (print (equal? (selected-frame) (frame-older (newest-frame))))" \
+ "= #f" "not equal? frame"
+
+gdb_test "guile (print (equal? (make-value 1) (make-value 1)))" \
+ "= #t" "equal? value"
+gdb_test "guile (print (equal? (make-value 1) (make-value 2)))" \
+ "= #f" "not equal? value"
+
+gdb_test "guile (print (equal? (value-type (make-value 1)) (value-type (make-value 2))))" \
+ "= #t" "equal? type"
+gdb_test "guile (print (equal? (value-type (make-value 1)) (value-type (make-value 2.5))))" \
+ "= #f" "not equal? type"
+
+gdb_test "guile (print (equal? (lookup-global-symbol \"main\") (lookup-global-symbol \"main\")))" \
+ "= #t" "equal? symbol"
+gdb_test "guile (print (equal? (lookup-global-symbol \"main\") (lookup-global-symbol \"x\")))" \
+ "= #f" "not equal? symbol"
diff --git a/gdb/testsuite/gdb.guile/scm-error-1.scm b/gdb/testsuite/gdb.guile/scm-error-1.scm
new file mode 100644
index 0000000..a68f491
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-error-1.scm
@@ -0,0 +1,19 @@
+;; Copyright (C) 2014 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/>.
+
+(use-modules (gdb))
+
+;; An intentional error to test error handling when loading a file.
+(define foo (+ 42 #f))
diff --git a/gdb/testsuite/gdb.guile/scm-error-2.scm b/gdb/testsuite/gdb.guile/scm-error-2.scm
new file mode 100644
index 0000000..87a7ee5
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-error-2.scm
@@ -0,0 +1,30 @@
+;; Copyright (C) 2014 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/>.
+
+(use-modules (gdb))
+
+;; Create a set of functions to call, with the last one having an error,
+;; so we can test backtrace printing.
+
+(define foo #f)
+
+(define (top-func x)
+ (+ (middle-func x) 1))
+
+(define (middle-func x)
+ (+ (bottom-func x) 1))
+
+(define (bottom-func x)
+ (+ x foo))
diff --git a/gdb/testsuite/gdb.guile/scm-error.exp b/gdb/testsuite/gdb.guile/scm-error.exp
new file mode 100644
index 0000000..b5a1028
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-error.exp
@@ -0,0 +1,117 @@
+# Copyright (C) 2010-2014 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/>.
+
+# Test various error conditions.
+
+set testfile "scm-error"
+
+load_lib gdb-guile.exp
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+# Test error while loading .scm.
+
+# Give the files a new name so we don't clobber the real one if
+# objfile == srcdir.
+set remote_guile_file_1 [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}-1.scm \
+ ${subdir}/t-${testfile}-1.scm]
+set remote_guile_file_2 [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}-2.scm \
+ ${subdir}/t-${testfile}-2.scm]
+
+gdb_test "source $remote_guile_file_1" \
+ "(ERROR: )?In procedure \[+\]: Wrong type: #f.*" \
+ "error loading scm file caught"
+
+gdb_test "p 1" " = 1" "no delayed error"
+
+# Test setting/showing the various states for "guile print-stack".
+
+gdb_test "show guile print-stack" \
+ "The mode of Guile exception printing on error is \"message\".*" \
+ "test print-stack show setting of default"
+gdb_test_no_output "set guile print-stack full" \
+ "test print-stack full setting"
+gdb_test "show guile print-stack" \
+ "The mode of Guile exception printing on error is \"full\".*" \
+ "test print-stack show setting to full"
+gdb_test_no_output "set guile print-stack none" \
+ "test print-stack none setting"
+gdb_test "show guile print-stack" \
+ "The mode of Guile exception printing on error is \"none\".*" \
+ "test print-stack show setting to none"
+# Reset back to default, just in case.
+gdb_test_no_output "set guile print-stack message" \
+ "reset print-stack to default, post set/show tests"
+
+# Test "set guile print-stack none".
+
+gdb_test_no_output "set guile print-stack none" \
+ "set print-stack to none, for error test"
+
+set test_name "no error printed"
+set command "guile (define x doesnt-exist)"
+gdb_test_multiple $command $test_name {
+ -re "Backtrace.*$gdb_prompt $" { fail $test_name }
+ -re "ERROR.*$gdb_prompt $" { fail $test_name }
+ -re "$gdb_prompt $" { pass $test_name }
+}
+
+# Test "set guile print-stack message".
+
+gdb_test_no_output "set guile print-stack message" \
+ "set print-stack to message, for error test"
+
+set test_name "error message printed"
+set command "guile (define x doesnt-exist)"
+gdb_test_multiple $command $test_name {
+ -re "Backtrace.*$gdb_prompt $" { fail $test_name }
+ -re "ERROR.*$gdb_prompt $" { pass $test_name }
+}
+
+# Test "set guile print-stack full".
+
+gdb_scm_test_silent_cmd "source $remote_guile_file_2" ""
+
+gdb_test_no_output "set guile print-stack full" \
+ "set print-stack to full, for backtrace test"
+
+gdb_test "guile (define x (top-func 42))" \
+ "Guile Backtrace:.*top-func 42.*middle-func 42.*bottom-func 42.*" \
+ "backtrace printed"
+
+# Verify gdb-specific errors are printed properly.
+# i.e., each gdb error is registered to use init.scm:%error-printer.
+
+gdb_test_no_output "set guile print-stack message" \
+ "set print-stack to message, for error printing tests"
+
+gdb_test "guile (throw 'gdb:error \"subr\" \"misc error: ~a\" (list 42))" \
+ "ERROR: In procedure subr: misc error: 42.*"
+
+gdb_test "guile (throw 'gdb:invalid-object-error \"subr\" \"invalid object error: ~a\" (list 42))" \
+ "ERROR: In procedure subr: invalid object error: 42.*"
+
+gdb_test "guile (throw 'gdb:memory-error \"subr\" \"memory error: ~a\" (list 42))" \
+ "ERROR: In procedure subr: memory error: 42.*"
+
+gdb_test "guile (throw 'gdb:pp-type-error \"subr\" \"pp-type error: ~a\" (list 42))" \
+ "ERROR: In procedure subr: pp-type error: 42.*"
diff --git a/gdb/testsuite/gdb.guile/scm-frame-args.c b/gdb/testsuite/gdb.guile/scm-frame-args.c
new file mode 100644
index 0000000..c20b1e1
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-frame-args.c
@@ -0,0 +1,60 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2014 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/>. */
+
+#include <string.h>
+
+struct s
+{
+ int m;
+};
+
+struct ss
+{
+ struct s a;
+ struct s b;
+};
+
+void
+init_s (struct s *s, int m)
+{
+ s->m = m;
+}
+
+void
+init_ss (struct ss *s, int a, int b)
+{
+ init_s (&s->a, a);
+ init_s (&s->b, b);
+}
+
+void
+foo (int x, struct ss ss)
+{
+ return; /* break-here */
+}
+
+int
+main ()
+{
+ struct ss ss;
+
+ init_ss (&ss, 1, 2);
+
+ foo (42, ss);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.guile/scm-frame-args.exp b/gdb/testsuite/gdb.guile/scm-frame-args.exp
new file mode 100644
index 0000000..22ce6fe
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-frame-args.exp
@@ -0,0 +1,76 @@
+# Copyright (C) 2014 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/>.
+
+load_lib gdb-guile.exp
+
+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
+}
+
+# Give the file a new name so we don't clobber the real one if
+# objfile == srcdir.
+set remote_guile_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.scm \
+ ${subdir}/t-${testfile}.scm]
+
+gdb_scm_load_file "$remote_guile_file" "load script"
+
+gdb_breakpoint [gdb_get_line_number "break-here"]
+gdb_continue_to_breakpoint "break-here" ".* break-here .*"
+
+# Test all combinations with raw off.
+
+gdb_test_no_output "set print raw frame-arguments off"
+
+gdb_test_no_output "set print frame-arguments none"
+gdb_test "frame" ".*foo \\(x=\[.\]{3}, ss=\[.\]{3}\\).*" \
+ "frame pretty,none"
+
+#gdb_test_no_output "set guile print-stack full"
+
+gdb_test_no_output "set print frame-arguments scalars"
+gdb_test "frame" ".*foo \\(x=42, ss=super struct = {\[.\]{3}}\\).*" \
+ "frame pretty,scalars"
+
+gdb_test_no_output "set print frame-arguments all"
+gdb_test "frame" \
+ ".*foo \\(x=42, ss=super struct = {a = m=<1>, b = m=<2>}\\).*" \
+ "frame pretty,all"
+
+# Test all combinations with raw on.
+
+gdb_test_no_output "set print raw frame-arguments on"
+
+gdb_test_no_output "set print frame-arguments none"
+gdb_test "frame" ".*foo \\(x=\[.\]{3}, ss=\[.\]{3}\\).*" \
+ "frame raw,none"
+
+gdb_test_no_output "set print frame-arguments scalars"
+gdb_test "frame" ".*foo \\(x=42, ss=\[.\]{3}\\).*" \
+ "frame raw,scalars"
+
+gdb_test_no_output "set print frame-arguments all"
+gdb_test "frame" \
+ ".*foo \\(x=42, ss={a = {m = 1}, b = {m = 2}}\\).*" \
+ "frame raw,all"
diff --git a/gdb/testsuite/gdb.guile/scm-frame-args.scm b/gdb/testsuite/gdb.guile/scm-frame-args.scm
new file mode 100644
index 0000000..20d42f8
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-frame-args.scm
@@ -0,0 +1,69 @@
+;; Copyright (C) 2014 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/>.
+
+(use-modules (gdb) (gdb printing))
+
+(define (make-pp_s-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (let ((m (value-field val "m")))
+ (format #f "m=<~A>" m)))
+ #f))
+
+(define (make-pp_ss-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer) "super struct")
+ (lambda (printer)
+ (make-iterator val
+ (make-field-iterator (value-type val))
+ (lambda (iter)
+ (let ((field (iterator-next!
+ (iterator-progress iter))))
+ (if (end-of-iteration? field)
+ field
+ (let ((name (field-name field)))
+ (cons name (value-field val name))))))))))
+
+(define (get-type-for-printing val)
+ "Return type of val, stripping away typedefs, etc."
+ (let ((type (value-type val)))
+ (if (= (type-code type) TYPE_CODE_REF)
+ (set! type (type-target type)))
+ (type-strip-typedefs (type-unqualified type))))
+
+(define (make-pretty-printer-dict)
+ (let ((dict (make-hash-table)))
+ (hash-set! dict "struct s" make-pp_s-printer)
+ (hash-set! dict "s" make-pp_s-printer)
+ (hash-set! dict "struct ss" make-pp_ss-printer)
+ (hash-set! dict "ss" make-pp_ss-printer)
+ dict))
+
+(define *pretty-printer*
+ (make-pretty-printer
+ "pretty-printer-test"
+ (let ((pretty-printers-dict (make-pretty-printer-dict)))
+ (lambda (matcher val)
+ "Look-up and return a pretty-printer that can print val."
+ (let ((type (get-type-for-printing val)))
+ (let ((typename (type-tag type)))
+ (if typename
+ (let ((printer-maker (hash-ref pretty-printers-dict typename)))
+ (and printer-maker (printer-maker val)))
+ #f)))))))
+
+(append-pretty-printer! #f *pretty-printer*)
diff --git a/gdb/testsuite/gdb.guile/scm-frame-inline.c b/gdb/testsuite/gdb.guile/scm-frame-inline.c
new file mode 100644
index 0000000..a3669bc
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-frame-inline.c
@@ -0,0 +1,43 @@
+/* This test is part of GDB, the GNU debugger.
+
+ Copyright 2011-2014 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/>. */
+
+volatile int v = 42;
+
+__attribute__((__always_inline__)) static inline int
+f (void)
+{
+ /* Provide first stub line so that GDB understand the PC is already inside
+ the inlined function and does not expect a step into it. */
+ v++;
+ v++; /* break-here */
+
+ return v;
+}
+
+__attribute__((__noinline__)) static int
+g (void)
+{
+ volatile int l = v;
+
+ return f ();
+}
+
+int
+main (void)
+{
+ return g ();
+}
diff --git a/gdb/testsuite/gdb.guile/scm-frame-inline.exp b/gdb/testsuite/gdb.guile/scm-frame-inline.exp
new file mode 100644
index 0000000..ed1c3b8
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-frame-inline.exp
@@ -0,0 +1,43 @@
+# Copyright (C) 2011-2014 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/>.
+
+load_lib gdb-guile.exp
+
+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 ![runto main] {
+ fail "Can't run to main"
+ return
+}
+
+gdb_install_guile_utils
+gdb_install_guile_module
+
+gdb_breakpoint [gdb_get_line_number "break-here"]
+gdb_continue_to_breakpoint "break-here"
+
+gdb_test "info frame" "inlined into frame 1\r\n.*"
+
+gdb_test "up" "#1 g .*"
+
+gdb_test "guile (print (frame-read-var (selected-frame) \"l\"))" \
+ "= 42"
diff --git a/gdb/testsuite/gdb.guile/scm-frame.c b/gdb/testsuite/gdb.guile/scm-frame.c
new file mode 100644
index 0000000..82db341
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-frame.c
@@ -0,0 +1,30 @@
+int f2 (int a)
+{
+ return ++a;
+}
+
+int f1 (int a, int b)
+{
+ return f2(a) + b;
+}
+
+int block (void)
+{
+ int i = 99;
+ {
+ double i = 1.1;
+ double f = 2.2;
+ {
+ const char *i = "stuff";
+ const char *f = "foo";
+ const char *b = "bar";
+ return 0; /* Block break here. */
+ }
+ }
+}
+
+int main (int argc, char *argv[])
+{
+ block ();
+ return f1 (1, 2);
+}
diff --git a/gdb/testsuite/gdb.guile/scm-frame.exp b/gdb/testsuite/gdb.guile/scm-frame.exp
new file mode 100644
index 0000000..04c8cda
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-frame.exp
@@ -0,0 +1,122 @@
+# Copyright (C) 2009-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the frame support in Guile.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+# The following tests require execution.
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_breakpoint [gdb_get_line_number "Block break here."]
+gdb_continue_to_breakpoint "Block break here."
+gdb_scm_test_silent_cmd "guile (define bf1 (selected-frame))" \
+ "get frame"
+
+# Test frame-architecture method.
+gdb_scm_test_silent_cmd "guile (define show-arch-str (execute \"show architecture\" #:to-string #t))" \
+ "show arch"
+gdb_test "guile (print (->bool (string-contains show-arch-str (arch-name (frame-arch bf1)))))" \
+ "#t" "test frame-arch"
+
+# First test that read-var is unaffected by PR 11036 changes.
+gdb_test "guile (print (frame-read-var bf1 \"i\"))" \
+ "\"stuff\"" "test i"
+gdb_test "guile (print (frame-read-var bf1 \"f\"))" \
+ "\"foo\"" "test f"
+gdb_test "guile (print (frame-read-var bf1 \"b\"))" \
+ "\"bar\"" "test b"
+
+# Test the read-var function in another block other than the current
+# block (in this case, the super block). Test thar read-var is reading
+# the correct variables of i and f but they are the correct value and type.
+gdb_scm_test_silent_cmd "guile (define sb (block-superblock (frame-block bf1)))" \
+ "get superblock"
+gdb_test "guile (print (frame-read-var bf1 \"i\" #:block sb))" "1.1.*" \
+ "test i = 1.1"
+gdb_test "guile (print (value-type (frame-read-var bf1 \"i\" #:block sb)))" \
+ "double" "test double i"
+gdb_test "guile (print (frame-read-var bf1 \"f\" #:block sb))" \
+ "2.2.*" "test f = 2.2"
+gdb_test "guile (print (value-type (frame-read-var bf1 \"f\" #:block sb)))" \
+ "double" "test double f"
+
+# And again test another outerblock, this time testing "i" is the
+# correct value and type.
+gdb_scm_test_silent_cmd "guile (set! sb (block-superblock sb))" \
+ "get superblock #2"
+gdb_test "guile (print (frame-read-var bf1 \"i\" #:block sb))" \
+ "99" "test i = 99"
+gdb_test "guile (print (value-type (frame-read-var bf1 \"i\" #:block sb)))" \
+ "int" "test int i"
+
+gdb_breakpoint "f2"
+gdb_continue_to_breakpoint "breakpoint at f2"
+gdb_scm_test_silent_cmd "guile (define bframe (selected-frame))" \
+ "get bottom-most frame"
+gdb_test "up" ".*" ""
+
+gdb_scm_test_silent_cmd "guile (define f1 (selected-frame))" \
+"get second frame"
+gdb_scm_test_silent_cmd "guile (define f0 (frame-newer f1))" \
+ "get first frame"
+
+gdb_test "guile (print (eq? f1 (newest-frame)))" \
+ #f "selected frame -vs- newest frame"
+gdb_test "guile (print (eq? bframe (newest-frame)))" \
+ #t "newest frame -vs- newest frame"
+
+gdb_test "guile (print (eq? f0 f1))" \
+ "#f" "test equality comparison (false)"
+gdb_test "guile (print (eq? f0 f0))" \
+ "#t" "test equality comparison (true)"
+gdb_test "guile (print (frame-valid? f0))" \
+ "#t" "test frame-valid?"
+gdb_test "guile (print (frame-name f0))" \
+ "f2" "test frame-name"
+gdb_test "guile (print (= (frame-type f0) NORMAL_FRAME))" \
+ "#t" "test frame-type"
+gdb_test "guile (print (= (frame-unwind-stop-reason f0) FRAME_UNWIND_NO_REASON))" \
+ "#t" "test frame-unwind-stop-reason"
+gdb_test "guile (print (unwind-stop-reason-string FRAME_UNWIND_INNER_ID))" \
+ "previous frame inner to this frame \\(corrupt stack\\?\\)" \
+ "test unwind-stop-reason-string"
+gdb_test "guile (print (format #f \"= ~A\" (frame-pc f0)))" \
+ "= \[0-9\]+" "test frame-pc"
+gdb_test "guile (print (format #f \"= ~A\" (eq? (frame-older f0) f1)))" \
+ "= #t" "test frame-older"
+gdb_test "guile (print (format #f \"= ~A\" (eq? (frame-newer f1) f0)))" \
+ "= #t" "test frame-newer"
+gdb_test "guile (print (frame-read-var f0 \"variable_which_surely_doesnt_exist\"))" \
+ "ERROR: .*: Out of range: variable not found: \"variable_which_surely_doesnt_exist\".*" \
+ "test frame-read-var - error"
+gdb_test "guile (print (format #f \"= ~A\" (frame-read-var f0 \"a\")))" \
+ "= 1" "test frame-read-var - success"
+
+gdb_test "guile (print (format #f \"= ~A\" (eq? (selected-frame) f1)))" \
+ "= #t" "test selected-frame"
diff --git a/gdb/testsuite/gdb.guile/scm-generics.exp b/gdb/testsuite/gdb.guile/scm-generics.exp
new file mode 100644
index 0000000..664affc
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-generics.exp
@@ -0,0 +1,42 @@
+# Copyright (C) 2010-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests using GDB smobs with generics.
+
+load_lib gdb-guile.exp
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_install_guile_utils
+gdb_install_guile_module
+
+gdb_test_no_output "guile (use-modules ((oop goops)))"
+
+gdb_test_no_output "guile (define-generic +)"
+gdb_test_no_output "guile (define-method (+ (x <gdb:value>) (y <gdb:value>)) (value-add x y))"
+
+gdb_test_no_output "guile (define x (make-value 42))"
+
+gdb_test_no_output "guile (define y (+ x x))"
+
+gdb_test "guile y" "#<gdb:value 84>"
diff --git a/gdb/testsuite/gdb.guile/scm-gsmob.exp b/gdb/testsuite/gdb.guile/scm-gsmob.exp
new file mode 100644
index 0000000..470afc4
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-gsmob.exp
@@ -0,0 +1,70 @@
+# Copyright (C) 2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests basic gsmob features.
+
+load_lib gdb-guile.exp
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_install_guile_utils
+gdb_install_guile_module
+
+# Test the transition from alist to htab in the property list.
+# N.B. This has the same value as gdb/guile/scm-gsmob.c.
+set SMOB_PROP_HTAB_THRESHOLD 7
+
+gdb_test_no_output "gu (define arch (current-arch))"
+
+# Return a property name for integer I suitable for sorting.
+
+proc prop_name { i } {
+ return [format "prop%02d" $i]
+}
+
+# Set and ref the properties in separate loops to verify previously set
+# properties are not lost when we set a new property or switch to htabs.
+for {set i 0} {$i <= $SMOB_PROP_HTAB_THRESHOLD} {incr i} {
+ gdb_test "gu (print (gsmob-has-property? arch '[prop_name $i]))" \
+ "= #f" "property prop$i not present before set"
+ gdb_test_no_output "gu (set-gsmob-property! arch '[prop_name $i] $i)" \
+ "set prop $i"
+ gdb_test "gu (print (gsmob-has-property? arch '[prop_name $i]))" \
+ "= #t" "property prop$i present after set"
+}
+for {set i 0} {$i <= $SMOB_PROP_HTAB_THRESHOLD} {incr i} {
+ gdb_test "gu (print (gsmob-has-property? arch '[prop_name $i]))" \
+ "= #t" "property prop$i present after all set"
+ gdb_test "gu (print (gsmob-property arch '[prop_name $i]))" \
+ "= $i" "ref prop $i"
+}
+
+# Verify gsmob-properties.
+set prop_list ""
+for {set i 0} {$i <= $SMOB_PROP_HTAB_THRESHOLD} {incr i} {
+ set prop_list "$prop_list [prop_name $i]"
+}
+set prop_list [lsort $prop_list]
+verbose -log "prop_list: $prop_list"
+gdb_test "gu (print (sort (gsmob-properties arch) (lambda (a b) (string<? (symbol->string a) (symbol->string b)))))" \
+ "= \\($prop_list\\)" "gsmob-properties"
diff --git a/gdb/testsuite/gdb.guile/scm-iterator.c b/gdb/testsuite/gdb.guile/scm-iterator.c
new file mode 100644
index 0000000..80e9178
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-iterator.c
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2014 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/>. */
+
+void
+foo (void)
+{
+}
+
+int
+main (void)
+{
+ foo ();
+ return 0; /* Break at end. */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-iterator.exp b/gdb/testsuite/gdb.guile/scm-iterator.exp
new file mode 100644
index 0000000..8ee67ed
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-iterator.exp
@@ -0,0 +1,62 @@
+# Copyright (C) 2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the iterator facility.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_breakpoint [gdb_get_line_number "Break at end."]
+gdb_continue_to_breakpoint "Break at end."
+
+gdb_scm_test_silent_cmd "guile (use-modules (gdb iterator))" \
+ "import (gdb iterator)"
+
+gdb_scm_test_silent_cmd "guile (define this-sal (find-pc-line (frame-pc (selected-frame))))" \
+ "get frame sal"
+
+gdb_scm_test_silent_cmd "guile (define this-symtab (sal-symtab this-sal))" \
+ "get frame symtab"
+
+gdb_scm_test_silent_cmd "guile (define this-global-block (symtab-global-block this-symtab))" \
+ "get frame global block"
+
+gdb_scm_test_silent_cmd "guile (define syms-iter (make-block-symbols-iterator this-global-block))" \
+ "get global block iterator"
+
+gdb_scm_test_silent_cmd "guile (define functions (iterator-filter symbol-function? syms-iter))" \
+ "get global functions"
+
+gdb_test "guile (print (sort (map symbol-name functions) string<?))" \
+ "= \\(foo main\\)" "test function list"
+
+gdb_scm_test_silent_cmd "guile (define syms-iter (make-block-symbols-iterator this-global-block))" \
+ "get global block iterator 2"
+
+gdb_test "guile (print (sort (map symbol-name (iterator->list syms-iter)) string<?))" \
+ "= \\(foo main\\)" "iterator->list"
diff --git a/gdb/testsuite/gdb.guile/scm-math.c b/gdb/testsuite/gdb.guile/scm-math.c
new file mode 100644
index 0000000..347fc22
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-math.c
@@ -0,0 +1,30 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2014 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/>. */
+
+enum e
+ {
+ ONE = 1,
+ TWO = 2
+ };
+
+enum e evalue = TWO;
+
+int
+main (int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.guile/scm-math.exp b/gdb/testsuite/gdb.guile/scm-math.exp
new file mode 100644
index 0000000..12caa71
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-math.exp
@@ -0,0 +1,309 @@
+# Copyright (C) 2008-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests <gdb:value> math operations.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+proc test_value_numeric_ops {} {
+ global gdb_prompt
+
+ gdb_scm_test_silent_cmd "gu (define i (make-value 5))" \
+ "create first integer value"
+ gdb_scm_test_silent_cmd "gu (define j (make-value 2))" \
+ "create second integer value"
+ gdb_test "gu (print (value-add i j))" \
+ "= 7" "add two integer values"
+ gdb_test "gu (raw-print (value-add i j))" \
+ "= #<gdb:value 7>" "verify type of integer add result"
+
+ gdb_scm_test_silent_cmd "gu (define f (make-value 1.25))" \
+ "create first double value"
+ gdb_scm_test_silent_cmd "gu (define g (make-value 2.5))" \
+ "create second double value"
+ gdb_test "gu (print (value-add f g))" \
+ "= 3.75" "add two double values"
+ gdb_test "gu (raw-print (value-add f g))" \
+ "= #<gdb:value 3.75>" "verify type of double add result"
+
+ gdb_test "gu (print (value-sub i j))" \
+ "= 3" "subtract two integer values"
+ gdb_test "gu (print (value-sub f g))" \
+ "= -1.25" "subtract two double values"
+
+ gdb_test "gu (print (value-mul i j))" \
+ "= 10" "multiply two integer values"
+ gdb_test "gu (print (value-mul f g))" \
+ "= 3.125" "multiply two double values"
+
+ gdb_test "gu (print (value-div i j))" \
+ "= 2" "divide two integer values"
+ gdb_test "gu (print (value-div f g))" \
+ "= 0.5" "divide two double values"
+ gdb_test "gu (print (value-rem i j))" \
+ "= 1" "take remainder of two integer values"
+ gdb_test "gu (print (value-mod i j))" \
+ "= 1" "take modulus of two integer values"
+
+ gdb_test "gu (print (value-pow i j))" \
+ "= 25" "integer value raised to the power of another integer value"
+ gdb_test "gu (print (value-pow g j))" \
+ "= 6.25" "double value raised to the power of integer value"
+
+ gdb_test "gu (print (value-neg i))" \
+ "= -5" "negated integer value"
+ gdb_test "gu (print (value-pos i))" \
+ "= 5" "positive integer value"
+ gdb_test "gu (print (value-neg f))" \
+ "= -1.25" "negated double value"
+ gdb_test "gu (print (value-pos f))" \
+ "= 1.25" "positive double value"
+ gdb_test "gu (print (value-abs (value-sub j i)))" \
+ "= 3" "absolute of integer value"
+ gdb_test "gu (print (value-abs (value-sub f g)))" \
+ "= 1.25" "absolute of double value"
+
+ gdb_test "gu (print (value-lsh i j))" \
+ "= 20" "left shift"
+ gdb_test "gu (print (value-rsh i j))" \
+ "= 1" "right shift"
+
+ gdb_test "gu (print (value-min i j))" \
+ "= 2" "min"
+ gdb_test "gu (print (value-max i j))" \
+ "= 5" "max"
+
+ gdb_test "gu (print (value-lognot i))" \
+ "= -6" "lognot"
+ gdb_test "gu (print (value-logand i j))" \
+ "= 0" "logand i j"
+ gdb_test "gu (print (value-logand 5 1))" \
+ "= 1" "logand 5 1"
+ gdb_test "gu (print (value-logior i j))" \
+ "= 7" "logior i j"
+ gdb_test "gu (print (value-logior 5 1))" \
+ "= 5" "logior 5 1"
+ gdb_test "gu (print (value-logxor i j))" \
+ "= 7" "logxor i j"
+ gdb_test "gu (print (value-logxor 5 1))" \
+ "= 4" "logxor 5 1"
+
+ # Test <gdb:value> mixed with Guile types.
+
+ gdb_test "gu (print (value-sub i 1))" \
+ "= 4" "subtract integer value from guile integer"
+ gdb_test "gu (raw-print (value-sub i 1))" \
+ "#<gdb:value 4>" \
+ "verify type of mixed integer subtraction result"
+ gdb_test "gu (print (value-add f 1.5))" \
+ "= 2.75" "add double value with guile float"
+
+ gdb_test "gu (print (value-sub 1 i))" \
+ "= -4" "subtract guile integer from integer value"
+ gdb_test "gu (print (value-add 1.5 f))" \
+ "= 2.75" "add guile float with double value"
+
+ # Enum conversion test.
+ gdb_test "print evalue" "= TWO"
+ gdb_test "gu (print (value->integer (history-ref 0)))" "= 2"
+
+ # Test pointer arithmetic.
+
+ # First, obtain the pointers.
+ gdb_test "print (void *) 2" ".*" ""
+ gdb_test_no_output "gu (define a (history-ref 0))"
+ gdb_test "print (void *) 5" ".*" ""
+ gdb_test_no_output "gu (define b (history-ref 0))"
+
+ gdb_test "gu (print (value-add a 5))" \
+ "= 0x7( <.*>)?" "add pointer value with guile integer"
+ gdb_test "gu (print (value-sub b 2))" \
+ "= 0x3( <.*>)?" "subtract guile integer from pointer value"
+ gdb_test "gu (print (value-sub b a))" \
+ "= 3" "subtract two pointer values"
+
+ # Test some invalid operations.
+
+ gdb_test_multiple "gu (print (value-add i '()))" "catch error in guile type conversion" {
+ -re "Wrong type argument in position 2.*$gdb_prompt $" {pass "catch error in guile type conversion"}
+ -re "= .*$gdb_prompt $" {fail "catch error in guile type conversion"}
+ -re "$gdb_prompt $" {fail "catch error in guile type conversion"}
+ }
+
+ gdb_test_multiple "gu (print (value-add i \"foo\"))" "catch throw of GDB error" {
+ -re "Argument to arithmetic operation not a number or boolean.*$gdb_prompt $" {pass "catch throw of GDB error"}
+ -re "= .*$gdb_prompt $" {fail "catch throw of GDB error"}
+ -re "$gdb_prompt $" {fail "catch throw of GDB error"}
+ }
+}
+
+# Return the max signed int of size SIZE.
+# TCL 8.5 required here. Use lookup table instead?
+
+proc get_max_int { size } {
+ return [expr "(1 << ($size - 1)) - 1"]
+}
+
+# Return the min signed int of size SIZE.
+# TCL 8.5 required here. Use lookup table instead?
+
+proc get_min_int { size } {
+ return [expr "-(1 << ($size - 1))"]
+}
+
+# Return the max unsigned int of size SIZE.
+# TCL 8.5 required here. Use lookup table instead?
+
+proc get_max_uint { size } {
+ return [expr "(1 << $size) - 1"]
+}
+
+# Helper routine for test_value_numeric_ranges.
+
+proc test_make_int_value { name size } {
+ set max [get_max_int $size]
+ set min [get_min_int $size]
+ set umax [get_max_uint $size]
+ gdb_test "gu (print (value-type (make-value $max)))" \
+ "= $name" "test make-value $name $size max"
+ gdb_test "gu (print (value-type (make-value $min)))" \
+ "= $name" "test make-value $name $size min"
+ gdb_test "gu (print (value-type (make-value $umax)))" \
+ "= unsigned $name" "test make-value unsigned $name $size umax"
+}
+
+# Helper routine for test_value_numeric_ranges.
+
+proc test_make_typed_int_value { size } {
+ set name "int$size"
+ set uname "uint$size"
+ set max [get_max_int $size]
+ set min [get_min_int $size]
+ set umax [get_max_uint $size]
+
+ gdb_test "gu (print (make-value $max #:type (arch-${name}-type arch)))" \
+ "= $max" "test make-value $name $size max"
+ gdb_test "gu (print (make-value $min #:type (arch-${name}-type arch)))" \
+ "= $min" "test make-value $name $size min"
+ gdb_test "gu (print (make-value $umax #:type (arch-${uname}-type arch)))" \
+ "= $umax" "test make-value $uname $size umax"
+
+ gdb_test "gu (print (make-value (+ $max 1) #:type (arch-${name}-type arch)))" \
+ "ERROR.*Out of range.*" "test make-value $name $size max+1"
+ gdb_test "gu (print (make-value (- $min 1) #:type (arch-${name}-type arch)))" \
+ "ERROR.*Out of range.*" "test make-value $name $size min-1"
+ gdb_test "gu (print (make-value (+ $umax 1) #:type (arch-${uname}-type arch)))" \
+ "ERROR.*Out of range.*" "test make-value $uname $size umax+1"
+}
+
+proc test_value_numeric_ranges {} {
+ # We can't assume anything about sizeof (int), etc. on the target.
+ # Keep it simple for now, this will cover everything important for
+ # the major targets.
+ set int_size [get_sizeof "int" 0]
+ set long_size [get_sizeof "long" 0]
+ gdb_test_no_output "gu (define arch (current-arch))"
+
+ if { $int_size == 4 } {
+ test_make_int_value int 32
+ }
+ if { $long_size == 8} {
+ test_make_int_value long 64
+ }
+ gdb_test "gu (print (value-type (make-value (ash 1 64))))" \
+ "ERROR:.*value not a number representable.*" \
+ "test make-value, number too large"
+
+ foreach size { 8 16 32 } {
+ test_make_typed_int_value $size
+ }
+ if { $long_size == 8 } {
+ test_make_typed_int_value 64
+ }
+}
+
+proc test_value_boolean {} {
+ # Note: Boolean values print as 0,1 because they are printed in the
+ # current language (in this case C).
+
+ gdb_test "gu (print (make-value #t))" "= 1" "create boolean true"
+ gdb_test "gu (print (make-value #f))" "= 0" "create boolean false"
+
+ gdb_test "gu (print (value-not (make-value #t)))" \
+ "= 0" "not true"
+ gdb_test "gu (print (value-not (make-value #f)))" \
+ "= 1" "not false"
+
+ gdb_test "gu (raw-print (make-value #t))" \
+ "#<gdb:value 1>" "verify type of boolean"
+}
+
+proc test_value_compare {} {
+ gdb_test "gu (print (value<? 1 1))" \
+ "#f" "less than, equal"
+ gdb_test "gu (print (value<? 1 2))" \
+ "#t" "less than, less"
+ gdb_test "gu (print (value<? 2 1))" \
+ "#f" "less than, greater"
+
+ gdb_test "gu (print (value<=? 1 1))" \
+ "#t" "less or equal, equal"
+ gdb_test "gu (print (value<=? 1 2))" \
+ "#t" "less or equal, less"
+ gdb_test "gu (print (value<=? 2 1))" \
+ "#f" "less or equal, greater"
+
+ gdb_test "gu (print (value=? 1 1))" \
+ "#t" "equality"
+ gdb_test "gu (print (value=? 1 2))" \
+ "#f" "inequality"
+ gdb_test "gu (print (value=? (make-value 1) 1.0))" \
+ "#t" "equality of gdb:value with Guile value"
+ gdb_test "gu (print (value=? (make-value 1) 2))" \
+ "#f" "inequality of gdb:value with Guile value"
+
+ gdb_test "gu (print (value>? 1 1))" \
+ "#f" "greater than, equal"
+ gdb_test "gu (print (value>? 1 2))" \
+ "#f" "greater than, less"
+ gdb_test "gu (print (value>? 2 1))" \
+ "#t" "greater than, greater"
+
+ gdb_test "gu (print (value>=? 1 1))" \
+ "#t" "greater or equal, equal"
+ gdb_test "gu (print (value>=? 1 2))" \
+ "#f" "greater or equal, less"
+ gdb_test "gu (print (value>=? 2 1))" \
+ "#t" "greater or equal, greater"
+}
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c}]} {
+ return
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+test_value_numeric_ops
+test_value_numeric_ranges
+test_value_boolean
+test_value_compare
diff --git a/gdb/testsuite/gdb.guile/scm-objfile-script-gdb.in b/gdb/testsuite/gdb.guile/scm-objfile-script-gdb.in
new file mode 100644
index 0000000..e576721
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-objfile-script-gdb.in
@@ -0,0 +1,55 @@
+;; Copyright (C) 2011-2014 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/>.
+
+;; This file is part of the GDB testsuite.
+
+(use-modules (gdb) (gdb printing))
+
+(define (make-pp_ss-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (let ((a (value-field val "a"))
+ (b (value-field val "b")))
+ (format #f "a=<~A> b=<~A>" a b)))
+ #f))
+
+(define (get-type-for-printing val)
+ "Return type of val, stripping away typedefs, etc."
+ (let ((type (value-type val)))
+ (if (= (type-code type) TYPE_CODE_REF)
+ (set! type (type-target type)))
+ (type-strip-typedefs (type-unqualified type))))
+
+(define (make-pretty-printer-dict)
+ (let ((dict (make-hash-table)))
+ (hash-set! dict "struct ss" make-pp_ss-printer)
+ (hash-set! dict "ss" make-pp_ss-printer)
+ dict))
+
+(define *pretty-printer*
+ (make-pretty-printer
+ "pretty-printer-test"
+ (let ((pretty-printers-dict (make-pretty-printer-dict)))
+ (lambda (matcher val)
+ "Look-up and return a pretty-printer that can print val."
+ (let ((type (get-type-for-printing val)))
+ (let ((typename (type-tag type)))
+ (if typename
+ (let ((printer-maker (hash-ref pretty-printers-dict typename)))
+ (and printer-maker (printer-maker val)))
+ #f)))))))
+
+(append-pretty-printer! #f *pretty-printer*)
diff --git a/gdb/testsuite/gdb.guile/scm-objfile-script.c b/gdb/testsuite/gdb.guile/scm-objfile-script.c
new file mode 100644
index 0000000..10f4776
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-objfile-script.c
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011-2014 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/>. */
+
+struct ss
+{
+ int a;
+ int b;
+};
+
+void
+init_ss (struct ss *s, int a, int b)
+{
+ s->a = a;
+ s->b = b;
+}
+
+int
+main ()
+{
+ struct ss ss;
+
+ init_ss (&ss, 1, 2);
+
+ return 0; /* break to inspect struct and union */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-objfile-script.exp b/gdb/testsuite/gdb.guile/scm-objfile-script.exp
new file mode 100644
index 0000000..65d0c44
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-objfile-script.exp
@@ -0,0 +1,57 @@
+# Copyright (C) 2011-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests automagic loading of -gdb.scm scripts.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
+ return
+}
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+# Make the -gdb.scm script available to gdb, it is automagically loaded by gdb.
+# Care is taken to put it in the same directory as the binary so that
+# gdb will find it.
+set remote_guile_file [remote_download host \
+ ${srcdir}/${subdir}/${testfile}-gdb.in \
+ [standard_output_file ${testfile}-gdb.scm]]
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_test_no_output "set auto-load safe-path ${remote_guile_file}" \
+ "set auto-load safe-path"
+gdb_load ${binfile}
+
+# Verify gdb loaded the script.
+gdb_test "info auto-load guile-scripts" "Yes.*/${testfile}-gdb.scm.*"
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
+ ".*Breakpoint.*"
+gdb_test "continue" ".*Breakpoint.*"
+
+gdb_test "print ss" " = a=<1> b=<2>"
diff --git a/gdb/testsuite/gdb.guile/scm-objfile.c b/gdb/testsuite/gdb.guile/scm-objfile.c
new file mode 100644
index 0000000..dbdc9b3
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-objfile.c
@@ -0,0 +1,23 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011-2014 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 ()
+{
+ int some_var = 0;
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.guile/scm-objfile.exp b/gdb/testsuite/gdb.guile/scm-objfile.exp
new file mode 100644
index 0000000..70da488
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-objfile.exp
@@ -0,0 +1,57 @@
+# Copyright (C) 2011-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the objfile support in Guile.
+
+load_lib gdb-guile.exp
+
+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] {
+ fail "Can't run to main"
+ return
+}
+
+gdb_scm_test_silent_cmd "gu (define sym (lookup-symbol \"some_var\"))" \
+ "Find a symbol in objfile"
+gdb_scm_test_silent_cmd "gu (define objfile (symtab-objfile (symbol-symtab (car sym))))" \
+ "Get backing object file"
+
+gdb_test "gu (print (objfile-filename objfile))" \
+ ".*scm-objfile.*" "Get objfile filename"
+gdb_test "gu (print (objfile-valid? objfile))" \
+ "#t" "Get objfile validity"
+
+gdb_test "gu (print (->bool (or-map (lambda (o) (string-contains (objfile-filename o) \"scm-objfile\")) (objfiles))))" \
+ "= #t" "scm-objfile in objfile list"
+
+gdb_test "gu (print (objfile-pretty-printers objfile))" \
+ "= \\(\\)"
+
+gdb_test "guile (set-objfile-pretty-printers! objfile 0)" \
+ "ERROR: .*: Wrong type argument in position 2 \\(expecting list\\): 0.*"
+
+# Do this last.
+gdb_unload
+gdb_test "gu (print (objfile-valid? objfile))" \
+ "#f" "Get objfile validity after unload"
diff --git a/gdb/testsuite/gdb.guile/scm-ports.exp b/gdb/testsuite/gdb.guile/scm-ports.exp
new file mode 100644
index 0000000..ceb9a5f
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-ports.exp
@@ -0,0 +1,37 @@
+# Copyright (C) 2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests GDB provided ports.
+
+load_lib gdb-guile.exp
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_install_guile_utils
+gdb_install_guile_module
+
+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"
diff --git a/gdb/testsuite/gdb.guile/scm-pretty-print.c b/gdb/testsuite/gdb.guile/scm-pretty-print.c
new file mode 100644
index 0000000..0fd05f5
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-pretty-print.c
@@ -0,0 +1,353 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008-2014 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/>. */
+
+#include <string.h>
+
+struct s
+{
+ int a;
+ int *b;
+};
+
+struct ss
+{
+ struct s a;
+ struct s b;
+};
+
+struct arraystruct
+{
+ int y;
+ struct s x[2];
+};
+
+struct ns {
+ const char *null_str;
+ int length;
+};
+
+struct lazystring {
+ const char *lazy_str;
+};
+
+struct hint_error {
+ int x;
+};
+
+struct children_as_list {
+ int x;
+};
+
+#ifdef __cplusplus
+struct S : public s {
+ int zs;
+};
+
+struct SS {
+ int zss;
+ S s;
+};
+
+struct SSS
+{
+ SSS (int x, const S& r);
+ int a;
+ const S &b;
+};
+SSS::SSS (int x, const S& r) : a(x), b(r) { }
+
+class VirtualTest
+{
+ private:
+ int value;
+
+ public:
+ VirtualTest ()
+ {
+ value = 1;
+ }
+};
+
+class Vbase1 : public virtual VirtualTest { };
+class Vbase2 : public virtual VirtualTest { };
+class Vbase3 : public virtual VirtualTest { };
+
+class Derived : public Vbase1, public Vbase2, public Vbase3
+{
+ private:
+ int value;
+
+ public:
+ Derived ()
+ {
+ value = 2;
+ }
+};
+
+class Fake
+{
+ int sname;
+
+ public:
+ Fake (const int name = 0):
+ sname (name)
+ {
+ }
+};
+#endif
+
+struct substruct {
+ int a;
+ int b;
+};
+
+struct outerstruct {
+ struct substruct s;
+ int x;
+};
+
+struct outerstruct
+substruct_test (void)
+{
+ struct outerstruct outer;
+ outer.s.a = 0;
+ outer.s.b = 0;
+ outer.x = 0;
+
+ outer.s.a = 3; /* MI outer breakpoint here */
+
+ return outer;
+}
+
+typedef struct string_repr
+{
+ struct whybother
+ {
+ const char *contents;
+ } whybother;
+} string;
+
+/* This lets us avoid malloc. */
+int array[100];
+int narray[10];
+
+struct justchildren
+{
+ int len;
+ int *elements;
+};
+
+typedef struct justchildren nostring_type;
+
+struct memory_error
+{
+ const char *s;
+};
+
+struct container
+{
+ string name;
+ int len;
+ int *elements;
+};
+
+typedef struct container zzz_type;
+
+string
+make_string (const char *s)
+{
+ string result;
+ result.whybother.contents = s;
+ return result;
+}
+
+zzz_type
+make_container (const char *s)
+{
+ zzz_type result;
+
+ result.name = make_string (s);
+ result.len = 0;
+ result.elements = 0;
+
+ return result;
+}
+
+void
+add_item (zzz_type *c, int val)
+{
+ if (c->len == 0)
+ c->elements = array;
+ c->elements[c->len] = val;
+ ++c->len;
+}
+
+void
+set_item(zzz_type *c, int i, int val)
+{
+ if (i < c->len)
+ c->elements[i] = val;
+}
+
+void init_s(struct s *s, int a)
+{
+ s->a = a;
+ s->b = &s->a;
+}
+
+void init_ss(struct ss *s, int a, int b)
+{
+ init_s(&s->a, a);
+ init_s(&s->b, b);
+}
+
+void do_nothing(void)
+{
+ int c;
+
+ c = 23; /* Another MI breakpoint */
+}
+
+struct nullstr
+{
+ char *s;
+};
+
+struct string_repr string_1 = { { "one" } };
+struct string_repr string_2 = { { "two" } };
+
+static int
+eval_func (int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8)
+{
+ return p1;
+}
+
+static void
+eval_sub (void)
+{
+ struct eval_type_s { int x; } eval1 = { 1 }, eval2 = { 2 }, eval3 = { 3 },
+ eval4 = { 4 }, eval5 = { 5 }, eval6 = { 6 },
+ eval7 = { 7 }, eval8 = { 8 }, eval9 = { 9 };
+
+ eval1.x++; /* eval-break */
+}
+
+static void
+bug_14741()
+{
+ zzz_type c = make_container ("bug_14741");
+ add_item (&c, 71);
+ set_item(&c, 0, 42); /* breakpoint bug 14741 */
+ set_item(&c, 0, 5);
+}
+
+int
+main ()
+{
+ struct ss ss;
+ struct ss ssa[2];
+ struct arraystruct arraystruct;
+ string x = make_string ("this is x");
+ zzz_type c = make_container ("container");
+ zzz_type c2 = make_container ("container2");
+ const struct string_repr cstring = { { "const string" } };
+ /* Clearing by being `static' could invoke an other GDB C++ bug. */
+ struct nullstr nullstr;
+ nostring_type nstype, nstype2;
+ struct memory_error me;
+ struct ns ns, ns2;
+ struct lazystring estring, estring2;
+ struct hint_error hint_error;
+ struct children_as_list children_as_list;
+
+ nstype.elements = narray;
+ nstype.len = 0;
+
+ me.s = "blah";
+
+ init_ss(&ss, 1, 2);
+ init_ss(ssa+0, 3, 4);
+ init_ss(ssa+1, 5, 6);
+ memset (&nullstr, 0, sizeof nullstr);
+
+ arraystruct.y = 7;
+ init_s (&arraystruct.x[0], 23);
+ init_s (&arraystruct.x[1], 24);
+
+ ns.null_str = "embedded\0null\0string";
+ ns.length = 20;
+
+ /* Make a "corrupted" string. */
+ ns2.null_str = NULL;
+ ns2.length = 20;
+
+ estring.lazy_str = "embedded x\201\202\203\204" ;
+
+ /* Incomplete UTF-8, but ok Latin-1. */
+ estring2.lazy_str = "embedded x\302";
+
+#ifdef __cplusplus
+ S cps;
+
+ cps.zs = 7;
+ init_s(&cps, 8);
+
+ SS cpss;
+ cpss.zss = 9;
+ init_s(&cpss.s, 10);
+
+ SS cpssa[2];
+ cpssa[0].zss = 11;
+ init_s(&cpssa[0].s, 12);
+ cpssa[1].zss = 13;
+ init_s(&cpssa[1].s, 14);
+
+ SSS sss(15, cps);
+
+ SSS& ref (sss);
+
+ Derived derived;
+
+ Fake fake (42);
+#endif
+
+ add_item (&c, 23); /* MI breakpoint here */
+ add_item (&c, 72);
+
+#ifdef MI
+ add_item (&c, 1011);
+ c.elements[0] = 1023;
+ c.elements[0] = 2323;
+
+ add_item (&c2, 2222);
+ add_item (&c2, 3333);
+
+ substruct_test ();
+ do_nothing ();
+#endif
+
+ nstype.elements[0] = 7;
+ nstype.elements[1] = 42;
+ nstype.len = 2;
+
+ nstype2 = nstype;
+
+ eval_sub ();
+
+ bug_14741(); /* break to inspect struct and union */
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.guile/scm-pretty-print.exp b/gdb/testsuite/gdb.guile/scm-pretty-print.exp
new file mode 100644
index 0000000..cd3ae95
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-pretty-print.exp
@@ -0,0 +1,148 @@
+# Copyright (C) 2008-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests Guile-based pretty-printing for the CLI.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+proc run_lang_tests {exefile lang} {
+ global srcdir subdir srcfile testfile hex
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${exefile}" executable "debug $lang"] != "" } {
+ untested "Couldn't compile ${srcfile} in $lang mode"
+ return
+ }
+
+ set nl "\[\r\n\]+"
+
+ # Start with a fresh gdb.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${exefile}
+
+ if ![gdb_guile_runto_main] {
+ return
+ }
+
+ gdb_test_no_output "set print pretty on"
+
+ gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
+ ".*Breakpoint.*"
+ gdb_test "continue" ".*Breakpoint.*"
+
+ set remote_scheme_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.scm]
+
+ gdb_scm_load_file ${remote_scheme_file}
+
+ gdb_test "print ss" " = a=<a=<1> b=<$hex>> b=<a=<2> b=<$hex>>"
+ gdb_test "print ssa\[1\]" " = a=<a=<5> b=<$hex>> b=<a=<6> b=<$hex>>"
+ gdb_test "print ssa" " = {a=<a=<3> b=<$hex>> b=<a=<4> b=<$hex>>, a=<a=<5> b=<$hex>> b=<a=<6> b=<$hex>>}"
+
+ gdb_test "print arraystruct" " = {$nl *y = 7, *$nl *x = {a=<23> b=<$hex>, a=<24> b=<$hex>} *$nl *}"
+
+ if {$lang == "c++"} {
+ gdb_test "print cps" "= a=<8> b=<$hex>"
+ gdb_test "print cpss" " = {$nl *zss = 9, *$nl *s = a=<10> b=<$hex>$nl}"
+ gdb_test "print cpssa\[0\]" " = {$nl *zss = 11, *$nl *s = a=<12> b=<$hex>$nl}"
+ gdb_test "print cpssa\[1\]" " = {$nl *zss = 13, *$nl *s = a=<14> b=<$hex>$nl}"
+ gdb_test "print cpssa" " = {{$nl *zss = 11, *$nl *s = a=<12> b=<$hex>$nl *}, {$nl *zss = 13, *$nl *s = a=<14> b=<$hex>$nl *}}"
+ gdb_test "print sss" "= a=<15> b=<a=<8> b=<$hex>>"
+ gdb_test "print ref" "= a=<15> b=<a=<8> b=<$hex>>"
+ gdb_test "print derived" \
+ " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
+ gdb_test "print ns " "\"embedded\\\\000null\\\\000string\""
+ gdb_scm_test_silent_cmd "set print elements 3" "" 1
+ gdb_test "print ns" "emb\.\.\.."
+ gdb_scm_test_silent_cmd "set print elements 10" "" 1
+ gdb_test "print ns" "embedded\\\\000n\.\.\.."
+ gdb_scm_test_silent_cmd "set print elements 200" "" 1
+ }
+
+ gdb_test "print ns2" "<error reading variable: ERROR: Cannot access memory at address 0x0>"
+
+ gdb_test "print x" " = \"this is x\""
+ gdb_test "print cstring" " = \"const string\""
+
+ gdb_test "print estring" " = \"embedded x\\\\201\\\\202\\\\203\\\\204\""
+
+ gdb_test_no_output "guile (set! *pp-ls-encoding* \"UTF-8\")"
+ gdb_test "print estring2" "\"embedded \", <incomplete sequence \\\\302>"
+
+ gdb_test_no_output "set guile print-stack full"
+ gdb_test "print hint_error" "ERROR: Invalid display hint: 42\r\nhint_error_val"
+
+ gdb_test "print c" " = container \"container\" with 2 elements = {$nl *.0. = 23,$nl *.1. = 72$nl}"
+
+ gdb_test "print nstype" " = {$nl *.0. = 7,$nl *.1. = 42$nl}"
+
+ gdb_test_no_output "set print pretty off"
+ gdb_test "print nstype" " = {.0. = 7, .1. = 42}" \
+ "print nstype on one line"
+
+ gdb_continue_to_end
+}
+
+run_lang_tests "${binfile}" "c"
+run_lang_tests "${binfile}-cxx" "c++"
+
+# Run various other tests.
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+set remote_scheme_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.scm]
+
+gdb_scm_load_file ${remote_scheme_file}
+
+gdb_breakpoint [gdb_get_line_number "eval-break"]
+gdb_continue_to_breakpoint "eval-break" ".* eval-break .*"
+
+gdb_test "info locals" "eval9 = eval=<123456789>"
+
+gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
+ ".*Breakpoint.*"
+gdb_test "continue" ".*Breakpoint.*"
+
+gdb_test "print ss" " = a=<a=<1> b=<$hex>> b=<a=<2> b=<$hex>>" \
+ "print ss enabled #1"
+
+gdb_test_no_output "guile (disable-matcher!)"
+
+gdb_test "print ss" " = {a = {a = 1, b = $hex}, b = {a = 2, b = $hex}}" \
+ "print ss disabled"
+
+gdb_test_no_output "guile (enable-matcher!)"
+
+gdb_test "print ss" " = a=<a=<1> b=<$hex>> b=<a=<2> b=<$hex>>" \
+ "print ss enabled #2"
diff --git a/gdb/testsuite/gdb.guile/scm-pretty-print.scm b/gdb/testsuite/gdb.guile/scm-pretty-print.scm
new file mode 100644
index 0000000..a42527c
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-pretty-print.scm
@@ -0,0 +1,301 @@
+;; Copyright (C) 2008-2014 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/>.
+
+;; This file is part of the GDB testsuite.
+;; It tests Scheme pretty printers.
+
+(use-modules (gdb) (gdb printing))
+
+(define (make-pointer-iterator pointer len)
+ (let ((next! (lambda (iter)
+ (let* ((start (iterator-object iter))
+ (progress (iterator-progress iter))
+ (current (car progress))
+ (len (cdr progress)))
+ (if (= current len)
+ (end-of-iteration)
+ (let ((pointer (value-add start current)))
+ (set-car! progress (+ current 1))
+ (cons (format #f "[~A]" current)
+ (value-dereference pointer))))))))
+ (make-iterator pointer (cons 0 len) next!)))
+
+(define (make-pointer-iterator-except pointer len)
+ (let ((next! (lambda (iter)
+ (if *exception-flag*
+ (throw 'gdb:memory-error "hi bob"))
+ (let* ((start (iterator-object iter))
+ (progress (iterator-progress iter))
+ (current (car progress))
+ (len (cdr progress)))
+ (if (= current len)
+ (end-of-iteration)
+ (let ((pointer (value-add start current)))
+ (set-car! progress (+ current 1))
+ (cons (format #f "[~A]" current)
+ (value-dereference pointer))))))))
+ (make-iterator pointer (cons 0 len) next!)))
+
+;; Test returning a <gdb:value> from a printer.
+
+(define (make-string-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (value-field (value-field val "whybother")
+ "contents"))
+ #f))
+
+;; Test a printer with children.
+
+(define (make-container-printer val)
+ ;; This is a little different than the Python version in that if there's
+ ;; an error accessing these fields we'll throw it at matcher time instead
+ ;; of at printer time. Done this way to explore the possibilities.
+ (let ((name (value-field val "name"))
+ (len (value-field val "len"))
+ (elements (value-field val "elements")))
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (format #f "container ~A with ~A elements"
+ name len))
+ (lambda (printer)
+ (make-pointer-iterator elements (value->integer len))))))
+
+;; Test "array" display hint.
+
+(define (make-array-printer val)
+ (let ((name (value-field val "name"))
+ (len (value-field val "len"))
+ (elements (value-field val "elements")))
+ (make-pretty-printer-worker
+ "array"
+ (lambda (printer)
+ (format #f "array ~A with ~A elements"
+ name len))
+ (lambda (printer)
+ (make-pointer-iterator elements (value->integer len))))))
+
+;; Flag to make no-string-container printer throw an exception.
+
+(define *exception-flag* #f)
+
+;; Test a printer where to_string returns #f.
+
+(define (make-no-string-container-printer val)
+ (let ((len (value-field val "len"))
+ (elements (value-field val "elements")))
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer) #f)
+ (lambda (printer)
+ (make-pointer-iterator-except elements (value->integer len))))))
+
+(define (make-pp_s-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (let ((a (value-field val "a"))
+ (b (value-field val "b")))
+ (if (not (value=? (value-address a) b))
+ (error (format #f "&a(~A) != b(~A)"
+ (value-address a) b)))
+ (format #f "a=<~A> b=<~A>" a b)))
+ #f))
+
+(define (make-pp_ss-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (let ((a (value-field val "a"))
+ (b (value-field val "b")))
+ (format #f "a=<~A> b=<~A>" a b)))
+ #f))
+
+(define (make-pp_sss-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (let ((a (value-field val "a"))
+ (b (value-field val "b")))
+ (format #f "a=<~A> b=<~A>" a b)))
+ #f))
+
+(define (make-pp_multiple_virtual-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (format #f "pp value variable is: ~A" (value-field val "value")))
+ #f))
+
+(define (make-pp_vbase1-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (format #f "pp class name: ~A" (type-tag (value-type val))))
+ #f))
+
+(define (make-pp_nullstr-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (value->string (value-field val "s")
+ #:encoding (arch-charset (current-arch))))
+ #f))
+
+(define (make-pp_ns-printer val)
+ (make-pretty-printer-worker
+ "string"
+ (lambda (printer)
+ (let ((len (value-field val "length")))
+ (value->string (value-field val "null_str")
+ #:encoding (arch-charset (current-arch))
+ #:length (value->integer len))))
+ #f))
+
+(define *pp-ls-encoding* #f)
+
+(define (make-pp_ls-printer val)
+ (make-pretty-printer-worker
+ "string"
+ (lambda (printer)
+ (if *pp-ls-encoding*
+ (value->lazy-string (value-field val "lazy_str")
+ #:encoding *pp-ls-encoding*)
+ (value->lazy-string (value-field val "lazy_str"))))
+ #f))
+
+(define (make-pp_hint_error-printer val)
+ "Use an invalid value for the display hint."
+ (make-pretty-printer-worker
+ 42
+ (lambda (printer) "hint_error_val")
+ #f))
+
+(define (make-pp_children_as_list-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer) "children_as_list_val")
+ (lambda (printer) (make-list-iterator (list (cons "one" 1))))))
+
+(define (make-pp_outer-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (format #f "x = ~A" (value-field val "x")))
+ (lambda (printer)
+ (make-list-iterator (list (cons "s" (value-field val "s"))
+ (cons "x" (value-field val "x")))))))
+
+(define (make-memory-error-string-printer val)
+ (make-pretty-printer-worker
+ "string"
+ (lambda (printer)
+ (scm-error 'gdb:memory-error "memory-error-printer"
+ "Cannot access memory." '() '()))
+ #f))
+
+(define (make-pp_eval_type-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (execute "bt" #:to-string #t)
+ (format #f "eval=<~A>"
+ (value-print
+ (parse-and-eval
+ "eval_func (123456789, 2, 3, 4, 5, 6, 7, 8)"))))
+ #f))
+
+(define (get-type-for-printing val)
+ "Return type of val, stripping away typedefs, etc."
+ (let ((type (value-type val)))
+ (if (= (type-code type) TYPE_CODE_REF)
+ (set! type (type-target type)))
+ (type-strip-typedefs (type-unqualified type))))
+
+(define (disable-matcher!)
+ (set-pretty-printer-enabled! *pretty-printer* #f))
+
+(define (enable-matcher!)
+ (set-pretty-printer-enabled! *pretty-printer* #t))
+
+(define (make-pretty-printer-dict)
+ (let ((dict (make-hash-table)))
+ (hash-set! dict "struct s" make-pp_s-printer)
+ (hash-set! dict "s" make-pp_s-printer)
+ (hash-set! dict "S" make-pp_s-printer)
+
+ (hash-set! dict "struct ss" make-pp_ss-printer)
+ (hash-set! dict "ss" make-pp_ss-printer)
+ (hash-set! dict "const S &" make-pp_s-printer)
+ (hash-set! dict "SSS" make-pp_sss-printer)
+
+ (hash-set! dict "VirtualTest" make-pp_multiple_virtual-printer)
+ (hash-set! dict "Vbase1" make-pp_vbase1-printer)
+
+ (hash-set! dict "struct nullstr" make-pp_nullstr-printer)
+ (hash-set! dict "nullstr" make-pp_nullstr-printer)
+
+ ;; Note that we purposely omit the typedef names here.
+ ;; Printer lookup is based on canonical name.
+ ;; However, we do need both tagged and untagged variants, to handle
+ ;; both the C and C++ cases.
+ (hash-set! dict "struct string_repr" make-string-printer)
+ (hash-set! dict "struct container" make-container-printer)
+ (hash-set! dict "struct justchildren" make-no-string-container-printer)
+ (hash-set! dict "string_repr" make-string-printer)
+ (hash-set! dict "container" make-container-printer)
+ (hash-set! dict "justchildren" make-no-string-container-printer)
+
+ (hash-set! dict "struct ns" make-pp_ns-printer)
+ (hash-set! dict "ns" make-pp_ns-printer)
+
+ (hash-set! dict "struct lazystring" make-pp_ls-printer)
+ (hash-set! dict "lazystring" make-pp_ls-printer)
+
+ (hash-set! dict "struct outerstruct" make-pp_outer-printer)
+ (hash-set! dict "outerstruct" make-pp_outer-printer)
+
+ (hash-set! dict "struct hint_error" make-pp_hint_error-printer)
+ (hash-set! dict "hint_error" make-pp_hint_error-printer)
+
+ (hash-set! dict "struct children_as_list"
+ make-pp_children_as_list-printer)
+ (hash-set! dict "children_as_list" make-pp_children_as_list-printer)
+
+ (hash-set! dict "memory_error" make-memory-error-string-printer)
+
+ (hash-set! dict "eval_type_s" make-pp_eval_type-printer)
+
+ dict))
+
+;; This is one way to register a printer that is composed of several
+;; subprinters, but there's no way to disable or list individual subprinters.
+
+(define *pretty-printer*
+ (make-pretty-printer
+ "pretty-printer-test"
+ (let ((pretty-printers-dict (make-pretty-printer-dict)))
+ (lambda (matcher val)
+ "Look-up and return a pretty-printer that can print val."
+ (let ((type (get-type-for-printing val)))
+ (let ((typename (type-tag type)))
+ (if typename
+ (let ((printer-maker (hash-ref pretty-printers-dict typename)))
+ (and printer-maker (printer-maker val)))
+ #f)))))))
+
+(append-pretty-printer! #f *pretty-printer*)
diff --git a/gdb/testsuite/gdb.guile/scm-section-script.c b/gdb/testsuite/gdb.guile/scm-section-script.c
new file mode 100644
index 0000000..8a1ede9
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-section-script.c
@@ -0,0 +1,55 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2014 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/>. */
+
+#include "symcat.h"
+#include "gdb/section-scripts.h"
+
+/* Put the path to the pretty-printer script in .debug_gdb_scripts so
+ gdb will automagically loaded it. */
+
+#define DEFINE_GDB_SCRIPT(script_name) \
+ asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
+.byte " XSTRING (SECTION_SCRIPT_ID_SCHEME_FILE) "\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+
+DEFINE_GDB_SCRIPT (SCRIPT_FILE)
+
+struct ss
+{
+ int a;
+ int b;
+};
+
+void
+init_ss (struct ss *s, int a, int b)
+{
+ s->a = a;
+ s->b = b;
+}
+
+int
+main ()
+{
+ struct ss ss;
+
+ init_ss (&ss, 1, 2);
+
+ return 0; /* break to inspect struct and union */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-section-script.exp b/gdb/testsuite/gdb.guile/scm-section-script.exp
new file mode 100644
index 0000000..0c5e489
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-section-script.exp
@@ -0,0 +1,80 @@
+# Copyright (C) 2010-2014 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/>.
+
+# This file is part of the GDB testsuite. It tests automagic loading of
+# scripts specified in the .debug_gdb_scripts section.
+
+# This test can only be run on targets which support ELF and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+ && ![istarget *-*-gnu*]
+ && ![istarget *-*-elf*]
+ && ![istarget *-*-openbsd*]
+ && ![istarget arm*-*-eabi*]
+ && ![istarget arm*-*-symbianelf*]
+ && ![istarget powerpc-*-eabi*]} {
+ verbose "Skipping scm-section-script.exp because of lack of support."
+ return
+}
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+# Make this available to gdb before the program starts, it is
+# automagically loaded by gdb.
+# Give the file a new name so we don't clobber the real one if
+# objfile == srcdir.
+# We also need to do this before compiling the program because the name
+# of the script file is encoded in the binary.
+# FIXME: Can we get gdb_remote_download to call standard_output_file for us?
+set remote_guile_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.scm \
+ ${subdir}/t-${testfile}.scm]
+
+if {[build_executable $testfile.exp $testfile $srcfile \
+ [list debug "additional_flags=-I${srcdir}/../../include -DSCRIPT_FILE=\"$remote_guile_file\""]] == -1} {
+ return
+}
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_test_no_output "set auto-load safe-path ${remote_guile_file}" \
+ "set auto-load safe-path"
+gdb_load ${binfile}
+
+# Verify gdb loaded the script.
+gdb_test "info auto-load guile-scripts" "Yes.*${testfile}.scm.*"
+# Again, with a regexp this time.
+gdb_test "info auto-load guile-scripts ${testfile}" "Yes.*${testfile}.scm.*"
+# Again, with a regexp that matches no scripts.
+gdb_test "info auto-load guile-scripts no-script-matches-this" \
+ "No auto-load scripts matching no-script-matches-this."
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
+ ".*Breakpoint.*"
+gdb_test "continue" ".*Breakpoint.*"
+
+gdb_test "print ss" " = a=<1> b=<2>"
diff --git a/gdb/testsuite/gdb.guile/scm-section-script.scm b/gdb/testsuite/gdb.guile/scm-section-script.scm
new file mode 100644
index 0000000..cd31db9
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-section-script.scm
@@ -0,0 +1,55 @@
+;; Copyright (C) 2010-2014 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/>.
+
+;; This file is part of the GDB testsuite.
+
+(use-modules (gdb) (gdb printing))
+
+(define (make-pp_ss-printer val)
+ (make-pretty-printer-worker
+ #f
+ (lambda (printer)
+ (let ((a (value-field val "a"))
+ (b (value-field val "b")))
+ (format #f "a=<~A> b=<~A>" a b)))
+ #f))
+
+(define (get-type-for-printing val)
+ "Return type of val, stripping away typedefs, etc."
+ (let ((type (value-type val)))
+ (if (= (type-code type) TYPE_CODE_REF)
+ (set! type (type-target type)))
+ (type-strip-typedefs (type-unqualified type))))
+
+(define (make-pretty-printer-dict)
+ (let ((dict (make-hash-table)))
+ (hash-set! dict "struct ss" make-pp_ss-printer)
+ (hash-set! dict "ss" make-pp_ss-printer)
+ dict))
+
+(define *pretty-printer*
+ (make-pretty-printer
+ "pretty-printer-test"
+ (let ((pretty-printers-dict (make-pretty-printer-dict)))
+ (lambda (matcher val)
+ "Look-up and return a pretty-printer that can print val."
+ (let ((type (get-type-for-printing val)))
+ (let ((typename (type-tag type)))
+ (if typename
+ (let ((printer-maker (hash-ref pretty-printers-dict typename)))
+ (and printer-maker (printer-maker val)))
+ #f)))))))
+
+(append-pretty-printer! #f *pretty-printer*)
diff --git a/gdb/testsuite/gdb.guile/scm-symbol.c b/gdb/testsuite/gdb.guile/scm-symbol.c
new file mode 100644
index 0000000..3201365
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-symbol.c
@@ -0,0 +1,69 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2014 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/>. */
+
+#ifdef __cplusplus
+class SimpleClass
+{
+ private:
+ int i;
+
+ public:
+ void seti (int arg)
+ {
+ i = arg;
+ }
+
+ int valueofi (void)
+ {
+ return i; /* Break in class. */
+ }
+};
+#endif
+
+int qq = 72; /* line of qq */
+
+int func (int arg)
+{
+ int i = 2;
+ i = i * arg; /* Block break here. */
+ return arg;
+}
+
+struct simple_struct
+{
+ int a;
+};
+
+int main (int argc, char *argv[])
+{
+#ifdef __cplusplus
+ SimpleClass sclass;
+#endif
+ int a = 0;
+ int result;
+ struct simple_struct ss = { 10 };
+ enum tag {one, two, three};
+ enum tag t = one;
+
+ result = func (42);
+
+#ifdef __cplusplus
+ sclass.seti (42);
+ sclass.valueofi ();
+#endif
+ return 0; /* Break at end. */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-symbol.exp b/gdb/testsuite/gdb.guile/scm-symbol.exp
new file mode 100644
index 0000000..5d25c53
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-symbol.exp
@@ -0,0 +1,196 @@
+# Copyright (C) 2010-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the mechanism exposing symbols to Guile.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} {
+ return -1
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+# These tests are done before we call gdb_guile_runto_main so we have to
+# import the gdb module ourselves.
+gdb_install_guile_utils
+gdb_install_guile_module
+
+# Test looking up a global symbol before we runto_main as this is the
+# point where we don't have a current frame, and we don't want to
+# require one.
+gdb_scm_test_silent_cmd "guile (define main-func (lookup-global-symbol \"main\"))" \
+ "lookup main"
+gdb_test "guile (print (symbol-function? main-func))" \
+ "= #t" "test (symbol-function? main)"
+gdb_test "guile (print (lookup-global-symbol \"junk\"))" \
+ "= #f" "test (lookup-global-symbol junk)"
+
+gdb_test "guile (print (symbol-value main-func))" \
+ "= {int \\(int, char \[*\]\[*\]\\)} $hex \\<main\\>" "print value of main"
+
+set qq_line [gdb_get_line_number "line of qq"]
+gdb_scm_test_silent_cmd "guile (define qq-var (lookup-global-symbol \"qq\"))" \
+ "lookup qq"
+gdb_test "guile (print (symbol-line qq-var))" \
+ "= $qq_line" "print line number of qq"
+gdb_test "guile (print (symbol-value qq-var))" \
+ "= 72" "print value of qq"
+gdb_test "guile (print (symbol-needs-frame? qq-var))" \
+ "= #f" "print whether qq needs a frame"
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+# Test symbol eq? and equal?.
+gdb_test "guile (print (eq? (lookup-global-symbol \"main\") (lookup-global-symbol \"main\")))" \
+ "= #t"
+gdb_test "guile (print (equal? (lookup-global-symbol \"main\") (lookup-global-symbol \"main\")))" \
+ "= #t"
+
+gdb_breakpoint [gdb_get_line_number "Block break here."]
+gdb_continue_to_breakpoint "Block break here."
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \
+ "get frame at block break"
+gdb_scm_test_silent_cmd "guile (define block (frame-block frame))" \
+ "get block at block break"
+
+# Test symbol-argument?.
+gdb_scm_test_silent_cmd "guile (define arg (car (lookup-symbol \"arg\")))" \
+ "get variable arg"
+gdb_test "guile (print (symbol-variable? arg))" "= #f"
+gdb_test "guile (print (symbol-constant? arg))" "= #f"
+gdb_test "guile (print (symbol-argument? arg))" "= #t"
+gdb_test "guile (print (symbol-function? arg))" "= #f"
+
+# Test symbol-function?.
+gdb_scm_test_silent_cmd "guile (define func (block-function block))" \
+ "get block function"
+gdb_test "guile (print (symbol-variable? func))" "= #f"
+gdb_test "guile (print (symbol-constant? func))" "= #f"
+gdb_test "guile (print (symbol-argument? func))" "= #f"
+gdb_test "guile (print (symbol-function? func))" "= #t"
+
+# Test attributes of func.
+gdb_test "guile (print (symbol-name func))" "func"
+gdb_test "guile (print (symbol-print-name func))" "func"
+gdb_test "guile (print (symbol-linkage-name func))" "func"
+gdb_test "guile (print (= (symbol-addr-class func) SYMBOL_LOC_BLOCK))" "= #t"
+
+gdb_breakpoint [gdb_get_line_number "Break at end."]
+gdb_continue_to_breakpoint "Break at end."
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \
+ "get frame at end"
+
+# Test symbol-variable?.
+gdb_scm_test_silent_cmd "guile (define a (car (lookup-symbol \"a\")))" \
+ "get variable a"
+gdb_test "guile (print (symbol-variable? a))" "= #t"
+gdb_test "guile (print (symbol-constant? a))" "= #f"
+gdb_test "guile (print (symbol-argument? a))" "= #f"
+gdb_test "guile (print (symbol-function? a))" "= #f"
+
+# Test attributes of a.
+gdb_test "guile (print (= (symbol-addr-class a) SYMBOL_LOC_COMPUTED))" "= #t"
+
+gdb_test "guile (print (symbol-value a))" \
+ "ERROR: Symbol requires a frame to compute its value.*"\
+ "try to print value of a without a frame"
+gdb_test "guile (print (symbol-value a #:frame frame))" \
+ "= 0" "print value of a"
+gdb_test "guile (print (symbol-needs-frame? a))" \
+ "= #t" "print whether a needs a frame"
+
+# Test symbol-constant?.
+gdb_scm_test_silent_cmd "guile (define t (car (lookup-symbol \"one\")))" \
+ "get constant t"
+gdb_test "guile (print (symbol-variable? t))" "= #f"
+gdb_test "guile (print (symbol-constant? t))" "= #t"
+gdb_test "guile (print (symbol-argument? t))" "= #f"
+gdb_test "guile (print (symbol-function? t))" "= #f"
+
+# Test attributes of t.
+gdb_test "guile (print (= (symbol-addr-class t) SYMBOL_LOC_CONST))" "= #t"
+
+# Test type attribute.
+gdb_test "guile (print (symbol-type t))" "= enum tag"
+
+# Test symtab attribute.
+gdb_test "guile (print (symbol-symtab t))" "= #<gdb:symtab .*gdb.guile/scm-symbol.c>"
+
+# C++ tests
+# Recompile binary.
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-cxx" executable "debug c++"] != "" } {
+ untested "Couldn't compile ${srcfile} in c++ mode"
+ return -1
+}
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}-cxx
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_breakpoint [gdb_get_line_number "Break in class."]
+gdb_continue_to_breakpoint "Break in class."
+
+gdb_scm_test_silent_cmd "guile (define cplusframe (selected-frame))" \
+ "get frame at class"
+gdb_scm_test_silent_cmd "guile (define cplusfunc (block-function (frame-block cplusframe)))" \
+ "get function at class"
+
+gdb_test "guile (print (symbol-variable? cplusfunc))" "= #f"
+gdb_test "guile (print (symbol-constant? cplusfunc))" "= #f"
+gdb_test "guile (print (symbol-argument? cplusfunc))" "= #f"
+gdb_test "guile (print (symbol-function? cplusfunc))" "= #t"
+
+gdb_test "guile (print (symbol-name cplusfunc))" \
+ "= SimpleClass::valueofi().*" "test method.name"
+gdb_test "guile (print (symbol-print-name cplusfunc))" \
+ "= SimpleClass::valueofi().*" "test method.print_name"
+# FIXME: GDB is broken here and we're verifying broken behaviour.
+# (linkage-name should be the mangled name)
+gdb_test "guile (print (symbol-linkage-name cplusfunc))" \
+ "SimpleClass::valueofi().*" "test method.linkage_name"
+gdb_test "guile (print (= (symbol-addr-class cplusfunc) SYMBOL_LOC_BLOCK))" "= #t"
+
+# Test is_valid when the objfile is unloaded. This must be the last
+# test as it unloads the object file in GDB.
+# Start with a fresh gdb.
+clean_restart ${testfile}
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_breakpoint [gdb_get_line_number "Break at end."]
+gdb_continue_to_breakpoint "Break at end."
+gdb_scm_test_silent_cmd "guile (define a (car (lookup-symbol \"a\")))" \
+ "get variable a for unload"
+gdb_test "guile (print (symbol-valid? a))" \
+ "= #t" "test symbol validity pre-unload"
+delete_breakpoints
+gdb_unload
+gdb_test "guile (print (symbol-valid? a))" \
+ "= #f" "test symbol validity post-unload"
+gdb_test_no_output "guile (set! a #f) (gc)" "test symbol destructor"
diff --git a/gdb/testsuite/gdb.guile/scm-symtab-2.c b/gdb/testsuite/gdb.guile/scm-symtab-2.c
new file mode 100644
index 0000000..d45aa6c
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-symtab-2.c
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2014 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/>. */
+
+void
+func1 ()
+{
+ return;
+}
+
+int
+func2 ()
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.guile/scm-symtab.c b/gdb/testsuite/gdb.guile/scm-symtab.c
new file mode 100644
index 0000000..e4662cd
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-symtab.c
@@ -0,0 +1,45 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2014 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/>. */
+
+/* In scm-symtab-2.c. */
+extern void func1 (void);
+extern int func2 (void);
+
+struct simple_struct
+{
+ int a;
+};
+
+struct simple_struct qq;
+
+int
+func (int arg)
+{
+ int i = 2;
+ i = i * arg; /* Block break here. */
+ return arg;
+}
+
+int
+main (int argc, char *argv[])
+{
+ qq.a = func (42);
+
+ func1 ();
+ func2 (); /* Break at func2 call site. */
+ return 0; /* Break to end. */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-symtab.exp b/gdb/testsuite/gdb.guile/scm-symtab.exp
new file mode 100644
index 0000000..4309ae6
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-symtab.exp
@@ -0,0 +1,142 @@
+# Copyright (C) 2010-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the Guile symbol table support.
+
+load_lib gdb-guile.exp
+
+standard_testfile scm-symtab.c scm-symtab-2.c
+
+if {[prepare_for_testing $testfile.exp $testfile \
+ [list $srcfile $srcfile2] debug]} {
+ return
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+# Setup and get the symbol table.
+set line_no [gdb_get_line_number "Block break here."]
+gdb_breakpoint $line_no
+gdb_continue_to_breakpoint "Block break here."
+gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \
+ "get frame"
+gdb_scm_test_silent_cmd "guile (define sal (frame-sal frame))" \
+ "get sal"
+gdb_scm_test_silent_cmd "guile (define symtab (sal-symtab sal))" \
+ "get symtab"
+gdb_scm_test_silent_cmd "guile (define global-block (symtab-global-block symtab))" \
+ "get global block"
+gdb_scm_test_silent_cmd "guile (define static-block (symtab-static-block symtab))" \
+ "get static block"
+
+gdb_scm_test_silent_cmd "guile (define global-symbols (map symbol-name (block-symbols global-block)))" \
+ "get global symbol names"
+gdb_scm_test_silent_cmd "guile (define static-symbols (map symbol-name (block-symbols static-block)))" \
+ "get static symbol names"
+gdb_scm_test_silent_cmd "guile (define global-isymbols '()) (define static-isymbols '())" \
+ "set up iterated symbol name lists"
+# TODO: iterated symbols
+gdb_scm_test_silent_cmd "step" "Step to the next line"
+gdb_scm_test_silent_cmd "guile (define new-pc (sal-pc (frame-sal (selected-frame))))" \
+ "get new pc"
+
+# Test sal.
+gdb_test "guile (print (sal-symtab sal))" \
+ ".*gdb.guile/scm-symtab.c.*" "Test sal-symtab"
+gdb_test "guile (print (sal-pc sal))" \
+ "${decimal}" "test sal-pc"
+gdb_test "guile (print (= (sal-last sal) (- new-pc 1)))" \
+ "#t" "test sal-last"
+gdb_test "guile (print (sal-line sal))" \
+ "$line_no" "test sal-line"
+gdb_test "guile (print (sal-valid? sal))" \
+ "#t" "test sal-valid?"
+
+# Test eq? on symtabs.
+gdb_scm_test_silent_cmd "guile (define sal1 (frame-sal frame))" \
+ "get sal1"
+gdb_scm_test_silent_cmd "guile (define sal2 (frame-sal (frame-older frame)))" \
+ "get sal2"
+gdb_test "guile (print (eq? symtab (sal-symtab sal1)))" \
+ "= #t" "test eq? of equal symtabs"
+gdb_test "guile (print (eq? symtab (sal-symtab sal2)))" \
+ "= #t" "test eq? of equal symtabs from different sals"
+gdb_test "guile (print (eq? symtab (symbol-symtab (lookup-global-symbol \"func1\"))))" \
+ "= #f" "test eq? of not-equal symtabs"
+
+# Test symbol table.
+gdb_test "guile (print (symtab-filename symtab))" \
+ ".*gdb.guile/scm-symtab.c.*" "test symtab-filename"
+gdb_test "guile (print (symtab-objfile symtab))" \
+ "#<gdb:objfile .*scm-symtab>" "test symtab-objfile"
+gdb_test "guile (print (symtab-fullname symtab))" \
+ "testsuite/gdb.guile/scm-symtab.c.*" "test symtab-fullname"
+gdb_test "guile (print (symtab-valid? symtab))" \
+ "#t" "test symtab-valid?"
+gdb_test "guile (print (->bool (member \"qq\" global-symbols)))" \
+ "#t" "test qq in global symbols"
+gdb_test "guile (print (->bool (member \"func\" global-symbols)))" \
+ "#t" "test func in global symbols"
+gdb_test "guile (print (->bool (member \"main\" global-symbols)))" \
+ "#t" "test main in global symbols"
+gdb_test "guile (print (->bool (member \"int\" static-symbols)))" \
+ "#t" "test int in static symbols"
+gdb_test "guile (print (->bool (member \"char\" static-symbols)))" \
+ "#t" "test char in static symbols"
+gdb_test "guile (print (->bool (member \"simple_struct\" static-symbols)))" \
+ "#t" "test simple_struct in static symbols"
+
+# Test is_valid when the objfile is unloaded. This must be the last
+# test as it unloads the object file in GDB.
+gdb_unload
+gdb_test "guile (print (sal-valid? sal))" \
+ "#f" "test sal-valid? after unloading"
+gdb_test "guile (print (symtab-valid? symtab))" \
+ "#f" "test symtab-valid? after unloading"
+
+gdb_test_no_output "guile (set! sal #f)" \
+ "test sal destructor"
+gdb_test_no_output "guile (set! symtab #f)" \
+ "test symtab destructor"
+gdb_test_no_output "guile (gc)" "GC to trigger destructors"
+
+# Start with a fresh gdb.
+clean_restart ${testfile}
+
+# Test find-pc-line.
+# The following tests require execution.
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+runto [gdb_get_line_number "Break at func2 call site."]
+
+gdb_scm_test_silent_cmd "guile (define line (sal-line (frame-sal (selected-frame))))" \
+ "get line number of func2 call site"
+gdb_test "guile (print (= (sal-line (find-pc-line (frame-pc (selected-frame)))) line))" \
+ "#t" "test find-pc-line at func2 call site"
+
+gdb_scm_test_silent_cmd "step" "step into func2"
+gdb_scm_test_silent_cmd "up" "step out of func2"
+
+gdb_test "guile (print (> (sal-line (find-pc-line (frame-pc (selected-frame)))) line))" \
+ "#t" "test find-pc-line with resume address"
diff --git a/gdb/testsuite/gdb.guile/scm-type.c b/gdb/testsuite/gdb.guile/scm-type.c
new file mode 100644
index 0000000..7cee383
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-type.c
@@ -0,0 +1,77 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009-2014 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/>. */
+
+struct s
+{
+ int a;
+ int b;
+};
+
+typedef struct s TS;
+TS ts;
+
+#ifdef __cplusplus
+struct C
+{
+ int c;
+ int d;
+};
+
+struct D : C
+{
+ int e;
+ int f;
+};
+
+template<typename T, int I, int C::*MP>
+struct Temargs
+{
+};
+
+Temargs<D, 23, &C::c> temvar;
+
+#endif
+
+enum E
+{ v1, v2, v3
+};
+
+struct s vec_data_1 = {1, 1};
+struct s vec_data_2 = {1, 2};
+
+int
+main ()
+{
+ int ar[2] = {1,2};
+ struct s st;
+#ifdef __cplusplus
+ C c;
+ c.c = 1;
+ c.d = 2;
+ D d;
+ d.e = 3;
+ d.f = 4;
+#endif
+ enum E e;
+
+ st.a = 3;
+ st.b = 5;
+
+ e = v2;
+
+ return 0; /* break to inspect struct and array. */
+}
diff --git a/gdb/testsuite/gdb.guile/scm-type.exp b/gdb/testsuite/gdb.guile/scm-type.exp
new file mode 100644
index 0000000..4a3969e
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-type.exp
@@ -0,0 +1,299 @@
+# Copyright (C) 2009-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the mechanism of exposing types to Guile.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+if [get_compiler_info c++] {
+ return -1
+}
+
+# Build inferior to language specification.
+
+proc build_inferior {exefile lang} {
+ global srcdir subdir srcfile
+
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${exefile}" executable "debug $lang"] != "" } {
+ untested "Couldn't compile ${srcfile} in $lang mode"
+ return -1
+ }
+ return 0
+}
+
+# Restart GDB.
+# The result is the same as gdb_guile_runto_main.
+
+proc restart_gdb {exefile} {
+ global srcdir subdir
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${exefile}
+
+ if { [skip_guile_tests] } {
+ return 0
+ }
+
+ if ![gdb_guile_runto_main] {
+ return 0
+ }
+ gdb_scm_test_silent_cmd "guile (use-modules (gdb iterator))" \
+ "load iterator module"
+
+ return 1
+}
+
+# Set breakpoint and run to that breakpoint.
+
+proc runto_bp {bp} {
+ gdb_breakpoint [gdb_get_line_number $bp]
+ gdb_continue_to_breakpoint $bp
+}
+
+proc test_fields {lang} {
+ with_test_prefix "test_fields" {
+ global gdb_prompt
+
+ # fields of a typedef should still return the underlying field list
+ gdb_test "guile (print (length (type-fields (value-type (parse-and-eval \"ts\")))))" \
+ "= 2" "$lang typedef field list"
+
+ if {$lang == "c++"} {
+ # Test usage with a class.
+ gdb_scm_test_silent_cmd "print c" "print value (c)"
+ gdb_scm_test_silent_cmd "guile (define c (history-ref 0))" \
+ "get value (c) from history"
+ gdb_scm_test_silent_cmd "guile (define fields (type-fields (value-type c)))" \
+ "get fields from c type"
+ gdb_test "guile (print (length fields))" \
+ "= 2" "check number of fields of c"
+ gdb_test "guile (print (field-name (car fields)))" \
+ "= c" "check class field c name"
+ gdb_test "guile (print (field-name (cadr fields)))" \
+ "= d" "check class field d name"
+ }
+
+ # Test normal fields usage in structs.
+ gdb_scm_test_silent_cmd "print st" "print value (st)"
+ gdb_scm_test_silent_cmd "guile (define st (history-ref 0))" \
+ "get value (st) from history"
+ gdb_scm_test_silent_cmd "guile (define st-type (value-type st))" \
+ "get st-type"
+ gdb_scm_test_silent_cmd "guile (define fields (type-fields st-type))" \
+ "get fields from st.type"
+ gdb_test "guile (print (length fields))" \
+ "= 2" "check number of fields (st)"
+ gdb_test "guile (print (field-name (car fields)))" \
+ "= a" "check structure field a name"
+ gdb_test "guile (print (field-name (cadr fields)))" \
+ "= b" "check structure field b name"
+ gdb_test "guile (print (field-name (type-field st-type \"a\")))" \
+ "= a" "check fields lookup by name"
+
+ # Test has-field?
+ gdb_test "guile (print (type-has-field? st-type \"b\"))" \
+ "= #t" "check existent field"
+ gdb_test "guile (print (type-has-field? st-type \"nosuch\"))" \
+ "= #f" "check non-existent field"
+
+ # Test Guile mapping behavior of gdb:type for structs/classes.
+ gdb_test "guile (print (type-num-fields (value-type st)))" \
+ "= 2" "check number of fields (st) with type-num-fields"
+ gdb_scm_test_silent_cmd "guile (define fi (make-field-iterator st-type))" \
+ "create field iterator"
+ gdb_test "guile (print (iterator-map field-bitpos fi))" \
+ "= \\(0 32\\)" "check field iterator"
+
+ # Test rejection of mapping operations on scalar types.
+ gdb_test "guile (print (make-field-iterator (field-type (type-field st-type \"a\"))))" \
+ "ERROR: .*: Out of range: type is not a structure, union, or enum type in position 1: .*" \
+ "check field iterator on bad type"
+
+ # Test type-array.
+ gdb_scm_test_silent_cmd "print ar" "print value (ar)"
+ gdb_scm_test_silent_cmd "guile (define ar (history-ref 0))" \
+ "get value (ar) from history"
+ gdb_scm_test_silent_cmd "guile (define ar0 (value-subscript ar 0))" \
+ "define ar0"
+ gdb_test "guile (print (value-cast ar0 (type-array (value-type ar0) 1)))" \
+ "= \\{1, 2\\}" "cast to array with one argument"
+ gdb_test "guile (print (value-cast ar0 (type-array (value-type ar0) 0 1)))" \
+ "= \\{1, 2\\}" "cast to array with two arguments"
+
+ # Test type-vector.
+ # Note: vectors cast differently than arrays. Here ar[0] is replicated
+ # for the size of the vector.
+ gdb_scm_test_silent_cmd "print vec_data_1" "print value (vec_data_1)"
+ gdb_scm_test_silent_cmd "guile (define vec_data_1 (history-ref 0))" \
+ "get value (vec_data_1) from history"
+
+ gdb_scm_test_silent_cmd "print vec_data_2" "print value (vec_data_2)"
+ gdb_scm_test_silent_cmd "guile (define vec_data_2 (history-ref 0))" \
+ "get value (vec_data_2) from history"
+
+ gdb_scm_test_silent_cmd "guile (define vec1 (value-cast vec_data_1 (type-vector (value-type ar0) 1)))" \
+ "set vec1"
+ gdb_test "guile (print vec1)" \
+ "= \\{1, 1\\}" "cast to vector with one argument"
+ gdb_scm_test_silent_cmd "guile (define vec2 (value-cast vec_data_1 (type-vector (value-type ar0) 0 1)))" \
+ "set vec2"
+ gdb_test "guile (print vec2)" \
+ "= \\{1, 1\\}" "cast to vector with two arguments"
+ gdb_test "guile (print (value=? vec1 vec2))" \
+ "= #t"
+ gdb_scm_test_silent_cmd "guile (define vec3 (value-cast vec_data_2 (type-vector (value-type ar0) 1)))" \
+ "set vec3"
+ gdb_test "guile (print (value=? vec1 vec3))" \
+ "= #f"
+ }
+}
+
+proc test_equality {lang} {
+ with_test_prefix "test_equality" {
+ gdb_scm_test_silent_cmd "guile (define st (parse-and-eval \"st\"))" \
+ "get st"
+ gdb_scm_test_silent_cmd "guile (define ar (parse-and-eval \"ar\"))" \
+ "get ar"
+ gdb_test "guile (print (eq? (value-type st) (value-type st)))" \
+ "= #t" "test type eq? on equal types"
+ gdb_test "guile (print (eq? (value-type st) (value-type ar)))" \
+ "= #f" "test type eq? on not-equal types"
+ gdb_test "guile (print (equal? (value-type st) (value-type st)))" \
+ "= #t" "test type eq? on equal types"
+ gdb_test "guile (print (equal? (value-type st) (value-type ar)))" \
+ "= #f" "test type eq? on not-equal types"
+
+ if {$lang == "c++"} {
+ gdb_scm_test_silent_cmd "guile (define c (parse-and-eval \"c\"))" \
+ "get c"
+ gdb_scm_test_silent_cmd "guile (define d (parse-and-eval \"d\"))" \
+ "get d"
+ gdb_test "guile (print (eq? (value-type c) (field-type (car (type-fields (value-type d))))))" \
+ "= #t" "test c++ type eq? on equal types"
+ gdb_test "guile (print (eq? (value-type c) (value-type d)))" \
+ "= #f" "test c++ type eq? on not-equal types"
+ gdb_test "guile (print (equal? (value-type c) (field-type (car (type-fields (value-type d))))))" \
+ "= #t" "test c++ type equal? on equal types"
+ gdb_test "guile (print (equal? (value-type c) (value-type d)))" \
+ "= #f" "test c++ type equal? on not-equal types"
+ }
+ }
+}
+
+proc test_enums {} {
+ with_test_prefix "test_enum" {
+ gdb_scm_test_silent_cmd "print e" "print value (e)"
+ gdb_scm_test_silent_cmd "guile (define e (history-ref 0))" \
+ "get value (e) from history"
+ gdb_scm_test_silent_cmd "guile (define fields (type-fields (value-type e)))" \
+ "extract type fields from e"
+ gdb_test "guile (print (length fields))" \
+ "= 3" "check the number of enum fields"
+ gdb_test "guile (print (field-name (car fields)))" \
+ "= v1" "check enum field\[0\] name"
+ gdb_test "guile (print (field-name (cadr fields)))" \
+ "= v2" "check enum field\[1\]name"
+
+ # Ditto but by mapping operations.
+ gdb_test "guile (print (type-num-fields (value-type e)))" \
+ "= 3" "check the number of enum values"
+ gdb_test "guile (print (field-name (type-field (value-type e) \"v1\")))" \
+ "= v1" "check enum field lookup by name (v1)"
+ gdb_test "guile (print (field-name (type-field (value-type e) \"v3\")))" \
+ "= v3" "check enum field lookup by name (v3)"
+ gdb_test "guile (print (iterator-map field-enumval (make-field-iterator (value-type e))))" \
+ "\\(0 1 2\\)" "check enum fields iteration"
+ }
+}
+
+proc test_base_class {} {
+ with_test_prefix "test_base_class" {
+ gdb_scm_test_silent_cmd "print d" "print value (d)"
+ gdb_scm_test_silent_cmd "guile (define d (history-ref 0))" \
+ "get value (d) from history"
+ gdb_scm_test_silent_cmd "guile (define fields (type-fields (value-type d)))" \
+ "extract type fields from d"
+ gdb_test "guile (print (length fields))" \
+ "= 3" "check the number of fields"
+ gdb_test "guile (print (field-baseclass? (car fields)))" \
+ "= #t" "check base class (fields\[0\])"
+ gdb_test "guile (print (field-baseclass? (cadr fields)))" \
+ "= #f" "check base class (fields\[1\])"
+ }
+}
+
+proc test_range {} {
+ with_test_prefix "test_range" {
+ with_test_prefix "on ranged value" {
+ # Test a valid range request.
+ gdb_scm_test_silent_cmd "print ar" "print value (ar)"
+ gdb_scm_test_silent_cmd "guile (define ar (history-ref 0))" \
+ "get value (ar) from history"
+ gdb_test "guile (print (length (type-range (value-type ar))))" \
+ "= 2" "check correct tuple length"
+ gdb_test "guile (print (type-range (value-type ar)))" \
+ "= \\(0 1\\)" "check range"
+ }
+
+ with_test_prefix "on unranged value" {
+ # Test where a range does not exist.
+ gdb_scm_test_silent_cmd "print st" "print value (st)"
+ gdb_scm_test_silent_cmd "guile (define st (history-ref 0))" \
+ "get value (st) from history"
+ gdb_test "guile (print (type-range (value-type st)))" \
+ "ERROR: .*: Wrong type argument in position 1 \\(expecting ranged type\\): .*" \
+ "check range for non ranged type"
+ }
+ }
+}
+
+# Perform C Tests.
+
+if { [build_inferior "${binfile}" "c"] < 0 } {
+ return
+}
+if ![restart_gdb "${binfile}"] {
+ return
+}
+
+with_test_prefix "lang_c" {
+ runto_bp "break to inspect struct and array."
+ test_fields "c"
+ test_equality "c"
+ test_enums
+}
+
+# Perform C++ Tests.
+
+if { [build_inferior "${binfile}-cxx" "c++"] < 0 } {
+ return
+}
+if ![restart_gdb "${binfile}-cxx"] {
+ return
+}
+
+with_test_prefix "lang_cpp" {
+ runto_bp "break to inspect struct and array."
+ test_fields "c++"
+ test_base_class
+ test_range
+ test_equality "c++"
+ test_enums
+}
diff --git a/gdb/testsuite/gdb.guile/scm-value-cc.cc b/gdb/testsuite/gdb.guile/scm-value-cc.cc
new file mode 100644
index 0000000..df19f0b
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-value-cc.cc
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2012-2014 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/>. */
+
+class A {
+};
+
+typedef int *int_ptr;
+
+int
+func (const A &a)
+{
+ int val = 10;
+ int &int_ref = val;
+ int_ptr ptr = &val;
+ int_ptr &int_ptr_ref = ptr;
+
+ return 0; /* Break here. */
+}
+
+int
+main ()
+{
+ A obj;
+ return func (obj);
+}
diff --git a/gdb/testsuite/gdb.guile/scm-value-cc.exp b/gdb/testsuite/gdb.guile/scm-value-cc.exp
new file mode 100644
index 0000000..685deb1
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-value-cc.exp
@@ -0,0 +1,57 @@
+# Copyright (C) 2012-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the mechanism exposing c++ values to Guile.
+
+load_lib gdb-guile.exp
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+ return
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_breakpoint [gdb_get_line_number "Break here."]
+gdb_continue_to_breakpoint "Break here" ".*Break here.*"
+
+gdb_test "gu (print (value-type (parse-and-eval \"a\")))" \
+ "= const A &"
+gdb_test "gu (print (value-type (value-referenced-value (parse-and-eval \"a\"))))" \
+ "= const A"
+gdb_test "gu (print (value-type (parse-and-eval \"int_ref\")))" \
+ "= int &"
+gdb_test "gu (print (value-type (value-referenced-value (parse-and-eval \"int_ref\"))))" \
+ "= int"
+gdb_test "gu (print (value-referenced-value (parse-and-eval \"int_ref\")))" \
+ "= 10"
+
+gdb_test "gu (print (value-type (value-dereference (parse-and-eval \"int_ptr_ref\"))))" \
+ "= int"
+gdb_test "gu (print (value-type (value-referenced-value (parse-and-eval \"int_ptr_ref\"))))" \
+ "= int_ptr"
+gdb_test "gu (print (value-dereference (value-referenced-value (parse-and-eval \"int_ptr_ref\"))))" \
+ "= 10"
+gdb_test "gu (print (value-referenced-value (value-referenced-value (parse-and-eval \"int_ptr_ref\"))))" \
+ "= 10"
diff --git a/gdb/testsuite/gdb.guile/scm-value.c b/gdb/testsuite/gdb.guile/scm-value.c
new file mode 100644
index 0000000..3c61911
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-value.c
@@ -0,0 +1,101 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008-2014 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/>. */
+
+#include <stdio.h>
+
+struct s
+{
+ int a;
+ int b;
+};
+
+union u
+{
+ int a;
+ float b;
+};
+
+enum e
+ {
+ ONE = 1,
+ TWO = 2
+ };
+
+typedef struct s *PTR;
+
+enum e evalue = TWO;
+
+#ifdef __cplusplus
+
+struct Base {
+ virtual int x() { return 5; }
+};
+
+struct Derived : public Base {
+};
+
+Base *base = new Derived ();
+
+void ptr_ref(int*& rptr_int)
+{
+ return; /* break to inspect pointer by reference. */
+}
+#endif
+
+void func1 ()
+{
+ printf ("void function called\n");
+}
+
+int func2 (int arg1, int arg2)
+{
+ return arg1 + arg2;
+}
+
+char **save_argv;
+
+int
+main (int argc, char *argv[])
+{
+ char *cp = argv[0]; /* Prevent gcc from optimizing argv[] out. */
+ struct s s;
+ union u u;
+ PTR x = &s;
+ char st[17] = "divide et impera";
+ char nullst[17] = "divide\0et\0impera";
+ void (*fp1) (void) = &func1;
+ int (*fp2) (int, int) = &func2;
+ const char *sptr = "pointer";
+ const char *embed = "embedded x\201\202\203\204";
+ int a[3] = {1,2,3};
+ int *p = a;
+ int i = 2;
+ int *ptr_i = &i;
+ const char *sn = 0;
+ s.a = 3;
+ s.b = 5;
+ u.a = 7;
+ (*fp1) ();
+ (*fp2) (10,20);
+
+#ifdef __cplusplus
+ ptr_ref(ptr_i);
+#endif
+
+ save_argv = argv; /* break to inspect struct and union */
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.guile/scm-value.exp b/gdb/testsuite/gdb.guile/scm-value.exp
new file mode 100644
index 0000000..3ebdd58
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/scm-value.exp
@@ -0,0 +1,449 @@
+# Copyright (C) 2008-2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the mechanism exposing values to Guile.
+
+load_lib gdb-guile.exp
+
+standard_testfile
+
+# Build inferior to language specification.
+# LANG is one of "c" or "c++".
+proc build_inferior {exefile lang} {
+ global srcdir subdir srcfile testfile hex
+
+ # Use different names for .o files based on the language.
+ # For Fission, the debug info goes in foo.dwo and we don't want,
+ # for example, a C++ compile to clobber the dwo of a C compile.
+ # ref: http://gcc.gnu.org/wiki/DebugFission
+ switch ${lang} {
+ "c" { set filename ${testfile}.o }
+ "c++" { set filename ${testfile}-cxx.o }
+ }
+ set objfile [standard_output_file $filename]
+
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object "debug $lang"] != ""
+ || [gdb_compile "${objfile}" "${exefile}" executable "debug $lang"] != "" } {
+ untested "Couldn't compile ${srcfile} in $lang mode"
+ return -1
+ }
+ return 0
+}
+
+proc test_value_in_inferior {} {
+ global gdb_prompt
+ global testfile
+
+ gdb_breakpoint [gdb_get_line_number "break to inspect struct and union"]
+
+ gdb_continue_to_breakpoint "break to inspect struct and union"
+
+ # Just get inferior variable s in the value history, available to guile.
+ gdb_test "print s" "= {a = 3, b = 5}" ""
+
+ gdb_scm_test_silent_cmd "gu (define s (history-ref 0))" "set s"
+
+ gdb_test "gu (print (value-field s \"a\"))" \
+ "= 3" "access element inside struct using string name"
+
+ # Test dereferencing the argv pointer.
+
+ # Just get inferior variable argv the value history, available to guile.
+ gdb_test "print argv" "= \\(char \\*\\*\\) 0x.*" ""
+
+ gdb_scm_test_silent_cmd "gu (define argv (history-ref 0))" \
+ "set argv"
+ gdb_scm_test_silent_cmd "gu (define arg0 (value-dereference argv))" \
+ "set arg0"
+
+ # Check that the dereferenced value is sane.
+ if { ! [target_info exists noargs] } {
+ gdb_test "gu (print arg0)" \
+ "0x.*$testfile\"" "verify dereferenced value"
+ }
+
+ # Smoke-test value-optimized-out?.
+ gdb_test "gu (print (value-optimized-out? arg0))" \
+ "= #f" "Test value-optimized-out?"
+
+ # Test address attribute.
+ gdb_test "gu (print (value-address arg0))" \
+ "= 0x\[\[:xdigit:\]\]+" "Test address attribute"
+ # Test address attribute is #f in a non-addressable value.
+ gdb_test "gu (print (value-address (make-value 42)))" \
+ "= #f" "Test address attribute in non-addressable value"
+
+ # Test displaying a variable that is temporarily at a bad address.
+ # But if we can examine what's at memory address 0, then we'll also be
+ # able to display it without error. Don't run the test in that case.
+ set can_read_0 0
+ gdb_test_multiple "x 0" "memory at address 0" {
+ -re "0x0:\[ \t\]*Cannot access memory at address 0x0\r\n$gdb_prompt $" { }
+ -re "0x0:\[ \t\]*Error accessing memory address 0x0\r\n$gdb_prompt $" { }
+ -re "\r\n$gdb_prompt $" {
+ set can_read_0 1
+ }
+ }
+
+ # Test memory error.
+ set test "parse_and_eval with memory error"
+ if {$can_read_0} {
+ untested $test
+ } else {
+ gdb_test "gu (print (parse-and-eval \"*(int*)0\"))" \
+ "ERROR: Cannot access memory at address 0x0.*" $test
+ }
+
+ # Test Guile lazy value handling
+ set test "memory error and lazy values"
+ if {$can_read_0} {
+ untested $test
+ } else {
+ gdb_test_no_output "gu (define inval (parse-and-eval \"*(int*)0\"))"
+ gdb_test "gu (print (value-lazy? inval))" \
+ "#t"
+ gdb_test "gu (define inval2 (value-add inval 1))" \
+ "ERROR: Cannot access memory at address 0x0.*" $test
+ gdb_test "gu (value-fetch-lazy! inval))" \
+ "ERROR: Cannot access memory at address 0x0.*" $test
+ }
+ gdb_test_no_output "gu (define argc-lazy (parse-and-eval \"argc\"))"
+ gdb_test_no_output "gu (define argc-notlazy (parse-and-eval \"argc\"))"
+ gdb_test_no_output "gu (value-fetch-lazy! argc-notlazy)"
+ gdb_test "gu (print (value-lazy? argc-lazy))" "= #t"
+ gdb_test "gu (print (value-lazy? argc-notlazy))" "= #f"
+ gdb_test "print argc" "= 1" "sanity check argc"
+ gdb_test "gu (print (value-lazy? argc-lazy))" "= #t"
+ gdb_test_no_output "set argc=2"
+ gdb_test "gu (print argc-notlazy)" "= 1"
+ gdb_test "gu (print argc-lazy)" "= 2"
+ gdb_test "gu (print (value-lazy? argc-lazy))" "= #f"
+
+ # Test string fetches, both partial and whole.
+ gdb_test "print st" "\"divide et impera\""
+ gdb_scm_test_silent_cmd "gu (define st (history-ref 0))" \
+ "inf: get st value from history"
+ gdb_test "gu (print (value->string st))" \
+ "= divide et impera" "Test string with no length"
+ gdb_test "gu (print (value->string st #:length -1))" \
+ "= divide et impera" "Test string (length = -1) is all of the string"
+ gdb_test "gu (print (value->string st #:length 6))" \
+ "= divide"
+ gdb_test "gu (print (string-append \"---\" (value->string st #:length 0) \"---\"))" \
+ "= ------" "Test string (length = 0) is empty"
+ gdb_test "gu (print (string-length (value->string st #:length 0)))" \
+ "= 0" "Test length is 0"
+
+ # Fetch a string that has embedded nulls.
+ gdb_test "print nullst" "\"divide\\\\000et\\\\000impera\".*"
+ gdb_scm_test_silent_cmd "gu (define nullst (history-ref 0))" \
+ "inf: get nullst value from history"
+ gdb_test "gu (print (value->string nullst))" \
+ "divide" "Test string to first null"
+ gdb_scm_test_silent_cmd "gu (set! nullst (value->string nullst #:length 9))" \
+ "get string beyond null"
+ gdb_test "gu (print nullst)" \
+ "= divide\\\\000et"
+}
+
+proc test_strings {} {
+ gdb_test "gu (make-value \"test\")" "#<gdb:value \"test\">" "make string"
+
+ # Test string conversion errors.
+ set save_charset [get_target_charset]
+ gdb_test_no_output "set target-charset UTF-8"
+
+ gdb_test_no_output "gu (set-port-conversion-strategy! #f 'error)"
+ gdb_test "gu (print (value->string (make-value (string #\\x1234)) #:encoding \"ASCII\"))" \
+ "ERROR.*decoding-error.*" \
+ "value->string with default #:errors = 'error"
+
+ # There is no 'escape strategy for C->SCM string conversions, but it's
+ # still a legitimate value for %default-port-conversion-strategy.
+ # GDB handles this by, umm, substituting 'substitute.
+ # Use this case to also handle "#:errors #f" which explicitly says
+ # "use %default-port-conversion-strategy".
+ gdb_test_no_output "gu (set-port-conversion-strategy! #f 'escape)"
+ gdb_test "gu (print (value->string (make-value (string #\\x1234)) #:encoding \"ASCII\" #:errors #f))" \
+ "= \[?\]{3}" "value->string with default #:errors = 'escape"
+
+ # This is last in the default conversion tests so that
+ # %default-port-conversion-strategy ends up with the default value.
+ gdb_test_no_output "gu (set-port-conversion-strategy! #f 'substitute)"
+ gdb_test "gu (print (value->string (make-value (string #\\x1234)) #:encoding \"ASCII\"))" \
+ "= \[?\]{3}" "value->string with default #:errors = 'substitute"
+
+ gdb_test "gu (print (value->string (make-value (string #\\x1234)) #:encoding \"ASCII\" #:errors 'error))" \
+ "ERROR.*decoding-error.*" "value->string #:errors 'error"
+ gdb_test "gu (print (value->string (make-value (string #\\x1234)) #:encoding \"ASCII\" #:errors 'substitute))" \
+ "= \[?\]{3}" "value->string #:errors 'substitute"
+ gdb_test "gu (print (value->string (make-value \"abc\") #:errors \"foo\"))" \
+ "ERROR.*invalid error kind.*" "bad value for #:errors"
+
+ gdb_test_no_output "set target-charset $save_charset" \
+ "restore target-charset"
+}
+
+proc test_lazy_strings {} {
+ global hex
+
+ gdb_test "print sptr" "\"pointer\""
+ gdb_scm_test_silent_cmd "gu (define sptr (history-ref 0))" \
+ "lazy strings: get sptr value from history"
+
+ gdb_scm_test_silent_cmd "gu (define lstr (value->lazy-string sptr))" \
+ "Aquire lazy string"
+ gdb_test "gu (print (lazy-string-type lstr))" \
+ "= const char \*." "Test lazy-string type name equality"
+ gdb_test "gu (print (value-type sptr))" \
+ "= const char \*." "Test string type name equality"
+ gdb_test "print sn" "0x0"
+ gdb_scm_test_silent_cmd "gu (define snptr (history-ref 0))" \
+ "lazy strings: get snptr value from history"
+ gdb_test "gu (define snstr (value->lazy-string snptr #:length 5))" \
+ ".*cannot create a lazy string with address.*" "Test lazy string"
+ gdb_scm_test_silent_cmd "gu (define snstr (value->lazy-string snptr #:length 0))" \
+ "Successfully create a lazy string"
+ gdb_test "gu (print (lazy-string-length snstr))" \
+ "= 0" "Test lazy string length"
+ gdb_test "gu (print (lazy-string-address snstr))" \
+ "= 0" "Test lazy string address"
+}
+
+proc test_inferior_function_call {} {
+ global gdb_prompt hex decimal
+
+ # Correct inferior call without arguments.
+ gdb_test "p/x fp1" "= $hex.*"
+ gdb_scm_test_silent_cmd "gu (define fp1 (history-ref 0))" \
+ "get fp1 value from history"
+ gdb_scm_test_silent_cmd "gu (set! fp1 (value-dereference fp1))" \
+ "dereference fp1"
+ gdb_test "gu (print (value-call fp1 '()))" \
+ "= void"
+
+ # Correct inferior call with arguments.
+ gdb_test "p/x fp2" "= $hex.*"
+ gdb_scm_test_silent_cmd "gu (define fp2 (history-ref 0))" \
+ "get fp2 value from history"
+ gdb_scm_test_silent_cmd "gu (set! fp2 (value-dereference fp2))" \
+ "dereference fp2"
+ gdb_test "gu (print (value-call fp2 (list 10 20)))" \
+ "= 30"
+
+ # Incorrect to call an int value.
+ gdb_test "p i" "= $decimal.*"
+ gdb_scm_test_silent_cmd "gu (define i (history-ref 0))" \
+ "inf call: get i value from history"
+ gdb_test "gu (print (value-call i '()))" \
+ "ERROR: .*: Wrong type argument in position 1 \\(expecting function \\(value of TYPE_CODE_FUNC\\)\\): .*"
+
+ # Incorrect number of arguments.
+ gdb_test "p/x fp2" "= $hex.*"
+ gdb_scm_test_silent_cmd "gu (define fp3 (history-ref 0))" \
+ "get fp3 value from history"
+ gdb_scm_test_silent_cmd "gu (set! fp3 (value-dereference fp3))" \
+ "dereference fp3"
+ gdb_test "gu (print (value-call fp3 (list 10)))" \
+ "ERROR: Too few arguments in function call.*"
+}
+
+proc test_value_after_death {} {
+ # Construct a type while the inferior is still running.
+ gdb_scm_test_silent_cmd "gu (define ptrtype (lookup-type \"PTR\"))" \
+ "create PTR type"
+
+ # Kill the inferior and remove the symbols.
+ gdb_test "kill" "" "kill the inferior" \
+ "Kill the program being debugged. .y or n. $" \
+ "y"
+ gdb_test "file" "" "Discard the symbols" \
+ "Discard symbol table from.*y or n. $" \
+ "y"
+
+ # Now create a value using that type. Relies on arg0, created by
+ # test_value_in_inferior.
+ gdb_scm_test_silent_cmd "gu (define castval (value-cast arg0 (type-pointer ptrtype)))" \
+ "cast arg0 to PTR"
+
+ # Make sure the type is deleted.
+ gdb_scm_test_silent_cmd "gu (set! ptrtype #f)" \
+ "delete PTR type"
+
+ # Now see if the value's type is still valid.
+ gdb_test "gu (print (value-type castval))" \
+ "= PTR ." "print value's type"
+}
+
+# Regression test for invalid subscript operations. The bug was that
+# the type of the value was not being checked before allowing a
+# subscript operation to proceed.
+
+proc test_subscript_regression {exefile lang} {
+ # Start with a fresh gdb.
+ clean_restart ${exefile}
+
+ if ![gdb_guile_runto_main ] {
+ fail "Can't run to main"
+ return
+ }
+
+ if {$lang == "c++"} {
+ gdb_breakpoint [gdb_get_line_number "break to inspect pointer by reference"]
+ gdb_continue_to_breakpoint "break to inspect pointer by reference"
+
+ gdb_scm_test_silent_cmd "print rptr_int" \
+ "Obtain address"
+ gdb_scm_test_silent_cmd "gu (define rptr (history-ref 0))" \
+ "set rptr"
+ gdb_test "gu (print (value-subscript rptr 0))" \
+ "= 2" "Check pointer passed as reference"
+
+ # Just the most basic test of dynamic_cast -- it is checked in
+ # the C++ tests.
+ gdb_test "gu (print (value->bool (value-dynamic-cast (parse-and-eval \"base\") (type-pointer (lookup-type \"Derived\")))))" \
+ "= #t"
+
+ # Likewise.
+ gdb_test "gu (print (value-dynamic-type (parse-and-eval \"base\")))" \
+ "= Derived \[*\]"
+ # A static type case.
+ gdb_test "gu (print (value-dynamic-type (parse-and-eval \"5\")))" \
+ "= int"
+ }
+
+ gdb_breakpoint [gdb_get_line_number "break to inspect struct and union"]
+ gdb_continue_to_breakpoint "break to inspect struct and union"
+
+ gdb_scm_test_silent_cmd "gu (define intv (make-value 1))" \
+ "Create int value for subscript test"
+ gdb_scm_test_silent_cmd "gu (define stringv (make-value \"foo\"))" \
+ "Create string value for subscript test"
+
+ # Try to access an int with a subscript. This should fail.
+ gdb_test "gu (print intv)" \
+ "= 1" "Baseline print of an int Guile value"
+ gdb_test "gu (print (value-subscript intv 0))" \
+ "ERROR: Cannot subscript requested type.*" \
+ "Attempt to access an integer with a subscript"
+
+ # Try to access a string with a subscript. This should pass.
+ gdb_test "gu (print stringv)" \
+ "= \"foo\"" "Baseline print of a string Guile value"
+ gdb_test "gu (print (value-subscript stringv 0))" \
+ "= 102 'f'" "Attempt to access a string with a subscript"
+
+ # Try to access an int array via a pointer with a subscript.
+ # This should pass.
+ gdb_scm_test_silent_cmd "print p" "Build pointer to array"
+ gdb_scm_test_silent_cmd "gu (define pointer (history-ref 0))" "set pointer"
+ gdb_test "gu (print (value-subscript pointer 0))" \
+ "= 1" "Access array via pointer with int subscript"
+ gdb_test "gu (print (value-subscript pointer intv))" \
+ "= 2" "Access array via pointer with value subscript"
+
+ # Try to access a single dimension array with a subscript to the
+ # result. This should fail.
+ gdb_test "gu (print (value-subscript (value-subscript pointer intv) 0))" \
+ "ERROR: Cannot subscript requested type.*" \
+ "Attempt to access an integer with a subscript 2"
+
+ # Lastly, test subscript access to an array with multiple
+ # dimensions. This should pass.
+ gdb_scm_test_silent_cmd "print {\"fu \",\"foo\",\"bar\"}" "Build array"
+ gdb_scm_test_silent_cmd "gu (define marray (history-ref 0))" ""
+ gdb_test "gu (print (value-subscript (value-subscript marray 1) 2))" \
+ "o." "Test multiple subscript"
+}
+
+# A few tests of gdb:parse-and-eval.
+
+proc test_parse_and_eval {} {
+ gdb_test "gu (print (parse-and-eval \"23\"))" \
+ "= 23" "parse-and-eval constant test"
+ gdb_test "gu (print (parse-and-eval \"5 + 7\"))" \
+ "= 12" "parse-and-eval simple expression test"
+ gdb_test "gu (raw-print (parse-and-eval \"5 + 7\"))" \
+ "#<gdb:value 12>" "parse-and-eval type test"
+}
+
+# Test that values are hashable.
+# N.B.: While smobs are hashable, the hash is really non-existent,
+# they all get hashed to the same value. Guile may provide a hash function
+# for smobs in a future release. In the meantime one should use a custom
+# hash table that uses gdb:hash-gsmob.
+
+proc test_value_hash {} {
+ gdb_test_multiline "Simple Guile value dictionary" \
+ "guile" "" \
+ "(define one (make-value 1))" "" \
+ "(define two (make-value 2))" "" \
+ "(define three (make-value 3))" "" \
+ "(define vdict (make-hash-table 5))" "" \
+ "(hash-set! vdict one \"one str\")" "" \
+ "(hash-set! vdict two \"two str\")" "" \
+ "(hash-set! vdict three \"three str\")" "" \
+ "end"
+ gdb_test "gu (print (hash-ref vdict one))" \
+ "one str" "Test dictionary hash 1"
+ gdb_test "gu (print (hash-ref vdict two))" \
+ "two str" "Test dictionary hash 2"
+ gdb_test "gu (print (hash-ref vdict three))" \
+ "three str" "Test dictionary hash 3"
+}
+
+# Build C version of executable. C++ is built later.
+if { [build_inferior "${binfile}" "c"] < 0 } {
+ return
+}
+
+# Start with a fresh gdb.
+clean_restart ${binfile}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+gdb_install_guile_utils
+gdb_install_guile_module
+
+test_parse_and_eval
+test_value_hash
+
+# The following tests require execution.
+
+if ![gdb_guile_runto_main] {
+ fail "Can't run to main"
+ return
+}
+
+test_value_in_inferior
+test_inferior_function_call
+test_strings
+test_lazy_strings
+test_value_after_death
+
+# Test either C or C++ values.
+
+test_subscript_regression "${binfile}" "c"
+
+if ![skip_cplus_tests] {
+ if { [build_inferior "${binfile}-cxx" "c++"] < 0 } {
+ return
+ }
+ with_test_prefix "c++" {
+ test_subscript_regression "${binfile}-cxx" "c++"
+ }
+}
diff --git a/gdb/testsuite/gdb.guile/source2.scm b/gdb/testsuite/gdb.guile/source2.scm
new file mode 100644
index 0000000..f00c269
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/source2.scm
@@ -0,0 +1,19 @@
+;; This testcase is part of GDB, the GNU debugger.
+;;
+;; Copyright 2008-2014 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/>.
+
+(display (format "y~As" "e"))
+(newline)
diff --git a/gdb/testsuite/gdb.guile/types-module.cc b/gdb/testsuite/gdb.guile/types-module.cc
new file mode 100644
index 0000000..90c682a
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/types-module.cc
@@ -0,0 +1,38 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2014 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/>. */
+
+enum enum_type { A, B, C };
+
+class base
+{
+ public:
+ int base_member;
+};
+
+class derived : public base
+{
+ public:
+ enum_type derived_member;
+};
+
+derived d;
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.guile/types-module.exp b/gdb/testsuite/gdb.guile/types-module.exp
new file mode 100644
index 0000000..8562f3c
--- /dev/null
+++ b/gdb/testsuite/gdb.guile/types-module.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 2014 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/>.
+
+# This file is part of the GDB testsuite.
+# It tests the (gdb types) module.
+
+load_lib gdb-guile.exp
+
+standard_testfile .cc
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Skip all tests if Guile scripting is not enabled.
+if { [skip_guile_tests] } { continue }
+
+if ![gdb_guile_runto_main] {
+ return
+}
+
+gdb_scm_test_silent_cmd "guile (use-modules (gdb types))" \
+ "import (gdb types)"
+
+gdb_scm_test_silent_cmd "guile (define d (lookup-type \"derived\"))" \
+ "get derived type"
+
+gdb_test "guile (print (type-has-field? d \"base_member\"))" \
+ "= #f" "type-has-field? member in baseclass"
+
+gdb_test "guile (print (type-has-field-deep? d \"base_member\"))" \
+ "= #t" "type-has-field-deep? member in baseclass"
+
+gdb_scm_test_silent_cmd "guile (define enum-htab (make-enum-hashtable (lookup-type \"enum_type\")))" \
+ "create enum hash table"
+
+gdb_test "guile (print (hash-ref enum-htab \"B\"))" \
+ "= 1" "verify make-enum-hashtable"
diff --git a/gdb/testsuite/lib/gdb-guile.exp b/gdb/testsuite/lib/gdb-guile.exp
new file mode 100644
index 0000000..d46f200
--- /dev/null
+++ b/gdb/testsuite/lib/gdb-guile.exp
@@ -0,0 +1,127 @@
+# Copyright 2010-2014 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/>.
+
+# Utilities for Guile-scripting related tests.
+
+# Guile doesn't print the 0x prefix on hex numbers.
+set ghex {[0-9a-f]+}
+
+# Return a 1 for configurations that do not support Guile scripting.
+
+proc skip_guile_tests {} {
+ global gdb_prompt
+
+ gdb_test_multiple "guile (display \"test\\n\")" "verify guile support" {
+ -re "Undefined command.*$gdb_prompt $" {
+ unsupported "Guile not supported."
+ return 1
+ }
+ -re "not supported.*$gdb_prompt $" {
+ unsupported "Guile support is disabled."
+ return 1
+ }
+ -re "$gdb_prompt $" {}
+ }
+
+ return 0
+}
+
+# Run a command in GDB, and report a failure if a Scheme exception is thrown.
+# If report_pass is true, report a pass if no exception is thrown.
+# This also catches the "Undefined command" error that happens if the user
+# passes, e.g., "(print foo)" instead of "guile (print foo)".
+
+proc gdb_scm_test_silent_cmd { cmd name {report_pass 1} } {
+ global gdb_prompt
+
+ gdb_test_multiple $cmd $name {
+ -re "Backtrace.*$gdb_prompt $" { fail $name }
+ -re "ERROR.*$gdb_prompt $" { fail $name }
+ -re "Undefined command: .*$gdb_prompt $" { fail $name }
+ -re "$gdb_prompt $" { if $report_pass { pass $name } }
+ }
+}
+
+# Usage: gdb_test_multiline NAME INPUT RESULT {INPUT RESULT} ...
+# Run a test named NAME, consisting of multiple lines of input.
+# After each input line INPUT, search for result line RESULT.
+# Succeed if all results are seen; fail otherwise.
+# FIXME: Move to gdb.exp and remove Python's gdb_py_test_multiple.
+
+proc gdb_test_multiline { name args } {
+ global gdb_prompt
+ foreach {input result} $args {
+ if {[gdb_test_multiple $input "$name - $input" {
+ -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" {
+ pass "$name - $input"
+ }
+ }]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+# Load Scheme file FILE_NAME.
+# TEST_NAME can be used to specify the name of the test,
+# otherwise a standard test name is provided.
+#
+# Note: When Guile loads something and auto-compilation is enabled
+# (which is useful and the default), then the first time a file is loaded
+# Guile will compile the file and store the result somewhere
+# (e.g., $HOME/.cache/guile). Output of the compilation process will
+# appear in gdb.log. But since Guile only does this when necessary
+# don't be confused if you don't always see it - Guile just skipped it
+# because it thought it was unnecessary.
+
+proc gdb_scm_load_file { file_name {test_name ""} } {
+ if { $test_name == "" } {
+ set test_name "guile (load \"[file tail $file_name]\")"
+ }
+ # Note: This can produce output if Guile compiles the file.
+ gdb_scm_test_silent_cmd "guile (load \"$file_name\")" $test_name
+}
+
+# Install various utilities in Guile to simplify tests.
+#
+# print - combination of display + newline
+
+proc gdb_install_guile_utils { } {
+ # Define utilities in Guile to save needing (newline) all the time,
+ # and in the case of "print" add a prefix to help erroneous passes.
+ gdb_test_no_output "guile (define (print x) (format #t \"= ~A\" x) (newline))"
+ gdb_test_no_output "guile (define (raw-print x) (format #t \"= ~S\" x) (newline))"
+}
+
+# Install the gdb module.
+
+proc gdb_install_guile_module { } {
+ gdb_test_no_output "guile (use-modules (gdb))"
+}
+
+# Wrapper around runto_main that installs the guile utils and module.
+# The result is the same as for runto_main.
+
+proc gdb_guile_runto_main { } {
+ if ![runto_main] {
+ fail "Can't run to main"
+ return 0
+ }
+
+ gdb_install_guile_utils
+ gdb_install_guile_module
+
+ return 1
+}
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 3716472..66dc8f7 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -4399,6 +4399,23 @@ proc get_sizeof { type default } {
return [get_integer_valueof "sizeof (${type})" $default]
}
+proc get_target_charset { } {
+ global gdb_prompt
+
+ gdb_test_multiple "show target-charset" "" {
+ -re "The target character set is \"auto; currently (\[^\"\]*)\".*$gdb_prompt $" {
+ return $expect_out(1,string)
+ }
+ -re "The target character set is \"(\[^\"\]*)\".*$gdb_prompt $" {
+ return $expect_out(1,string)
+ }
+ }
+
+ # Pick a reasonable default.
+ warning "Unable to read target-charset."
+ return "UTF-8"
+}
+
# Get the current value for remotetimeout and return it.
proc get_remotetimeout { } {
global gdb_prompt