tui: Simplify tui_alloc_content
[deliverable/binutils-gdb.git] / gdb / guile / scm-ports.c
CommitLineData
ed3ef339
DE
1/* Support for connecting Guile's stdio to GDB's.
2 as well as r/w memory via ports.
3
32d0add0 4 Copyright (C) 2014-2015 Free Software Foundation, Inc.
ed3ef339
DE
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21/* See README file in this directory for implementation notes, coding
22 conventions, et.al. */
23
24#include "defs.h"
25#include "gdb_select.h"
26#include "interps.h"
27#include "target.h"
28#include "guile-internal.h"
29
30#ifdef HAVE_POLL
31#if defined (HAVE_POLL_H)
32#include <poll.h>
33#elif defined (HAVE_SYS_POLL_H)
34#include <sys/poll.h>
35#endif
36#endif
37
38/* A ui-file for sending output to Guile. */
39
40typedef struct
41{
42 int *magic;
43 SCM port;
44} ioscm_file_port;
45
46/* Data for a memory port. */
47
48typedef struct
49{
37442ce1
DE
50 /* Bounds of memory range this port is allowed to access: [start, end).
51 This means that 0xff..ff is not accessible. I can live with that. */
ed3ef339
DE
52 CORE_ADDR start, end;
53
37442ce1 54 /* (end - start), recorded for convenience. */
ed3ef339
DE
55 ULONGEST size;
56
57 /* Think of this as the lseek value maintained by the kernel.
58 This value is always in the range [0, size]. */
59 ULONGEST current;
60
61 /* The size of the internal r/w buffers.
62 Scheme ports aren't a straightforward mapping to memory r/w.
63 Generally the user specifies how much to r/w and all access is
64 unbuffered. We don't try to provide equivalent access, but we allow
65 the user to specify these values to help get something similar. */
66 unsigned read_buf_size, write_buf_size;
67} ioscm_memory_port;
68
69/* Copies of the original system input/output/error ports.
70 These are recorded for debugging purposes. */
71static SCM orig_input_port_scm;
72static SCM orig_output_port_scm;
73static SCM orig_error_port_scm;
74
75/* This is the stdio port descriptor, scm_ptob_descriptor. */
76static scm_t_bits stdio_port_desc;
77
78/* Note: scm_make_port_type takes a char * instead of a const char *. */
79static /*const*/ char stdio_port_desc_name[] = "gdb:stdio-port";
80
81/* Names of each gdb port. */
82static const char input_port_name[] = "gdb:stdin";
83static const char output_port_name[] = "gdb:stdout";
84static const char error_port_name[] = "gdb:stderr";
85
86/* This is the actual port used from Guile.
87 We don't expose these to the user though, to ensure they're not
88 overwritten. */
89static SCM input_port_scm;
90static SCM output_port_scm;
91static SCM error_port_scm;
92
93/* Magic number to identify port ui-files.
94 Actually, the address of this variable is the magic number. */
95static int file_port_magic;
96
97/* Internal enum for specifying output port. */
98enum oport { GDB_STDOUT, GDB_STDERR };
99
100/* This is the memory port descriptor, scm_ptob_descriptor. */
101static scm_t_bits memory_port_desc;
102
103/* Note: scm_make_port_type takes a char * instead of a const char *. */
104static /*const*/ char memory_port_desc_name[] = "gdb:memory-port";
105
106/* The default amount of memory to fetch for each read/write request.
107 Scheme ports don't provide a way to specify the size of a read,
108 which is important to us to minimize the number of inferior interactions,
109 which over a remote link can be important. To compensate we augment the
110 port API with a new function that let's the user specify how much the next
111 read request should fetch. This is the initial value for each new port. */
112static const unsigned default_read_buf_size = 16;
113static const unsigned default_write_buf_size = 16;
114
115/* Arbitrarily limit memory port buffers to 1 byte to 4K. */
116static const unsigned min_memory_port_buf_size = 1;
117static const unsigned max_memory_port_buf_size = 4096;
118
119/* "out of range" error message for buf sizes. */
120static char *out_of_range_buf_size;
121
122/* Keywords used by open-memory. */
123static SCM mode_keyword;
124static SCM start_keyword;
125static SCM size_keyword;
126\f
127/* Helper to do the low level work of opening a port.
128 Newer versions of Guile (2.1.x) have scm_c_make_port. */
129
130static SCM
131ioscm_open_port (scm_t_bits port_type, long mode_bits)
132{
133 SCM port;
134
135#if 0 /* TODO: Guile doesn't export this. What to do? */
136 scm_i_scm_pthread_mutex_lock (&scm_i_port_table_mutex);
137#endif
138
139 port = scm_new_port_table_entry (port_type);
140
141 SCM_SET_CELL_TYPE (port, port_type | mode_bits);
142
143#if 0 /* TODO: Guile doesn't export this. What to do? */
144 scm_i_pthread_mutex_unlock (&scm_i_port_table_mutex);
145#endif
146
147 return port;
148}
149\f
150/* Support for connecting Guile's stdio ports to GDB's stdio ports. */
151
152/* The scm_t_ptob_descriptor.input_waiting "method".
153 Return a lower bound on the number of bytes available for input. */
154
155static int
156ioscm_input_waiting (SCM port)
157{
158 int fdes = 0;
159
160 if (! scm_is_eq (port, input_port_scm))
161 return 0;
162
163#ifdef HAVE_POLL
164 {
165 /* This is copied from libguile/fports.c. */
166 struct pollfd pollfd = { fdes, POLLIN, 0 };
167 static int use_poll = -1;
168
169 if (use_poll < 0)
170 {
171 /* This is copied from event-loop.c: poll cannot be used for stdin on
172 m68k-motorola-sysv. */
173 struct pollfd test_pollfd = { fdes, POLLIN, 0 };
174
175 if (poll (&test_pollfd, 1, 0) == 1 && (test_pollfd.revents & POLLNVAL))
176 use_poll = 0;
177 else
178 use_poll = 1;
179 }
180
181 if (use_poll)
182 {
183 /* Guile doesn't export SIGINT hooks like Python does.
184 For now pass EINTR to scm_syserror, that's what fports.c does. */
185 if (poll (&pollfd, 1, 0) < 0)
186 scm_syserror (FUNC_NAME);
187
188 return pollfd.revents & POLLIN ? 1 : 0;
189 }
190 }
191 /* Fall through. */
192#endif
193
194 {
195 struct timeval timeout;
196 fd_set input_fds;
197 int num_fds = fdes + 1;
198 int num_found;
199
200 memset (&timeout, 0, sizeof (timeout));
201 FD_ZERO (&input_fds);
202 FD_SET (fdes, &input_fds);
203
204 num_found = gdb_select (num_fds, &input_fds, NULL, NULL, &timeout);
205 if (num_found < 0)
206 {
207 /* Guile doesn't export SIGINT hooks like Python does.
208 For now pass EINTR to scm_syserror, that's what fports.c does. */
209 scm_syserror (FUNC_NAME);
210 }
211 return num_found > 0 && FD_ISSET (fdes, &input_fds);
212 }
213}
214
215/* The scm_t_ptob_descriptor.fill_input "method". */
216
217static int
218ioscm_fill_input (SCM port)
219{
220 /* Borrowed from libguile/fports.c. */
221 long count;
222 scm_t_port *pt = SCM_PTAB_ENTRY (port);
223
224 /* If we're called on stdout,stderr, punt. */
225 if (! scm_is_eq (port, input_port_scm))
226 return (scm_t_wchar) EOF; /* Set errno and return -1? */
227
228 gdb_flush (gdb_stdout);
229 gdb_flush (gdb_stderr);
230
231 count = ui_file_read (gdb_stdin, (char *) pt->read_buf, pt->read_buf_size);
232 if (count == -1)
233 scm_syserror (FUNC_NAME);
234 if (count == 0)
235 return (scm_t_wchar) EOF;
236
237 pt->read_pos = pt->read_buf;
238 pt->read_end = pt->read_buf + count;
239 return *pt->read_buf;
240}
241
242/* Like fputstrn_filtered, but don't escape characters, except nul.
243 Also like fputs_filtered, but a length is specified. */
244
245static void
246fputsn_filtered (const char *s, size_t size, struct ui_file *stream)
247{
248 size_t i;
249
250 for (i = 0; i < size; ++i)
251 {
252 if (s[i] == '\0')
253 fputs_filtered ("\\000", stream);
254 else
255 fputc_filtered (s[i], stream);
256 }
257}
258
259/* Write to gdb's stdout or stderr. */
260
261static void
262ioscm_write (SCM port, const void *data, size_t size)
263{
ed3ef339
DE
264
265 /* If we're called on stdin, punt. */
266 if (scm_is_eq (port, input_port_scm))
267 return;
268
492d29ea 269 TRY
ed3ef339
DE
270 {
271 if (scm_is_eq (port, error_port_scm))
9a3c8263 272 fputsn_filtered ((const char *) data, size, gdb_stderr);
ed3ef339 273 else
9a3c8263 274 fputsn_filtered ((const char *) data, size, gdb_stdout);
ed3ef339 275 }
492d29ea
PA
276 CATCH (except, RETURN_MASK_ALL)
277 {
278 GDBSCM_HANDLE_GDB_EXCEPTION (except);
279 }
280 END_CATCH
ed3ef339
DE
281}
282
283/* Flush gdb's stdout or stderr. */
284
285static void
286ioscm_flush (SCM port)
287{
288 /* If we're called on stdin, punt. */
289 if (scm_is_eq (port, input_port_scm))
290 return;
291
292 if (scm_is_eq (port, error_port_scm))
293 gdb_flush (gdb_stderr);
294 else
295 gdb_flush (gdb_stdout);
296}
297
298/* Initialize the gdb stdio port type.
299
300 N.B. isatty? will fail on these ports, it is only supported for file
301 ports. IWBN if we could "subclass" file ports. */
302
303static void
304ioscm_init_gdb_stdio_port (void)
305{
306 stdio_port_desc = scm_make_port_type (stdio_port_desc_name,
307 ioscm_fill_input, ioscm_write);
308
309 scm_set_port_input_waiting (stdio_port_desc, ioscm_input_waiting);
310 scm_set_port_flush (stdio_port_desc, ioscm_flush);
311}
312
313/* Subroutine of ioscm_make_gdb_stdio_port to simplify it.
314 Set up the buffers of port PORT.
315 MODE_BITS are the mode bits of PORT. */
316
317static void
318ioscm_init_stdio_buffers (SCM port, long mode_bits)
319{
320 scm_t_port *pt = SCM_PTAB_ENTRY (port);
321#define GDB_STDIO_BUFFER_DEFAULT_SIZE 1024
322 int size = mode_bits & SCM_BUF0 ? 0 : GDB_STDIO_BUFFER_DEFAULT_SIZE;
323 int writing = (mode_bits & SCM_WRTNG) != 0;
324
325 /* This is heavily copied from scm_fport_buffer_add. */
326
327 if (!writing && size > 0)
328 {
224c3ddb
SM
329 pt->read_buf
330 = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
ed3ef339
DE
331 pt->read_pos = pt->read_end = pt->read_buf;
332 pt->read_buf_size = size;
333 }
334 else
335 {
336 pt->read_pos = pt->read_buf = pt->read_end = &pt->shortbuf;
337 pt->read_buf_size = 1;
338 }
339
340 if (writing && size > 0)
341 {
224c3ddb
SM
342 pt->write_buf
343 = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
ed3ef339
DE
344 pt->write_pos = pt->write_buf;
345 pt->write_buf_size = size;
346 }
347 else
348 {
349 pt->write_buf = pt->write_pos = &pt->shortbuf;
350 pt->write_buf_size = 1;
351 }
352 pt->write_end = pt->write_buf + pt->write_buf_size;
353}
354
355/* Create a gdb stdio port. */
356
357static SCM
358ioscm_make_gdb_stdio_port (int fd)
359{
ed3ef339
DE
360 const char *name;
361 long mode_bits;
362 SCM port;
48ffa2b8
SM
363 char buf[3];
364
365 memset (buf, 0, sizeof (buf));
ed3ef339
DE
366
367 switch (fd)
368 {
369 case 0:
370 name = input_port_name;
48ffa2b8 371 buf[0] = 'r';
ed3ef339
DE
372 break;
373 case 1:
374 name = output_port_name;
48ffa2b8 375 buf[0] = 'w';
ed3ef339
DE
376 break;
377 case 2:
378 name = error_port_name;
48ffa2b8 379 buf[0] = 'w';
ed3ef339
DE
380 break;
381 default:
382 gdb_assert_not_reached ("bad stdio file descriptor");
383 }
384
48ffa2b8
SM
385 if (isatty (fd))
386 buf[1] = '0';
387
388 mode_bits = scm_mode_bits (buf);
389
ed3ef339
DE
390 port = ioscm_open_port (stdio_port_desc, mode_bits);
391
392 scm_set_port_filename_x (port, gdbscm_scm_from_c_string (name));
393
394 ioscm_init_stdio_buffers (port, mode_bits);
395
396 return port;
397}
398
399/* (stdio-port? object) -> boolean */
400
401static SCM
402gdbscm_stdio_port_p (SCM scm)
403{
404 /* This is copied from SCM_FPORTP. */
405 return scm_from_bool (!SCM_IMP (scm)
406 && (SCM_TYP16 (scm) == stdio_port_desc));
407}
408\f
409/* GDB's ports are accessed via functions to keep them read-only. */
410
411/* (input-port) -> port */
412
413static SCM
414gdbscm_input_port (void)
415{
416 return input_port_scm;
417}
418
419/* (output-port) -> port */
420
421static SCM
422gdbscm_output_port (void)
423{
424 return output_port_scm;
425}
426
427/* (error-port) -> port */
428
429static SCM
430gdbscm_error_port (void)
431{
432 return error_port_scm;
433}
434\f
435/* Support for sending GDB I/O to Guile ports. */
436
437static void
438ioscm_file_port_delete (struct ui_file *file)
439{
9a3c8263 440 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
ed3ef339
DE
441
442 if (stream->magic != &file_port_magic)
443 internal_error (__FILE__, __LINE__,
444 _("ioscm_file_port_delete: bad magic number"));
445 xfree (stream);
446}
447
448static void
449ioscm_file_port_rewind (struct ui_file *file)
450{
9a3c8263 451 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
ed3ef339
DE
452
453 if (stream->magic != &file_port_magic)
454 internal_error (__FILE__, __LINE__,
455 _("ioscm_file_port_rewind: bad magic number"));
456
457 scm_truncate_file (stream->port, 0);
458}
459
460static void
461ioscm_file_port_put (struct ui_file *file,
462 ui_file_put_method_ftype *write,
463 void *dest)
464{
9a3c8263 465 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
ed3ef339
DE
466
467 if (stream->magic != &file_port_magic)
468 internal_error (__FILE__, __LINE__,
469 _("ioscm_file_port_put: bad magic number"));
470
471 /* This function doesn't meld with ports very well. */
472}
473
474static void
475ioscm_file_port_write (struct ui_file *file,
476 const char *buffer,
477 long length_buffer)
478{
9a3c8263 479 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
ed3ef339
DE
480
481 if (stream->magic != &file_port_magic)
482 internal_error (__FILE__, __LINE__,
483 _("ioscm_pot_file_write: bad magic number"));
484
485 scm_c_write (stream->port, buffer, length_buffer);
486}
487
488/* Return a ui_file that writes to PORT. */
489
490static struct ui_file *
491ioscm_file_port_new (SCM port)
492{
493 ioscm_file_port *stream = XCNEW (ioscm_file_port);
494 struct ui_file *file = ui_file_new ();
495
496 set_ui_file_data (file, stream, ioscm_file_port_delete);
497 set_ui_file_rewind (file, ioscm_file_port_rewind);
498 set_ui_file_put (file, ioscm_file_port_put);
499 set_ui_file_write (file, ioscm_file_port_write);
500 stream->magic = &file_port_magic;
501 stream->port = port;
502
503 return file;
504}
505\f
506/* Helper routine for with-{output,error}-to-port. */
507
508static SCM
509ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
510 const char *func_name)
511{
512 struct ui_file *port_file;
513 struct cleanup *cleanups;
514 SCM result;
515
516 SCM_ASSERT_TYPE (gdbscm_is_true (scm_output_port_p (port)), port,
517 SCM_ARG1, func_name, _("output port"));
518 SCM_ASSERT_TYPE (gdbscm_is_true (scm_thunk_p (thunk)), thunk,
519 SCM_ARG2, func_name, _("thunk"));
520
521 cleanups = set_batch_flag_and_make_cleanup_restore_page_info ();
522
523 make_cleanup_restore_integer (&interpreter_async);
524 interpreter_async = 0;
525
526 port_file = ioscm_file_port_new (port);
527
528 make_cleanup_ui_file_delete (port_file);
529
530 if (oport == GDB_STDERR)
531 {
532 make_cleanup_restore_ui_file (&gdb_stderr);
533 gdb_stderr = port_file;
534 }
535 else
536 {
537 make_cleanup_restore_ui_file (&gdb_stdout);
538
539 if (ui_out_redirect (current_uiout, port_file) < 0)
540 warning (_("Current output protocol does not support redirection"));
541 else
542 make_cleanup_ui_out_redirect_pop (current_uiout);
543
544 gdb_stdout = port_file;
545 }
546
547 result = gdbscm_safe_call_0 (thunk, NULL);
548
549 do_cleanups (cleanups);
550
551 if (gdbscm_is_exception (result))
552 gdbscm_throw (result);
553
554 return result;
555}
556
557/* (%with-gdb-output-to-port port thunk) -> object
558 This function is experimental.
559 IWBN to not include "gdb" in the name, but it would collide with a standard
560 procedure, and it's common to import the gdb module without a prefix.
561 There are ways around this, but they're more cumbersome.
562
563 This has % in the name because it's experimental, and we want the
564 user-visible version to come from module (gdb experimental). */
565
566static SCM
567gdbscm_percent_with_gdb_output_to_port (SCM port, SCM thunk)
568{
569 return ioscm_with_output_to_port_worker (port, thunk, GDB_STDOUT, FUNC_NAME);
570}
571
572/* (%with-gdb-error-to-port port thunk) -> object
573 This function is experimental.
574 IWBN to not include "gdb" in the name, but it would collide with a standard
575 procedure, and it's common to import the gdb module without a prefix.
576 There are ways around this, but they're more cumbersome.
577
578 This has % in the name because it's experimental, and we want the
579 user-visible version to come from module (gdb experimental). */
580
581static SCM
582gdbscm_percent_with_gdb_error_to_port (SCM port, SCM thunk)
583{
584 return ioscm_with_output_to_port_worker (port, thunk, GDB_STDERR, FUNC_NAME);
585}
586\f
587/* Support for r/w memory via ports. */
588
589/* Perform an "lseek" to OFFSET,WHENCE on memory port IOMEM.
590 OFFSET must be in the range [0,size].
591 The result is non-zero for success, zero for failure. */
592
593static int
594ioscm_lseek_address (ioscm_memory_port *iomem, LONGEST offset, int whence)
595{
596 CORE_ADDR new_current;
597
598 gdb_assert (iomem->current <= iomem->size);
599
600 switch (whence)
601 {
602 case SEEK_CUR:
603 /* Catch over/underflow. */
604 if ((offset < 0 && iomem->current + offset > iomem->current)
37442ce1 605 || (offset > 0 && iomem->current + offset < iomem->current))
ed3ef339
DE
606 return 0;
607 new_current = iomem->current + offset;
608 break;
609 case SEEK_SET:
610 new_current = offset;
611 break;
612 case SEEK_END:
613 if (offset == 0)
614 {
615 new_current = iomem->size;
616 break;
617 }
618 /* TODO: Not supported yet. */
619 return 0;
620 default:
621 return 0;
622 }
623
624 if (new_current > iomem->size)
625 return 0;
626 iomem->current = new_current;
627 return 1;
628}
629
630/* "fill_input" method for memory ports. */
631
632static int
633gdbscm_memory_port_fill_input (SCM port)
634{
635 scm_t_port *pt = SCM_PTAB_ENTRY (port);
636 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
637 size_t to_read;
638
639 /* "current" is the offset of the first byte we want to read. */
37442ce1
DE
640 gdb_assert (iomem->current <= iomem->size);
641 if (iomem->current == iomem->size)
ed3ef339
DE
642 return EOF;
643
644 /* Don't read outside the allowed memory range. */
645 to_read = pt->read_buf_size;
646 if (to_read > iomem->size - iomem->current)
647 to_read = iomem->size - iomem->current;
648
649 if (target_read_memory (iomem->start + iomem->current, pt->read_buf,
650 to_read) != 0)
651 gdbscm_memory_error (FUNC_NAME, _("error reading memory"), SCM_EOL);
652
37442ce1 653 iomem->current += to_read;
ed3ef339
DE
654 pt->read_pos = pt->read_buf;
655 pt->read_end = pt->read_buf + to_read;
ed3ef339
DE
656 return *pt->read_buf;
657}
658
659/* "end_input" method for memory ports.
660 Clear the read buffer and adjust the file position for unread bytes. */
661
662static void
663gdbscm_memory_port_end_input (SCM port, int offset)
664{
665 scm_t_port *pt = SCM_PTAB_ENTRY (port);
666 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
667 size_t remaining = pt->read_end - pt->read_pos;
668
669 /* Note: Use of "int offset" is specified by Guile ports API. */
670 if ((offset < 0 && remaining + offset > remaining)
671 || (offset > 0 && remaining + offset < remaining))
672 {
673 gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
674 _("overflow in offset calculation"));
675 }
676 offset += remaining;
677
678 if (offset > 0)
679 {
680 pt->read_pos = pt->read_end;
681 /* Throw error if unread-char used at beginning of file
682 then attempting to write. Seems correct. */
683 if (!ioscm_lseek_address (iomem, -offset, SEEK_CUR))
684 {
685 gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
686 _("bad offset"));
687 }
688 }
689
690 pt->rw_active = SCM_PORT_NEITHER;
691}
692
693/* "flush" method for memory ports. */
694
695static void
696gdbscm_memory_port_flush (SCM port)
697{
698 scm_t_port *pt = SCM_PTAB_ENTRY (port);
699 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
700 size_t to_write = pt->write_pos - pt->write_buf;
701
702 if (to_write == 0)
703 return;
704
705 /* There's no way to indicate a short write, so if the request goes past
706 the end of the port's memory range, flag an error. */
707 if (to_write > iomem->size - iomem->current)
708 {
709 gdbscm_out_of_range_error (FUNC_NAME, 0,
710 gdbscm_scm_from_ulongest (to_write),
711 _("writing beyond end of memory range"));
712 }
713
714 if (target_write_memory (iomem->start + iomem->current, pt->write_buf,
715 to_write) != 0)
716 gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
717
718 iomem->current += to_write;
719 pt->write_pos = pt->write_buf;
720 pt->rw_active = SCM_PORT_NEITHER;
721}
722
723/* "write" method for memory ports. */
724
725static void
e0dd41e9 726gdbscm_memory_port_write (SCM port, const void *void_data, size_t size)
ed3ef339
DE
727{
728 scm_t_port *pt = SCM_PTAB_ENTRY (port);
729 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
e0dd41e9 730 const gdb_byte *data = (const gdb_byte *) void_data;
ed3ef339
DE
731
732 /* There's no way to indicate a short write, so if the request goes past
733 the end of the port's memory range, flag an error. */
734 if (size > iomem->size - iomem->current)
735 {
736 gdbscm_out_of_range_error (FUNC_NAME, 0, gdbscm_scm_from_ulongest (size),
737 _("writing beyond end of memory range"));
738 }
739
37442ce1
DE
740 if (pt->write_buf == &pt->shortbuf)
741 {
742 /* Unbuffered port. */
743 if (target_write_memory (iomem->start + iomem->current, data, size) != 0)
744 gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
745 iomem->current += size;
746 return;
747 }
748
749 /* Note: The edge case of what to do when the buffer exactly fills is
750 debatable. Guile flushes when the buffer exactly fills up, so we
751 do too. It's counter-intuitive to my mind, but in case there's a
752 subtlety somewhere that depends on this, we do the same. */
753
754 {
755 size_t space = pt->write_end - pt->write_pos;
756
757 if (size < space)
758 {
759 /* Data fits in buffer, and does not fill it. */
760 memcpy (pt->write_pos, data, size);
761 pt->write_pos += size;
762 }
763 else
764 {
765 memcpy (pt->write_pos, data, space);
766 pt->write_pos = pt->write_end;
767 gdbscm_memory_port_flush (port);
768 {
e0dd41e9 769 const gdb_byte *ptr = data + space;
37442ce1 770 size_t remaining = size - space;
ed3ef339 771
37442ce1
DE
772 if (remaining >= pt->write_buf_size)
773 {
774 if (target_write_memory (iomem->start + iomem->current, ptr,
775 remaining) != 0)
776 gdbscm_memory_error (FUNC_NAME, _("error writing memory"),
777 SCM_EOL);
778 iomem->current += remaining;
779 }
780 else
781 {
782 memcpy (pt->write_pos, ptr, remaining);
783 pt->write_pos += remaining;
784 }
785 }
786 }
787 }
ed3ef339
DE
788}
789
790/* "seek" method for memory ports. */
791
792static scm_t_off
793gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence)
794{
795 scm_t_port *pt = SCM_PTAB_ENTRY (port);
796 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
797 CORE_ADDR result;
798 int rc;
799
800 if (pt->rw_active == SCM_PORT_WRITE)
801 {
802 if (offset != 0 || whence != SEEK_CUR)
803 {
804 gdbscm_memory_port_flush (port);
805 rc = ioscm_lseek_address (iomem, offset, whence);
806 result = iomem->current;
807 }
808 else
809 {
810 /* Read current position without disturbing the buffer,
811 but flag an error if what's in the buffer goes outside the
812 allowed range. */
813 CORE_ADDR current = iomem->current;
814 size_t delta = pt->write_pos - pt->write_buf;
815
816 if (current + delta < current
37442ce1 817 || current + delta > iomem->size)
ed3ef339
DE
818 rc = 0;
819 else
820 {
821 result = current + delta;
822 rc = 1;
823 }
824 }
825 }
826 else if (pt->rw_active == SCM_PORT_READ)
827 {
828 if (offset != 0 || whence != SEEK_CUR)
829 {
830 scm_end_input (port);
831 rc = ioscm_lseek_address (iomem, offset, whence);
832 result = iomem->current;
833 }
834 else
835 {
836 /* Read current position without disturbing the buffer
837 (particularly the unread-char buffer). */
838 CORE_ADDR current = iomem->current;
839 size_t remaining = pt->read_end - pt->read_pos;
840
841 if (current - remaining > current
842 || current - remaining < iomem->start)
843 rc = 0;
844 else
845 {
846 result = current - remaining;
847 rc = 1;
848 }
849
850 if (rc != 0 && pt->read_buf == pt->putback_buf)
851 {
852 size_t saved_remaining = pt->saved_read_end - pt->saved_read_pos;
853
854 if (result - saved_remaining > result
855 || result - saved_remaining < iomem->start)
856 rc = 0;
857 else
858 result -= saved_remaining;
859 }
860 }
861 }
862 else /* SCM_PORT_NEITHER */
863 {
864 rc = ioscm_lseek_address (iomem, offset, whence);
865 result = iomem->current;
866 }
867
868 if (rc == 0)
869 {
870 gdbscm_out_of_range_error (FUNC_NAME, 0,
871 gdbscm_scm_from_longest (offset),
872 _("bad seek"));
873 }
874
875 /* TODO: The Guile API doesn't support 32x64. We can't fix that here,
876 and there's no need to throw an error if the new address can't be
877 represented in a scm_t_off. But we could return something less
878 clumsy. */
879 return result;
880}
881
882/* "close" method for memory ports. */
883
884static int
885gdbscm_memory_port_close (SCM port)
886{
887 scm_t_port *pt = SCM_PTAB_ENTRY (port);
888 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
889
890 gdbscm_memory_port_flush (port);
891
892 if (pt->read_buf == pt->putback_buf)
893 pt->read_buf = pt->saved_read_buf;
37442ce1
DE
894 if (pt->read_buf != &pt->shortbuf)
895 xfree (pt->read_buf);
896 if (pt->write_buf != &pt->shortbuf)
897 xfree (pt->write_buf);
ed3ef339
DE
898 scm_gc_free (iomem, sizeof (*iomem), "memory port");
899
900 return 0;
901}
902
903/* "free" method for memory ports. */
904
905static size_t
906gdbscm_memory_port_free (SCM port)
907{
908 gdbscm_memory_port_close (port);
909
910 return 0;
911}
912
913/* "print" method for memory ports. */
914
915static int
916gdbscm_memory_port_print (SCM exp, SCM port, scm_print_state *pstate)
917{
918 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (exp);
919 char *type = SCM_PTOBNAME (SCM_PTOBNUM (exp));
920
921 scm_puts ("#<", port);
922 scm_print_port_mode (exp, port);
923 /* scm_print_port_mode includes a trailing space. */
924 gdbscm_printf (port, "%s %s-%s", type,
925 hex_string (iomem->start), hex_string (iomem->end));
926 scm_putc ('>', port);
927 return 1;
928}
929
930/* Create the port type used for memory. */
931
932static void
933ioscm_init_memory_port_type (void)
934{
935 memory_port_desc = scm_make_port_type (memory_port_desc_name,
936 gdbscm_memory_port_fill_input,
937 gdbscm_memory_port_write);
938
939 scm_set_port_end_input (memory_port_desc, gdbscm_memory_port_end_input);
940 scm_set_port_flush (memory_port_desc, gdbscm_memory_port_flush);
941 scm_set_port_seek (memory_port_desc, gdbscm_memory_port_seek);
942 scm_set_port_close (memory_port_desc, gdbscm_memory_port_close);
943 scm_set_port_free (memory_port_desc, gdbscm_memory_port_free);
944 scm_set_port_print (memory_port_desc, gdbscm_memory_port_print);
945}
946
947/* Helper for gdbscm_open_memory to parse the mode bits.
948 An exception is thrown if MODE is invalid. */
949
950static long
951ioscm_parse_mode_bits (const char *func_name, const char *mode)
952{
953 const char *p;
954 long mode_bits;
955
956 if (*mode != 'r' && *mode != 'w')
957 {
958 gdbscm_out_of_range_error (func_name, 0,
959 gdbscm_scm_from_c_string (mode),
960 _("bad mode string"));
961 }
962 for (p = mode + 1; *p != '\0'; ++p)
963 {
964 switch (*p)
965 {
37442ce1 966 case '0':
ed3ef339
DE
967 case 'b':
968 case '+':
969 break;
970 default:
971 gdbscm_out_of_range_error (func_name, 0,
972 gdbscm_scm_from_c_string (mode),
973 _("bad mode string"));
974 }
975 }
976
977 /* Kinda awkward to convert the mode from SCM -> string only to have Guile
978 convert it back to SCM, but that's the API we have to work with. */
979 mode_bits = scm_mode_bits ((char *) mode);
980
981 return mode_bits;
982}
983
984/* Helper for gdbscm_open_memory to finish initializing the port.
37442ce1
DE
985 The port has address range [start,end).
986 This means that address of 0xff..ff is not accessible.
ed3ef339
DE
987 I can live with that. */
988
989static void
990ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end)
991{
992 scm_t_port *pt;
993 ioscm_memory_port *iomem;
37442ce1 994 int buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0;
ed3ef339
DE
995
996 gdb_assert (start <= end);
ed3ef339
DE
997
998 iomem = (ioscm_memory_port *) scm_gc_malloc_pointerless (sizeof (*iomem),
999 "memory port");
1000
1001 iomem->start = start;
1002 iomem->end = end;
37442ce1 1003 iomem->size = end - start;
ed3ef339 1004 iomem->current = 0;
37442ce1
DE
1005 if (buffered)
1006 {
1007 iomem->read_buf_size = default_read_buf_size;
1008 iomem->write_buf_size = default_write_buf_size;
1009 }
1010 else
1011 {
1012 iomem->read_buf_size = 1;
1013 iomem->write_buf_size = 1;
1014 }
ed3ef339
DE
1015
1016 pt = SCM_PTAB_ENTRY (port);
1017 /* Match the expectation of `binary-port?'. */
1018 pt->encoding = NULL;
1019 pt->rw_random = 1;
1020 pt->read_buf_size = iomem->read_buf_size;
ed3ef339 1021 pt->write_buf_size = iomem->write_buf_size;
37442ce1
DE
1022 if (buffered)
1023 {
224c3ddb
SM
1024 pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
1025 pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
37442ce1
DE
1026 }
1027 else
1028 {
1029 pt->read_buf = &pt->shortbuf;
1030 pt->write_buf = &pt->shortbuf;
1031 }
1032 pt->read_pos = pt->read_end = pt->read_buf;
ed3ef339
DE
1033 pt->write_pos = pt->write_buf;
1034 pt->write_end = pt->write_buf + pt->write_buf_size;
1035
1036 SCM_SETSTREAM (port, iomem);
1037}
1038
1039/* Re-initialize a memory port, updating its read/write buffer sizes.
37442ce1
DE
1040 An exception is thrown if the port is unbuffered.
1041 TODO: Allow switching buffered/unbuffered.
1042 An exception is also thrown if data is still buffered, except in the case
ed3ef339
DE
1043 where the buffer size isn't changing (since that's just a nop). */
1044
1045static void
1046ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
1047 size_t write_buf_size, const char *func_name)
1048{
1049 scm_t_port *pt = SCM_PTAB_ENTRY (port);
1050 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
1051
1052 gdb_assert (read_buf_size >= min_memory_port_buf_size
1053 && read_buf_size <= max_memory_port_buf_size);
1054 gdb_assert (write_buf_size >= min_memory_port_buf_size
1055 && write_buf_size <= max_memory_port_buf_size);
1056
37442ce1
DE
1057 /* First check if the port is unbuffered. */
1058
1059 if (pt->read_buf == &pt->shortbuf)
1060 {
1061 gdb_assert (pt->write_buf == &pt->shortbuf);
1062 scm_misc_error (func_name, _("port is unbuffered: ~a"),
1063 scm_list_1 (port));
1064 }
1065
1066 /* Next check if anything is buffered. */
ed3ef339
DE
1067
1068 if (read_buf_size != pt->read_buf_size
1069 && pt->read_end != pt->read_buf)
1070 {
1071 scm_misc_error (func_name, _("read buffer not empty: ~a"),
1072 scm_list_1 (port));
1073 }
1074
1075 if (write_buf_size != pt->write_buf_size
1076 && pt->write_pos != pt->write_buf)
1077 {
1078 scm_misc_error (func_name, _("write buffer not empty: ~a"),
1079 scm_list_1 (port));
1080 }
1081
1082 /* Now we can update the buffer sizes, but only if the size has changed. */
1083
1084 if (read_buf_size != pt->read_buf_size)
1085 {
1086 iomem->read_buf_size = read_buf_size;
1087 pt->read_buf_size = read_buf_size;
1088 xfree (pt->read_buf);
224c3ddb 1089 pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
ed3ef339
DE
1090 pt->read_pos = pt->read_end = pt->read_buf;
1091 }
1092
1093 if (write_buf_size != pt->write_buf_size)
1094 {
1095 iomem->write_buf_size = write_buf_size;
1096 pt->write_buf_size = write_buf_size;
1097 xfree (pt->write_buf);
224c3ddb 1098 pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
ed3ef339
DE
1099 pt->write_pos = pt->write_buf;
1100 pt->write_end = pt->write_buf + pt->write_buf_size;
1101 }
1102}
1103
1104/* (open-memory [#:mode string] [#:start address] [#:size integer]) -> port
1105 Return a port that can be used for reading and writing memory.
1106 MODE is a string, and must be one of "r", "w", or "r+".
37442ce1
DE
1107 "0" may be appended to MODE to mark the port as unbuffered.
1108 For compatibility "b" (binary) may also be appended, but we ignore it:
ed3ef339
DE
1109 memory ports are binary only.
1110
ed3ef339 1111 The chunk of memory that can be accessed can be bounded.
37442ce1
DE
1112 If both START,SIZE are unspecified, all of memory can be accessed
1113 (except 0xff..ff). If only START is specified, all of memory from that
1114 point on can be accessed (except 0xff..ff). If only SIZE if specified,
1115 all memory in [0,SIZE) can be accessed. If both are specified, all memory
1116 in [START,START+SIZE) can be accessed.
ed3ef339
DE
1117
1118 Note: If it becomes useful enough we can later add #:end as an alternative
1119 to #:size. For now it is left out.
1120
1121 The result is a Scheme port, and its semantics are a bit odd for accessing
1122 memory (e.g., unget), but we don't try to hide this. It's a port.
1123
37442ce1 1124 N.B. Seeks on the port must be in the range [0,size].
ed3ef339
DE
1125 This is for similarity with bytevector ports, and so that one can seek
1126 to the first byte. */
1127
1128static SCM
1129gdbscm_open_memory (SCM rest)
1130{
1131 const SCM keywords[] = {
1132 mode_keyword, start_keyword, size_keyword, SCM_BOOL_F
1133 };
1134 char *mode = NULL;
1135 CORE_ADDR start = 0;
1136 CORE_ADDR end;
1137 int mode_arg_pos = -1, start_arg_pos = -1, size_arg_pos = -1;
1138 ULONGEST size;
1139 SCM port;
1140 long mode_bits;
1141
1142 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "#sUU", rest,
1143 &mode_arg_pos, &mode,
1144 &start_arg_pos, &start,
1145 &size_arg_pos, &size);
1146
1147 scm_dynwind_begin (0);
1148
1149 if (mode == NULL)
1150 mode = xstrdup ("r");
1151 scm_dynwind_free (mode);
1152
ed3ef339
DE
1153 if (size_arg_pos > 0)
1154 {
ed3ef339
DE
1155 /* For now be strict about start+size overflowing. If it becomes
1156 a nuisance we can relax things later. */
1157 if (start + size < start)
1158 {
1159 gdbscm_out_of_range_error (FUNC_NAME, 0,
1160 scm_list_2 (gdbscm_scm_from_ulongest (start),
1161 gdbscm_scm_from_ulongest (size)),
1162 _("start+size overflows"));
1163 }
37442ce1 1164 end = start + size;
ed3ef339
DE
1165 }
1166 else
37442ce1 1167 end = ~(CORE_ADDR) 0;
ed3ef339
DE
1168
1169 mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode);
1170
1171 port = ioscm_open_port (memory_port_desc, mode_bits);
1172
1173 ioscm_init_memory_port (port, start, end);
1174
1175 scm_dynwind_end ();
1176
1177 /* TODO: Set the file name as "memory-start-end"? */
1178 return port;
1179}
1180
1181/* Return non-zero if OBJ is a memory port. */
1182
1183static int
1184gdbscm_is_memory_port (SCM obj)
1185{
1186 return !SCM_IMP (obj) && (SCM_TYP16 (obj) == memory_port_desc);
1187}
1188
1189/* (memory-port? obj) -> boolean */
1190
1191static SCM
1192gdbscm_memory_port_p (SCM obj)
1193{
1194 return scm_from_bool (gdbscm_is_memory_port (obj));
1195}
1196
1197/* (memory-port-range port) -> (start end) */
1198
1199static SCM
1200gdbscm_memory_port_range (SCM port)
1201{
1202 ioscm_memory_port *iomem;
1203
1204 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1205 memory_port_desc_name);
1206
1207 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1208 return scm_list_2 (gdbscm_scm_from_ulongest (iomem->start),
1209 gdbscm_scm_from_ulongest (iomem->end));
1210}
1211
1212/* (memory-port-read-buffer-size port) -> integer */
1213
1214static SCM
1215gdbscm_memory_port_read_buffer_size (SCM port)
1216{
1217 ioscm_memory_port *iomem;
1218
1219 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1220 memory_port_desc_name);
1221
1222 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1223 return scm_from_uint (iomem->read_buf_size);
1224}
1225
1226/* (set-memory-port-read-buffer-size! port size) -> unspecified
37442ce1
DE
1227 An exception is thrown if read data is still buffered or if the port
1228 is unbuffered. */
ed3ef339
DE
1229
1230static SCM
1231gdbscm_set_memory_port_read_buffer_size_x (SCM port, SCM size)
1232{
1233 ioscm_memory_port *iomem;
1234
1235 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1236 memory_port_desc_name);
1237 SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
1238 _("integer"));
1239
1240 if (!scm_is_unsigned_integer (size, min_memory_port_buf_size,
1241 max_memory_port_buf_size))
1242 {
1243 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, size,
1244 out_of_range_buf_size);
1245 }
1246
1247 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1248 ioscm_reinit_memory_port (port, scm_to_uint (size), iomem->write_buf_size,
1249 FUNC_NAME);
1250
1251 return SCM_UNSPECIFIED;
1252}
1253
1254/* (memory-port-write-buffer-size port) -> integer */
1255
1256static SCM
1257gdbscm_memory_port_write_buffer_size (SCM port)
1258{
1259 ioscm_memory_port *iomem;
1260
1261 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1262 memory_port_desc_name);
1263
1264 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1265 return scm_from_uint (iomem->write_buf_size);
1266}
1267
1268/* (set-memory-port-write-buffer-size! port size) -> unspecified
37442ce1
DE
1269 An exception is thrown if write data is still buffered or if the port
1270 is unbuffered. */
ed3ef339
DE
1271
1272static SCM
1273gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM size)
1274{
1275 ioscm_memory_port *iomem;
1276
1277 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1278 memory_port_desc_name);
1279 SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
1280 _("integer"));
1281
1282 if (!scm_is_unsigned_integer (size, min_memory_port_buf_size,
1283 max_memory_port_buf_size))
1284 {
1285 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, size,
1286 out_of_range_buf_size);
1287 }
1288
1289 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1290 ioscm_reinit_memory_port (port, iomem->read_buf_size, scm_to_uint (size),
1291 FUNC_NAME);
1292
1293 return SCM_UNSPECIFIED;
1294}
1295\f
1296/* Initialize gdb ports. */
1297
1298static const scheme_function port_functions[] =
1299{
72e02483 1300 { "input-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_input_port),
ed3ef339
DE
1301 "\
1302Return gdb's input port." },
1303
72e02483 1304 { "output-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_output_port),
ed3ef339
DE
1305 "\
1306Return gdb's output port." },
1307
72e02483 1308 { "error-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_error_port),
ed3ef339
DE
1309 "\
1310Return gdb's error port." },
1311
72e02483 1312 { "stdio-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_stdio_port_p),
ed3ef339
DE
1313 "\
1314Return #t if the object is a gdb:stdio-port." },
1315
72e02483 1316 { "open-memory", 0, 0, 1, as_a_scm_t_subr (gdbscm_open_memory),
ed3ef339
DE
1317 "\
1318Return a port that can be used for reading/writing inferior memory.\n\
1319\n\
1320 Arguments: [#:mode string] [#:start address] [#:size integer]\n\
1321 Returns: A port object." },
1322
72e02483 1323 { "memory-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_p),
ed3ef339
DE
1324 "\
1325Return #t if the object is a memory port." },
1326
72e02483 1327 { "memory-port-range", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_range),
ed3ef339
DE
1328 "\
1329Return the memory range of the port as (start end)." },
1330
1331 { "memory-port-read-buffer-size", 1, 0, 0,
72e02483 1332 as_a_scm_t_subr (gdbscm_memory_port_read_buffer_size),
ed3ef339
DE
1333 "\
1334Return the size of the read buffer for the memory port." },
1335
1336 { "set-memory-port-read-buffer-size!", 2, 0, 0,
72e02483 1337 as_a_scm_t_subr (gdbscm_set_memory_port_read_buffer_size_x),
ed3ef339
DE
1338 "\
1339Set the size of the read buffer for the memory port.\n\
1340\n\
1341 Arguments: port integer\n\
1342 Returns: unspecified." },
1343
1344 { "memory-port-write-buffer-size", 1, 0, 0,
72e02483 1345 as_a_scm_t_subr (gdbscm_memory_port_write_buffer_size),
ed3ef339
DE
1346 "\
1347Return the size of the write buffer for the memory port." },
1348
1349 { "set-memory-port-write-buffer-size!", 2, 0, 0,
72e02483 1350 as_a_scm_t_subr (gdbscm_set_memory_port_write_buffer_size_x),
ed3ef339
DE
1351 "\
1352Set the size of the write buffer for the memory port.\n\
1353\n\
1354 Arguments: port integer\n\
1355 Returns: unspecified." },
1356
1357 END_FUNCTIONS
1358};
1359
1360static const scheme_function private_port_functions[] =
1361{
1362#if 0 /* TODO */
1363 { "%with-gdb-input-from-port", 2, 0, 0,
72e02483 1364 as_a_scm_t_subr (gdbscm_percent_with_gdb_input_from_port),
ed3ef339
DE
1365 "\
1366Temporarily set GDB's input port to PORT and then invoke THUNK.\n\
1367\n\
1368 Arguments: port thunk\n\
1369 Returns: The result of calling THUNK.\n\
1370\n\
1371This procedure is experimental." },
1372#endif
1373
1374 { "%with-gdb-output-to-port", 2, 0, 0,
72e02483 1375 as_a_scm_t_subr (gdbscm_percent_with_gdb_output_to_port),
ed3ef339
DE
1376 "\
1377Temporarily set GDB's output port to PORT and then invoke THUNK.\n\
1378\n\
1379 Arguments: port thunk\n\
1380 Returns: The result of calling THUNK.\n\
1381\n\
1382This procedure is experimental." },
1383
1384 { "%with-gdb-error-to-port", 2, 0, 0,
72e02483 1385 as_a_scm_t_subr (gdbscm_percent_with_gdb_error_to_port),
ed3ef339
DE
1386 "\
1387Temporarily set GDB's error port to PORT and then invoke THUNK.\n\
1388\n\
1389 Arguments: port thunk\n\
1390 Returns: The result of calling THUNK.\n\
1391\n\
1392This procedure is experimental." },
1393
1394 END_FUNCTIONS
1395};
1396
1397void
1398gdbscm_initialize_ports (void)
1399{
1400 /* Save the original stdio ports for debugging purposes. */
1401
1402 orig_input_port_scm = scm_current_input_port ();
1403 orig_output_port_scm = scm_current_output_port ();
1404 orig_error_port_scm = scm_current_error_port ();
1405
1406 /* Set up the stdio ports. */
1407
1408 ioscm_init_gdb_stdio_port ();
1409 input_port_scm = ioscm_make_gdb_stdio_port (0);
1410 output_port_scm = ioscm_make_gdb_stdio_port (1);
1411 error_port_scm = ioscm_make_gdb_stdio_port (2);
1412
1413 /* Set up memory ports. */
1414
1415 ioscm_init_memory_port_type ();
1416
1417 /* Install the accessor functions. */
1418
1419 gdbscm_define_functions (port_functions, 1);
1420 gdbscm_define_functions (private_port_functions, 0);
1421
1422 /* Keyword args for open-memory. */
1423
1424 mode_keyword = scm_from_latin1_keyword ("mode");
1425 start_keyword = scm_from_latin1_keyword ("start");
1426 size_keyword = scm_from_latin1_keyword ("size");
1427
1428 /* Error message text for "out of range" memory port buffer sizes. */
1429
1430 out_of_range_buf_size = xstrprintf ("size not between %u - %u",
1431 min_memory_port_buf_size,
1432 max_memory_port_buf_size);
1433}
This page took 0.218687 seconds and 4 git commands to generate.