Add support for guile 2.0.5.

* guile/guile-internal.h (gdbscm_guile_major_version): Declare.
	(gdbscm_guile_minor_version, gdbscm_guile_micro_version): Declare.
	(gdbscm_guile_version_is_at_least): Declare.
	(gdbscm_scm_string_to_int): Declare.
	* guile/guile.c (gdbscm_guile_major_version): New global.
	(gdbscm_guile_minor_version, gdbscm_guile_micro_version): New globals.
	(guile_datadir): New static global.
	(gdbscm_guile_data_directory): New function.
	(initialize_scheme_side): Update.
	(misc_guile_functions): Add guile-data-directory.
	(initialize_gdb_module): Fetch guile version number.
	* guile/lib/gdb.scm: Remove call to add-to-load-path.
	* guile/lib/gdb/init.scm (%initialize!): Ditto.
	* guile/lib/gdb/boot.scm: Use guile-data-directory.
	* guile/scm-exception.c (gdbscm_print_exception_with_stack): Fix
	comments.
	* guile/scm-string.c (gdbscm_scm_string_to_int): New function.
	* guile/scm-utils.c (gdbscm_guile_version_is_at_least): New function.
	* guile/scm-value.c (gdbscm_value_to_string): Only call
	scm_port_conversion_strategy if Guile version >= 2.0.6.

	doc/
	* guile.texi (Guile Configuration): Document guile-data-directory.
This commit is contained in:
Doug Evans 2014-06-06 15:57:03 -07:00 committed by Doug Evans
parent 6da01dbef2
commit d2929fdcf0
12 changed files with 127 additions and 23 deletions

View file

@ -1,3 +1,26 @@
2014-06-06 Doug Evans <dje@google.com>
* guile/guile-internal.h (gdbscm_guile_major_version): Declare.
(gdbscm_guile_minor_version, gdbscm_guile_micro_version): Declare.
(gdbscm_guile_version_is_at_least): Declare.
(gdbscm_scm_string_to_int): Declare.
* guile/guile.c (gdbscm_guile_major_version): New global.
(gdbscm_guile_minor_version, gdbscm_guile_micro_version): New globals.
(guile_datadir): New static global.
(gdbscm_guile_data_directory): New function.
(initialize_scheme_side): Update.
(misc_guile_functions): Add guile-data-directory.
(initialize_gdb_module): Fetch guile version number.
* guile/lib/gdb.scm: Remove call to add-to-load-path.
* guile/lib/gdb/init.scm (%initialize!): Ditto.
* guile/lib/gdb/boot.scm: Use guile-data-directory.
* guile/scm-exception.c (gdbscm_print_exception_with_stack): Fix
comments.
* guile/scm-string.c (gdbscm_scm_string_to_int): New function.
* guile/scm-utils.c (gdbscm_guile_version_is_at_least): New function.
* guile/scm-value.c (gdbscm_value_to_string): Only call
scm_port_conversion_strategy if Guile version >= 2.0.6.
2014-06-06 Mingjie Xing <mingjie.xing@gmail.com> 2014-06-06 Mingjie Xing <mingjie.xing@gmail.com>
* main.c (print_gdb_help): Add -q and --silent. * main.c (print_gdb_help): Add -q and --silent.

View file

@ -1,3 +1,7 @@
2014-06-06 Doug Evans <dje@google.com>
* guile.texi (Guile Configuration): Document guile-data-directory.
2014-06-06 Mingjie Xing <mingjie.xing@gmail.com> 2014-06-06 Mingjie Xing <mingjie.xing@gmail.com>
* gdb.texinfo (Invoking GDB): Add -q and --quiet. * gdb.texinfo (Invoking GDB): Add -q and --quiet.

View file

@ -312,8 +312,12 @@ parameters.
@deffn {Scheme Procedure} data-directory @deffn {Scheme Procedure} data-directory
Return a string containing @value{GDBN}'s data directory. Return a string containing @value{GDBN}'s data directory.
This directory contains @value{GDBN}'s ancillary files, including This directory contains @value{GDBN}'s ancillary files.
the Guile modules provided by @value{GDBN}. @end deffn
@deffn {Scheme Procedure} guile-data-directory
Return a string containing @value{GDBN}'s Guile data directory.
This directory contains the Guile modules provided by @value{GDBN}.
@end deffn @end deffn
@deffn {Scheme Procedure} gdb-version @deffn {Scheme Procedure} gdb-version

View file

@ -121,6 +121,10 @@ extern const char gdbscm_init_module_name[];
extern int gdb_scheme_initialized; extern int gdb_scheme_initialized;
extern int gdbscm_guile_major_version;
extern int gdbscm_guile_minor_version;
extern int gdbscm_guile_micro_version;
extern const char gdbscm_print_excp_none[]; extern const char gdbscm_print_excp_none[];
extern const char gdbscm_print_excp_full[]; extern const char gdbscm_print_excp_full[];
extern const char gdbscm_print_excp_message[]; extern const char gdbscm_print_excp_message[];
@ -168,6 +172,8 @@ extern int gdbscm_is_procedure (SCM proc);
extern char *gdbscm_gc_xstrdup (const char *); extern char *gdbscm_gc_xstrdup (const char *);
extern const char * const *gdbscm_gc_dup_argv (char **argv); extern const char * const *gdbscm_gc_dup_argv (char **argv);
extern int gdbscm_guile_version_is_at_least (int major, int minor, int micro);
/* GDB smobs, from scm-gsmob.c */ /* GDB smobs, from scm-gsmob.c */
@ -472,6 +478,8 @@ extern SCM psscm_scm_from_pspace (struct program_space *);
/* scm-string.c */ /* scm-string.c */
extern int gdbscm_scm_string_to_int (SCM string);
extern char *gdbscm_scm_to_c_string (SCM string); extern char *gdbscm_scm_to_c_string (SCM string);
extern SCM gdbscm_scm_from_c_string (const char *string); extern SCM gdbscm_scm_from_c_string (const char *string);

View file

@ -37,6 +37,18 @@
#include "guile-internal.h" #include "guile-internal.h"
#endif #endif
/* The Guile version we're using.
We *could* use the macros in libguile/version.h but that would preclude
handling the user switching in a different version with, e.g.,
LD_LIBRARY_PATH (using a different version than what gdb was compiled with
is not something to be done lightly, but can be useful). */
int gdbscm_guile_major_version;
int gdbscm_guile_minor_version;
int gdbscm_guile_micro_version;
/* The guile subdirectory within gdb's data-directory. */
static const char *guile_datadir;
/* Declared constants and enum for guile exception printing. */ /* Declared constants and enum for guile exception printing. */
const char gdbscm_print_excp_none[] = "none"; const char gdbscm_print_excp_none[] = "none";
const char gdbscm_print_excp_full[] = "full"; const char gdbscm_print_excp_full[] = "full";
@ -353,6 +365,14 @@ gdbscm_data_directory (void)
return gdbscm_scm_from_c_string (gdb_datadir); return gdbscm_scm_from_c_string (gdb_datadir);
} }
/* (guile-data-directory) -> string */
static SCM
gdbscm_guile_data_directory (void)
{
return gdbscm_scm_from_c_string (guile_datadir);
}
/* (gdb-version) -> string */ /* (gdb-version) -> string */
static SCM static SCM
@ -468,6 +488,10 @@ Execute the given GDB command.\n\
"\ "\
Return the name of GDB's data directory." }, Return the name of GDB's data directory." },
{ "guile-data-directory", 0, 0, 0, gdbscm_guile_data_directory,
"\
Return the name of the Guile directory within GDB's data directory." },
{ "gdb-version", 0, 0, 0, gdbscm_gdb_version, { "gdb-version", 0, 0, 0, gdbscm_gdb_version,
"\ "\
Return GDB's version string." }, Return GDB's version string." },
@ -489,11 +513,13 @@ Return the name of the target configuration." },
static void static void
initialize_scheme_side (void) initialize_scheme_side (void)
{ {
char *gdb_guile_dir = concat (gdb_datadir, SLASH_STRING, "guile", NULL); char *boot_scm_path;
char *boot_scm_path = concat (gdb_guile_dir, SLASH_STRING, "gdb",
SLASH_STRING, boot_scm_filename, NULL);
char *msg; char *msg;
guile_datadir = concat (gdb_datadir, SLASH_STRING, "guile", NULL);
boot_scm_path = concat (guile_datadir, SLASH_STRING, "gdb",
SLASH_STRING, boot_scm_filename, NULL);
/* While scm_c_primitive_load works, the loaded code is not compiled, /* While scm_c_primitive_load works, the loaded code is not compiled,
instead it is left to be interpreted. Eh? instead it is left to be interpreted. Eh?
Anyways, this causes a ~100x slowdown, so we only use it to load Anyways, this causes a ~100x slowdown, so we only use it to load
@ -512,7 +538,6 @@ initialize_scheme_side (void)
boot_scm_path); boot_scm_path);
} }
xfree (gdb_guile_dir);
xfree (boot_scm_path); xfree (boot_scm_path);
} }
@ -524,6 +549,13 @@ initialize_scheme_side (void)
static void static void
initialize_gdb_module (void *data) initialize_gdb_module (void *data)
{ {
/* Computing these is a pain, so only do it once.
Also, do it here and save the result so that obtaining the values
is thread-safe. */
gdbscm_guile_major_version = gdbscm_scm_string_to_int (scm_major_version ());
gdbscm_guile_minor_version = gdbscm_scm_string_to_int (scm_minor_version ());
gdbscm_guile_micro_version = gdbscm_scm_string_to_int (scm_micro_version ());
/* The documentation symbol needs to be defined before any calls to /* The documentation symbol needs to be defined before any calls to
gdbscm_define_{variables,functions}. */ gdbscm_define_{variables,functions}. */
gdbscm_documentation_symbol = scm_from_latin1_symbol ("documentation"); gdbscm_documentation_symbol = scm_from_latin1_symbol ("documentation");

View file

@ -491,10 +491,6 @@
) )
;; Load the rest of the Scheme side. ;; Load the rest of the Scheme side.
;; data-directory is provided by the C code.
(add-to-load-path
(string-append (data-directory) file-name-separator-string "guile"))
(use-modules ((gdb init))) (use-modules ((gdb init)))

View file

@ -21,10 +21,9 @@
;; loaded with it are not compiled. So we do very little here, and do ;; loaded with it are not compiled. So we do very little here, and do
;; most of the initialization elsewhere. ;; most of the initialization elsewhere.
;; data-directory is provided by the C code. ;; guile-data-directory is provided by the C code.
(load (string-append (add-to-load-path (guile-data-directory))
(data-directory) file-name-separator-string "guile" (load-from-path "gdb.scm")
file-name-separator-string "gdb.scm"))
;; Now that the Scheme side support is loaded, initialize it. ;; Now that the Scheme side support is loaded, initialize it.
(let ((init-proc (@@ (gdb init) %initialize!))) (let ((init-proc (@@ (gdb init) %initialize!)))

View file

@ -155,9 +155,6 @@
;; GDB+Guile. ;; GDB+Guile.
(define (%initialize!) (define (%initialize!)
(add-to-load-path (string-append (data-directory)
file-name-separator-string "guile"))
(for-each (lambda (key) (for-each (lambda (key)
(set-exception-printer! key %exception-printer)) (set-exception-printer! key %exception-printer))
%exception-keys) %exception-keys)

View file

@ -521,7 +521,7 @@ gdbscm_print_exception_message (SCM port, SCM frame, SCM key, SCM args)
KEY, ARGS are the standard arguments to scm_throw, et.al. KEY, ARGS are the standard arguments to scm_throw, et.al.
Basically this function is just a wrapper around calling Basically this function is just a wrapper around calling
%print-exception-with-args. */ %print-exception-with-stack. */
void void
gdbscm_print_exception_with_stack (SCM port, SCM stack, SCM key, SCM args) gdbscm_print_exception_with_stack (SCM port, SCM stack, SCM key, SCM args)
@ -536,7 +536,7 @@ gdbscm_print_exception_with_stack (SCM port, SCM stack, SCM key, SCM args)
percent_print_exception_with_stack_var percent_print_exception_with_stack_var
= scm_c_private_variable (gdbscm_init_module_name, = scm_c_private_variable (gdbscm_init_module_name,
percent_print_exception_with_stack_name); percent_print_exception_with_stack_name);
/* If we can't find %print-exception-with-args, there's a problem on the /* If we can't find %print-exception-with-stack, there's a problem on the
Scheme side. Don't kill GDB, just flag an error and leave it at Scheme side. Don't kill GDB, just flag an error and leave it at
that. */ that. */
if (gdbscm_is_false (percent_print_exception_with_stack_var)) if (gdbscm_is_false (percent_print_exception_with_stack_var))

View file

@ -25,6 +25,19 @@
#include "charset.h" #include "charset.h"
#include "guile-internal.h" #include "guile-internal.h"
/* Convert STRING to an int.
STRING must be a valid integer. */
int
gdbscm_scm_string_to_int (SCM string)
{
char *s = scm_to_latin1_string (string);
int r = atoi (s);
free (s);
return r;
}
/* Convert a C (latin1) string to an SCM string. /* Convert a C (latin1) string to an SCM string.
"latin1" is chosen because Guile won't throw an exception. */ "latin1" is chosen because Guile won't throw an exception. */

View file

@ -624,3 +624,22 @@ gdbscm_gc_dup_argv (char **argv)
return (const char * const *) result; return (const char * const *) result;
} }
/* Return non-zero if the version of Guile being used it at least
MAJOR.MINOR.MICRO. */
int
gdbscm_guile_version_is_at_least (int major, int minor, int micro)
{
if (major > gdbscm_guile_major_version)
return 0;
if (major < gdbscm_guile_major_version)
return 1;
if (minor > gdbscm_guile_minor_version)
return 0;
if (minor < gdbscm_guile_minor_version)
return 1;
if (micro > gdbscm_guile_micro_version)
return 0;
return 1;
}

View file

@ -1016,9 +1016,11 @@ gdbscm_value_to_real (SCM self)
the target's charset. the target's charset.
ERRORS is one of #f, 'error or 'substitute. ERRORS is one of #f, 'error or 'substitute.
An error setting of #f means use the default, which is An error setting of #f means use the default, which is Guile's
Guile's %default-port-conversion-strategy. If the default is not one %default-port-conversion-strategy when using Guile >= 2.0.6, or 'error if
of 'error or 'substitute, 'substitute is used. using an earlier version of Guile. Earlier versions do not properly
support obtaining the default port conversion strategy.
If the default is not one of 'error or 'substitute, 'substitute is used.
An error setting of "error" causes an exception to be thrown if there's An error setting of "error" causes an exception to be thrown if there's
a decoding error. An error setting of "substitute" causes invalid a decoding error. An error setting of "substitute" causes invalid
characters to be replaced with "?". characters to be replaced with "?".
@ -1069,7 +1071,14 @@ gdbscm_value_to_string (SCM self, SCM rest)
gdbscm_throw (excp); gdbscm_throw (excp);
} }
if (errors == SCM_BOOL_F) if (errors == SCM_BOOL_F)
errors = scm_port_conversion_strategy (SCM_BOOL_F); {
/* N.B. scm_port_conversion_strategy in Guile versions prior to 2.0.6
will throw a Scheme error when passed #f. */
if (gdbscm_guile_version_is_at_least (2, 0, 6))
errors = scm_port_conversion_strategy (SCM_BOOL_F);
else
errors = error_symbol;
}
/* We don't assume anything about the result of scm_port_conversion_strategy. /* We don't assume anything about the result of scm_port_conversion_strategy.
From this point on, if errors is not 'errors, use 'substitute. */ From this point on, if errors is not 'errors, use 'substitute. */