7b4ac7e1 |
1 | /* Top level for GDB, the GNU debugger. |
4187119d |
2 | Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc. |
3 | |
4 | This file is part of GDB. |
5 | |
6 | GDB is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 1, or (at your option) |
9 | any later version. |
10 | |
11 | GDB is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with GDB; see the file COPYING. If not, write to |
18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
19 | |
7a67dd45 |
20 | #include <stdio.h> |
e91b87a3 |
21 | #include "defs.h" |
22 | #include "command.h" |
23 | #include "param.h" |
24 | |
25 | #ifdef USG |
26 | #include <sys/types.h> |
27 | #include <unistd.h> |
28 | #endif |
7b4ac7e1 |
29 | |
7b4ac7e1 |
30 | #include <sys/file.h> |
7b4ac7e1 |
31 | #include <setjmp.h> |
32 | #include <signal.h> |
33 | #include <sys/param.h> |
4187119d |
34 | #include <sys/stat.h> |
7b4ac7e1 |
35 | |
36 | #ifdef SET_STACK_LIMIT_HUGE |
37 | #include <sys/time.h> |
38 | #include <sys/resource.h> |
4187119d |
39 | #include <ctype.h> |
e91b87a3 |
40 | |
41 | int original_stack_limit; |
7b4ac7e1 |
42 | #endif |
43 | |
4187119d |
44 | /* If this definition isn't overridden by the header files, assume |
45 | that isatty and fileno exist on this system. */ |
46 | #ifndef ISATTY |
47 | #define ISATTY(FP) (isatty (fileno (FP))) |
48 | #endif |
49 | |
50 | extern void free (); |
51 | |
7b4ac7e1 |
52 | /* Version number of GDB, as a string. */ |
53 | |
54 | extern char *version; |
55 | |
e91b87a3 |
56 | /* |
57 | * Declare all cmd_list_element's |
58 | */ |
59 | |
7b4ac7e1 |
60 | /* Chain containing all defined commands. */ |
61 | |
62 | struct cmd_list_element *cmdlist; |
63 | |
64 | /* Chain containing all defined info subcommands. */ |
65 | |
66 | struct cmd_list_element *infolist; |
67 | |
e91b87a3 |
68 | /* Chain containing all defined enable subcommands. */ |
69 | |
70 | struct cmd_list_element *enablelist; |
71 | |
72 | /* Chain containing all defined disable subcommands. */ |
73 | |
74 | struct cmd_list_element *disablelist; |
75 | |
76 | /* Chain containing all defined delete subcommands. */ |
77 | |
78 | struct cmd_list_element *deletelist; |
79 | |
80 | /* Chain containing all defined "enable breakpoint" subcommands. */ |
81 | |
82 | struct cmd_list_element *enablebreaklist; |
83 | |
84 | /* Chain containing all defined set subcommands */ |
85 | |
86 | struct cmd_list_element *setlist; |
87 | |
4187119d |
88 | /* Chain containing all defined \"set history\". */ |
89 | |
90 | struct cmd_list_element *sethistlist; |
91 | |
92 | /* Chain containing all defined \"unset history\". */ |
93 | |
94 | struct cmd_list_element *unsethistlist; |
95 | |
7b4ac7e1 |
96 | /* stdio stream that command input is being read from. */ |
97 | |
98 | FILE *instream; |
99 | |
632ea0cc |
100 | /* Current working directory. */ |
101 | |
102 | char *current_directory; |
103 | |
3bf57d21 |
104 | /* The directory name is actually stored here (usually). */ |
632ea0cc |
105 | static char dirbuf[MAXPATHLEN]; |
106 | |
4187119d |
107 | /* The number of lines on a page, and the number of spaces |
108 | in a line. */ |
109 | int linesize, pagesize; |
110 | |
7b4ac7e1 |
111 | /* Nonzero if we should refrain from using an X window. */ |
112 | |
113 | int inhibit_windows = 0; |
114 | |
115 | /* Function to call before reading a command, if nonzero. |
116 | The function receives two args: an input stream, |
117 | and a prompt string. */ |
118 | |
119 | void (*window_hook) (); |
120 | |
632ea0cc |
121 | extern int frame_file_full_name; |
4187119d |
122 | int xgdb_verbose; |
632ea0cc |
123 | |
7b4ac7e1 |
124 | void free_command_lines (); |
4187119d |
125 | char *gdb_readline (); |
126 | char *command_line_input (); |
127 | static void initialize_main (); |
128 | static void initialize_cmd_lists (); |
7b4ac7e1 |
129 | void command_loop (); |
130 | static void source_command (); |
e91b87a3 |
131 | static void print_gdb_version (); |
4187119d |
132 | static void float_handler (); |
133 | static void cd_command (); |
134 | |
135 | char *getenv (); |
7b4ac7e1 |
136 | |
137 | /* gdb prints this when reading a command interactively */ |
138 | static char *prompt; |
139 | |
140 | /* Buffer used for reading command lines, and the size |
141 | allocated for it so far. */ |
142 | |
143 | char *line; |
144 | int linesize; |
4187119d |
145 | |
146 | |
147 | /* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ |
148 | |
149 | #ifndef STOP_SIGNAL |
150 | #ifdef SIGTSTP |
151 | #define STOP_SIGNAL SIGTSTP |
152 | #endif |
153 | #endif |
3bf57d21 |
154 | \f |
7b4ac7e1 |
155 | /* This is how `error' returns to command level. */ |
156 | |
157 | jmp_buf to_top_level; |
158 | |
e91b87a3 |
159 | void |
7b4ac7e1 |
160 | return_to_top_level () |
161 | { |
162 | quit_flag = 0; |
163 | immediate_quit = 0; |
164 | clear_breakpoint_commands (); |
165 | clear_momentary_breakpoints (); |
4187119d |
166 | disable_current_display (); |
7b4ac7e1 |
167 | do_cleanups (0); |
168 | longjmp (to_top_level, 1); |
169 | } |
3bf57d21 |
170 | |
171 | /* Call FUNC with arg ARG, catching any errors. |
172 | If there is no error, return the value returned by FUNC. |
173 | If there is an error, return zero after printing ERRSTRING |
174 | (which is in addition to the specific error message already printed). */ |
175 | |
176 | int |
177 | catch_errors (func, arg, errstring) |
178 | int (*func) (); |
179 | int arg; |
180 | char *errstring; |
181 | { |
182 | jmp_buf saved; |
183 | int val; |
e91b87a3 |
184 | struct cleanup *saved_cleanup_chain; |
185 | |
186 | saved_cleanup_chain = save_cleanups (); |
3bf57d21 |
187 | |
188 | bcopy (to_top_level, saved, sizeof (jmp_buf)); |
189 | |
190 | if (setjmp (to_top_level) == 0) |
191 | val = (*func) (arg); |
192 | else |
193 | { |
194 | fprintf (stderr, "%s\n", errstring); |
195 | val = 0; |
196 | } |
197 | |
e91b87a3 |
198 | restore_cleanups (saved_cleanup_chain); |
199 | |
3bf57d21 |
200 | bcopy (saved, to_top_level, sizeof (jmp_buf)); |
201 | return val; |
202 | } |
203 | |
204 | /* Handler for SIGHUP. */ |
205 | |
206 | static void |
207 | disconnect () |
208 | { |
209 | kill_inferior_fast (); |
210 | signal (SIGHUP, SIG_DFL); |
211 | kill (getpid (), SIGHUP); |
212 | } |
7b4ac7e1 |
213 | \f |
e91b87a3 |
214 | /* Clean up on error during a "source" command (or execution of a |
215 | user-defined command). |
216 | Close the file opened by the command |
217 | and restore the previous input stream. */ |
218 | |
219 | static void |
220 | source_cleanup (stream) |
221 | FILE *stream; |
222 | { |
223 | /* Instream may be 0; set to it when executing user-defined command. */ |
224 | if (instream) |
225 | fclose (instream); |
226 | instream = stream; |
227 | } |
228 | |
229 | \f |
230 | int |
7b4ac7e1 |
231 | main (argc, argv, envp) |
232 | int argc; |
233 | char **argv; |
234 | char **envp; |
235 | { |
7b4ac7e1 |
236 | int count; |
237 | int inhibit_gdbinit = 0; |
238 | int quiet = 0; |
239 | int batch = 0; |
240 | register int i; |
241 | |
7a67dd45 |
242 | #if defined (ALIGN_STACK_ON_STARTUP) |
243 | i = (int) &count & 0x3; |
244 | if (i != 0) |
245 | alloca (4 - i); |
246 | #endif |
247 | |
7b4ac7e1 |
248 | quit_flag = 0; |
249 | linesize = 100; |
250 | line = (char *) xmalloc (linesize); |
251 | instream = stdin; |
252 | |
632ea0cc |
253 | getwd (dirbuf); |
254 | current_directory = dirbuf; |
255 | |
7b4ac7e1 |
256 | #ifdef SET_STACK_LIMIT_HUGE |
257 | { |
258 | struct rlimit rlim; |
259 | |
260 | /* Set the stack limit huge so that alloca (particularly stringtab |
261 | * in dbxread.c) does not fail. */ |
262 | getrlimit (RLIMIT_STACK, &rlim); |
e91b87a3 |
263 | original_stack_limit = rlim.rlim_cur; |
7b4ac7e1 |
264 | rlim.rlim_cur = rlim.rlim_max; |
265 | setrlimit (RLIMIT_STACK, &rlim); |
266 | } |
267 | #endif /* SET_STACK_LIMIT_HUGE */ |
268 | |
269 | /* Look for flag arguments. */ |
270 | |
271 | for (i = 1; i < argc; i++) |
272 | { |
273 | if (!strcmp (argv[i], "-q") || !strcmp (argv[i], "-quiet")) |
274 | quiet = 1; |
275 | else if (!strcmp (argv[i], "-nx")) |
276 | inhibit_gdbinit = 1; |
277 | else if (!strcmp (argv[i], "-nw")) |
278 | inhibit_windows = 1; |
279 | else if (!strcmp (argv[i], "-batch")) |
280 | batch = 1, quiet = 1; |
3bf57d21 |
281 | else if (!strcmp (argv[i], "-fullname")) |
282 | frame_file_full_name = 1; |
4187119d |
283 | else if (!strcmp (argv[i], "-xgdb_verbose")) |
284 | xgdb_verbose = 1; |
7a67dd45 |
285 | /* -help: print a summary of command line switches. */ |
286 | else if (!strcmp (argv[i], "-help")) |
287 | { |
288 | fputs ("\ |
289 | This is GDB, the GNU debugger. Use the command\n\ |
290 | gdb [options] [executable [core-file]]\n\ |
291 | to enter the debugger.\n\ |
292 | \n\ |
293 | Options available are:\n\ |
294 | -help Print this message.\n\ |
295 | -quiet Do not print version number on startup.\n\ |
296 | -fullname Output information used by emacs-GDB interface.\n\ |
297 | -batch Exit after processing options.\n\ |
298 | -nx Do not read .gdbinit file.\n\ |
299 | -tty TTY Use TTY for input/output by the program being debugged.\n\ |
300 | -cd DIR Change current directory to DIR.\n\ |
301 | -directory DIR Search for source files in DIR.\n\ |
302 | -command FILE Execute GDB commands from FILE.\n\ |
303 | -symbols SYMFILE Read symbols from SYMFILE.\n\ |
304 | -exec EXECFILE Use EXECFILE as the executable.\n\ |
305 | -se FILE Use FILE as symbol file and executable file.\n\ |
306 | -core COREFILE Analyze the core dump COREFILE.\n\ |
307 | \n\ |
308 | For more information, type \"help\" from within GDB, or consult the\n\ |
309 | GDB manual (available as on-line info or a printed manual).\n", stderr); |
310 | /* Exiting after printing this message seems like |
311 | the most useful thing to do. */ |
312 | exit (0); |
313 | } |
7b4ac7e1 |
314 | else if (argv[i][0] == '-') |
7a67dd45 |
315 | /* Other options take arguments, so don't confuse an |
316 | argument with an option. */ |
7b4ac7e1 |
317 | i++; |
318 | } |
319 | |
320 | /* Run the init function of each source file */ |
321 | |
4187119d |
322 | initialize_cmd_lists (); /* This needs to be done first */ |
323 | initialize_all_files (); |
324 | initialize_main (); /* But that omits this file! Do it now */ |
325 | initialize_signals (); |
7b4ac7e1 |
326 | |
327 | if (!quiet) |
328 | print_gdb_version (); |
329 | |
330 | /* Process the command line arguments. */ |
331 | |
332 | count = 0; |
333 | for (i = 1; i < argc; i++) |
334 | { |
335 | register char *arg = argv[i]; |
336 | /* Args starting with - say what to do with the following arg |
337 | as a filename. */ |
338 | if (arg[0] == '-') |
339 | { |
340 | extern void exec_file_command (), symbol_file_command (); |
341 | extern void core_file_command (), directory_command (); |
342 | extern void tty_command (); |
343 | |
344 | if (!strcmp (arg, "-q") || !strcmp (arg, "-nx") |
632ea0cc |
345 | || !strcmp (arg, "-quiet") || !strcmp (arg, "-batch") |
4187119d |
346 | || !strcmp (arg, "-fullname") || !strcmp (arg, "-nw") |
7a67dd45 |
347 | || !strcmp (arg, "-xgdb_verbose") |
348 | || !strcmp (arg, "-help")) |
7b4ac7e1 |
349 | /* Already processed above */ |
350 | continue; |
351 | |
352 | if (++i == argc) |
353 | fprintf (stderr, "No argument follows \"%s\".\n", arg); |
354 | if (!setjmp (to_top_level)) |
355 | { |
356 | /* -s foo: get syms from foo. -e foo: execute foo. |
357 | -se foo: do both with foo. -c foo: use foo as core dump. */ |
358 | if (!strcmp (arg, "-se")) |
359 | { |
360 | exec_file_command (argv[i], !batch); |
361 | symbol_file_command (argv[i], !batch); |
362 | } |
363 | else if (!strcmp (arg, "-s") || !strcmp (arg, "-symbols")) |
364 | symbol_file_command (argv[i], !batch); |
365 | else if (!strcmp (arg, "-e") || !strcmp (arg, "-exec")) |
366 | exec_file_command (argv[i], !batch); |
367 | else if (!strcmp (arg, "-c") || !strcmp (arg, "-core")) |
368 | core_file_command (argv[i], !batch); |
369 | /* -x foo: execute commands from foo. */ |
370 | else if (!strcmp (arg, "-x") || !strcmp (arg, "-command") |
371 | || !strcmp (arg, "-commands")) |
372 | source_command (argv[i]); |
373 | /* -d foo: add directory `foo' to source-file directory |
374 | search-list */ |
375 | else if (!strcmp (arg, "-d") || !strcmp (arg, "-dir") |
376 | || !strcmp (arg, "-directory")) |
377 | directory_command (argv[i], 0); |
3bf57d21 |
378 | /* -cd FOO: specify current directory as FOO. |
379 | GDB remembers the precise string FOO as the dirname. */ |
380 | else if (!strcmp (arg, "-cd")) |
381 | { |
4187119d |
382 | cd_command (argv[i], 0); |
3bf57d21 |
383 | init_source_path (); |
384 | } |
7b4ac7e1 |
385 | /* -t /def/ttyp1: use /dev/ttyp1 for inferior I/O. */ |
386 | else if (!strcmp (arg, "-t") || !strcmp (arg, "-tty")) |
387 | tty_command (argv[i], 0); |
1c997a4a |
388 | |
7b4ac7e1 |
389 | else |
390 | error ("Unknown command-line switch: \"%s\"\n", arg); |
391 | } |
392 | } |
393 | else |
394 | { |
395 | /* Args not thus accounted for |
396 | are treated as, first, the symbol/executable file |
397 | and, second, the core dump file. */ |
398 | count++; |
399 | if (!setjmp (to_top_level)) |
400 | switch (count) |
401 | { |
402 | case 1: |
403 | exec_file_command (arg, !batch); |
404 | symbol_file_command (arg, !batch); |
405 | break; |
406 | |
407 | case 2: |
408 | core_file_command (arg, !batch); |
409 | break; |
410 | |
411 | case 3: |
412 | fprintf (stderr, "Excess command line args ignored. (%s%s)\n", |
413 | arg, (i == argc - 1) ? "" : " ..."); |
414 | } |
415 | } |
416 | } |
417 | |
4187119d |
418 | { |
419 | struct stat homebuf, cwdbuf; |
420 | char *homedir, *homeinit; |
7b4ac7e1 |
421 | |
4187119d |
422 | /* Read init file, if it exists in home directory */ |
423 | homedir = getenv ("HOME"); |
424 | if (homedir) |
425 | { |
426 | homeinit = (char *) alloca (strlen (getenv ("HOME")) + 10); |
427 | strcpy (homeinit, getenv ("HOME")); |
428 | strcat (homeinit, "/.gdbinit"); |
429 | if (!inhibit_gdbinit && access (homeinit, R_OK) == 0) |
430 | if (!setjmp (to_top_level)) |
431 | source_command (homeinit); |
432 | |
433 | /* Do stats; no need to do them elsewhere since we'll only |
434 | need them if homedir is set. Make sure that they are |
435 | zero in case one of them fails (guarantees that they |
436 | won't match if either exits). */ |
437 | |
438 | bzero (&homebuf, sizeof (struct stat)); |
439 | bzero (&cwdbuf, sizeof (struct stat)); |
440 | |
441 | stat (homeinit, &homebuf); |
442 | stat ("./.gdbinit", &cwdbuf); /* We'll only need this if |
443 | homedir was set. */ |
444 | } |
445 | |
446 | /* Read the input file in the current directory, *if* it isn't |
447 | the same file (it should exist, also). */ |
448 | |
449 | if (!homedir |
450 | || bcmp ((char *) &homebuf, |
451 | (char *) &cwdbuf, |
452 | sizeof (struct stat))) |
453 | if (!inhibit_gdbinit && access (".gdbinit", R_OK) == 0) |
454 | if (!setjmp (to_top_level)) |
455 | source_command (".gdbinit"); |
456 | } |
7b4ac7e1 |
457 | |
458 | if (batch) |
4187119d |
459 | { |
460 | #if 0 |
461 | fatal ("Attempt to read commands from stdin in batch mode."); |
462 | #endif |
463 | /* We have hit the end of the batch file. */ |
464 | exit (0); |
465 | } |
7b4ac7e1 |
466 | |
467 | if (!quiet) |
468 | printf ("Type \"help\" for a list of commands.\n"); |
469 | |
470 | /* The command loop. */ |
471 | |
472 | while (1) |
473 | { |
474 | if (!setjmp (to_top_level)) |
475 | command_loop (); |
476 | clearerr (stdin); /* Don't get hung if C-d is typed. */ |
477 | } |
478 | } |
479 | |
480 | /* Execute the line P as a command. |
481 | Pass FROM_TTY as second argument to the defining function. */ |
482 | |
483 | void |
484 | execute_command (p, from_tty) |
485 | char *p; |
486 | int from_tty; |
487 | { |
488 | register struct cmd_list_element *c; |
489 | register struct command_line *cmdlines; |
490 | |
491 | free_all_values (); |
492 | while (*p == ' ' || *p == '\t') p++; |
493 | if (*p) |
494 | { |
4187119d |
495 | c = lookup_cmd (&p, cmdlist, "", 0, 1); |
7b4ac7e1 |
496 | if (c->function == 0) |
497 | error ("That is not a command, just a help topic."); |
498 | else if (c->class == (int) class_user) |
499 | { |
e91b87a3 |
500 | struct cleanup *old_chain; |
501 | |
7b4ac7e1 |
502 | if (*p) |
3bf57d21 |
503 | error ("User-defined commands cannot take arguments."); |
7b4ac7e1 |
504 | cmdlines = (struct command_line *) c->function; |
505 | if (cmdlines == (struct command_line *) 0) |
506 | /* Null command */ |
507 | return; |
e91b87a3 |
508 | |
509 | /* Set the instream to 0, indicating execution of a |
510 | user-defined function. */ |
511 | old_chain = make_cleanup (source_cleanup, instream); |
512 | instream = (FILE *) 0; |
7b4ac7e1 |
513 | while (cmdlines) |
514 | { |
515 | execute_command (cmdlines->line, 0); |
516 | cmdlines = cmdlines->next; |
517 | } |
e91b87a3 |
518 | do_cleanups (old_chain); |
7b4ac7e1 |
519 | } |
520 | else |
521 | /* Pass null arg rather than an empty one. */ |
522 | (*c->function) (*p ? p : 0, from_tty); |
523 | } |
524 | } |
525 | |
526 | static void |
527 | do_nothing () |
528 | { |
529 | } |
530 | |
531 | /* Read commands from `instream' and execute them |
532 | until end of file. */ |
533 | void |
534 | command_loop () |
535 | { |
536 | struct cleanup *old_chain; |
537 | while (!feof (instream)) |
538 | { |
7b4ac7e1 |
539 | if (window_hook && instream == stdin) |
540 | (*window_hook) (instream, prompt); |
541 | |
542 | quit_flag = 0; |
4187119d |
543 | if (instream == stdin && ISATTY (stdin)) |
544 | reinitialize_more_filter (); |
7b4ac7e1 |
545 | old_chain = make_cleanup (do_nothing, 0); |
4187119d |
546 | execute_command (command_line_input (instream == stdin ? prompt : 0, |
e91b87a3 |
547 | instream == stdin), |
548 | instream == stdin); |
7b4ac7e1 |
549 | /* Do any commands attached to breakpoint we stopped at. */ |
550 | do_breakpoint_commands (); |
551 | do_cleanups (old_chain); |
552 | } |
553 | } |
554 | \f |
4187119d |
555 | /* Commands call this if they do not want to be repeated by null lines. */ |
556 | |
557 | void |
558 | dont_repeat () |
559 | { |
560 | /* If we aren't reading from standard input, we are saving the last |
561 | thing read from stdin in line and don't want to delete it. Null lines |
562 | won't repeat here in any case. */ |
563 | if (instream == stdin) |
564 | *line = 0; |
565 | } |
566 | \f |
567 | /* Read a line from the stream "instream" without command line editing. |
568 | |
569 | It prints PROMPT once at the start. |
570 | |
571 | If RETURN_RESULT is set it allocates |
572 | space for whatever the user types and returns the result. |
573 | If not, it just discards what the user types. */ |
574 | char * |
575 | gdb_readline (prompt, return_result) |
576 | char *prompt; |
577 | int return_result; |
578 | { |
579 | int c; |
580 | char *result; |
581 | int input_index = 0; |
582 | int result_size = 80; |
583 | |
584 | if (prompt) |
585 | { |
586 | printf (prompt); |
587 | fflush (stdout); |
588 | } |
589 | |
590 | if (return_result) |
591 | result = (char *) xmalloc (result_size); |
592 | |
593 | while (1) |
594 | { |
595 | c = fgetc (instream); |
596 | if (c == -1 || c == '\n') |
597 | break; |
598 | if (return_result) |
599 | { |
600 | result[input_index++] = c; |
601 | while (input_index >= result_size) |
602 | { |
603 | result_size *= 2; |
604 | result = (char *) xrealloc (result, result_size); |
605 | } |
606 | } |
607 | } |
608 | if (return_result) |
609 | { |
610 | result[input_index++] = '\0'; |
611 | return result; |
612 | } |
613 | else |
614 | return (char *) 0; |
615 | } |
616 | |
617 | /* Declaration for fancy readline with command line editing. */ |
618 | char *readline (); |
619 | |
620 | /* Variables which control command line editing and history |
621 | substitution. These variables are given default values at the end |
622 | of this file. */ |
623 | static int command_editing_p; |
624 | static int history_expansion_p; |
625 | static int write_history_p; |
626 | static int history_size; |
627 | static char *history_filename; |
628 | |
629 | /* Variables which are necessary for fancy command line editing. */ |
630 | char *gdb_completer_word_break_characters = |
631 | " \t\n!@#$%^&*()-+=|~`}{[]\"';:?/>.<,"; |
632 | |
633 | /* Functions that are used as part of the fancy command line editing. */ |
634 | |
635 | /* Generate symbol names one by one for the completer. If STATE is |
636 | zero, then we need to initialize, otherwise the initialization has |
637 | already taken place. TEXT is what we expect the symbol to start |
638 | with. RL_LINE_BUFFER is available to be looked at; it contains the |
639 | entire text of the line. RL_POINT is the offset in that line of |
640 | the cursor. You should pretend that the line ends at RL_POINT. */ |
641 | char * |
642 | symbol_completion_function (text, state) |
643 | char *text; |
644 | int state; |
645 | { |
646 | char **make_symbol_completion_list (); |
647 | static char **list = (char **)NULL; |
648 | static int index; |
649 | char *output; |
650 | extern char *rl_line_buffer; |
651 | extern int rl_point; |
652 | char *tmp_command, *p; |
653 | struct cmd_list_element *c, *result_list; |
654 | |
655 | if (!state) |
656 | { |
657 | /* Free the storage used by LIST, but not by the strings inside. This is |
658 | because rl_complete_internal () frees the strings. */ |
659 | if (list) |
660 | free (list); |
661 | list = 0; |
662 | index = 0; |
663 | |
664 | /* Decide whether to complete on a list of gdb commands or on |
665 | symbols. */ |
666 | tmp_command = (char *) alloca (rl_point + 1); |
667 | p = tmp_command; |
668 | |
669 | strncpy (tmp_command, rl_line_buffer, rl_point); |
670 | tmp_command[rl_point] = '\0'; |
671 | |
672 | if (rl_point == 0) |
673 | { |
674 | /* An empty line we want to consider ambiguous; that is, |
675 | it could be any command. */ |
676 | c = (struct cmd_list_element *) -1; |
677 | result_list = 0; |
678 | } |
679 | else |
680 | c = lookup_cmd_1 (&p, cmdlist, &result_list, 1); |
681 | |
682 | /* Move p up to the next interesting thing. */ |
683 | while (*p == ' ' || *p == '\t') |
684 | p++; |
685 | |
686 | if (!c) |
687 | /* He's typed something unrecognizable. Sigh. */ |
688 | list = (char **) 0; |
689 | else if (c == (struct cmd_list_element *) -1) |
690 | { |
691 | if (p + strlen(text) != tmp_command + rl_point) |
692 | error ("Unrecognized command."); |
693 | |
694 | /* He's typed something ambiguous. This is easier. */ |
695 | if (result_list) |
696 | list = complete_on_cmdlist (*result_list->prefixlist, text); |
697 | else |
698 | list = complete_on_cmdlist (cmdlist, text); |
699 | } |
700 | else |
701 | { |
702 | /* If we've gotten this far, gdb has recognized a full |
703 | command. There are several possibilities: |
704 | |
705 | 1) We need to complete on the command. |
706 | 2) We need to complete on the possibilities coming after |
707 | the command. |
708 | 2) We need to complete the text of what comes after the |
709 | command. */ |
710 | |
711 | if (!*p && *text) |
712 | /* Always (might be longer versions of thie command). */ |
713 | list = complete_on_cmdlist (result_list, text); |
714 | else if (!*p && !*text) |
715 | { |
716 | if (c->prefixlist) |
717 | list = complete_on_cmdlist (*c->prefixlist, ""); |
718 | else |
719 | list = make_symbol_completion_list (""); |
720 | } |
721 | else |
722 | { |
723 | if (c->prefixlist && !c->allow_unknown) |
724 | { |
725 | *p = '\0'; |
726 | error ("\"%s\" command requires a subcommand.", |
727 | tmp_command); |
728 | } |
729 | else |
730 | list = make_symbol_completion_list (text); |
731 | } |
732 | } |
733 | } |
734 | |
735 | /* If the debugged program wasn't compiled with symbols, or if we're |
736 | clearly completing on a command and no command matches, return |
737 | NULL. */ |
738 | if (!list) |
739 | return ((char *)NULL); |
740 | |
741 | output = list[index]; |
742 | if (output) |
743 | index++; |
744 | |
745 | return (output); |
746 | } |
747 | \f |
748 | #ifdef STOP_SIGNAL |
7b4ac7e1 |
749 | static void |
750 | stop_sig () |
751 | { |
4187119d |
752 | #if STOP_SIGNAL == SIGTSTP |
7b4ac7e1 |
753 | signal (SIGTSTP, SIG_DFL); |
754 | sigsetmask (0); |
755 | kill (getpid (), SIGTSTP); |
756 | signal (SIGTSTP, stop_sig); |
4187119d |
757 | #else |
758 | signal (STOP_SIGNAL, stop_sig); |
759 | #endif |
7b4ac7e1 |
760 | printf ("%s", prompt); |
761 | fflush (stdout); |
762 | |
763 | /* Forget about any previous command -- null line now will do nothing. */ |
4187119d |
764 | dont_repeat (); |
7b4ac7e1 |
765 | } |
4187119d |
766 | #endif /* STOP_SIGNAL */ |
767 | |
768 | #if 0 |
769 | Writing the history file upon a terminating signal is not useful, |
770 | because the info is rarely relevant and is in the core dump anyway. |
771 | It is an annoyance to have the file cluttering up the place. |
772 | /* The list of signals that would terminate us if not caught. |
773 | We catch them, but just so that we can write the history file, |
774 | and so forth. */ |
775 | int terminating_signals[] = { |
776 | SIGHUP, SIGINT, SIGILL, SIGTRAP, SIGIOT, |
777 | SIGEMT, SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS, |
778 | SIGPIPE, SIGALRM, SIGTERM, |
779 | #ifdef SIGXCPU |
780 | SIGXCPU, |
781 | #endif |
782 | #ifdef SIGXFSZ |
783 | SIGXFSZ, |
784 | #endif |
785 | #ifdef SIGVTALRM |
786 | SIGVTALRM, |
787 | #endif |
788 | #ifdef SIGPROF |
789 | SIGPROF, |
790 | #endif |
791 | #ifdef SIGLOST |
792 | SIGLOST, |
793 | #endif |
794 | #ifdef SIGUSR1 |
795 | SIGUSR1, SIGUSR2 |
796 | #endif |
797 | }; |
7b4ac7e1 |
798 | |
4187119d |
799 | #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (int)) |
7b4ac7e1 |
800 | |
4187119d |
801 | static void |
802 | catch_termination (sig) |
803 | int sig; |
7b4ac7e1 |
804 | { |
4187119d |
805 | /* We are probably here because GDB has a bug. Write out the history |
806 | so that we might have a better chance of reproducing it. */ |
807 | /* Tell the user what we are doing so he can delete the file if |
808 | it is unwanted. */ |
809 | write_history (history_filename); |
810 | printf ("\n%s written.\n", history_filename); |
811 | signal (sig, SIG_DFL); |
812 | kill (getpid (), sig); |
7b4ac7e1 |
813 | } |
4187119d |
814 | #endif |
815 | |
816 | /* Initialize signal handlers. */ |
817 | initialize_signals () |
818 | { |
819 | extern void request_quit (); |
820 | #if 0 |
821 | register int i; |
822 | |
823 | for (i = 0; i < TERMSIGS_LENGTH; i++) |
824 | signal (terminating_signals[i], catch_termination); |
825 | #endif |
826 | |
827 | signal (SIGINT, request_quit); |
7b4ac7e1 |
828 | |
4187119d |
829 | /* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get |
830 | passed to the inferior, which we don't want. It would be |
831 | possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but |
832 | on BSD4.3 systems using vfork, that will (apparently) affect the |
833 | GDB process as well as the inferior (the signal handling tables |
834 | being shared between the two, apparently). Since we establish |
835 | a handler for SIGQUIT, when we call exec it will set the signal |
836 | to SIG_DFL for us. */ |
837 | signal (SIGQUIT, do_nothing); |
838 | if (signal (SIGHUP, do_nothing) != SIG_IGN) |
839 | signal (SIGHUP, disconnect); |
840 | signal (SIGFPE, float_handler); |
841 | } |
842 | \f |
7b4ac7e1 |
843 | /* Read one line from the command input stream `instream' |
4187119d |
844 | into the local static buffer `linebuffer' (whose current length |
845 | is `linelength'). |
7b4ac7e1 |
846 | The buffer is made bigger as necessary. |
4187119d |
847 | Returns the address of the start of the line. |
848 | |
849 | *If* the instream == stdin & stdin is a terminal, the line read |
850 | is copied into the file line saver (global var char *line, |
851 | length linesize) so that it can be duplicated. |
852 | |
853 | This routine either uses fancy command line editing or |
854 | simple input as the user has requested. */ |
7b4ac7e1 |
855 | |
856 | char * |
4187119d |
857 | command_line_input (prompt, repeat) |
e91b87a3 |
858 | char *prompt; |
7b4ac7e1 |
859 | int repeat; |
860 | { |
4187119d |
861 | static char *linebuffer = 0; |
862 | static int linelength = 0; |
863 | register char *p; |
864 | register char *p1, *rl; |
865 | char *local_prompt = prompt; |
7b4ac7e1 |
866 | register int c; |
867 | char *nline; |
868 | |
4187119d |
869 | if (linebuffer == 0) |
870 | { |
871 | linelength = 80; |
872 | linebuffer = (char *) xmalloc (linelength); |
873 | } |
874 | |
875 | p = linebuffer; |
876 | |
7b4ac7e1 |
877 | /* Control-C quits instantly if typed while in this loop |
878 | since it should not wait until the user types a newline. */ |
879 | immediate_quit++; |
4187119d |
880 | #ifdef STOP_SIGNAL |
881 | signal (STOP_SIGNAL, stop_sig); |
3bf57d21 |
882 | #endif |
7b4ac7e1 |
883 | |
884 | while (1) |
885 | { |
4187119d |
886 | /* Don't use fancy stuff if not talking to stdin. */ |
887 | if (command_editing_p && instream == stdin |
888 | && ISATTY (instream)) |
889 | rl = readline (local_prompt); |
890 | else |
891 | rl = gdb_readline (local_prompt, 1); |
3bf57d21 |
892 | |
4187119d |
893 | if (!rl || rl == (char *) EOF) break; |
894 | if (strlen(rl) + 1 + (p - linebuffer) > linelength) |
7b4ac7e1 |
895 | { |
4187119d |
896 | linelength = strlen(rl) + 1 + (p - linebuffer); |
897 | nline = (char *) xrealloc (linebuffer, linelength); |
898 | p += nline - linebuffer; |
899 | linebuffer = nline; |
7b4ac7e1 |
900 | } |
4187119d |
901 | p1 = rl; |
902 | /* Copy line. Don't copy null at end. (Leaves line alone |
903 | if this was just a newline) */ |
904 | while (*p1) |
905 | *p++ = *p1++; |
3bf57d21 |
906 | |
4187119d |
907 | free (rl); /* Allocated in readline. */ |
908 | |
909 | if (p == linebuffer || *(p - 1) != '\\') |
910 | break; |
911 | |
912 | p--; /* Put on top of '\'. */ |
913 | local_prompt = (char *) 0; |
914 | } |
915 | |
916 | #ifdef STOP_SIGNAL |
7b4ac7e1 |
917 | signal (SIGTSTP, SIG_DFL); |
3bf57d21 |
918 | #endif |
7b4ac7e1 |
919 | immediate_quit--; |
920 | |
4187119d |
921 | /* Do history expansion if that is wished. */ |
922 | if (history_expansion_p && instream == stdin |
923 | && ISATTY (instream)) |
924 | { |
925 | char *history_value; |
926 | int expanded; |
927 | |
928 | *p = '\0'; /* Insert null now. */ |
929 | expanded = history_expand (linebuffer, &history_value); |
930 | if (expanded) |
931 | { |
932 | /* Print the changes. */ |
933 | printf ("%s\n", history_value); |
934 | |
935 | /* If there was an error, call this function again. */ |
936 | if (expanded < 0) |
937 | { |
938 | free (history_value); |
939 | return command_line_input (prompt, repeat); |
940 | } |
941 | if (strlen (history_value) > linelength) |
942 | { |
943 | linelength = strlen (history_value) + 1; |
944 | linebuffer = (char *) xrealloc (linebuffer, linelength); |
945 | } |
946 | strcpy (linebuffer, history_value); |
947 | p = linebuffer + strlen(linebuffer); |
948 | free (history_value); |
949 | } |
950 | } |
951 | |
7b4ac7e1 |
952 | /* If we just got an empty line, and that is supposed |
4187119d |
953 | to repeat the previous command, return the value in the |
954 | global buffer. */ |
955 | if (repeat) |
956 | { |
957 | if (p == linebuffer) |
958 | return line; |
959 | p1 = linebuffer; |
960 | while (*p1 == ' ' || *p1 == '\t') |
961 | p1++; |
962 | if (!*p1) |
963 | return line; |
964 | } |
965 | |
966 | *p = 0; |
967 | |
968 | /* Add line to history if appropriate. */ |
969 | if (instream == stdin |
970 | && ISATTY (stdin) && *linebuffer) |
971 | add_history (linebuffer); |
7b4ac7e1 |
972 | |
973 | /* If line is a comment, clear it out. */ |
4187119d |
974 | /* Note: comments are added to the command history. |
975 | This is useful when you type a command, and then realize |
976 | you don't want to execute it quite yet. You can comment out the |
977 | command and then later fetch it from the value history and |
978 | remove the '#'. */ |
979 | p1 = linebuffer; |
7b4ac7e1 |
980 | while ((c = *p1) == ' ' || c == '\t') p1++; |
981 | if (c == '#') |
4187119d |
982 | *linebuffer = 0; |
7b4ac7e1 |
983 | |
4187119d |
984 | /* Save into global buffer if appropriate. */ |
985 | if (repeat) |
986 | { |
987 | if (linelength > linesize) |
988 | { |
989 | line = xrealloc (line, linelength); |
990 | linesize = linelength; |
991 | } |
992 | strcpy (line, linebuffer); |
993 | return line; |
994 | } |
7b4ac7e1 |
995 | |
4187119d |
996 | return linebuffer; |
7b4ac7e1 |
997 | } |
998 | \f |
999 | /* Read lines from the input stream |
1000 | and accumulate them in a chain of struct command_line's |
1001 | which is then returned. */ |
1002 | |
1003 | struct command_line * |
1004 | read_command_lines () |
1005 | { |
1006 | struct command_line *first = 0; |
1007 | register struct command_line *next, *tail = 0; |
1008 | register char *p, *p1; |
1009 | struct cleanup *old_chain = 0; |
1010 | |
1011 | while (1) |
1012 | { |
1013 | dont_repeat (); |
4187119d |
1014 | p = command_line_input (0, instream == stdin); |
7b4ac7e1 |
1015 | /* Remove leading and trailing blanks. */ |
1016 | while (*p == ' ' || *p == '\t') p++; |
1017 | p1 = p + strlen (p); |
1018 | while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t')) p1--; |
1019 | |
1020 | /* Is this "end"? */ |
1021 | if (p1 - p == 3 && !strncmp (p, "end", 3)) |
1022 | break; |
1023 | |
1024 | /* No => add this line to the chain of command lines. */ |
1025 | next = (struct command_line *) xmalloc (sizeof (struct command_line)); |
1026 | next->line = savestring (p, p1 - p); |
1027 | next->next = 0; |
1028 | if (tail) |
1029 | { |
1030 | tail->next = next; |
1031 | } |
1032 | else |
1033 | { |
1034 | /* We just read the first line. |
1035 | From now on, arrange to throw away the lines we have |
1036 | if we quit or get an error while inside this function. */ |
1037 | first = next; |
1038 | old_chain = make_cleanup (free_command_lines, &first); |
1039 | } |
1040 | tail = next; |
1041 | } |
1042 | |
1043 | dont_repeat (); |
1044 | |
1045 | /* Now we are about to return the chain to our caller, |
1046 | so freeing it becomes his responsibility. */ |
1047 | if (first) |
1048 | discard_cleanups (old_chain); |
1049 | return first; |
1050 | } |
1051 | |
1052 | /* Free a chain of struct command_line's. */ |
1053 | |
1054 | void |
1055 | free_command_lines (lptr) |
1056 | struct command_line **lptr; |
1057 | { |
1058 | register struct command_line *l = *lptr; |
1059 | register struct command_line *next; |
1060 | |
1061 | while (l) |
1062 | { |
1063 | next = l->next; |
1064 | free (l->line); |
1065 | free (l); |
1066 | l = next; |
1067 | } |
1068 | } |
1069 | \f |
1070 | /* Add an element to the list of info subcommands. */ |
1071 | |
1072 | void |
1073 | add_info (name, fun, doc) |
1074 | char *name; |
1075 | void (*fun) (); |
1076 | char *doc; |
1077 | { |
e91b87a3 |
1078 | add_cmd (name, no_class, fun, doc, &infolist); |
7b4ac7e1 |
1079 | } |
1080 | |
1081 | /* Add an alias to the list of info subcommands. */ |
1082 | |
1083 | void |
1084 | add_info_alias (name, oldname, abbrev_flag) |
1085 | char *name; |
1086 | char *oldname; |
1087 | int abbrev_flag; |
1088 | { |
1089 | add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist); |
1090 | } |
1091 | |
1092 | /* The "info" command is defined as a prefix, with allow_unknown = 0. |
1093 | Therefore, its own definition is called only for "info" with no args. */ |
1094 | |
1095 | static void |
1096 | info_command () |
1097 | { |
1098 | printf ("\"info\" must be followed by the name of an info command.\n"); |
e91b87a3 |
1099 | help_list (infolist, "info ", -1, stdout); |
7b4ac7e1 |
1100 | } |
1101 | \f |
1102 | /* Add an element to the list of commands. */ |
1103 | |
1104 | void |
1105 | add_com (name, class, fun, doc) |
1106 | char *name; |
1107 | int class; |
1108 | void (*fun) (); |
1109 | char *doc; |
1110 | { |
1111 | add_cmd (name, class, fun, doc, &cmdlist); |
1112 | } |
1113 | |
1114 | /* Add an alias or abbreviation command to the list of commands. */ |
1115 | |
1116 | void |
1117 | add_com_alias (name, oldname, class, abbrev_flag) |
1118 | char *name; |
1119 | char *oldname; |
1120 | int class; |
1121 | int abbrev_flag; |
1122 | { |
1123 | add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist); |
1124 | } |
1125 | |
1126 | void |
1127 | error_no_arg (why) |
1128 | char *why; |
1129 | { |
1130 | error ("Argument required (%s).", why); |
1131 | } |
1132 | |
1133 | static void |
1134 | help_command (command, from_tty) |
1135 | char *command; |
1136 | int from_tty; /* Ignored */ |
1137 | { |
e91b87a3 |
1138 | help_cmd (command, stdout); |
7b4ac7e1 |
1139 | } |
1140 | \f |
1141 | static void |
1142 | validate_comname (comname) |
1143 | char *comname; |
1144 | { |
1145 | register char *p; |
1146 | |
1147 | if (comname == 0) |
1148 | error_no_arg ("name of command to define"); |
1149 | |
1150 | p = comname; |
1151 | while (*p) |
1152 | { |
1153 | if (!(*p >= 'A' && *p <= 'Z') |
1154 | && !(*p >= 'a' && *p <= 'z') |
3bf57d21 |
1155 | && !(*p >= '0' && *p <= '9') |
7b4ac7e1 |
1156 | && *p != '-') |
1157 | error ("Junk in argument list: \"%s\"", p); |
1158 | p++; |
1159 | } |
1160 | } |
1161 | |
1162 | static void |
1163 | define_command (comname, from_tty) |
1164 | char *comname; |
1165 | int from_tty; |
1166 | { |
1167 | register struct command_line *cmds; |
1168 | register struct cmd_list_element *c; |
1169 | char *tem = comname; |
1170 | |
1171 | validate_comname (comname); |
1172 | |
4187119d |
1173 | c = lookup_cmd (&tem, cmdlist, "", -1, 1); |
7b4ac7e1 |
1174 | if (c) |
1175 | { |
1176 | if (c->class == (int) class_user || c->class == (int) class_alias) |
1177 | tem = "Redefine command \"%s\"? "; |
1178 | else |
1179 | tem = "Really redefine built-in command \"%s\"? "; |
1180 | if (!query (tem, comname)) |
1181 | error ("Command \"%s\" not redefined.", comname); |
1182 | } |
1183 | |
1184 | if (from_tty) |
e91b87a3 |
1185 | { |
1186 | printf ("Type commands for definition of \"%s\".\n\ |
7b4ac7e1 |
1187 | End with a line saying just \"end\".\n", comname); |
e91b87a3 |
1188 | fflush (stdout); |
1189 | } |
7b4ac7e1 |
1190 | comname = savestring (comname, strlen (comname)); |
1191 | |
1192 | cmds = read_command_lines (); |
1193 | |
1194 | if (c && c->class == (int) class_user) |
1195 | free_command_lines (&c->function); |
1196 | |
1197 | add_com (comname, class_user, cmds, |
1198 | (c && c->class == (int) class_user) |
1199 | ? c->doc : savestring ("User-defined.", 13)); |
1200 | } |
1201 | |
1202 | static void |
1203 | document_command (comname, from_tty) |
1204 | char *comname; |
1205 | int from_tty; |
1206 | { |
1207 | struct command_line *doclines; |
1208 | register struct cmd_list_element *c; |
1209 | char *tem = comname; |
1210 | |
1211 | validate_comname (comname); |
1212 | |
4187119d |
1213 | c = lookup_cmd (&tem, cmdlist, "", 0, 1); |
7b4ac7e1 |
1214 | |
1215 | if (c->class != (int) class_user) |
1216 | error ("Command \"%s\" is built-in.", comname); |
1217 | |
1218 | if (from_tty) |
1219 | printf ("Type documentation for \"%s\".\n\ |
1220 | End with a line saying just \"end\".\n", comname); |
1221 | |
1222 | doclines = read_command_lines (); |
1223 | |
1224 | if (c->doc) free (c->doc); |
1225 | |
1226 | { |
1227 | register struct command_line *cl1; |
1228 | register int len = 0; |
1229 | |
1230 | for (cl1 = doclines; cl1; cl1 = cl1->next) |
1231 | len += strlen (cl1->line) + 1; |
1232 | |
1233 | c->doc = (char *) xmalloc (len + 1); |
1234 | *c->doc = 0; |
1235 | |
1236 | for (cl1 = doclines; cl1; cl1 = cl1->next) |
1237 | { |
1238 | strcat (c->doc, cl1->line); |
1239 | if (cl1->next) |
1240 | strcat (c->doc, "\n"); |
1241 | } |
1242 | } |
1243 | |
1244 | free_command_lines (&doclines); |
1245 | } |
1246 | \f |
1247 | static void |
7b4ac7e1 |
1248 | print_gdb_version () |
1249 | { |
4187119d |
1250 | printf ("GDB %s, Copyright (C) 1989 Free Software Foundation, Inc.\n\ |
7b4ac7e1 |
1251 | There is ABSOLUTELY NO WARRANTY for GDB; type \"info warranty\" for details.\n\ |
1252 | GDB is free software and you are welcome to distribute copies of it\n\ |
1253 | under certain conditions; type \"info copying\" to see the conditions.\n", |
1254 | version); |
1255 | } |
1256 | |
1257 | static void |
1258 | version_info () |
1259 | { |
1260 | immediate_quit++; |
1261 | print_gdb_version (); |
1262 | immediate_quit--; |
1263 | } |
1264 | \f |
3bf57d21 |
1265 | /* xgdb calls this to reprint the usual GDB prompt. */ |
1266 | |
1267 | void |
1268 | print_prompt () |
1269 | { |
1270 | printf ("%s", prompt); |
1271 | fflush (stdout); |
1272 | } |
1273 | |
1274 | /* Command to specify a prompt string instead of "(gdb) ". */ |
1275 | |
7b4ac7e1 |
1276 | static void |
1277 | set_prompt_command (text) |
1278 | char *text; |
1279 | { |
1280 | char *p, *q; |
1281 | register int c; |
1282 | char *new; |
1283 | |
1284 | if (text == 0) |
1285 | error_no_arg ("string to which to set prompt"); |
1286 | |
1287 | new = (char *) xmalloc (strlen (text) + 2); |
1288 | p = text; q = new; |
1289 | while (c = *p++) |
1290 | { |
1291 | if (c == '\\') |
1292 | { |
1293 | /* \ at end of argument is used after spaces |
1294 | so they won't be lost. */ |
1295 | if (*p == 0) |
1296 | break; |
1297 | c = parse_escape (&p); |
1298 | if (c == 0) |
1299 | break; /* C loses */ |
1300 | else if (c > 0) |
1301 | *q++ = c; |
1302 | } |
1303 | else |
1304 | *q++ = c; |
1305 | } |
1306 | if (*(p - 1) != '\\') |
1307 | *q++ = ' '; |
1308 | *q++ = '\0'; |
1309 | new = (char *) xrealloc (new, q - new); |
1310 | free (prompt); |
1311 | prompt = new; |
1312 | } |
1313 | \f |
1314 | static void |
1315 | quit_command () |
1316 | { |
1317 | if (have_inferior_p ()) |
1318 | { |
1319 | if (query ("The program is running. Quit anyway? ")) |
1320 | { |
1321 | /* Prevent any warning message from reopen_exec_file, in case |
1322 | we have a core file that's inconsistent with the exec file. */ |
1323 | exec_file_command (0, 0); |
1324 | kill_inferior (); |
1325 | } |
1326 | else |
1327 | error ("Not confirmed."); |
1328 | } |
4187119d |
1329 | /* Save the history information if it is appropriate to do so. */ |
1330 | if (write_history_p && history_filename) |
1331 | write_history (history_filename); |
7b4ac7e1 |
1332 | exit (0); |
1333 | } |
1334 | |
1335 | int |
1336 | input_from_terminal_p () |
1337 | { |
1338 | return instream == stdin; |
1339 | } |
1340 | \f |
1341 | static void |
1342 | pwd_command (arg, from_tty) |
1343 | char *arg; |
1344 | int from_tty; |
1345 | { |
7b4ac7e1 |
1346 | if (arg) error ("The \"pwd\" command does not take an argument: %s", arg); |
3bf57d21 |
1347 | getwd (dirbuf); |
1348 | |
1349 | if (strcmp (dirbuf, current_directory)) |
1350 | printf ("Working directory %s\n (canonically %s).\n", |
1351 | current_directory, dirbuf); |
1352 | else |
1353 | printf ("Working directory %s.\n", current_directory); |
7b4ac7e1 |
1354 | } |
1355 | |
1356 | static void |
1357 | cd_command (dir, from_tty) |
1358 | char *dir; |
1359 | int from_tty; |
1360 | { |
3bf57d21 |
1361 | int len; |
1362 | int change; |
1363 | |
7b4ac7e1 |
1364 | if (dir == 0) |
1365 | error_no_arg ("new working directory"); |
1366 | |
4187119d |
1367 | dir = tilde_expand (dir); |
1368 | make_cleanup (free, dir); |
1369 | |
3bf57d21 |
1370 | len = strlen (dir); |
1371 | dir = savestring (dir, len - (len > 1 && dir[len-1] == '/')); |
1372 | if (dir[0] == '/') |
1373 | current_directory = dir; |
1374 | else |
1375 | { |
1376 | current_directory = concat (current_directory, "/", dir); |
1377 | free (dir); |
1378 | } |
1379 | |
1380 | /* Now simplify any occurrences of `.' and `..' in the pathname. */ |
1381 | |
1382 | change = 1; |
1383 | while (change) |
1384 | { |
1385 | char *p; |
1386 | change = 0; |
1387 | |
1388 | for (p = current_directory; *p;) |
1389 | { |
1390 | if (!strncmp (p, "/./", 2) |
1391 | && (p[2] == 0 || p[2] == '/')) |
1392 | strcpy (p, p + 2); |
1393 | else if (!strncmp (p, "/..", 3) |
1394 | && (p[3] == 0 || p[3] == '/') |
1395 | && p != current_directory) |
1396 | { |
1397 | char *q = p; |
1398 | while (q != current_directory && q[-1] != '/') q--; |
1399 | if (q != current_directory) |
1400 | { |
1401 | strcpy (q-1, p+3); |
1402 | p = q-1; |
1403 | } |
1404 | } |
1405 | else p++; |
1406 | } |
1407 | } |
1408 | |
7b4ac7e1 |
1409 | if (chdir (dir) < 0) |
1410 | perror_with_name (dir); |
3bf57d21 |
1411 | |
7b4ac7e1 |
1412 | if (from_tty) |
1413 | pwd_command ((char *) 0, 1); |
1414 | } |
7b4ac7e1 |
1415 | \f |
7b4ac7e1 |
1416 | static void |
4187119d |
1417 | source_command (arg, from_tty) |
1418 | char *arg; |
1419 | int from_tty; |
7b4ac7e1 |
1420 | { |
1421 | FILE *stream; |
1422 | struct cleanup *cleanups; |
4187119d |
1423 | char *file = arg; |
7b4ac7e1 |
1424 | |
1425 | if (file == 0) |
4187119d |
1426 | /* Let source without arguments read .gdbinit. */ |
1427 | file = ".gdbinit"; |
1428 | |
1429 | file = tilde_expand (file); |
1430 | make_cleanup (free, file); |
7b4ac7e1 |
1431 | |
1432 | stream = fopen (file, "r"); |
1433 | if (stream == 0) |
1434 | perror_with_name (file); |
1435 | |
1436 | cleanups = make_cleanup (source_cleanup, instream); |
1437 | |
1438 | instream = stream; |
1439 | |
1440 | command_loop (); |
1441 | |
1442 | do_cleanups (cleanups); |
1443 | } |
1444 | |
1445 | static void |
1446 | echo_command (text) |
1447 | char *text; |
1448 | { |
1449 | char *p = text; |
1450 | register int c; |
1451 | |
1452 | if (text) |
1453 | while (c = *p++) |
1454 | { |
1455 | if (c == '\\') |
1456 | { |
1457 | /* \ at end of argument is used after spaces |
1458 | so they won't be lost. */ |
1459 | if (*p == 0) |
1460 | return; |
1461 | |
1462 | c = parse_escape (&p); |
1463 | if (c >= 0) |
1464 | fputc (c, stdout); |
1465 | } |
1466 | else |
1467 | fputc (c, stdout); |
1468 | } |
1469 | } |
1470 | |
1471 | static void |
1472 | dump_me_command () |
1473 | { |
1474 | if (query ("Should GDB dump core? ")) |
1475 | { |
1476 | signal (SIGQUIT, SIG_DFL); |
1477 | kill (getpid (), SIGQUIT); |
1478 | } |
1479 | } |
4187119d |
1480 | \f |
1481 | int |
1482 | parse_binary_operation (caller, arg) |
1483 | char *caller, *arg; |
1484 | { |
1485 | int length; |
1486 | |
1487 | if (!arg || !*arg) |
1488 | return 1; |
1489 | |
1490 | length = strlen (arg); |
1491 | |
1492 | while (arg[length - 1] == ' ' || arg[length - 1] == '\t') |
1493 | length--; |
1494 | |
1495 | if (!strncmp (arg, "on", length) |
1496 | || !strncmp (arg, "1", length) |
1497 | || !strncmp (arg, "yes", length)) |
1498 | return 1; |
1499 | else |
1500 | if (!strncmp (arg, "off", length) |
1501 | || !strncmp (arg, "0", length) |
1502 | || !strncmp (arg, "no", length)) |
1503 | return 0; |
1504 | else |
1505 | error ("\"%s\" not given a binary valued argument.", caller); |
1506 | } |
1507 | |
1508 | /* Functions to manipulate command line editing control variables. */ |
1509 | |
1510 | static void |
1511 | set_editing (arg, from_tty) |
1512 | char *arg; |
1513 | int from_tty; |
1514 | { |
1515 | command_editing_p = parse_binary_operation ("set command-editing", arg); |
1516 | } |
1517 | |
1518 | /* Number of commands to print in each call to editing_info. */ |
1519 | #define Hist_print 10 |
1520 | static void |
1521 | editing_info (arg, from_tty) |
1522 | char *arg; |
1523 | int from_tty; |
1524 | { |
1525 | /* Index for history commands. Relative to history_base. */ |
1526 | int offset; |
1527 | |
1528 | /* Number of the history entry which we are planning to display next. |
1529 | Relative to history_base. */ |
1530 | static int num = 0; |
1531 | |
1532 | /* The first command in the history which doesn't exist (i.e. one more |
1533 | than the number of the last command). Relative to history_base. */ |
1534 | int hist_len; |
1535 | |
1536 | struct _hist_entry { |
1537 | char *line; |
1538 | char *data; |
1539 | } *history_get(); |
1540 | extern int history_base; |
1541 | |
1542 | printf_filtered ("Interactive command editing is %s.\n", |
1543 | command_editing_p ? "on" : "off"); |
1544 | |
1545 | printf_filtered ("History expansion of command input is %s.\n", |
1546 | history_expansion_p ? "on" : "off"); |
1547 | printf_filtered ("Writing of a history record upon exit is %s.\n", |
1548 | write_history_p ? "enabled" : "disabled"); |
1549 | printf_filtered ("The size of the history list (number of stored commands) is %d.\n", |
1550 | history_size); |
1551 | printf_filtered ("The name of the history record is \"%s\".\n\n", |
1552 | history_filename ? history_filename : ""); |
1553 | |
1554 | /* Print out some of the commands from the command history. */ |
1555 | /* First determine the length of the history list. */ |
1556 | hist_len = history_size; |
1557 | for (offset = 0; offset < history_size; offset++) |
1558 | { |
1559 | if (!history_get (history_base + offset)) |
1560 | { |
1561 | hist_len = offset; |
1562 | break; |
1563 | } |
1564 | } |
1565 | |
1566 | if (arg) |
1567 | { |
1568 | if (arg[0] == '+' && arg[1] == '\0') |
1569 | /* "info editing +" should print from the stored position. */ |
1570 | ; |
1571 | else |
1572 | /* "info editing <exp>" should print around command number <exp>. */ |
1573 | num = (parse_and_eval_address (arg) - history_base) - Hist_print / 2; |
1574 | } |
1575 | /* "info editing" means print the last Hist_print commands. */ |
1576 | else |
1577 | { |
1578 | num = hist_len - Hist_print; |
1579 | } |
1580 | |
1581 | if (num < 0) |
1582 | num = 0; |
1583 | |
1584 | /* If there are at least Hist_print commands, we want to display the last |
1585 | Hist_print rather than, say, the last 6. */ |
1586 | if (hist_len - num < Hist_print) |
1587 | { |
1588 | num = hist_len - Hist_print; |
1589 | if (num < 0) |
1590 | num = 0; |
1591 | } |
1592 | |
1593 | if (num == hist_len - Hist_print) |
1594 | printf_filtered ("The list of the last %d commands is:\n\n", Hist_print); |
1595 | else |
1596 | printf_filtered ("Some of the stored commands are:\n\n"); |
1597 | |
1598 | for (offset = num; offset < num + Hist_print && offset < hist_len; offset++) |
1599 | { |
1600 | printf_filtered ("%5d %s\n", history_base + offset, |
1601 | (history_get (history_base + offset))->line); |
1602 | } |
1603 | |
1604 | /* The next command we want to display is the next one that we haven't |
1605 | displayed yet. */ |
1606 | num += Hist_print; |
1607 | |
1608 | /* If the user repeats this command with return, it should do what |
1609 | "info editing +" does. This is unnecessary if arg is null, |
1610 | because "info editing +" is not useful after "info editing". */ |
1611 | if (from_tty && arg) |
1612 | { |
1613 | arg[0] = '+'; |
1614 | arg[1] = '\0'; |
1615 | } |
1616 | } |
1617 | |
1618 | static void |
1619 | set_history_expansion (arg, from_tty) |
1620 | char *arg; |
1621 | int from_tty; |
1622 | { |
1623 | history_expansion_p = parse_binary_operation ("set history expansion", arg); |
1624 | } |
1625 | |
1626 | static void |
1627 | set_history_write (arg, from_tty) |
1628 | char *arg; |
1629 | int from_tty; |
1630 | { |
1631 | write_history_p = parse_binary_operation ("set history write", arg); |
1632 | } |
1633 | |
1634 | static void |
1635 | set_history (arg, from_tty) |
1636 | char *arg; |
1637 | int from_tty; |
1638 | { |
1639 | printf ("\"set history\" must be followed by the name of a history subcommand.\n"); |
1640 | help_list (sethistlist, "set history ", -1, stdout); |
1641 | } |
1642 | |
1643 | static void |
1644 | set_history_size (arg, from_tty) |
1645 | char *arg; |
1646 | int from_tty; |
1647 | { |
1648 | if (!*arg) |
1649 | error_no_arg ("set history size"); |
1650 | |
1651 | history_size = atoi (arg); |
1652 | } |
1653 | |
1654 | static void |
1655 | set_history_filename (arg, from_tty) |
1656 | char *arg; |
1657 | int from_tty; |
1658 | { |
1659 | int i; |
1660 | |
1661 | if (!arg) |
1662 | error_no_arg ("history file name"); |
1663 | |
1664 | arg = tilde_expand (arg); |
1665 | make_cleanup (free, arg); |
1666 | |
1667 | i = strlen (arg) - 1; |
1668 | |
1669 | free (history_filename); |
1670 | |
1671 | while (i > 0 && (arg[i] == ' ' || arg[i] == '\t')) |
1672 | i--; |
1673 | |
1674 | if (!*arg) |
1675 | history_filename = (char *) 0; |
1676 | else |
1677 | history_filename = savestring (arg, i + 1); |
1678 | history_filename[i] = '\0'; |
1679 | } |
1680 | |
1681 | int info_verbose; |
1682 | |
1683 | static void |
1684 | set_verbose_command (arg, from_tty) |
1685 | char *arg; |
1686 | int from_tty; |
1687 | { |
1688 | info_verbose = parse_binary_operation ("set verbose", arg); |
1689 | } |
1690 | |
1691 | static void |
1692 | verbose_info (arg, from_tty) |
1693 | char *arg; |
1694 | int from_tty; |
1695 | { |
1696 | if (arg) |
1697 | error ("\"info verbose\" does not take any arguments.\n"); |
1698 | |
1699 | printf ("Verbose printing of information is %s.\n", |
1700 | info_verbose ? "on" : "off"); |
1701 | } |
1702 | |
1703 | static void |
1704 | float_handler () |
1705 | { |
1706 | error ("Invalid floating value encountered or computed."); |
1707 | } |
1708 | |
7b4ac7e1 |
1709 | \f |
1710 | static void |
4187119d |
1711 | initialize_cmd_lists () |
e91b87a3 |
1712 | { |
1713 | cmdlist = (struct cmd_list_element *) 0; |
1714 | infolist = (struct cmd_list_element *) 0; |
1715 | enablelist = (struct cmd_list_element *) 0; |
1716 | disablelist = (struct cmd_list_element *) 0; |
1717 | deletelist = (struct cmd_list_element *) 0; |
1718 | enablebreaklist = (struct cmd_list_element *) 0; |
1719 | setlist = (struct cmd_list_element *) 0; |
4187119d |
1720 | sethistlist = (struct cmd_list_element *) 0; |
1721 | unsethistlist = (struct cmd_list_element *) 0; |
e91b87a3 |
1722 | } |
1723 | |
1724 | static void |
4187119d |
1725 | initialize_main () |
7b4ac7e1 |
1726 | { |
4187119d |
1727 | char *tmpenv; |
1728 | /* Command line editing externals. */ |
1729 | extern int (*rl_completion_entry_function)(); |
1730 | extern char *rl_completer_word_break_characters; |
1731 | |
1732 | /* Set default verbose mode on. */ |
1733 | info_verbose = 1; |
1734 | |
e91b87a3 |
1735 | prompt = savestring ("(gdb) ", 6); |
7b4ac7e1 |
1736 | |
4187119d |
1737 | /* Set the important stuff up for command editing. */ |
1738 | command_editing_p = 1; |
1739 | history_expansion_p = 0; |
1740 | write_history_p = 0; |
1741 | |
1742 | if (tmpenv = getenv ("HISTSIZE")) |
1743 | history_size = atoi (tmpenv); |
1744 | else |
1745 | history_size = 256; |
1746 | |
1747 | stifle_history (history_size); |
1748 | |
1749 | if (tmpenv = getenv ("GDBHISTFILE")) |
1750 | history_filename = savestring (tmpenv, strlen(tmpenv)); |
1751 | else |
1752 | /* We include the current directory so that if the user changes |
1753 | directories the file written will be the same as the one |
1754 | that was read. */ |
1755 | history_filename = concat (current_directory, "/.gdb_history", ""); |
1756 | |
1757 | read_history (history_filename); |
1758 | |
1759 | /* Setup important stuff for command line editing. */ |
1760 | rl_completion_entry_function = (int (*)()) symbol_completion_function; |
1761 | rl_completer_word_break_characters = gdb_completer_word_break_characters; |
1762 | |
7b4ac7e1 |
1763 | /* Define the classes of commands. |
1764 | They will appear in the help list in the reverse of this order. */ |
1765 | |
1766 | add_cmd ("obscure", class_obscure, 0, "Obscure features.", &cmdlist); |
1767 | add_cmd ("alias", class_alias, 0, "Aliases of other commands.", &cmdlist); |
1768 | add_cmd ("user", class_user, 0, "User-defined commands.\n\ |
1769 | The commands in this class are those defined by the user.\n\ |
1770 | Use the \"define\" command to define a command.", &cmdlist); |
1771 | add_cmd ("support", class_support, 0, "Support facilities.", &cmdlist); |
1772 | add_cmd ("status", class_info, 0, "Status inquiries.", &cmdlist); |
1773 | add_cmd ("files", class_files, 0, "Specifying and examining files.", &cmdlist); |
1774 | add_cmd ("breakpoints", class_breakpoint, 0, "Making program stop at certain points.", &cmdlist); |
1775 | add_cmd ("data", class_vars, 0, "Examining data.", &cmdlist); |
1776 | add_cmd ("stack", class_stack, 0, "Examining the stack.\n\ |
1777 | The stack is made up of stack frames. Gdb assigns numbers to stack frames\n\ |
1778 | counting from zero for the innermost (currently executing) frame.\n\n\ |
1779 | At any time gdb identifies one frame as the \"selected\" frame.\n\ |
1780 | Variable lookups are done with respect to the selected frame.\n\ |
1781 | When the program being debugged stops, gdb selects the innermost frame.\n\ |
1782 | The commands below can be used to select other frames by number or address.", |
1783 | &cmdlist); |
1784 | add_cmd ("running", class_run, 0, "Running the program.", &cmdlist); |
1785 | |
1786 | add_com ("pwd", class_files, pwd_command, |
1787 | "Print working directory. This is used for your program as well."); |
1788 | add_com ("cd", class_files, cd_command, |
1789 | "Set working directory to DIR for debugger and program being debugged.\n\ |
1790 | The change does not take effect for the program being debugged\n\ |
1791 | until the next time it is started."); |
1792 | |
e91b87a3 |
1793 | add_cmd ("prompt", class_support, set_prompt_command, |
1794 | "Change gdb's prompt from the default of \"(gdb)\"", |
1795 | &setlist); |
7b4ac7e1 |
1796 | add_com ("echo", class_support, echo_command, |
1797 | "Print a constant string. Give string as argument.\n\ |
1798 | C escape sequences may be used in the argument.\n\ |
1799 | No newline is added at the end of the argument;\n\ |
1800 | use \"\\n\" if you want a newline to be printed.\n\ |
1801 | Since leading and trailing whitespace are ignored in command arguments,\n\ |
1802 | if you want to print some you must use \"\\\" before leading whitespace\n\ |
1803 | to be printed or after trailing whitespace."); |
1804 | add_com ("document", class_support, document_command, |
1805 | "Document a user-defined command.\n\ |
1806 | Give command name as argument. Give documentation on following lines.\n\ |
1807 | End with a line of just \"end\"."); |
1808 | add_com ("define", class_support, define_command, |
1809 | "Define a new command name. Command name is argument.\n\ |
1810 | Definition appears on following lines, one command per line.\n\ |
1811 | End with a line of just \"end\".\n\ |
1812 | Use the \"document\" command to give documentation for the new command.\n\ |
1813 | Commands defined in this way do not take arguments."); |
1814 | |
1815 | add_com ("source", class_support, source_command, |
1816 | "Read commands from a file named FILE.\n\ |
1817 | Note that the file \".gdbinit\" is read automatically in this way\n\ |
1818 | when gdb is started."); |
1819 | add_com ("quit", class_support, quit_command, "Exit gdb."); |
1820 | add_com ("help", class_support, help_command, "Print list of commands."); |
1821 | add_com_alias ("q", "quit", class_support, 1); |
1822 | add_com_alias ("h", "help", class_support, 1); |
1823 | |
4187119d |
1824 | add_cmd ("verbose", class_support, set_verbose_command, |
1825 | "Change the number of informational messages gdb prints.", |
1826 | &setlist); |
1827 | add_info ("verbose", verbose_info, |
1828 | "Status of gdb's verbose printing option.\n"); |
1829 | |
7b4ac7e1 |
1830 | add_com ("dump-me", class_obscure, dump_me_command, |
1831 | "Get fatal error; make debugger dump its core."); |
1832 | |
4187119d |
1833 | add_cmd ("editing", class_support, set_editing, |
1834 | "Enable or disable command line editing.\n\ |
1835 | Use \"on\" to enable to enable the editing, and \"off\" to disable it.\n\ |
1836 | Without an argument, command line editing is enabled.", &setlist); |
1837 | |
1838 | add_prefix_cmd ("history", class_support, set_history, |
1839 | "Generic command for setting command history parameters.", |
1840 | &sethistlist, "set history ", 0, &setlist); |
1841 | |
1842 | add_cmd ("expansion", no_class, set_history_expansion, |
1843 | "Enable or disable history expansion on command input.\n\ |
1844 | Without an argument, history expansion is enabled.", &sethistlist); |
1845 | |
1846 | add_cmd ("write", no_class, set_history_write, |
1847 | "Enable or disable saving of the history record on exit.\n\ |
1848 | Use \"on\" to enable to enable the saving, and \"off\" to disable it.\n\ |
1849 | Without an argument, saving is enabled.", &sethistlist); |
1850 | |
1851 | add_cmd ("size", no_class, set_history_size, |
1852 | "Set the size of the command history, \n\ |
1853 | ie. the number of previous commands to keep a record of.", &sethistlist); |
1854 | |
1855 | add_cmd ("filename", no_class, set_history_filename, |
1856 | "Set the filename in which to record the command history\n\ |
1857 | (the list of previous commands of which a record is kept).", &sethistlist); |
1858 | |
7b4ac7e1 |
1859 | add_prefix_cmd ("info", class_info, info_command, |
1860 | "Generic command for printing status.", |
1861 | &infolist, "info ", 0, &cmdlist); |
1862 | add_com_alias ("i", "info", class_info, 1); |
1863 | |
4187119d |
1864 | add_info ("editing", editing_info, "Status of command editor."); |
1865 | |
7b4ac7e1 |
1866 | add_info ("version", version_info, "Report what version of GDB this is."); |
1867 | } |