Print the faulty object upon invalid-keyword errors.
[bpt/guile.git] / libguile / gdbint.c
CommitLineData
4907ff5a 1/* GDB interface for Guile
62e15979 2 * Copyright (C) 1996,1997,1999,2000,2001,2002,2004,2009,2011,2012
434f2f7a 3 * Free Software Foundation, Inc.
4907ff5a 4 *
73be1d9e 5 * This library is free software; you can redistribute it and/or
53befeb7
NJ
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 3 of
8 * the License, or (at your option) any later version.
4907ff5a 9 *
53befeb7
NJ
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
4907ff5a 14 *
73be1d9e
MV
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
53befeb7
NJ
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
73be1d9e 19 */
4907ff5a 20
dbb605f5 21#ifdef HAVE_CONFIG_H
5ebbe4ef
RB
22# include <config.h>
23#endif
1bbd0b84 24
a0599745 25#include "libguile/_scm.h"
681b9005
MD
26
27#include <stdio.h>
783e7774 28#include <string.h>
681b9005
MD
29#ifdef HAVE_UNISTD_H
30#include <unistd.h>
31#endif
32
a0599745
MD
33#include "libguile/strports.h"
34#include "libguile/read.h"
35#include "libguile/eval.h"
36#include "libguile/chars.h"
37#include "libguile/modules.h"
38#include "libguile/ports.h"
7e73eaee 39#include "libguile/fluids.h"
a0599745 40#include "libguile/strings.h"
9293b3c6 41#include "libguile/init.h"
4907ff5a 42
a0599745 43#include "libguile/gdbint.h"
4907ff5a
MD
44\f
45/* {Support for debugging with gdb}
46 *
47 * TODO:
48 *
49 * 1. Redirect outputs
50 * 2. Catch errors
51 * 3. Prevent print from causing segmentation fault when given broken pairs
52 */
53
4907ff5a
MD
54#define GDB_TYPE SCM
55
a0599745 56#include "libguile/gdb_interface.h"
4907ff5a
MD
57
58\f
59
60/* Be carefull when this macro is true.
406c7d90 61 scm_gc_running_p is set during gc.
4907ff5a 62 */
406c7d90 63#define SCM_GC_P (scm_gc_running_p)
4907ff5a
MD
64
65/* Macros that encapsulate blocks of code which can be called by the
66 * debugger.
67 */
68#define SCM_BEGIN_FOREIGN_BLOCK \
d3a6bc94 69do { \
4907ff5a 70 scm_print_carefully_p = 1; \
d3a6bc94 71} while (0)
4907ff5a
MD
72
73
74#define SCM_END_FOREIGN_BLOCK \
d3a6bc94 75do { \
4907ff5a 76 scm_print_carefully_p = 0; \
d3a6bc94 77} while (0)
4907ff5a
MD
78
79
80#define RESET_STRING { gdb_output_length = 0; }
81
82#define SEND_STRING(str) \
d3a6bc94 83do { \
a57c1cc7
MD
84 gdb_output = (char *) (str); \
85 gdb_output_length = strlen ((const char *) (str)); \
d3a6bc94 86} while (0)
380b6b4c 87
4907ff5a
MD
88
89/* {Gdb interface}
90 */
91
92unsigned short gdb_options = GDB_HAVE_BINDINGS;
93
94char *gdb_language = "lisp/c";
95
96SCM gdb_result;
97
98char *gdb_output;
99
100int gdb_output_length;
101
102int scm_print_carefully_p;
103
104static SCM gdb_input_port;
105static SCM gdb_output_port;
4907ff5a 106
1cc91f1b 107
4907ff5a 108int
6e8d25a6 109gdb_maybe_valid_type_p (SCM value)
4907ff5a 110{
26224b3f
LC
111 return SCM_IMP (value); /* || scm_in_heap_p (value); */ /* FIXME: What to
112 do? */
4907ff5a
MD
113}
114
1cc91f1b 115
4907ff5a 116int
6e8d25a6 117gdb_read (char *str)
4907ff5a 118{
26224b3f 119#if 0
4907ff5a
MD
120 SCM ans;
121 int status = 0;
122 RESET_STRING;
123 /* Need to be restrictive about what to read? */
26224b3f 124 if (1) /* (SCM_GC_P) */ /* FIXME */
4907ff5a
MD
125 {
126 char *p;
127 for (p = str; *p != '\0'; ++p)
128 switch (*p)
129 {
130 case '(':
131 case '\'':
132 case '"':
133 SEND_STRING ("Can't read this kind of expressions during gc");
134 return -1;
135 case '#':
136 if (*++p == '\0')
137 goto premature;
138 if (*p == '\\')
139 {
140 if (*++p != '\0')
141 continue;
142 premature:
143 SEND_STRING ("Premature end of lisp expression");
144 return -1;
145 }
146 default:
147 continue;
148 }
149 }
150 SCM_BEGIN_FOREIGN_BLOCK;
380b6b4c 151 unmark_port (gdb_input_port);
e11e83f3 152 scm_seek (gdb_input_port, SCM_INUM0, scm_from_int (SEEK_SET));
840ae05d 153 scm_puts (str, gdb_input_port);
69bc9ff3 154 scm_truncate_file (gdb_input_port, SCM_UNDEFINED);
e11e83f3 155 scm_seek (gdb_input_port, SCM_INUM0, scm_from_int (SEEK_SET));
7337d56d 156
4907ff5a 157 /* Read one object */
7337d56d 158 ans = scm_read (gdb_input_port);
4907ff5a
MD
159 if (SCM_GC_P)
160 {
380b6b4c 161 if (SCM_NIMP (ans))
4907ff5a
MD
162 {
163 SEND_STRING ("Non-immediate created during gc. Memory may be trashed.");
164 status = -1;
165 goto exit;
166 }
167 }
380b6b4c 168 gdb_result = ans;
f39448c5 169 /* Protect answer from future GC (FIXME: still needed with BDW-GC?) */
380b6b4c
MD
170 if (SCM_NIMP (ans))
171 scm_permanent_object (ans);
4907ff5a 172exit:
380b6b4c 173 remark_port (gdb_input_port);
4907ff5a
MD
174 SCM_END_FOREIGN_BLOCK;
175 return status;
26224b3f
LC
176#else
177 abort ();
178#endif
4907ff5a
MD
179}
180
1cc91f1b 181
4907ff5a 182int
6e8d25a6 183gdb_eval (SCM exp)
4907ff5a
MD
184{
185 RESET_STRING;
4907ff5a
MD
186 if (SCM_GC_P)
187 {
188 SEND_STRING ("Can't evaluate lisp expressions during gc");
189 return -1;
190 }
191 SCM_BEGIN_FOREIGN_BLOCK;
192 {
c2c4e281 193 gdb_result = scm_permanent_object (scm_primitive_eval (exp));
4907ff5a
MD
194 }
195 SCM_END_FOREIGN_BLOCK;
196 return 0;
197}
198
1cc91f1b 199
4907ff5a 200int
6e8d25a6 201gdb_print (SCM obj)
4907ff5a 202{
9293b3c6
MD
203 if (!scm_initialized_p)
204 SEND_STRING ("*** Guile not initialized ***");
205 else
206 {
207 RESET_STRING;
208 SCM_BEGIN_FOREIGN_BLOCK;
209 /* Reset stream */
e11e83f3 210 scm_seek (gdb_output_port, SCM_INUM0, scm_from_int (SEEK_SET));
9293b3c6
MD
211 scm_write (obj, gdb_output_port);
212 scm_truncate_file (gdb_output_port, SCM_UNDEFINED);
213 {
92c2555f 214 scm_t_port *pt = SCM_PTAB_ENTRY (gdb_output_port);
9293b3c6
MD
215
216 scm_flush (gdb_output_port);
217 *(pt->write_buf + pt->read_buf_size) = 0;
218 SEND_STRING (pt->read_buf);
219 }
220 SCM_END_FOREIGN_BLOCK;
221 }
4907ff5a
MD
222 return 0;
223}
224
1cc91f1b 225
4907ff5a 226int
6e8d25a6 227gdb_binding (SCM name, SCM value)
4907ff5a
MD
228{
229 RESET_STRING;
230 if (SCM_GC_P)
231 {
232 SEND_STRING ("Can't create new bindings during gc");
233 return -1;
234 }
235 SCM_BEGIN_FOREIGN_BLOCK;
236 {
62e15979 237 scm_define (name, value);
4907ff5a
MD
238 }
239 SCM_END_FOREIGN_BLOCK;
240 return 0;
241}
242
243void
244scm_init_gdbint ()
245{
246 static char *s = "scm_init_gdb_interface";
247 SCM port;
248
249 scm_print_carefully_p = 0;
0b2c2ba3
LC
250
251 port = scm_mkstrport (SCM_INUM0, SCM_BOOL_F,
4907ff5a
MD
252 SCM_OPN | SCM_WRTNG,
253 s);
254 gdb_output_port = scm_permanent_object (port);
0b2c2ba3
LC
255
256 port = scm_mkstrport (SCM_INUM0, SCM_BOOL_F,
840ae05d 257 SCM_OPN | SCM_RDNG | SCM_WRTNG,
4907ff5a
MD
258 s);
259 gdb_input_port = scm_permanent_object (port);
260}
89e00824
ML
261
262/*
263 Local Variables:
264 c-file-style: "gnu"
265 End:
266*/