1 /* Dump-to-file commands, for GDB, the GNU debugger.
3 Copyright (C) 2002-2017 Free Software Foundation, Inc.
5 Contributed by Red Hat.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "cli/cli-decode.h"
24 #include "cli/cli-cmds.h"
26 #include "completer.h"
29 #include "readline/readline.h"
31 #include "cli/cli-utils.h"
33 #include "filestuff.h"
34 #include "common/byte-vector.h"
37 scan_expression_with_cleanup (const char **cmd
, const char *def
)
39 if ((*cmd
) == NULL
|| (**cmd
) == '\0')
41 char *exp
= xstrdup (def
);
43 make_cleanup (xfree
, exp
);
51 end
= (*cmd
) + strcspn (*cmd
, " \t");
52 exp
= savestring ((*cmd
), end
- (*cmd
));
53 make_cleanup (xfree
, exp
);
54 (*cmd
) = skip_spaces_const (end
);
61 scan_filename_with_cleanup (const char **cmd
, const char *defname
)
66 /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */
72 error (_("Missing filename."));
73 filename
= xstrdup (defname
);
74 make_cleanup (xfree
, filename
);
78 /* FIXME: should parse a possibly quoted string. */
81 (*cmd
) = skip_spaces_const (*cmd
);
82 end
= *cmd
+ strcspn (*cmd
, " \t");
83 filename
= savestring ((*cmd
), end
- (*cmd
));
84 make_cleanup (xfree
, filename
);
85 (*cmd
) = skip_spaces_const (end
);
87 gdb_assert (filename
!= NULL
);
89 fullname
= tilde_expand (filename
);
90 make_cleanup (xfree
, fullname
);
95 static gdb_bfd_ref_ptr
96 bfd_openr_or_error (const char *filename
, const char *target
)
98 gdb_bfd_ref_ptr
ibfd (gdb_bfd_openr (filename
, target
));
100 error (_("Failed to open %s: %s."), filename
,
101 bfd_errmsg (bfd_get_error ()));
103 if (!bfd_check_format (ibfd
.get (), bfd_object
))
104 error (_("'%s' is not a recognized file format."), filename
);
109 static gdb_bfd_ref_ptr
110 bfd_openw_or_error (const char *filename
, const char *target
, const char *mode
)
112 gdb_bfd_ref_ptr obfd
;
114 if (*mode
== 'w') /* Write: create new file */
116 obfd
= gdb_bfd_openw (filename
, target
);
118 error (_("Failed to open %s: %s."), filename
,
119 bfd_errmsg (bfd_get_error ()));
120 if (!bfd_set_format (obfd
.get (), bfd_object
))
121 error (_("bfd_openw_or_error: %s."), bfd_errmsg (bfd_get_error ()));
123 else if (*mode
== 'a') /* Append to existing file. */
124 { /* FIXME -- doesn't work... */
125 error (_("bfd_openw does not work with append."));
128 error (_("bfd_openw_or_error: unknown mode %s."), mode
);
133 static struct cmd_list_element
*dump_cmdlist
;
134 static struct cmd_list_element
*append_cmdlist
;
135 static struct cmd_list_element
*srec_cmdlist
;
136 static struct cmd_list_element
*ihex_cmdlist
;
137 static struct cmd_list_element
*verilog_cmdlist
;
138 static struct cmd_list_element
*tekhex_cmdlist
;
139 static struct cmd_list_element
*binary_dump_cmdlist
;
140 static struct cmd_list_element
*binary_append_cmdlist
;
143 dump_command (char *cmd
, int from_tty
)
145 printf_unfiltered (_("\"dump\" must be followed by a subcommand.\n\n"));
146 help_list (dump_cmdlist
, "dump ", all_commands
, gdb_stdout
);
150 append_command (char *cmd
, int from_tty
)
152 printf_unfiltered (_("\"append\" must be followed by a subcommand.\n\n"));
153 help_list (dump_cmdlist
, "append ", all_commands
, gdb_stdout
);
157 dump_binary_file (const char *filename
, const char *mode
,
158 const bfd_byte
*buf
, ULONGEST len
)
162 gdb_file_up file
= gdb_fopen_cloexec (filename
, mode
);
163 status
= fwrite (buf
, len
, 1, file
.get ());
165 perror_with_name (filename
);
169 dump_bfd_file (const char *filename
, const char *mode
,
170 const char *target
, CORE_ADDR vaddr
,
171 const bfd_byte
*buf
, ULONGEST len
)
175 gdb_bfd_ref_ptr
obfd (bfd_openw_or_error (filename
, target
, mode
));
176 osection
= bfd_make_section_anyway (obfd
.get (), ".newsec");
177 bfd_set_section_size (obfd
.get (), osection
, len
);
178 bfd_set_section_vma (obfd
.get (), osection
, vaddr
);
179 bfd_set_section_alignment (obfd
.get (), osection
, 0);
180 bfd_set_section_flags (obfd
.get (), osection
, (SEC_HAS_CONTENTS
183 osection
->entsize
= 0;
184 if (!bfd_set_section_contents (obfd
.get (), osection
, buf
, 0, len
))
185 warning (_("writing dump file '%s' (%s)"), filename
,
186 bfd_errmsg (bfd_get_error ()));
190 dump_memory_to_file (const char *cmd
, const char *mode
, const char *file_format
)
192 struct cleanup
*old_cleanups
= make_cleanup (null_cleanup
, NULL
);
196 const char *filename
;
201 filename
= scan_filename_with_cleanup (&cmd
, NULL
);
203 /* Find the low address. */
204 if (cmd
== NULL
|| *cmd
== '\0')
205 error (_("Missing start address."));
206 lo_exp
= scan_expression_with_cleanup (&cmd
, NULL
);
208 /* Find the second address - rest of line. */
209 if (cmd
== NULL
|| *cmd
== '\0')
210 error (_("Missing stop address."));
213 lo
= parse_and_eval_address (lo_exp
);
214 hi
= parse_and_eval_address (hi_exp
);
216 error (_("Invalid memory address range (start >= end)."));
219 /* FIXME: Should use read_memory_partial() and a magic blocking
221 gdb::byte_vector
buf (count
);
222 read_memory (lo
, buf
.data (), count
);
224 /* Have everything. Open/write the data. */
225 if (file_format
== NULL
|| strcmp (file_format
, "binary") == 0)
227 dump_binary_file (filename
, mode
, buf
.data (), count
);
231 dump_bfd_file (filename
, mode
, file_format
, lo
, buf
.data (), count
);
234 do_cleanups (old_cleanups
);
238 dump_memory_command (char *cmd
, const char *mode
)
240 dump_memory_to_file (cmd
, mode
, "binary");
244 dump_value_to_file (const char *cmd
, const char *mode
, const char *file_format
)
246 struct cleanup
*old_cleanups
= make_cleanup (null_cleanup
, NULL
);
248 const char *filename
;
251 filename
= scan_filename_with_cleanup (&cmd
, NULL
);
253 /* Find the value. */
254 if (cmd
== NULL
|| *cmd
== '\0')
255 error (_("No value to %s."), *mode
== 'a' ? "append" : "dump");
256 val
= parse_and_eval (cmd
);
258 error (_("Invalid expression."));
260 /* Have everything. Open/write the data. */
261 if (file_format
== NULL
|| strcmp (file_format
, "binary") == 0)
263 dump_binary_file (filename
, mode
, value_contents (val
),
264 TYPE_LENGTH (value_type (val
)));
270 if (VALUE_LVAL (val
))
272 vaddr
= value_address (val
);
277 warning (_("value is not an lval: address assumed to be zero"));
280 dump_bfd_file (filename
, mode
, file_format
, vaddr
,
281 value_contents (val
),
282 TYPE_LENGTH (value_type (val
)));
285 do_cleanups (old_cleanups
);
289 dump_value_command (char *cmd
, const char *mode
)
291 dump_value_to_file (cmd
, mode
, "binary");
295 dump_srec_memory (char *args
, int from_tty
)
297 dump_memory_to_file (args
, FOPEN_WB
, "srec");
301 dump_srec_value (char *args
, int from_tty
)
303 dump_value_to_file (args
, FOPEN_WB
, "srec");
307 dump_ihex_memory (char *args
, int from_tty
)
309 dump_memory_to_file (args
, FOPEN_WB
, "ihex");
313 dump_ihex_value (char *args
, int from_tty
)
315 dump_value_to_file (args
, FOPEN_WB
, "ihex");
319 dump_verilog_memory (char *args
, int from_tty
)
321 dump_memory_to_file (args
, FOPEN_WB
, "verilog");
325 dump_verilog_value (char *args
, int from_tty
)
327 dump_value_to_file (args
, FOPEN_WB
, "verilog");
331 dump_tekhex_memory (char *args
, int from_tty
)
333 dump_memory_to_file (args
, FOPEN_WB
, "tekhex");
337 dump_tekhex_value (char *args
, int from_tty
)
339 dump_value_to_file (args
, FOPEN_WB
, "tekhex");
343 dump_binary_memory (char *args
, int from_tty
)
345 dump_memory_to_file (args
, FOPEN_WB
, "binary");
349 dump_binary_value (char *args
, int from_tty
)
351 dump_value_to_file (args
, FOPEN_WB
, "binary");
355 append_binary_memory (char *args
, int from_tty
)
357 dump_memory_to_file (args
, FOPEN_AB
, "binary");
361 append_binary_value (char *args
, int from_tty
)
363 dump_value_to_file (args
, FOPEN_AB
, "binary");
368 void (*func
) (char *cmd
, const char *mode
);
373 call_dump_func (struct cmd_list_element
*c
, char *args
, int from_tty
)
375 struct dump_context
*d
= (struct dump_context
*) get_cmd_context (c
);
377 d
->func (args
, d
->mode
);
381 add_dump_command (const char *name
,
382 void (*func
) (char *args
, const char *mode
),
386 struct cmd_list_element
*c
;
387 struct dump_context
*d
;
389 c
= add_cmd (name
, all_commands
, NULL
, descr
, &dump_cmdlist
);
390 c
->completer
= filename_completer
;
391 d
= XNEW (struct dump_context
);
394 set_cmd_context (c
, d
);
395 c
->func
= call_dump_func
;
397 c
= add_cmd (name
, all_commands
, NULL
, descr
, &append_cmdlist
);
398 c
->completer
= filename_completer
;
399 d
= XNEW (struct dump_context
);
402 set_cmd_context (c
, d
);
403 c
->func
= call_dump_func
;
405 /* Replace "Dump " at start of docstring with "Append " (borrowed
406 from [deleted] deprecated_add_show_from_set). */
407 if ( c
->doc
[0] == 'W'
413 c
->doc
= concat ("Append ", c
->doc
+ 6, (char *)NULL
);
416 /* Opaque data for restore_section_callback. */
417 struct callback_data
{
418 CORE_ADDR load_offset
;
419 CORE_ADDR load_start
;
423 /* Function: restore_section_callback.
425 Callback function for bfd_map_over_sections.
426 Selectively loads the sections into memory. */
429 restore_section_callback (bfd
*ibfd
, asection
*isec
, void *args
)
431 struct callback_data
*data
= (struct callback_data
*) args
;
432 bfd_vma sec_start
= bfd_section_vma (ibfd
, isec
);
433 bfd_size_type size
= bfd_section_size (ibfd
, isec
);
434 bfd_vma sec_end
= sec_start
+ size
;
435 bfd_size_type sec_offset
= 0;
436 bfd_size_type sec_load_count
= size
;
439 /* Ignore non-loadable sections, eg. from elf files. */
440 if (!(bfd_get_section_flags (ibfd
, isec
) & SEC_LOAD
))
443 /* Does the section overlap with the desired restore range? */
444 if (sec_end
<= data
->load_start
445 || (data
->load_end
> 0 && sec_start
>= data
->load_end
))
447 /* No, no useable data in this section. */
448 printf_filtered (_("skipping section %s...\n"),
449 bfd_section_name (ibfd
, isec
));
453 /* Compare section address range with user-requested
454 address range (if any). Compute where the actual
455 transfer should start and end. */
456 if (sec_start
< data
->load_start
)
457 sec_offset
= data
->load_start
- sec_start
;
458 /* Size of a partial transfer. */
459 sec_load_count
-= sec_offset
;
460 if (data
->load_end
> 0 && sec_end
> data
->load_end
)
461 sec_load_count
-= sec_end
- data
->load_end
;
464 gdb::byte_vector
buf (size
);
465 if (!bfd_get_section_contents (ibfd
, isec
, buf
.data (), 0, size
))
466 error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd
),
467 bfd_errmsg (bfd_get_error ()));
469 printf_filtered ("Restoring section %s (0x%lx to 0x%lx)",
470 bfd_section_name (ibfd
, isec
),
471 (unsigned long) sec_start
,
472 (unsigned long) sec_end
);
474 if (data
->load_offset
!= 0 || data
->load_start
!= 0 || data
->load_end
!= 0)
475 printf_filtered (" into memory (%s to %s)\n",
476 paddress (target_gdbarch (),
477 (unsigned long) sec_start
478 + sec_offset
+ data
->load_offset
),
479 paddress (target_gdbarch (),
480 (unsigned long) sec_start
+ sec_offset
481 + data
->load_offset
+ sec_load_count
));
483 puts_filtered ("\n");
485 /* Write the data. */
486 ret
= target_write_memory (sec_start
+ sec_offset
+ data
->load_offset
,
487 &buf
[sec_offset
], sec_load_count
);
489 warning (_("restore: memory write failed (%s)."), safe_strerror (ret
));
493 restore_binary_file (const char *filename
, struct callback_data
*data
)
495 gdb_file_up file
= gdb_fopen_cloexec (filename
, FOPEN_RB
);
498 /* Get the file size for reading. */
499 if (fseek (file
.get (), 0, SEEK_END
) == 0)
501 len
= ftell (file
.get ());
503 perror_with_name (filename
);
506 perror_with_name (filename
);
508 if (len
<= data
->load_start
)
509 error (_("Start address is greater than length of binary file %s."),
512 /* Chop off "len" if it exceeds the requested load_end addr. */
513 if (data
->load_end
!= 0 && data
->load_end
< len
)
514 len
= data
->load_end
;
515 /* Chop off "len" if the requested load_start addr skips some bytes. */
516 if (data
->load_start
> 0)
517 len
-= data
->load_start
;
520 ("Restoring binary file %s into memory (0x%lx to 0x%lx)\n",
522 (unsigned long) (data
->load_start
+ data
->load_offset
),
523 (unsigned long) (data
->load_start
+ data
->load_offset
+ len
));
525 /* Now set the file pos to the requested load start pos. */
526 if (fseek (file
.get (), data
->load_start
, SEEK_SET
) != 0)
527 perror_with_name (filename
);
529 /* Now allocate a buffer and read the file contents. */
530 gdb::byte_vector
buf (len
);
531 if (fread (buf
.data (), 1, len
, file
.get ()) != len
)
532 perror_with_name (filename
);
534 /* Now write the buffer into target memory. */
535 len
= target_write_memory (data
->load_start
+ data
->load_offset
,
538 warning (_("restore: memory write failed (%s)."), safe_strerror (len
));
542 restore_command (char *args_in
, int from_tty
)
545 struct callback_data data
;
548 const char *args
= args_in
;
550 if (!target_has_execution
)
553 data
.load_offset
= 0;
557 /* Parse the input arguments. First is filename (required). */
558 filename
= scan_filename_with_cleanup (&args
, NULL
);
559 if (args
!= NULL
&& *args
!= '\0')
561 static const char binary_string
[] = "binary";
563 /* Look for optional "binary" flag. */
564 if (startswith (args
, binary_string
))
567 args
+= strlen (binary_string
);
568 args
= skip_spaces_const (args
);
570 /* Parse offset (optional). */
571 if (args
!= NULL
&& *args
!= '\0')
572 data
.load_offset
= binary_flag
?
573 parse_and_eval_address (scan_expression_with_cleanup (&args
, NULL
)) :
574 parse_and_eval_long (scan_expression_with_cleanup (&args
, NULL
));
575 if (args
!= NULL
&& *args
!= '\0')
577 /* Parse start address (optional). */
579 parse_and_eval_long (scan_expression_with_cleanup (&args
, NULL
));
580 if (args
!= NULL
&& *args
!= '\0')
582 /* Parse end address (optional). */
583 data
.load_end
= parse_and_eval_long (args
);
584 if (data
.load_end
<= data
.load_start
)
585 error (_("Start must be less than end."));
591 printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n",
592 filename
, (unsigned long) data
.load_offset
,
593 (unsigned long) data
.load_start
,
594 (unsigned long) data
.load_end
);
598 restore_binary_file (filename
, &data
);
602 /* Open the file for loading. */
603 gdb_bfd_ref_ptr
ibfd (bfd_openr_or_error (filename
, NULL
));
605 /* Process the sections. */
606 bfd_map_over_sections (ibfd
.get (), restore_section_callback
, &data
);
611 srec_dump_command (char *cmd
, int from_tty
)
613 printf_unfiltered (_("\"dump srec\" must be followed by a subcommand.\n"));
614 help_list (srec_cmdlist
, "dump srec ", all_commands
, gdb_stdout
);
618 ihex_dump_command (char *cmd
, int from_tty
)
620 printf_unfiltered (_("\"dump ihex\" must be followed by a subcommand.\n"));
621 help_list (ihex_cmdlist
, "dump ihex ", all_commands
, gdb_stdout
);
625 verilog_dump_command (char *cmd
, int from_tty
)
627 printf_unfiltered (_("\"dump verilog\" must be followed by a subcommand.\n"));
628 help_list (verilog_cmdlist
, "dump verilog ", all_commands
, gdb_stdout
);
632 tekhex_dump_command (char *cmd
, int from_tty
)
634 printf_unfiltered (_("\"dump tekhex\" must be followed by a subcommand.\n"));
635 help_list (tekhex_cmdlist
, "dump tekhex ", all_commands
, gdb_stdout
);
639 binary_dump_command (char *cmd
, int from_tty
)
641 printf_unfiltered (_("\"dump binary\" must be followed by a subcommand.\n"));
642 help_list (binary_dump_cmdlist
, "dump binary ", all_commands
, gdb_stdout
);
646 binary_append_command (char *cmd
, int from_tty
)
648 printf_unfiltered (_("\"append binary\" must be followed by a subcommand.\n"));
649 help_list (binary_append_cmdlist
, "append binary ", all_commands
,
653 extern initialize_file_ftype _initialize_cli_dump
; /* -Wmissing-prototypes */
656 _initialize_cli_dump (void)
658 struct cmd_list_element
*c
;
660 add_prefix_cmd ("dump", class_vars
, dump_command
,
661 _("Dump target code/data to a local file."),
662 &dump_cmdlist
, "dump ",
665 add_prefix_cmd ("append", class_vars
, append_command
,
666 _("Append target code/data to a local file."),
667 &append_cmdlist
, "append ",
671 add_dump_command ("memory", dump_memory_command
, "\
672 Write contents of memory to a raw binary file.\n\
673 Arguments are FILE START STOP. Writes the contents of memory within the\n\
674 range [START .. STOP) to the specified FILE in raw target ordered bytes.");
676 add_dump_command ("value", dump_value_command
, "\
677 Write the value of an expression to a raw binary file.\n\
678 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION to\n\
679 the specified FILE in raw target ordered bytes.");
681 add_prefix_cmd ("srec", all_commands
, srec_dump_command
,
682 _("Write target code/data to an srec file."),
683 &srec_cmdlist
, "dump srec ",
687 add_prefix_cmd ("ihex", all_commands
, ihex_dump_command
,
688 _("Write target code/data to an intel hex file."),
689 &ihex_cmdlist
, "dump ihex ",
693 add_prefix_cmd ("verilog", all_commands
, verilog_dump_command
,
694 _("Write target code/data to a verilog hex file."),
695 &verilog_cmdlist
, "dump verilog ",
699 add_prefix_cmd ("tekhex", all_commands
, tekhex_dump_command
,
700 _("Write target code/data to a tekhex file."),
701 &tekhex_cmdlist
, "dump tekhex ",
705 add_prefix_cmd ("binary", all_commands
, binary_dump_command
,
706 _("Write target code/data to a raw binary file."),
707 &binary_dump_cmdlist
, "dump binary ",
711 add_prefix_cmd ("binary", all_commands
, binary_append_command
,
712 _("Append target code/data to a raw binary file."),
713 &binary_append_cmdlist
, "append binary ",
717 add_cmd ("memory", all_commands
, dump_srec_memory
, _("\
718 Write contents of memory to an srec file.\n\
719 Arguments are FILE START STOP. Writes the contents of memory\n\
720 within the range [START .. STOP) to the specified FILE in srec format."),
723 add_cmd ("value", all_commands
, dump_srec_value
, _("\
724 Write the value of an expression to an srec file.\n\
725 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
726 to the specified FILE in srec format."),
729 add_cmd ("memory", all_commands
, dump_ihex_memory
, _("\
730 Write contents of memory to an ihex file.\n\
731 Arguments are FILE START STOP. Writes the contents of memory within\n\
732 the range [START .. STOP) to the specified FILE in intel hex format."),
735 add_cmd ("value", all_commands
, dump_ihex_value
, _("\
736 Write the value of an expression to an ihex file.\n\
737 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
738 to the specified FILE in intel hex format."),
741 add_cmd ("memory", all_commands
, dump_verilog_memory
, _("\
742 Write contents of memory to a verilog hex file.\n\
743 Arguments are FILE START STOP. Writes the contents of memory within\n\
744 the range [START .. STOP) to the specified FILE in verilog hex format."),
747 add_cmd ("value", all_commands
, dump_verilog_value
, _("\
748 Write the value of an expression to a verilog hex file.\n\
749 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
750 to the specified FILE in verilog hex format."),
753 add_cmd ("memory", all_commands
, dump_tekhex_memory
, _("\
754 Write contents of memory to a tekhex file.\n\
755 Arguments are FILE START STOP. Writes the contents of memory\n\
756 within the range [START .. STOP) to the specified FILE in tekhex format."),
759 add_cmd ("value", all_commands
, dump_tekhex_value
, _("\
760 Write the value of an expression to a tekhex file.\n\
761 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
762 to the specified FILE in tekhex format."),
765 add_cmd ("memory", all_commands
, dump_binary_memory
, _("\
766 Write contents of memory to a raw binary file.\n\
767 Arguments are FILE START STOP. Writes the contents of memory\n\
768 within the range [START .. STOP) to the specified FILE in binary format."),
769 &binary_dump_cmdlist
);
771 add_cmd ("value", all_commands
, dump_binary_value
, _("\
772 Write the value of an expression to a raw binary file.\n\
773 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
774 to the specified FILE in raw target ordered bytes."),
775 &binary_dump_cmdlist
);
777 add_cmd ("memory", all_commands
, append_binary_memory
, _("\
778 Append contents of memory to a raw binary file.\n\
779 Arguments are FILE START STOP. Writes the contents of memory within the\n\
780 range [START .. STOP) to the specified FILE in raw target ordered bytes."),
781 &binary_append_cmdlist
);
783 add_cmd ("value", all_commands
, append_binary_value
, _("\
784 Append the value of an expression to a raw binary file.\n\
785 Arguments are FILE EXPRESSION. Writes the value of EXPRESSION\n\
786 to the specified FILE in raw target ordered bytes."),
787 &binary_append_cmdlist
);
789 c
= add_com ("restore", class_vars
, restore_command
, _("\
790 Restore the contents of FILE to target memory.\n\
791 Arguments are FILE OFFSET START END where all except FILE are optional.\n\
792 OFFSET will be added to the base address of the file (default zero).\n\
793 If START and END are given, only the file contents within that range\n\
794 (file relative) will be restored to target memory."));
795 c
->completer
= filename_completer
;
796 /* FIXME: completers for other commands. */