1 /* List lines of source files for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc.
4 This file is part of GDB.
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)
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.
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. */
25 #include <sys/types.h>
30 #include <sys/param.h>
34 /* Path of directories to search for source files.
35 Same format as the PATH environment variable's value. */
37 static char *source_path;
39 /* Symtab of default file for listing lines of. */
41 struct symtab *current_source_symtab;
43 /* Default next line to list. */
45 int current_source_line;
47 /* Line number of last line printed. Default for various commands.
48 current_source_line is usually, but not always, the same as this. */
50 static int last_line_listed;
52 /* First line number listed by last listing command. */
54 static int first_line_listed;
57 struct symtab *psymtab_to_symtab ();
59 /* Set the source file default for the "list" command, specifying a
60 symtab. Sigh. Behaivior specification: If it is called with a
61 non-zero argument, that is the symtab to select. If it is not,
62 first lookup "main"; if it exists, use the symtab and line it
63 defines. If not, take the last symtab in the symtab_list (if it
64 exists) or the last symtab in the psytab_list (if *it* exists). If
65 none of this works, report an error. */
68 select_source_symtab (s)
69 register struct symtab *s;
71 struct symtabs_and_lines sals;
72 struct symtab_and_line sal;
73 struct partial_symtab *ps, *cs_pst;
77 current_source_symtab = s;
78 current_source_line = 1;
82 /* Make the default place to list be the function `main'
84 if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0))
86 sals = decode_line_spec ("main", 1);
89 current_source_symtab = sal.symtab;
90 current_source_line = max (sal.line - 9, 1);
94 /* All right; find the last file in the symtab list (ignoring .h's). */
100 char *name = s->filename;
101 int len = strlen (name);
102 if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
103 current_source_symtab = s;
107 current_source_line = 1;
109 else if (partial_symtab_list)
111 ps = partial_symtab_list;
114 char *name = ps->filename;
115 int len = strlen (name);
116 if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
122 fatal ("Internal: select_source_symtab: readin pst found and no symtabs.");
124 current_source_symtab = psymtab_to_symtab (cs_pst);
126 current_source_symtab = 0;
127 current_source_line = 1;
134 printf ("Source directories searched: %s\n", source_path);
140 register struct symtab *s;
142 source_path = savestring (current_directory, strlen (current_directory));
144 /* Forget what we learned about line positions in source files;
145 must check again now since files may be found in
146 a different directory now. */
147 for (s = symtab_list; s; s = s->next)
148 if (s->line_charpos != 0)
150 free (s->line_charpos);
156 directory_command (dirname, from_tty)
160 char *old = source_path;
166 if (query ("Reinitialize source path to %s? ", current_directory))
174 dirname = tilde_expand (dirname);
175 make_cleanup (free, dirname);
179 extern char *index ();
180 char *name = dirname;
185 char *colon = index (name, ':');
186 char *space = index (name, ' ');
187 char *tab = index (name, '\t');
188 if (colon == 0 && space == 0 && tab == 0)
189 p = dirname = name + strlen (name);
193 if (colon != 0 && (p == 0 || colon < p))
195 if (space != 0 && (p == 0 || space < p))
197 if (tab != 0 && (p == 0 || tab < p))
200 while (*dirname == ':' || *dirname == ' ' || *dirname == '\t')
206 /* Sigh. "foo/" => "foo" */
214 /* "." => getwd (). */
215 name = current_directory;
218 else if (p[-2] == '/')
228 /* "...foo/." => "...foo". */
239 name = concat (current_directory, "/", name);
241 name = savestring (name, p - name);
242 make_cleanup (free, name);
244 if (stat (name, &st) < 0)
245 perror_with_name (name);
246 if ((st.st_mode & S_IFMT) != S_IFDIR)
247 error ("%s is not a directory.", name);
251 register unsigned int len = strlen (name);
256 if (!strncmp (p, name, len)
257 && (p[len] == '\0' || p[len] == ':'))
260 printf ("\"%s\" is already in the source path.\n", name);
271 source_path = concat (old, ":", name);
276 } while (*dirname != '\0');
282 /* Open a file named STRING, searching path PATH (dir names sep by colons)
283 using mode MODE and protection bits PROT in the calls to open.
284 If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
285 (ie pretend the first element of PATH is ".")
286 If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
287 the actual file opened (this string will always start with a "/"
289 If a file is found, return the descriptor.
290 Otherwise, return -1, with errno set for the last name we tried to open. */
292 /* >>>> This should only allow files of certain types,
293 >>>> eg executable, non-directory */
295 openp (path, try_cwd_first, string, mode, prot, filename_opened)
301 char **filename_opened;
304 register char *filename;
305 register char *p, *p1;
312 while (string[0] == '.' && string[1] == '/')
315 if (try_cwd_first || string[0] == '/')
318 fd = open (filename, mode, prot);
319 if (fd >= 0 || string[0] == '/')
323 filename = (char *) alloca (strlen (path) + strlen (string) + 2);
325 for (p = path; p; p = p1 ? p1 + 1 : 0)
327 p1 = (char *) index (p, ':');
333 strncpy (filename, p, len);
335 strcat (filename, "/");
336 strcat (filename, string);
338 fd = open (filename, mode, prot);
345 *filename_opened = (char *) 0;
346 else if (filename[0] == '/')
347 *filename_opened = savestring (filename, strlen (filename));
350 *filename_opened = concat (current_directory, "/", filename);
356 /* Create and initialize the table S->line_charpos that records
357 the positions of the lines in the source file, which is assumed
358 to be open on descriptor DESC.
359 All set S->nlines to the number of such lines. */
362 find_source_lines (s, desc)
367 register char *data, *p, *end;
369 int lines_allocated = 1000;
370 int *line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
371 extern int exec_mtime;
374 if (get_exec_file (0) != 0 && exec_mtime < st.st_mtime)
375 printf ("Source file is more recent than executable.\n");
377 data = (char *) alloca (st.st_size);
378 myread (desc, data, st.st_size);
379 end = data + st.st_size;
386 /* A newline at the end does not start a new line. */
389 if (nlines == lines_allocated)
391 lines_allocated *= 2;
392 line_charpos = (int *) xrealloc (line_charpos,
393 sizeof (int) * lines_allocated);
395 line_charpos[nlines++] = p - data;
399 s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int));
402 /* Return the character position of a line LINE in symtab S.
403 Return 0 if anything is invalid. */
406 source_line_charpos (s, line)
411 if (!s->line_charpos || line <= 0) return 0;
412 if (line > s->nlines)
414 return s->line_charpos[line - 1];
417 /* Return the line number of character position POS in symtab S. */
420 source_charpos_line (s, chr)
421 register struct symtab *s;
424 register int line = 0;
427 if (s == 0 || s->line_charpos == 0) return 0;
428 lnp = s->line_charpos;
429 /* Files are usually short, so sequential search is Ok */
430 while (line < s->nlines && *lnp <= chr)
435 if (line >= s->nlines)
440 /* Get full pathname and line number positions for a symtab.
441 Return nonzero if line numbers may have changed.
442 Set *FULLNAME to actual name of the file as found by `openp',
443 or to 0 if the file is not found. */
446 get_filename_and_charpos (s, line, fullname)
451 register int desc, linenums_changed = 0;
453 desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname);
461 *fullname = s->fullname;
462 if (s->line_charpos == 0) linenums_changed = 1;
463 if (linenums_changed) find_source_lines (s, desc);
465 return linenums_changed;
468 /* Print text describing the full name of the source file S
469 and the line number LINE and its corresponding character position.
470 The text starts with two Ctrl-z so that the Emacs-GDB interface
473 MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
475 Return 1 if successful, 0 if could not find the file. */
478 identify_source_line (s, line, mid_statement)
483 if (s->line_charpos == 0)
484 get_filename_and_charpos (s, line, 0);
485 if (s->fullname == 0)
487 printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname,
488 line, s->line_charpos[line - 1],
489 mid_statement ? "middle" : "beg",
490 get_frame_pc (get_current_frame()));
491 current_source_line = line;
492 first_line_listed = line;
493 last_line_listed = line;
494 current_source_symtab = s;
498 /* Print source lines from the file of symtab S,
499 starting with line number LINE and stopping before line number STOPLINE. */
502 print_source_lines (s, line, stopline, noerror)
509 register FILE *stream;
510 int nlines = stopline - line;
512 desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname);
517 perror_with_name (s->filename);
518 print_sys_errmsg (s->filename, errno);
522 if (s->line_charpos == 0)
523 find_source_lines (s, desc);
525 if (line < 1 || line > s->nlines)
528 error ("Line number out of range; %s has %d lines.",
529 s->filename, s->nlines);
532 if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
535 perror_with_name (s->filename);
538 current_source_symtab = s;
539 current_source_line = line;
540 first_line_listed = line;
542 stream = fdopen (desc, "r");
549 last_line_listed = current_source_line;
550 printf_filtered ("%d\t", current_source_line++);
553 if (c < 040 && c != '\t' && c != '\n')
554 printf_filtered ("^%c", c + 0100);
556 printf_filtered ("^?");
558 printf_filtered ("%c", c);
559 } while (c != '\n' && (c = fgetc (stream)) >= 0);
569 Print a list of files and line numbers which a user may choose from
570 in order to list a function which was specified ambiguously
571 (as with `list classname::overloadedfuncname', for example).
572 The vector in SALS provides the filenames and line numbers.
575 ambiguous_line_spec (sals)
576 struct symtabs_and_lines *sals;
580 for (i = 0; i < sals->nelts; ++i)
581 printf("file: \"%s\", line number: %d\n",
582 sals->sals[i].symtab->filename, sals->sals[i].line);
587 list_command (arg, from_tty)
591 struct symtabs_and_lines sals, sals_end;
592 struct symtab_and_line sal, sal_end;
601 if (symtab_list == 0 && partial_symtab_list == 0)
602 error ("No symbol table is loaded. Use the \"symbol-file\" command.");
604 /* Pull in a current source symtab if necessary */
605 if (current_source_symtab == 0 &&
606 (arg == 0 || arg[0] == '+' || arg[0] == '-'))
607 select_source_symtab (0);
609 /* "l" or "l +" lists next ten lines. */
611 if (arg == 0 || !strcmp (arg, "+"))
613 if (current_source_symtab == 0)
614 error ("No default source file yet. Do \"help list\".");
615 print_source_lines (current_source_symtab, current_source_line,
616 current_source_line + 10, 0);
620 /* "l -" lists previous ten lines, the ones before the ten just listed. */
621 if (!strcmp (arg, "-"))
623 if (current_source_symtab == 0)
624 error ("No default source file yet. Do \"help list\".");
625 print_source_lines (current_source_symtab,
626 max (first_line_listed - 10, 1),
627 first_line_listed, 0);
631 /* Now if there is only one argument, decode it in SAL
633 If there are two arguments, decode them in SAL and SAL_END
634 and clear NO_END; however, if one of the arguments is blank,
635 set DUMMY_BEG or DUMMY_END to record that fact. */
642 sals = decode_line_1 (&arg1, 0, 0, 0);
644 if (! sals.nelts) return; /* C++ */
647 ambiguous_line_spec (&sals);
656 /* Record whether the BEG arg is all digits. */
658 for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
659 linenum_beg = (p == arg1);
661 while (*arg1 == ' ' || *arg1 == '\t')
667 while (*arg1 == ' ' || *arg1 == '\t')
674 sals_end = decode_line_1 (&arg1, 0, 0, 0);
676 sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
677 if (sals_end.nelts == 0)
679 if (sals_end.nelts > 1)
681 ambiguous_line_spec (&sals_end);
682 free (sals_end.sals);
685 sal_end = sals_end.sals[0];
686 free (sals_end.sals);
691 error ("Junk at end of line specification.");
693 if (!no_end && !dummy_beg && !dummy_end
694 && sal.symtab != sal_end.symtab)
695 error ("Specified start and end are in different files.");
696 if (dummy_beg && dummy_end)
697 error ("Two empty args do not say what lines to list.");
699 /* if line was specified by address,
700 first print exactly which line, and which file.
701 In this case, sal.symtab == 0 means address is outside
702 of all known source files, not that user failed to give a filename. */
706 error ("No source file for address 0x%x.", sal.pc);
707 sym = find_pc_function (sal.pc);
709 printf ("0x%x is in %s (%s, line %d).\n",
710 sal.pc, SYMBOL_NAME (sym), sal.symtab->filename, sal.line);
712 printf ("0x%x is in %s, line %d.\n",
713 sal.pc, sal.symtab->filename, sal.line);
716 /* If line was not specified by just a line number,
717 and it does not imply a symtab, it must be an undebuggable symbol
718 which means no source code. */
720 if (! linenum_beg && sal.symtab == 0)
721 error ("No line number known for %s.", arg);
723 /* If this command is repeated with RET,
724 turn it into the no-arg variant. */
729 if (dummy_beg && sal_end.symtab == 0)
730 error ("No default source file yet. Do \"help list\".");
732 print_source_lines (sal_end.symtab, max (sal_end.line - 9, 1),
733 sal_end.line + 1, 0);
734 else if (sal.symtab == 0)
735 error ("No default source file yet. Do \"help list\".");
737 print_source_lines (sal.symtab, max (sal.line - 5, 1), sal.line + 5, 0);
739 print_source_lines (sal.symtab, sal.line,
740 dummy_end ? sal.line + 10 : sal_end.line + 1,
744 /* Print info on range of pc's in a specified line. */
747 line_info (arg, from_tty)
751 struct symtabs_and_lines sals;
752 struct symtab_and_line sal;
753 int start_pc, end_pc;
758 sal.symtab = current_source_symtab;
759 sal.line = last_line_listed;
761 sals.sals = (struct symtab_and_line *)
762 xmalloc (sizeof (struct symtab_and_line));
767 sals = decode_line_spec_1 (arg, 0);
769 /* If this command is repeated with RET,
770 turn it into the no-arg variant. */
775 /* C++ More than one line may have been specified, as when the user
776 specifies an overloaded function name. Print info on them all. */
777 for (i = 0; i < sals.nelts; i++)
782 error ("No source file specified.");
785 && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
787 if (start_pc == end_pc)
788 printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n",
789 sal.line, sal.symtab->filename, start_pc);
791 printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n",
792 sal.line, sal.symtab->filename, start_pc, end_pc);
793 /* x/i should display this line's code. */
794 set_next_address (start_pc);
795 /* Repeating "info line" should do the following line. */
796 last_line_listed = sal.line + 1;
799 printf ("Line number %d is out of range for \"%s\".\n",
800 sal.line, sal.symtab->filename);
804 /* Commands to search the source file for a regexp. */
807 forward_search_command (regex, from_tty)
812 register FILE *stream;
813 int line = last_line_listed + 1;
816 msg = (char *) re_comp (regex);
820 if (current_source_symtab == 0)
821 select_source_symtab (0);
823 /* Search from last_line_listed+1 in current_source_symtab */
825 desc = openp (source_path, 0, current_source_symtab->filename,
826 O_RDONLY, 0, ¤t_source_symtab->fullname);
828 perror_with_name (current_source_symtab->filename);
830 if (current_source_symtab->line_charpos == 0)
831 find_source_lines (current_source_symtab, desc);
833 if (line < 1 || line > current_source_symtab->nlines)
836 error ("Expression not found");
839 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
842 perror_with_name (current_source_symtab->filename);
845 stream = fdopen (desc, "r");
848 char buf[4096]; /* Should be reasonable??? */
849 register char *p = buf;
856 } while (c != '\n' && (c = fgetc (stream)) >= 0);
858 /* we now have a source line in buf, null terminate and match */
860 if (re_exec (buf) > 0)
864 print_source_lines (current_source_symtab,
866 current_source_line = max (line - 5, 1);
872 printf ("Expression not found\n");
877 reverse_search_command (regex, from_tty)
882 register FILE *stream;
883 int line = last_line_listed - 1;
886 msg = (char *) re_comp (regex);
890 if (current_source_symtab == 0)
891 select_source_symtab (0);
893 /* Search from last_line_listed-1 in current_source_symtab */
895 desc = openp (source_path, 0, current_source_symtab->filename,
896 O_RDONLY, 0, ¤t_source_symtab->fullname);
898 perror_with_name (current_source_symtab->filename);
900 if (current_source_symtab->line_charpos == 0)
901 find_source_lines (current_source_symtab, desc);
903 if (line < 1 || line > current_source_symtab->nlines)
906 error ("Expression not found");
909 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
912 perror_with_name (current_source_symtab->filename);
915 stream = fdopen (desc, "r");
919 char buf[4096]; /* Should be reasonable??? */
920 register char *p = buf;
927 } while (c != '\n' && (c = fgetc (stream)) >= 0);
929 /* We now have a source line in buf; null terminate and match. */
931 if (re_exec (buf) > 0)
935 print_source_lines (current_source_symtab,
937 current_source_line = max (line - 5, 1);
941 if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
944 perror_with_name (current_source_symtab->filename);
948 printf ("Expression not found\n");
954 _initialize_source ()
956 current_source_symtab = 0;
959 add_com ("directory", class_files, directory_command,
960 "Add directory DIR to end of search path for source files.\n\
961 With no argument, reset the search path to just the working directory\n\
962 and forget cached info on line positions in source files.");
964 add_info ("directories", directories_info,
965 "Current search path for finding source files.");
967 add_info ("line", line_info,
968 "Core addresses of the code for a source line.\n\
969 Line can be specified as\n\
970 LINENUM, to list around that line in current file,\n\
971 FILE:LINENUM, to list around that line in that file,\n\
972 FUNCTION, to list around beginning of that function,\n\
973 FILE:FUNCTION, to distinguish among like-named static functions.\n\
974 Default is to describe the last source line that was listed.\n\n\
975 This sets the default address for \"x\" to the line's first instruction\n\
976 so that \"x/i\" suffices to start examining the machine code.\n\
977 The address is also stored as the value of \"$_\".");
979 add_com ("forward-search", class_files, forward_search_command,
980 "Search for regular expression (see regex(3)) from last line listed.");
981 add_com_alias ("search", "forward-search", class_files, 0);
983 add_com ("reverse-search", class_files, reverse_search_command,
984 "Search backward for regular expression (see regex(3)) from last line listed.");
986 add_com ("list", class_files, list_command,
987 "List specified function or line.\n\
988 With no argument, lists ten more lines after or around previous listing.\n\
989 \"list -\" lists the ten lines before a previous ten-line listing.\n\
990 One argument specifies a line, and ten lines are listed around that line.\n\
991 Two arguments with comma between specify starting and ending lines to list.\n\
992 Lines can be specified in these ways:\n\
993 LINENUM, to list around that line in current file,\n\
994 FILE:LINENUM, to list around that line in that file,\n\
995 FUNCTION, to list around beginning of that function,\n\
996 FILE:FUNCTION, to distinguish among like-named static functions.\n\
997 *ADDRESS, to list around the line containing that address.\n\
998 With two args if one is empty it stands for ten lines away from the other arg.");