GDB copyright headers update after running GDB's copyright.py script.
[deliverable/binutils-gdb.git] / gdb / guile / scm-ports.c
1 /* Support for connecting Guile's stdio to GDB's.
2 as well as r/w memory via ports.
3
4 Copyright (C) 2014-2016 Free Software Foundation, Inc.
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
40 typedef struct
41 {
42 int *magic;
43 SCM port;
44 } ioscm_file_port;
45
46 /* Data for a memory port. */
47
48 typedef struct
49 {
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. */
52 CORE_ADDR start, end;
53
54 /* (end - start), recorded for convenience. */
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. */
71 static SCM orig_input_port_scm;
72 static SCM orig_output_port_scm;
73 static SCM orig_error_port_scm;
74
75 /* This is the stdio port descriptor, scm_ptob_descriptor. */
76 static scm_t_bits stdio_port_desc;
77
78 /* Note: scm_make_port_type takes a char * instead of a const char *. */
79 static /*const*/ char stdio_port_desc_name[] = "gdb:stdio-port";
80
81 /* Names of each gdb port. */
82 static const char input_port_name[] = "gdb:stdin";
83 static const char output_port_name[] = "gdb:stdout";
84 static 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. */
89 static SCM input_port_scm;
90 static SCM output_port_scm;
91 static SCM error_port_scm;
92
93 /* Magic number to identify port ui-files.
94 Actually, the address of this variable is the magic number. */
95 static int file_port_magic;
96
97 /* Internal enum for specifying output port. */
98 enum oport { GDB_STDOUT, GDB_STDERR };
99
100 /* This is the memory port descriptor, scm_ptob_descriptor. */
101 static scm_t_bits memory_port_desc;
102
103 /* Note: scm_make_port_type takes a char * instead of a const char *. */
104 static /*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. */
112 static const unsigned default_read_buf_size = 16;
113 static const unsigned default_write_buf_size = 16;
114
115 /* Arbitrarily limit memory port buffers to 1 byte to 4K. */
116 static const unsigned min_memory_port_buf_size = 1;
117 static const unsigned max_memory_port_buf_size = 4096;
118
119 /* "out of range" error message for buf sizes. */
120 static char *out_of_range_buf_size;
121
122 /* Keywords used by open-memory. */
123 static SCM mode_keyword;
124 static SCM start_keyword;
125 static 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
130 static SCM
131 ioscm_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
155 static int
156 ioscm_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
217 static int
218 ioscm_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
245 static void
246 fputsn_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
261 static void
262 ioscm_write (SCM port, const void *data, size_t size)
263 {
264
265 /* If we're called on stdin, punt. */
266 if (scm_is_eq (port, input_port_scm))
267 return;
268
269 TRY
270 {
271 if (scm_is_eq (port, error_port_scm))
272 fputsn_filtered ((const char *) data, size, gdb_stderr);
273 else
274 fputsn_filtered ((const char *) data, size, gdb_stdout);
275 }
276 CATCH (except, RETURN_MASK_ALL)
277 {
278 GDBSCM_HANDLE_GDB_EXCEPTION (except);
279 }
280 END_CATCH
281 }
282
283 /* Flush gdb's stdout or stderr. */
284
285 static void
286 ioscm_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
303 static void
304 ioscm_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
317 static void
318 ioscm_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 {
329 pt->read_buf
330 = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
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 {
342 pt->write_buf
343 = (unsigned char *) scm_gc_malloc_pointerless (size, "port buffer");
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
357 static SCM
358 ioscm_make_gdb_stdio_port (int fd)
359 {
360 int is_a_tty = isatty (fd);
361 const char *name;
362 const char *mode_str;
363 long mode_bits;
364 SCM port;
365
366 switch (fd)
367 {
368 case 0:
369 name = input_port_name;
370 mode_str = is_a_tty ? "r0" : "r";
371 break;
372 case 1:
373 name = output_port_name;
374 mode_str = is_a_tty ? "w0" : "w";
375 break;
376 case 2:
377 name = error_port_name;
378 mode_str = is_a_tty ? "w0" : "w";
379 break;
380 default:
381 gdb_assert_not_reached ("bad stdio file descriptor");
382 }
383
384 mode_bits = scm_mode_bits ((char *) mode_str);
385 port = ioscm_open_port (stdio_port_desc, mode_bits);
386
387 scm_set_port_filename_x (port, gdbscm_scm_from_c_string (name));
388
389 ioscm_init_stdio_buffers (port, mode_bits);
390
391 return port;
392 }
393
394 /* (stdio-port? object) -> boolean */
395
396 static SCM
397 gdbscm_stdio_port_p (SCM scm)
398 {
399 /* This is copied from SCM_FPORTP. */
400 return scm_from_bool (!SCM_IMP (scm)
401 && (SCM_TYP16 (scm) == stdio_port_desc));
402 }
403 \f
404 /* GDB's ports are accessed via functions to keep them read-only. */
405
406 /* (input-port) -> port */
407
408 static SCM
409 gdbscm_input_port (void)
410 {
411 return input_port_scm;
412 }
413
414 /* (output-port) -> port */
415
416 static SCM
417 gdbscm_output_port (void)
418 {
419 return output_port_scm;
420 }
421
422 /* (error-port) -> port */
423
424 static SCM
425 gdbscm_error_port (void)
426 {
427 return error_port_scm;
428 }
429 \f
430 /* Support for sending GDB I/O to Guile ports. */
431
432 static void
433 ioscm_file_port_delete (struct ui_file *file)
434 {
435 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
436
437 if (stream->magic != &file_port_magic)
438 internal_error (__FILE__, __LINE__,
439 _("ioscm_file_port_delete: bad magic number"));
440 xfree (stream);
441 }
442
443 static void
444 ioscm_file_port_rewind (struct ui_file *file)
445 {
446 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
447
448 if (stream->magic != &file_port_magic)
449 internal_error (__FILE__, __LINE__,
450 _("ioscm_file_port_rewind: bad magic number"));
451
452 scm_truncate_file (stream->port, 0);
453 }
454
455 static void
456 ioscm_file_port_put (struct ui_file *file,
457 ui_file_put_method_ftype *write,
458 void *dest)
459 {
460 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
461
462 if (stream->magic != &file_port_magic)
463 internal_error (__FILE__, __LINE__,
464 _("ioscm_file_port_put: bad magic number"));
465
466 /* This function doesn't meld with ports very well. */
467 }
468
469 static void
470 ioscm_file_port_write (struct ui_file *file,
471 const char *buffer,
472 long length_buffer)
473 {
474 ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
475
476 if (stream->magic != &file_port_magic)
477 internal_error (__FILE__, __LINE__,
478 _("ioscm_pot_file_write: bad magic number"));
479
480 scm_c_write (stream->port, buffer, length_buffer);
481 }
482
483 /* Return a ui_file that writes to PORT. */
484
485 static struct ui_file *
486 ioscm_file_port_new (SCM port)
487 {
488 ioscm_file_port *stream = XCNEW (ioscm_file_port);
489 struct ui_file *file = ui_file_new ();
490
491 set_ui_file_data (file, stream, ioscm_file_port_delete);
492 set_ui_file_rewind (file, ioscm_file_port_rewind);
493 set_ui_file_put (file, ioscm_file_port_put);
494 set_ui_file_write (file, ioscm_file_port_write);
495 stream->magic = &file_port_magic;
496 stream->port = port;
497
498 return file;
499 }
500 \f
501 /* Helper routine for with-{output,error}-to-port. */
502
503 static SCM
504 ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
505 const char *func_name)
506 {
507 struct ui_file *port_file;
508 struct cleanup *cleanups;
509 SCM result;
510
511 SCM_ASSERT_TYPE (gdbscm_is_true (scm_output_port_p (port)), port,
512 SCM_ARG1, func_name, _("output port"));
513 SCM_ASSERT_TYPE (gdbscm_is_true (scm_thunk_p (thunk)), thunk,
514 SCM_ARG2, func_name, _("thunk"));
515
516 cleanups = set_batch_flag_and_make_cleanup_restore_page_info ();
517
518 make_cleanup_restore_integer (&interpreter_async);
519 interpreter_async = 0;
520
521 port_file = ioscm_file_port_new (port);
522
523 make_cleanup_ui_file_delete (port_file);
524
525 if (oport == GDB_STDERR)
526 {
527 make_cleanup_restore_ui_file (&gdb_stderr);
528 gdb_stderr = port_file;
529 }
530 else
531 {
532 make_cleanup_restore_ui_file (&gdb_stdout);
533
534 if (ui_out_redirect (current_uiout, port_file) < 0)
535 warning (_("Current output protocol does not support redirection"));
536 else
537 make_cleanup_ui_out_redirect_pop (current_uiout);
538
539 gdb_stdout = port_file;
540 }
541
542 result = gdbscm_safe_call_0 (thunk, NULL);
543
544 do_cleanups (cleanups);
545
546 if (gdbscm_is_exception (result))
547 gdbscm_throw (result);
548
549 return result;
550 }
551
552 /* (%with-gdb-output-to-port port thunk) -> object
553 This function is experimental.
554 IWBN to not include "gdb" in the name, but it would collide with a standard
555 procedure, and it's common to import the gdb module without a prefix.
556 There are ways around this, but they're more cumbersome.
557
558 This has % in the name because it's experimental, and we want the
559 user-visible version to come from module (gdb experimental). */
560
561 static SCM
562 gdbscm_percent_with_gdb_output_to_port (SCM port, SCM thunk)
563 {
564 return ioscm_with_output_to_port_worker (port, thunk, GDB_STDOUT, FUNC_NAME);
565 }
566
567 /* (%with-gdb-error-to-port port thunk) -> object
568 This function is experimental.
569 IWBN to not include "gdb" in the name, but it would collide with a standard
570 procedure, and it's common to import the gdb module without a prefix.
571 There are ways around this, but they're more cumbersome.
572
573 This has % in the name because it's experimental, and we want the
574 user-visible version to come from module (gdb experimental). */
575
576 static SCM
577 gdbscm_percent_with_gdb_error_to_port (SCM port, SCM thunk)
578 {
579 return ioscm_with_output_to_port_worker (port, thunk, GDB_STDERR, FUNC_NAME);
580 }
581 \f
582 /* Support for r/w memory via ports. */
583
584 /* Perform an "lseek" to OFFSET,WHENCE on memory port IOMEM.
585 OFFSET must be in the range [0,size].
586 The result is non-zero for success, zero for failure. */
587
588 static int
589 ioscm_lseek_address (ioscm_memory_port *iomem, LONGEST offset, int whence)
590 {
591 CORE_ADDR new_current;
592
593 gdb_assert (iomem->current <= iomem->size);
594
595 switch (whence)
596 {
597 case SEEK_CUR:
598 /* Catch over/underflow. */
599 if ((offset < 0 && iomem->current + offset > iomem->current)
600 || (offset > 0 && iomem->current + offset < iomem->current))
601 return 0;
602 new_current = iomem->current + offset;
603 break;
604 case SEEK_SET:
605 new_current = offset;
606 break;
607 case SEEK_END:
608 if (offset == 0)
609 {
610 new_current = iomem->size;
611 break;
612 }
613 /* TODO: Not supported yet. */
614 return 0;
615 default:
616 return 0;
617 }
618
619 if (new_current > iomem->size)
620 return 0;
621 iomem->current = new_current;
622 return 1;
623 }
624
625 /* "fill_input" method for memory ports. */
626
627 static int
628 gdbscm_memory_port_fill_input (SCM port)
629 {
630 scm_t_port *pt = SCM_PTAB_ENTRY (port);
631 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
632 size_t to_read;
633
634 /* "current" is the offset of the first byte we want to read. */
635 gdb_assert (iomem->current <= iomem->size);
636 if (iomem->current == iomem->size)
637 return EOF;
638
639 /* Don't read outside the allowed memory range. */
640 to_read = pt->read_buf_size;
641 if (to_read > iomem->size - iomem->current)
642 to_read = iomem->size - iomem->current;
643
644 if (target_read_memory (iomem->start + iomem->current, pt->read_buf,
645 to_read) != 0)
646 gdbscm_memory_error (FUNC_NAME, _("error reading memory"), SCM_EOL);
647
648 iomem->current += to_read;
649 pt->read_pos = pt->read_buf;
650 pt->read_end = pt->read_buf + to_read;
651 return *pt->read_buf;
652 }
653
654 /* "end_input" method for memory ports.
655 Clear the read buffer and adjust the file position for unread bytes. */
656
657 static void
658 gdbscm_memory_port_end_input (SCM port, int offset)
659 {
660 scm_t_port *pt = SCM_PTAB_ENTRY (port);
661 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
662 size_t remaining = pt->read_end - pt->read_pos;
663
664 /* Note: Use of "int offset" is specified by Guile ports API. */
665 if ((offset < 0 && remaining + offset > remaining)
666 || (offset > 0 && remaining + offset < remaining))
667 {
668 gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
669 _("overflow in offset calculation"));
670 }
671 offset += remaining;
672
673 if (offset > 0)
674 {
675 pt->read_pos = pt->read_end;
676 /* Throw error if unread-char used at beginning of file
677 then attempting to write. Seems correct. */
678 if (!ioscm_lseek_address (iomem, -offset, SEEK_CUR))
679 {
680 gdbscm_out_of_range_error (FUNC_NAME, 0, scm_from_int (offset),
681 _("bad offset"));
682 }
683 }
684
685 pt->rw_active = SCM_PORT_NEITHER;
686 }
687
688 /* "flush" method for memory ports. */
689
690 static void
691 gdbscm_memory_port_flush (SCM port)
692 {
693 scm_t_port *pt = SCM_PTAB_ENTRY (port);
694 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
695 size_t to_write = pt->write_pos - pt->write_buf;
696
697 if (to_write == 0)
698 return;
699
700 /* There's no way to indicate a short write, so if the request goes past
701 the end of the port's memory range, flag an error. */
702 if (to_write > iomem->size - iomem->current)
703 {
704 gdbscm_out_of_range_error (FUNC_NAME, 0,
705 gdbscm_scm_from_ulongest (to_write),
706 _("writing beyond end of memory range"));
707 }
708
709 if (target_write_memory (iomem->start + iomem->current, pt->write_buf,
710 to_write) != 0)
711 gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
712
713 iomem->current += to_write;
714 pt->write_pos = pt->write_buf;
715 pt->rw_active = SCM_PORT_NEITHER;
716 }
717
718 /* "write" method for memory ports. */
719
720 static void
721 gdbscm_memory_port_write (SCM port, const void *void_data, size_t size)
722 {
723 scm_t_port *pt = SCM_PTAB_ENTRY (port);
724 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
725 const gdb_byte *data = (const gdb_byte *) void_data;
726
727 /* There's no way to indicate a short write, so if the request goes past
728 the end of the port's memory range, flag an error. */
729 if (size > iomem->size - iomem->current)
730 {
731 gdbscm_out_of_range_error (FUNC_NAME, 0, gdbscm_scm_from_ulongest (size),
732 _("writing beyond end of memory range"));
733 }
734
735 if (pt->write_buf == &pt->shortbuf)
736 {
737 /* Unbuffered port. */
738 if (target_write_memory (iomem->start + iomem->current, data, size) != 0)
739 gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
740 iomem->current += size;
741 return;
742 }
743
744 /* Note: The edge case of what to do when the buffer exactly fills is
745 debatable. Guile flushes when the buffer exactly fills up, so we
746 do too. It's counter-intuitive to my mind, but in case there's a
747 subtlety somewhere that depends on this, we do the same. */
748
749 {
750 size_t space = pt->write_end - pt->write_pos;
751
752 if (size < space)
753 {
754 /* Data fits in buffer, and does not fill it. */
755 memcpy (pt->write_pos, data, size);
756 pt->write_pos += size;
757 }
758 else
759 {
760 memcpy (pt->write_pos, data, space);
761 pt->write_pos = pt->write_end;
762 gdbscm_memory_port_flush (port);
763 {
764 const gdb_byte *ptr = data + space;
765 size_t remaining = size - space;
766
767 if (remaining >= pt->write_buf_size)
768 {
769 if (target_write_memory (iomem->start + iomem->current, ptr,
770 remaining) != 0)
771 gdbscm_memory_error (FUNC_NAME, _("error writing memory"),
772 SCM_EOL);
773 iomem->current += remaining;
774 }
775 else
776 {
777 memcpy (pt->write_pos, ptr, remaining);
778 pt->write_pos += remaining;
779 }
780 }
781 }
782 }
783 }
784
785 /* "seek" method for memory ports. */
786
787 static scm_t_off
788 gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence)
789 {
790 scm_t_port *pt = SCM_PTAB_ENTRY (port);
791 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
792 CORE_ADDR result;
793 int rc;
794
795 if (pt->rw_active == SCM_PORT_WRITE)
796 {
797 if (offset != 0 || whence != SEEK_CUR)
798 {
799 gdbscm_memory_port_flush (port);
800 rc = ioscm_lseek_address (iomem, offset, whence);
801 result = iomem->current;
802 }
803 else
804 {
805 /* Read current position without disturbing the buffer,
806 but flag an error if what's in the buffer goes outside the
807 allowed range. */
808 CORE_ADDR current = iomem->current;
809 size_t delta = pt->write_pos - pt->write_buf;
810
811 if (current + delta < current
812 || current + delta > iomem->size)
813 rc = 0;
814 else
815 {
816 result = current + delta;
817 rc = 1;
818 }
819 }
820 }
821 else if (pt->rw_active == SCM_PORT_READ)
822 {
823 if (offset != 0 || whence != SEEK_CUR)
824 {
825 scm_end_input (port);
826 rc = ioscm_lseek_address (iomem, offset, whence);
827 result = iomem->current;
828 }
829 else
830 {
831 /* Read current position without disturbing the buffer
832 (particularly the unread-char buffer). */
833 CORE_ADDR current = iomem->current;
834 size_t remaining = pt->read_end - pt->read_pos;
835
836 if (current - remaining > current
837 || current - remaining < iomem->start)
838 rc = 0;
839 else
840 {
841 result = current - remaining;
842 rc = 1;
843 }
844
845 if (rc != 0 && pt->read_buf == pt->putback_buf)
846 {
847 size_t saved_remaining = pt->saved_read_end - pt->saved_read_pos;
848
849 if (result - saved_remaining > result
850 || result - saved_remaining < iomem->start)
851 rc = 0;
852 else
853 result -= saved_remaining;
854 }
855 }
856 }
857 else /* SCM_PORT_NEITHER */
858 {
859 rc = ioscm_lseek_address (iomem, offset, whence);
860 result = iomem->current;
861 }
862
863 if (rc == 0)
864 {
865 gdbscm_out_of_range_error (FUNC_NAME, 0,
866 gdbscm_scm_from_longest (offset),
867 _("bad seek"));
868 }
869
870 /* TODO: The Guile API doesn't support 32x64. We can't fix that here,
871 and there's no need to throw an error if the new address can't be
872 represented in a scm_t_off. But we could return something less
873 clumsy. */
874 return result;
875 }
876
877 /* "close" method for memory ports. */
878
879 static int
880 gdbscm_memory_port_close (SCM port)
881 {
882 scm_t_port *pt = SCM_PTAB_ENTRY (port);
883 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
884
885 gdbscm_memory_port_flush (port);
886
887 if (pt->read_buf == pt->putback_buf)
888 pt->read_buf = pt->saved_read_buf;
889 if (pt->read_buf != &pt->shortbuf)
890 xfree (pt->read_buf);
891 if (pt->write_buf != &pt->shortbuf)
892 xfree (pt->write_buf);
893 scm_gc_free (iomem, sizeof (*iomem), "memory port");
894
895 return 0;
896 }
897
898 /* "free" method for memory ports. */
899
900 static size_t
901 gdbscm_memory_port_free (SCM port)
902 {
903 gdbscm_memory_port_close (port);
904
905 return 0;
906 }
907
908 /* "print" method for memory ports. */
909
910 static int
911 gdbscm_memory_port_print (SCM exp, SCM port, scm_print_state *pstate)
912 {
913 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (exp);
914 char *type = SCM_PTOBNAME (SCM_PTOBNUM (exp));
915
916 scm_puts ("#<", port);
917 scm_print_port_mode (exp, port);
918 /* scm_print_port_mode includes a trailing space. */
919 gdbscm_printf (port, "%s %s-%s", type,
920 hex_string (iomem->start), hex_string (iomem->end));
921 scm_putc ('>', port);
922 return 1;
923 }
924
925 /* Create the port type used for memory. */
926
927 static void
928 ioscm_init_memory_port_type (void)
929 {
930 memory_port_desc = scm_make_port_type (memory_port_desc_name,
931 gdbscm_memory_port_fill_input,
932 gdbscm_memory_port_write);
933
934 scm_set_port_end_input (memory_port_desc, gdbscm_memory_port_end_input);
935 scm_set_port_flush (memory_port_desc, gdbscm_memory_port_flush);
936 scm_set_port_seek (memory_port_desc, gdbscm_memory_port_seek);
937 scm_set_port_close (memory_port_desc, gdbscm_memory_port_close);
938 scm_set_port_free (memory_port_desc, gdbscm_memory_port_free);
939 scm_set_port_print (memory_port_desc, gdbscm_memory_port_print);
940 }
941
942 /* Helper for gdbscm_open_memory to parse the mode bits.
943 An exception is thrown if MODE is invalid. */
944
945 static long
946 ioscm_parse_mode_bits (const char *func_name, const char *mode)
947 {
948 const char *p;
949 long mode_bits;
950
951 if (*mode != 'r' && *mode != 'w')
952 {
953 gdbscm_out_of_range_error (func_name, 0,
954 gdbscm_scm_from_c_string (mode),
955 _("bad mode string"));
956 }
957 for (p = mode + 1; *p != '\0'; ++p)
958 {
959 switch (*p)
960 {
961 case '0':
962 case 'b':
963 case '+':
964 break;
965 default:
966 gdbscm_out_of_range_error (func_name, 0,
967 gdbscm_scm_from_c_string (mode),
968 _("bad mode string"));
969 }
970 }
971
972 /* Kinda awkward to convert the mode from SCM -> string only to have Guile
973 convert it back to SCM, but that's the API we have to work with. */
974 mode_bits = scm_mode_bits ((char *) mode);
975
976 return mode_bits;
977 }
978
979 /* Helper for gdbscm_open_memory to finish initializing the port.
980 The port has address range [start,end).
981 This means that address of 0xff..ff is not accessible.
982 I can live with that. */
983
984 static void
985 ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end)
986 {
987 scm_t_port *pt;
988 ioscm_memory_port *iomem;
989 int buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0;
990
991 gdb_assert (start <= end);
992
993 iomem = (ioscm_memory_port *) scm_gc_malloc_pointerless (sizeof (*iomem),
994 "memory port");
995
996 iomem->start = start;
997 iomem->end = end;
998 iomem->size = end - start;
999 iomem->current = 0;
1000 if (buffered)
1001 {
1002 iomem->read_buf_size = default_read_buf_size;
1003 iomem->write_buf_size = default_write_buf_size;
1004 }
1005 else
1006 {
1007 iomem->read_buf_size = 1;
1008 iomem->write_buf_size = 1;
1009 }
1010
1011 pt = SCM_PTAB_ENTRY (port);
1012 /* Match the expectation of `binary-port?'. */
1013 pt->encoding = NULL;
1014 pt->rw_random = 1;
1015 pt->read_buf_size = iomem->read_buf_size;
1016 pt->write_buf_size = iomem->write_buf_size;
1017 if (buffered)
1018 {
1019 pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
1020 pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
1021 }
1022 else
1023 {
1024 pt->read_buf = &pt->shortbuf;
1025 pt->write_buf = &pt->shortbuf;
1026 }
1027 pt->read_pos = pt->read_end = pt->read_buf;
1028 pt->write_pos = pt->write_buf;
1029 pt->write_end = pt->write_buf + pt->write_buf_size;
1030
1031 SCM_SETSTREAM (port, iomem);
1032 }
1033
1034 /* Re-initialize a memory port, updating its read/write buffer sizes.
1035 An exception is thrown if the port is unbuffered.
1036 TODO: Allow switching buffered/unbuffered.
1037 An exception is also thrown if data is still buffered, except in the case
1038 where the buffer size isn't changing (since that's just a nop). */
1039
1040 static void
1041 ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
1042 size_t write_buf_size, const char *func_name)
1043 {
1044 scm_t_port *pt = SCM_PTAB_ENTRY (port);
1045 ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
1046
1047 gdb_assert (read_buf_size >= min_memory_port_buf_size
1048 && read_buf_size <= max_memory_port_buf_size);
1049 gdb_assert (write_buf_size >= min_memory_port_buf_size
1050 && write_buf_size <= max_memory_port_buf_size);
1051
1052 /* First check if the port is unbuffered. */
1053
1054 if (pt->read_buf == &pt->shortbuf)
1055 {
1056 gdb_assert (pt->write_buf == &pt->shortbuf);
1057 scm_misc_error (func_name, _("port is unbuffered: ~a"),
1058 scm_list_1 (port));
1059 }
1060
1061 /* Next check if anything is buffered. */
1062
1063 if (read_buf_size != pt->read_buf_size
1064 && pt->read_end != pt->read_buf)
1065 {
1066 scm_misc_error (func_name, _("read buffer not empty: ~a"),
1067 scm_list_1 (port));
1068 }
1069
1070 if (write_buf_size != pt->write_buf_size
1071 && pt->write_pos != pt->write_buf)
1072 {
1073 scm_misc_error (func_name, _("write buffer not empty: ~a"),
1074 scm_list_1 (port));
1075 }
1076
1077 /* Now we can update the buffer sizes, but only if the size has changed. */
1078
1079 if (read_buf_size != pt->read_buf_size)
1080 {
1081 iomem->read_buf_size = read_buf_size;
1082 pt->read_buf_size = read_buf_size;
1083 xfree (pt->read_buf);
1084 pt->read_buf = (unsigned char *) xmalloc (pt->read_buf_size);
1085 pt->read_pos = pt->read_end = pt->read_buf;
1086 }
1087
1088 if (write_buf_size != pt->write_buf_size)
1089 {
1090 iomem->write_buf_size = write_buf_size;
1091 pt->write_buf_size = write_buf_size;
1092 xfree (pt->write_buf);
1093 pt->write_buf = (unsigned char *) xmalloc (pt->write_buf_size);
1094 pt->write_pos = pt->write_buf;
1095 pt->write_end = pt->write_buf + pt->write_buf_size;
1096 }
1097 }
1098
1099 /* (open-memory [#:mode string] [#:start address] [#:size integer]) -> port
1100 Return a port that can be used for reading and writing memory.
1101 MODE is a string, and must be one of "r", "w", or "r+".
1102 "0" may be appended to MODE to mark the port as unbuffered.
1103 For compatibility "b" (binary) may also be appended, but we ignore it:
1104 memory ports are binary only.
1105
1106 The chunk of memory that can be accessed can be bounded.
1107 If both START,SIZE are unspecified, all of memory can be accessed
1108 (except 0xff..ff). If only START is specified, all of memory from that
1109 point on can be accessed (except 0xff..ff). If only SIZE if specified,
1110 all memory in [0,SIZE) can be accessed. If both are specified, all memory
1111 in [START,START+SIZE) can be accessed.
1112
1113 Note: If it becomes useful enough we can later add #:end as an alternative
1114 to #:size. For now it is left out.
1115
1116 The result is a Scheme port, and its semantics are a bit odd for accessing
1117 memory (e.g., unget), but we don't try to hide this. It's a port.
1118
1119 N.B. Seeks on the port must be in the range [0,size].
1120 This is for similarity with bytevector ports, and so that one can seek
1121 to the first byte. */
1122
1123 static SCM
1124 gdbscm_open_memory (SCM rest)
1125 {
1126 const SCM keywords[] = {
1127 mode_keyword, start_keyword, size_keyword, SCM_BOOL_F
1128 };
1129 char *mode = NULL;
1130 CORE_ADDR start = 0;
1131 CORE_ADDR end;
1132 int mode_arg_pos = -1, start_arg_pos = -1, size_arg_pos = -1;
1133 ULONGEST size;
1134 SCM port;
1135 long mode_bits;
1136
1137 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "#sUU", rest,
1138 &mode_arg_pos, &mode,
1139 &start_arg_pos, &start,
1140 &size_arg_pos, &size);
1141
1142 scm_dynwind_begin ((scm_t_dynwind_flags) 0);
1143
1144 if (mode == NULL)
1145 mode = xstrdup ("r");
1146 scm_dynwind_free (mode);
1147
1148 if (size_arg_pos > 0)
1149 {
1150 /* For now be strict about start+size overflowing. If it becomes
1151 a nuisance we can relax things later. */
1152 if (start + size < start)
1153 {
1154 gdbscm_out_of_range_error (FUNC_NAME, 0,
1155 scm_list_2 (gdbscm_scm_from_ulongest (start),
1156 gdbscm_scm_from_ulongest (size)),
1157 _("start+size overflows"));
1158 }
1159 end = start + size;
1160 }
1161 else
1162 end = ~(CORE_ADDR) 0;
1163
1164 mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode);
1165
1166 port = ioscm_open_port (memory_port_desc, mode_bits);
1167
1168 ioscm_init_memory_port (port, start, end);
1169
1170 scm_dynwind_end ();
1171
1172 /* TODO: Set the file name as "memory-start-end"? */
1173 return port;
1174 }
1175
1176 /* Return non-zero if OBJ is a memory port. */
1177
1178 static int
1179 gdbscm_is_memory_port (SCM obj)
1180 {
1181 return !SCM_IMP (obj) && (SCM_TYP16 (obj) == memory_port_desc);
1182 }
1183
1184 /* (memory-port? obj) -> boolean */
1185
1186 static SCM
1187 gdbscm_memory_port_p (SCM obj)
1188 {
1189 return scm_from_bool (gdbscm_is_memory_port (obj));
1190 }
1191
1192 /* (memory-port-range port) -> (start end) */
1193
1194 static SCM
1195 gdbscm_memory_port_range (SCM port)
1196 {
1197 ioscm_memory_port *iomem;
1198
1199 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1200 memory_port_desc_name);
1201
1202 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1203 return scm_list_2 (gdbscm_scm_from_ulongest (iomem->start),
1204 gdbscm_scm_from_ulongest (iomem->end));
1205 }
1206
1207 /* (memory-port-read-buffer-size port) -> integer */
1208
1209 static SCM
1210 gdbscm_memory_port_read_buffer_size (SCM port)
1211 {
1212 ioscm_memory_port *iomem;
1213
1214 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1215 memory_port_desc_name);
1216
1217 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1218 return scm_from_uint (iomem->read_buf_size);
1219 }
1220
1221 /* (set-memory-port-read-buffer-size! port size) -> unspecified
1222 An exception is thrown if read data is still buffered or if the port
1223 is unbuffered. */
1224
1225 static SCM
1226 gdbscm_set_memory_port_read_buffer_size_x (SCM port, SCM size)
1227 {
1228 ioscm_memory_port *iomem;
1229
1230 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1231 memory_port_desc_name);
1232 SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
1233 _("integer"));
1234
1235 if (!scm_is_unsigned_integer (size, min_memory_port_buf_size,
1236 max_memory_port_buf_size))
1237 {
1238 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, size,
1239 out_of_range_buf_size);
1240 }
1241
1242 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1243 ioscm_reinit_memory_port (port, scm_to_uint (size), iomem->write_buf_size,
1244 FUNC_NAME);
1245
1246 return SCM_UNSPECIFIED;
1247 }
1248
1249 /* (memory-port-write-buffer-size port) -> integer */
1250
1251 static SCM
1252 gdbscm_memory_port_write_buffer_size (SCM port)
1253 {
1254 ioscm_memory_port *iomem;
1255
1256 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1257 memory_port_desc_name);
1258
1259 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1260 return scm_from_uint (iomem->write_buf_size);
1261 }
1262
1263 /* (set-memory-port-write-buffer-size! port size) -> unspecified
1264 An exception is thrown if write data is still buffered or if the port
1265 is unbuffered. */
1266
1267 static SCM
1268 gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM size)
1269 {
1270 ioscm_memory_port *iomem;
1271
1272 SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
1273 memory_port_desc_name);
1274 SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
1275 _("integer"));
1276
1277 if (!scm_is_unsigned_integer (size, min_memory_port_buf_size,
1278 max_memory_port_buf_size))
1279 {
1280 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, size,
1281 out_of_range_buf_size);
1282 }
1283
1284 iomem = (ioscm_memory_port *) SCM_STREAM (port);
1285 ioscm_reinit_memory_port (port, iomem->read_buf_size, scm_to_uint (size),
1286 FUNC_NAME);
1287
1288 return SCM_UNSPECIFIED;
1289 }
1290 \f
1291 /* Initialize gdb ports. */
1292
1293 static const scheme_function port_functions[] =
1294 {
1295 { "input-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_input_port),
1296 "\
1297 Return gdb's input port." },
1298
1299 { "output-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_output_port),
1300 "\
1301 Return gdb's output port." },
1302
1303 { "error-port", 0, 0, 0, as_a_scm_t_subr (gdbscm_error_port),
1304 "\
1305 Return gdb's error port." },
1306
1307 { "stdio-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_stdio_port_p),
1308 "\
1309 Return #t if the object is a gdb:stdio-port." },
1310
1311 { "open-memory", 0, 0, 1, as_a_scm_t_subr (gdbscm_open_memory),
1312 "\
1313 Return a port that can be used for reading/writing inferior memory.\n\
1314 \n\
1315 Arguments: [#:mode string] [#:start address] [#:size integer]\n\
1316 Returns: A port object." },
1317
1318 { "memory-port?", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_p),
1319 "\
1320 Return #t if the object is a memory port." },
1321
1322 { "memory-port-range", 1, 0, 0, as_a_scm_t_subr (gdbscm_memory_port_range),
1323 "\
1324 Return the memory range of the port as (start end)." },
1325
1326 { "memory-port-read-buffer-size", 1, 0, 0,
1327 as_a_scm_t_subr (gdbscm_memory_port_read_buffer_size),
1328 "\
1329 Return the size of the read buffer for the memory port." },
1330
1331 { "set-memory-port-read-buffer-size!", 2, 0, 0,
1332 as_a_scm_t_subr (gdbscm_set_memory_port_read_buffer_size_x),
1333 "\
1334 Set the size of the read buffer for the memory port.\n\
1335 \n\
1336 Arguments: port integer\n\
1337 Returns: unspecified." },
1338
1339 { "memory-port-write-buffer-size", 1, 0, 0,
1340 as_a_scm_t_subr (gdbscm_memory_port_write_buffer_size),
1341 "\
1342 Return the size of the write buffer for the memory port." },
1343
1344 { "set-memory-port-write-buffer-size!", 2, 0, 0,
1345 as_a_scm_t_subr (gdbscm_set_memory_port_write_buffer_size_x),
1346 "\
1347 Set the size of the write buffer for the memory port.\n\
1348 \n\
1349 Arguments: port integer\n\
1350 Returns: unspecified." },
1351
1352 END_FUNCTIONS
1353 };
1354
1355 static const scheme_function private_port_functions[] =
1356 {
1357 #if 0 /* TODO */
1358 { "%with-gdb-input-from-port", 2, 0, 0,
1359 as_a_scm_t_subr (gdbscm_percent_with_gdb_input_from_port),
1360 "\
1361 Temporarily set GDB's input port to PORT and then invoke THUNK.\n\
1362 \n\
1363 Arguments: port thunk\n\
1364 Returns: The result of calling THUNK.\n\
1365 \n\
1366 This procedure is experimental." },
1367 #endif
1368
1369 { "%with-gdb-output-to-port", 2, 0, 0,
1370 as_a_scm_t_subr (gdbscm_percent_with_gdb_output_to_port),
1371 "\
1372 Temporarily set GDB's output port to PORT and then invoke THUNK.\n\
1373 \n\
1374 Arguments: port thunk\n\
1375 Returns: The result of calling THUNK.\n\
1376 \n\
1377 This procedure is experimental." },
1378
1379 { "%with-gdb-error-to-port", 2, 0, 0,
1380 as_a_scm_t_subr (gdbscm_percent_with_gdb_error_to_port),
1381 "\
1382 Temporarily set GDB's error port to PORT and then invoke THUNK.\n\
1383 \n\
1384 Arguments: port thunk\n\
1385 Returns: The result of calling THUNK.\n\
1386 \n\
1387 This procedure is experimental." },
1388
1389 END_FUNCTIONS
1390 };
1391
1392 void
1393 gdbscm_initialize_ports (void)
1394 {
1395 /* Save the original stdio ports for debugging purposes. */
1396
1397 orig_input_port_scm = scm_current_input_port ();
1398 orig_output_port_scm = scm_current_output_port ();
1399 orig_error_port_scm = scm_current_error_port ();
1400
1401 /* Set up the stdio ports. */
1402
1403 ioscm_init_gdb_stdio_port ();
1404 input_port_scm = ioscm_make_gdb_stdio_port (0);
1405 output_port_scm = ioscm_make_gdb_stdio_port (1);
1406 error_port_scm = ioscm_make_gdb_stdio_port (2);
1407
1408 /* Set up memory ports. */
1409
1410 ioscm_init_memory_port_type ();
1411
1412 /* Install the accessor functions. */
1413
1414 gdbscm_define_functions (port_functions, 1);
1415 gdbscm_define_functions (private_port_functions, 0);
1416
1417 /* Keyword args for open-memory. */
1418
1419 mode_keyword = scm_from_latin1_keyword ("mode");
1420 start_keyword = scm_from_latin1_keyword ("start");
1421 size_keyword = scm_from_latin1_keyword ("size");
1422
1423 /* Error message text for "out of range" memory port buffer sizes. */
1424
1425 out_of_range_buf_size = xstrprintf ("size not between %u - %u",
1426 min_memory_port_buf_size,
1427 max_memory_port_buf_size);
1428 }
This page took 0.073158 seconds and 4 git commands to generate.