1 /* List lines of source files for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY. No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License. A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities. It
14 should be in a file named COPYING. Among other things, the copyright
15 notice and this notice must be preserved on all copies.
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther. Help stamp out software hoarding!
26 #include <sys/types.h>
31 #include <sys/param.h>
35 /* Path of directories to search for source files.
36 Same format as the PATH environment variable's value. */
38 static char *source_path;
40 /* Symtab of default file for listing lines of. */
42 struct symtab *current_source_symtab;
44 /* Default next line to list. */
46 int current_source_line;
48 /* Line number of last line printed. Default for various commands.
49 current_source_line is usually, but not always, the same as this. */
51 static int last_line_listed;
53 /* First line number listed by last listing command. */
55 static int first_line_listed;
58 struct symtab *psymtab_to_symtab ();
60 /* Set the source file default for the "list" command,
61 specifying a symtab. */
64 select_source_symtab (s)
65 register struct symtab *s;
67 struct symtabs_and_lines sals;
68 struct symtab_and_line sal;
69 struct partial_symtab *ps, *cs_pst;
71 /* Make the default place to list be the function `main'
73 if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0))
75 sals = decode_line_spec ("main", 1);
78 current_source_symtab = sal.symtab;
79 current_source_line = sal.line - 9;
83 /* If there is no `main', use the last symtab in the list,
84 which is actually the first found in the file's symbol table.
85 But ignore .h files. */
90 char *name = s->filename;
91 int len = strlen (name);
92 if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
93 current_source_symtab = s;
97 current_source_line = 1;
101 ps = partial_symtab_list;
104 char *name = ps->filename;
105 int len = strlen (name);
106 if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
111 current_source_symtab = psymtab_to_symtab (cs_pst);
113 current_source_symtab = 0;
114 current_source_line = 1;
121 printf ("Source directories searched: %s\n", source_path);
127 register struct symtab *s;
129 source_path = savestring (current_directory, strlen (current_directory));
131 /* Forget what we learned about line positions in source files;
132 must check again now since files may be found in
133 a different directory now. */
134 for (s = symtab_list; s; s = s->next)
135 if (s->line_charpos != 0)
137 free (s->line_charpos);
143 directory_command (dirname, from_tty)
147 char *old = source_path;
151 if (query ("Reinitialize source path to %s? ", current_directory))
160 register int len = strlen (dirname);
162 extern char *index ();
164 if (index (dirname, ':'))
165 error ("Please add one directory at a time to the source path.");
166 if (dirname[len - 1] == '/')
167 /* Sigh. "foo/" => "foo" */
168 dirname[--len] == '\0';
170 while (dirname[len - 1] == '.')
174 /* "." => getwd () */
175 dirname = current_directory;
178 else if (dirname[len - 2] == '/')
183 dirname[--len] = '\0';
188 /* "...foo/." => "...foo" */
189 dirname[len -= 2] = '\0';
196 if (dirname[0] != '/')
197 dirname = concat (current_directory, "/", dirname);
199 dirname = savestring (dirname, len);
200 make_cleanup (free, dirname);
202 if (stat (dirname, &st) < 0)
203 perror_with_name (dirname);
204 if ((st.st_mode & S_IFMT) != S_IFDIR)
205 error ("%s is not a directory.", dirname);
208 len = strlen (dirname);
212 if (!strncmp (tem, dirname, len)
213 && (tem[len] == '\0' || tem[len] == ':'))
215 printf ("\"%s\" is already in the source path.\n",
219 tem = index (tem, ':');
224 source_path = concat (old, ":", dirname);
234 /* Open a file named STRING, searching path PATH (dir names sep by colons)
235 using mode MODE and protection bits PROT in the calls to open.
236 If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
237 (ie pretend the first element of PATH is ".")
238 If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
239 the actual file opened (this string will always start with a "/"
241 If a file is found, return the descriptor.
242 Otherwise, return -1, with errno set for the last name we tried to open. */
244 /* >>>> This should only allow files of certain types,
245 >>>> eg executable, non-directory */
247 openp (path, try_cwd_first, string, mode, prot, filename_opened)
253 char **filename_opened;
256 register char *filename;
257 register char *p, *p1;
261 while (string[0] == '.' && string[1] == '/')
264 if (try_cwd_first || string[0] == '/')
267 fd = open (filename, mode, prot);
268 if (fd >= 0 || string[0] == '/')
272 filename = (char *) alloca (strlen (path) + strlen (string) + 2);
274 for (p = path; p; p = p1 ? p1 + 1 : 0)
276 p1 = (char *) index (p, ':');
282 strncpy (filename, p, len);
284 strcat (filename, "/");
285 strcat (filename, string);
287 fd = open (filename, mode, prot);
294 *filename_opened = (char *) 0;
295 else if (filename[0] == '/')
296 *filename_opened = savestring (filename, strlen (filename));
299 *filename_opened = concat (current_directory, "/", filename);
305 /* Create and initialize the table S->line_charpos that records
306 the positions of the lines in the source file, which is assumed
307 to be open on descriptor DESC.
308 All set S->nlines to the number of such lines. */
311 find_source_lines (s, desc)
316 register char *data, *p, *end;
318 int lines_allocated = 1000;
319 int *line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
320 extern int exec_mtime;
323 if (get_exec_file (0) != 0 && exec_mtime < st.st_mtime)
324 printf ("Source file is more recent than executable.\n");
326 data = (char *) alloca (st.st_size);
327 myread (desc, data, st.st_size);
328 end = data + st.st_size;
335 /* A newline at the end does not start a new line. */
338 if (nlines == lines_allocated)
340 lines_allocated *= 2;
341 line_charpos = (int *) xrealloc (line_charpos,
342 sizeof (int) * lines_allocated);
344 line_charpos[nlines++] = p - data;
348 s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int));
351 /* Return the character position of a line LINE in symtab S.
352 Return 0 if anything is invalid. */
355 source_line_charpos (s, line)
360 if (!s->line_charpos || line <= 0) return 0;
361 if (line > s->nlines)
363 return s->line_charpos[line - 1];
366 /* Return the line number of character position POS in symtab S. */
369 source_charpos_line (s, chr)
370 register struct symtab *s;
373 register int line = 0;
376 if (s == 0 || s->line_charpos == 0) return 0;
377 lnp = s->line_charpos;
378 /* Files are usually short, so sequential search is Ok */
379 while (line < s->nlines && *lnp <= chr)
384 if (line >= s->nlines)
389 /* Get full pathname and line number positions for a symtab.
390 Return nonzero if line numbers may have changed.
391 Set *FULLNAME to actual name of the file as found by `openp',
392 or to 0 if the file is not found. */
395 get_filename_and_charpos (s, line, fullname)
400 register int desc, linenums_changed = 0;
402 desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname);
410 *fullname = s->fullname;
411 if (s->line_charpos == 0) linenums_changed = 1;
412 if (linenums_changed) find_source_lines (s, desc);
414 return linenums_changed;
417 /* Print text describing the full name of the source file S
418 and the line number LINE and its corresponding character position.
419 The text starts with two Ctrl-z so that the Emacs-GDB interface
422 MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
424 Return 1 if successful, 0 if could not find the file. */
427 identify_source_line (s, line, mid_statement)
432 if (s->line_charpos == 0)
433 get_filename_and_charpos (s, line, 0);
434 if (s->fullname == 0)
436 printf ("\032\032%s:%d:%d:%s\n", s->fullname,
437 line, s->line_charpos[line - 1],
438 mid_statement ? "middle" : "beg");
439 current_source_line = line;
440 first_line_listed = line;
441 last_line_listed = line;
442 current_source_symtab = s;
446 /* Print source lines from the file of symtab S,
447 starting with line number LINE and stopping before line number STOPLINE. */
450 print_source_lines (s, line, stopline, noerror)
457 register FILE *stream;
458 int nlines = stopline - line;
460 desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname);
465 perror_with_name (s->filename);
466 print_sys_errmsg (s->filename, errno);
470 if (s->line_charpos == 0)
471 find_source_lines (s, desc);
473 if (line < 1 || line > s->nlines)
476 error ("Line number out of range; %s has %d lines.",
477 s->filename, s->nlines);
480 if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
483 perror_with_name (s->filename);
486 current_source_symtab = s;
487 current_source_line = line;
488 first_line_listed = line;
490 stream = fdopen (desc, "r");
497 last_line_listed = current_source_line;
498 printf ("%d\t", current_source_line++);
501 if (c < 040 && c != '\t' && c != '\n')
504 fputc (c + 0100, stdout);
510 } while (c != '\n' && (c = fgetc (stream)) >= 0);
520 Print a list of files and line numbers which a user may choose from
521 in order to list a function which was specified ambiguously
522 (as with `list classname::overloadedfuncname', for example).
523 The vector in SALS provides the filenames and line numbers.
526 ambiguous_line_spec (sals)
527 struct symtabs_and_lines *sals;
531 for (i = 0; i < sals->nelts; ++i)
532 printf("file: \"%s\", line number: %d\n",
533 sals->sals[i].symtab->filename, sals->sals[i].line);
538 list_command (arg, from_tty)
542 struct symtabs_and_lines sals, sals_end;
543 struct symtab_and_line sal, sal_end;
552 if (symtab_list == 0 && partial_symtab_list == 0)
553 error ("Listing source lines requires symbols.");
555 /* Pull in a current source symtab if necessary */
556 if (current_source_symtab == 0 &&
557 (arg == 0 || arg[0] == '+' || arg[0] == '-'))
558 select_source_symtab (symtab_list);
560 /* "l" or "l +" lists next ten lines. */
562 if (arg == 0 || !strcmp (arg, "+"))
564 if (current_source_symtab == 0)
565 error ("No default source file yet. Do \"help list\".");
566 print_source_lines (current_source_symtab, current_source_line,
567 current_source_line + 10, 0);
571 /* "l -" lists previous ten lines, the ones before the ten just listed. */
572 if (!strcmp (arg, "-"))
574 if (current_source_symtab == 0)
575 error ("No default source file yet. Do \"help list\".");
576 print_source_lines (current_source_symtab,
577 max (first_line_listed - 10, 1),
578 first_line_listed, 0);
582 /* Now if there is only one argument, decode it in SAL
584 If there are two arguments, decode them in SAL and SAL_END
585 and clear NO_END; however, if one of the arguments is blank,
586 set DUMMY_BEG or DUMMY_END to record that fact. */
593 sals = decode_line_1 (&arg1, 0, 0, 0);
595 if (! sals.nelts) return; /* C++ */
598 ambiguous_line_spec (&sals);
607 /* Record whether the BEG arg is all digits. */
609 for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
610 linenum_beg = (p == arg1);
612 while (*arg1 == ' ' || *arg1 == '\t')
618 while (*arg1 == ' ' || *arg1 == '\t')
625 sals_end = decode_line_1 (&arg1, 0, 0, 0);
627 sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
628 if (sals_end.nelts == 0)
630 if (sals_end.nelts > 1)
632 ambiguous_line_spec (&sals_end);
633 free (sals_end.sals);
636 sal_end = sals_end.sals[0];
637 free (sals_end.sals);
642 error ("Junk at end of line specification.");
644 if (!no_end && !dummy_beg && !dummy_end
645 && sal.symtab != sal_end.symtab)
646 error ("Specified start and end are in different files.");
647 if (dummy_beg && dummy_end)
648 error ("Two empty args do not say what lines to list.");
650 /* if line was specified by address,
651 first print exactly which line, and which file.
652 In this case, sal.symtab == 0 means address is outside
653 of all known source files, not that user failed to give a filename. */
657 error ("No source file for address 0x%x.", sal.pc);
658 sym = find_pc_function (sal.pc);
660 printf ("0x%x is in %s (%s, line %d).\n",
661 sal.pc, SYMBOL_NAME (sym), sal.symtab->filename, sal.line);
663 printf ("0x%x is in %s, line %d.\n",
664 sal.pc, sal.symtab->filename, sal.line);
667 /* If line was not specified by just a line number,
668 and it does not imply a symtab, it must be an undebuggable symbol
669 which means no source code. */
671 if (! linenum_beg && sal.symtab == 0)
672 error ("No line number known for %s.", arg);
674 /* If this command is repeated with RET,
675 turn it into the no-arg variant. */
680 if (dummy_beg && sal_end.symtab == 0)
681 error ("No default source file yet. Do \"help list\".");
683 print_source_lines (sal_end.symtab, max (sal_end.line - 9, 1),
684 sal_end.line + 1, 0);
685 else if (sal.symtab == 0)
686 error ("No default source file yet. Do \"help list\".");
688 print_source_lines (sal.symtab, max (sal.line - 5, 1), sal.line + 5, 0);
690 print_source_lines (sal.symtab, sal.line,
691 dummy_end ? sal.line + 10 : sal_end.line + 1,
695 /* Print info on range of pc's in a specified line. */
698 line_info (arg, from_tty)
702 struct symtabs_and_lines sals;
703 struct symtab_and_line sal;
704 int start_pc, end_pc;
709 sal.symtab = current_source_symtab;
710 sal.line = last_line_listed;
712 sals.sals = (struct symtab_and_line *)
713 xmalloc (sizeof (struct symtab_and_line));
718 sals = decode_line_spec_1 (arg, 0);
720 /* If this command is repeated with RET,
721 turn it into the no-arg variant. */
726 /* C++ More than one line may have been specified, as when the user
727 specifies an overloaded function name. Print info on them all. */
728 for (i = 0; i < sals.nelts; i++)
733 error ("No source file specified.");
736 && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
738 if (start_pc == end_pc)
739 printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n",
740 sal.line, sal.symtab->filename, start_pc);
742 printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n",
743 sal.line, sal.symtab->filename, start_pc, end_pc);
744 /* x/i should display this line's code. */
745 set_next_address (start_pc);
746 /* Repeating "info line" should do the following line. */
747 last_line_listed = sal.line + 1;
750 printf ("Line number %d is out of range for \"%s\".\n",
751 sal.line, sal.symtab->filename);
755 /* Commands to search the source file for a regexp. */
758 forward_search_command (regex, from_tty)
763 register FILE *stream;
764 int line = last_line_listed + 1;
767 msg = (char *) re_comp (regex);
771 if (current_source_symtab == 0)
772 error ("No default source file yet. Do \"help list\".");
774 /* Search from last_line_listed+1 in current_source_symtab */
776 desc = openp (source_path, 0, current_source_symtab->filename,
777 O_RDONLY, 0, ¤t_source_symtab->fullname);
779 perror_with_name (current_source_symtab->filename);
781 if (current_source_symtab->line_charpos == 0)
782 find_source_lines (current_source_symtab, desc);
784 if (line < 1 || line > current_source_symtab->nlines)
787 error ("Expression not found");
790 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
793 perror_with_name (current_source_symtab->filename);
796 stream = fdopen (desc, "r");
799 char buf[4096]; /* Should be reasonable??? */
800 register char *p = buf;
807 } while (c != '\n' && (c = fgetc (stream)) >= 0);
809 /* we now have a source line in buf, null terminate and match */
811 if (re_exec (buf) > 0)
815 print_source_lines (current_source_symtab,
817 current_source_line = max (line - 5, 1);
823 printf ("Expression not found\n");
828 reverse_search_command (regex, from_tty)
833 register FILE *stream;
834 int line = last_line_listed - 1;
837 msg = (char *) re_comp (regex);
841 if (current_source_symtab == 0)
842 error ("No default source file yet. Do \"help list\".");
844 /* Search from last_line_listed-1 in current_source_symtab */
846 desc = openp (source_path, 0, current_source_symtab->filename,
847 O_RDONLY, 0, ¤t_source_symtab->fullname);
849 perror_with_name (current_source_symtab->filename);
851 if (current_source_symtab->line_charpos == 0)
852 find_source_lines (current_source_symtab, desc);
854 if (line < 1 || line > current_source_symtab->nlines)
857 error ("Expression not found");
860 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
863 perror_with_name (current_source_symtab->filename);
866 stream = fdopen (desc, "r");
870 char buf[4096]; /* Should be reasonable??? */
871 register char *p = buf;
878 } while (c != '\n' && (c = fgetc (stream)) >= 0);
880 /* We now have a source line in buf; null terminate and match. */
882 if (re_exec (buf) > 0)
886 print_source_lines (current_source_symtab,
888 current_source_line = max (line - 5, 1);
892 if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
895 perror_with_name (current_source_symtab->filename);
899 printf ("Expression not found\n");
905 _initialize_source ()
907 current_source_symtab = 0;
910 add_com ("directory", class_files, directory_command,
911 "Add directory DIR to end of search path for source files.\n\
912 With no argument, reset the search path to just the working directory\n\
913 and forget cached info on line positions in source files.");
915 add_info ("directories", directories_info,
916 "Current search path for finding source files.");
918 add_info ("line", line_info,
919 "Core addresses of the code for a source line.\n\
920 Line can be specified as\n\
921 LINENUM, to list around that line in current file,\n\
922 FILE:LINENUM, to list around that line in that file,\n\
923 FUNCTION, to list around beginning of that function,\n\
924 FILE:FUNCTION, to distinguish among like-named static functions.\n\
925 Default is to describe the last source line that was listed.\n\n\
926 This sets the default address for \"x\" to the line's first instruction\n\
927 so that \"x/i\" suffices to start examining the machine code.\n\
928 The address is also stored as the value of \"$_\".");
930 add_com ("forward-search", class_files, forward_search_command,
931 "Search for regular expression (see regex(3)) from last line listed.");
932 add_com_alias ("search", "forward-search", class_files, 0);
934 add_com ("reverse-search", class_files, reverse_search_command,
935 "Search backward for regular expression (see regex(3)) from last line listed.");
937 add_com ("list", class_files, list_command,
938 "List specified function or line.\n\
939 With no argument, lists ten more lines after or around previous listing.\n\
940 \"list -\" lists the ten lines before a previous ten-line listing.\n\
941 One argument specifies a line, and ten lines are listed around that line.\n\
942 Two arguments with comma between specify starting and ending lines to list.\n\
943 Lines can be specified in these ways:\n\
944 LINENUM, to list around that line in current file,\n\
945 FILE:LINENUM, to list around that line in that file,\n\
946 FUNCTION, to list around beginning of that function,\n\
947 FILE:FUNCTION, to distinguish among like-named static functions.\n\
948 *ADDRESS, to list around the line containing that address.\n\
949 With two args if one is empty it stands for ten lines away from the other arg.");