1 /* List lines of source files for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program 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 2 of the License, or
9 (at your option) any later version.
11 This program 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 this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #include <sys/types.h>
33 #include <sys/param.h>
39 extern char *strstr();
41 extern void set_next_address ();
43 /* Path of directories to search for source files.
44 Same format as the PATH environment variable's value. */
48 /* Symtab of default file for listing lines of. */
50 struct symtab *current_source_symtab;
52 /* Default next line to list. */
54 int current_source_line;
56 /* Line number of last line printed. Default for various commands.
57 current_source_line is usually, but not always, the same as this. */
59 static int last_line_listed;
61 /* First line number listed by last listing command. */
63 static int first_line_listed;
66 /* Set the source file default for the "list" command, specifying a
67 symtab. Sigh. Behavior specification: If it is called with a
68 non-zero argument, that is the symtab to select. If it is not,
69 first lookup "main"; if it exists, use the symtab and line it
70 defines. If not, take the last symtab in the symtab_list (if it
71 exists) or the last symtab in the psymtab_list (if *it* exists). If
72 none of this works, report an error. */
75 select_source_symtab (s)
76 register struct symtab *s;
78 struct symtabs_and_lines sals;
79 struct symtab_and_line sal;
80 struct partial_symtab *ps;
81 struct partial_symtab *cs_pst = 0;
85 current_source_symtab = s;
86 current_source_line = 1;
90 /* Make the default place to list be the function `main'
92 if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL))
94 sals = decode_line_spec ("main", 1);
97 current_source_symtab = sal.symtab;
98 current_source_line = max (sal.line - (lines_to_list () - 1), 1);
99 if (current_source_symtab)
103 /* All right; find the last file in the symtab list (ignoring .h's). */
105 current_source_line = 1;
107 for (s = symtab_list; s; s = s->next)
109 char *name = s->filename;
110 int len = strlen (name);
111 if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
112 current_source_symtab = s;
114 if (current_source_symtab)
117 /* Howabout the partial symtab list? */
119 if (partial_symtab_list)
121 ps = partial_symtab_list;
124 char *name = ps->filename;
125 int len = strlen (name);
126 if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
132 fatal ("Internal: select_source_symtab: readin pst found and no symtabs.");
134 current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
136 if (current_source_symtab)
139 error ("Can't find a default source file");
145 printf ("Source directories searched: %s\n", source_path);
148 /* Forget what we learned about line positions in source files,
149 and which directories contain them;
150 must check again now since files may be found in
151 a different directory now. */
154 forget_cached_source_info ()
156 register struct symtab *s;
158 for (s = symtab_list; s; s = s->next)
160 if (s->line_charpos != 0)
162 free (s->line_charpos);
165 if (s->fullname != 0)
176 source_path = savestring ("$cdir:$cwd", /* strlen of it */ 10);
177 forget_cached_source_info ();
180 /* Add zero or more directories to the front of the source path. */
183 directory_command (dirname, from_tty)
188 /* FIXME, this goes to "delete dir"... */
191 if (query ("Reinitialize source path to empty? ", ""))
198 mod_path (dirname, &source_path);
201 forget_cached_source_info ();
204 /* Add zero or more directories to the front of an arbitrary path. */
207 mod_path (dirname, which_path)
211 char *old = *which_path;
217 dirname = strsave (dirname);
218 make_cleanup (free, dirname);
222 extern char *index ();
223 char *name = dirname;
228 char *colon = index (name, ':');
229 char *space = index (name, ' ');
230 char *tab = index (name, '\t');
231 if (colon == 0 && space == 0 && tab == 0)
232 p = dirname = name + strlen (name);
236 if (colon != 0 && (p == 0 || colon < p))
238 if (space != 0 && (p == 0 || space < p))
240 if (tab != 0 && (p == 0 || tab < p))
243 while (*dirname == ':' || *dirname == ' ' || *dirname == '\t')
249 /* Sigh. "foo/" => "foo" */
257 /* "." => getwd (). */
258 name = current_directory;
261 else if (p[-2] == '/')
271 /* "...foo/." => "...foo". */
282 name = tilde_expand (name);
283 else if (name[0] != '/' && name[0] != '$')
284 name = concat (current_directory, "/", name);
286 name = savestring (name, p - name);
287 make_cleanup (free, name);
289 /* Unless it's a variable, check existence. */
290 if (name[0] != '$') {
291 if (stat (name, &st) < 0)
292 perror_with_name (name);
293 if ((st.st_mode & S_IFMT) != S_IFDIR)
294 error ("%s is not a directory.", name);
299 register unsigned int len = strlen (name);
304 if (!strncmp (p, name, len)
305 && (p[len] == '\0' || p[len] == ':'))
307 /* Found it in the search path, remove old copy */
309 p--; /* Back over leading colon */
310 if (prefix > p - *which_path)
311 goto skip_dup; /* Same dir twice in one cmd */
312 strcpy (p, &p[len+1]); /* Copy from next \0 or : */
322 /* If we have already tacked on a name(s) in this command, be sure they stay on the front as we tack on some more. */
329 temp = concat (old, ":", name);
331 *which_path = concat (temp, "", &old[prefix]);
332 prefix = strlen (temp);
337 *which_path = concat (name, (old[0]? ":" : old), old);
338 prefix = strlen (name);
345 } while (*dirname != '\0');
352 register struct symtab *s = current_source_symtab;
356 printf("No current source file.\n");
359 printf ("Current source file is %s\n", s->filename);
361 printf ("Compilation directory is %s\n", s->dirname);
363 printf ("Located in %s\n", s->fullname);
365 printf ("Contains %d lines\n", s->nlines);
367 switch (s->language) {
369 printf("Written in the C language.\n");
370 /* Add more cases here when -Wswitch complains... */
371 case language_unknown:
378 /* Open a file named STRING, searching path PATH (dir names sep by colons)
379 using mode MODE and protection bits PROT in the calls to open.
380 If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
381 (ie pretend the first element of PATH is ".")
382 If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
383 the actual file opened (this string will always start with a "/". We
384 have to take special pains to avoid doubling the "/" between the directory
385 and the file, sigh! Emacs gets confuzzed by this when we print the
388 If a file is found, return the descriptor.
389 Otherwise, return -1, with errno set for the last name we tried to open. */
391 /* >>>> This should only allow files of certain types,
392 >>>> eg executable, non-directory */
394 openp (path, try_cwd_first, string, mode, prot, filename_opened)
400 char **filename_opened;
403 register char *filename;
404 register char *p, *p1;
412 while (string[0] == '.' && string[1] == '/')
415 if (try_cwd_first || string[0] == '/')
418 fd = open (filename, mode, prot);
419 if (fd >= 0 || string[0] == '/')
423 alloclen = strlen (path) + strlen (string) + 2;
424 filename = (char *) alloca (alloclen);
426 for (p = path; p; p = p1 ? p1 + 1 : 0)
428 p1 = (char *) index (p, ':');
434 if (len == 4 && p[0] == '$' && p[1] == 'c'
435 && p[2] == 'w' && p[3] == 'd') {
436 /* Name is $cwd -- insert current directory name instead. */
439 /* First, realloc the filename buffer if too short. */
440 len = strlen (current_directory);
441 newlen = len + strlen (string) + 2;
442 if (newlen > alloclen) {
444 filename = (char *) alloca (alloclen);
446 strcpy (filename, current_directory);
448 /* Normal file name in path -- just use it. */
449 strncpy (filename, p, len);
453 /* Beware the // my son, the Emacs barfs, the botch that catch... */
454 while (len > 1 && filename[len-1] == '/')
456 strcat (filename+len, "/");
457 strcat (filename, string);
459 fd = open (filename, mode, prot);
466 *filename_opened = (char *) 0;
467 else if (filename[0] == '/')
468 *filename_opened = savestring (filename, strlen (filename));
471 /* Beware the // my son, the Emacs barfs, the botch that catch... */
473 *filename_opened = concat (current_directory,
474 '/' == current_directory[strlen(current_directory)-1]? "": "/",
481 /* Open a source file given a symtab S. Returns a file descriptor
482 or negative number for error. */
487 char *path = source_path;
491 /* Quick way out if we already know its full name */
494 result = open (s->fullname, O_RDONLY);
497 /* Didn't work -- free old one, try again. */
502 if (s->dirname != NULL)
504 /* Replace a path entry of $cdir with the compilation directory name */
506 p = strstr (source_path, "$cdir");
507 if (p && (p == path || p[-1] == ':')
508 && (p[cdir_len] == ':' || p[cdir_len] == '\0')) {
512 alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
513 len = p - source_path;
514 strncpy (path, source_path, len); /* Before $cdir */
515 strcpy (path + len, s->dirname); /* new stuff */
516 strcat (path + len, source_path + len + cdir_len); /* After $cdir */
520 return openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname);
524 /* Create and initialize the table S->line_charpos that records
525 the positions of the lines in the source file, which is assumed
526 to be open on descriptor DESC.
527 All set S->nlines to the number of such lines. */
530 find_source_lines (s, desc)
535 register char *data, *p, *end;
537 int lines_allocated = 1000;
538 int *line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
540 if (fstat (desc, &st) < 0)
541 perror_with_name (s->filename);
542 if (exec_bfd && bfd_get_mtime(exec_bfd) < st.st_mtime)
543 printf ("Source file is more recent than executable.\n");
545 #ifdef BROKEN_LARGE_ALLOCA
546 data = (char *) xmalloc (st.st_size);
547 make_cleanup (free, data);
549 data = (char *) alloca (st.st_size);
551 if (myread (desc, data, st.st_size) < 0)
552 perror_with_name (s->filename);
553 end = data + st.st_size;
560 /* A newline at the end does not start a new line. */
563 if (nlines == lines_allocated)
565 lines_allocated *= 2;
566 line_charpos = (int *) xrealloc (line_charpos,
567 sizeof (int) * lines_allocated);
569 line_charpos[nlines++] = p - data;
573 s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int));
576 /* Return the character position of a line LINE in symtab S.
577 Return 0 if anything is invalid. */
580 source_line_charpos (s, line)
585 if (!s->line_charpos || line <= 0) return 0;
586 if (line > s->nlines)
588 return s->line_charpos[line - 1];
591 /* Return the line number of character position POS in symtab S. */
594 source_charpos_line (s, chr)
595 register struct symtab *s;
598 register int line = 0;
601 if (s == 0 || s->line_charpos == 0) return 0;
602 lnp = s->line_charpos;
603 /* Files are usually short, so sequential search is Ok */
604 while (line < s->nlines && *lnp <= chr)
609 if (line >= s->nlines)
614 /* Get full pathname and line number positions for a symtab.
615 Return nonzero if line numbers may have changed.
616 Set *FULLNAME to actual name of the file as found by `openp',
617 or to 0 if the file is not found. */
620 get_filename_and_charpos (s, fullname)
624 register int desc, linenums_changed = 0;
626 desc = open_source_file (s);
634 *fullname = s->fullname;
635 if (s->line_charpos == 0) linenums_changed = 1;
636 if (linenums_changed) find_source_lines (s, desc);
638 return linenums_changed;
641 /* Print text describing the full name of the source file S
642 and the line number LINE and its corresponding character position.
643 The text starts with two Ctrl-z so that the Emacs-GDB interface
646 MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
648 Return 1 if successful, 0 if could not find the file. */
651 identify_source_line (s, line, mid_statement)
656 if (s->line_charpos == 0)
657 get_filename_and_charpos (s, (char **)NULL);
658 if (s->fullname == 0)
660 printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname,
661 line, s->line_charpos[line - 1],
662 mid_statement ? "middle" : "beg",
663 get_frame_pc (get_current_frame()));
664 current_source_line = line;
665 first_line_listed = line;
666 last_line_listed = line;
667 current_source_symtab = s;
671 /* Print source lines from the file of symtab S,
672 starting with line number LINE and stopping before line number STOPLINE. */
675 print_source_lines (s, line, stopline, noerror)
682 register FILE *stream;
683 int nlines = stopline - line;
685 /* Regardless of whether we can open the file, set current_source_symtab. */
686 current_source_symtab = s;
687 current_source_line = line;
688 first_line_listed = line;
690 desc = open_source_file (s);
694 char *name = alloca (strlen (s->filename) + 100);
695 sprintf (name, "%s:%d", s->filename, line);
696 print_sys_errmsg (name, errno);
701 if (s->line_charpos == 0)
702 find_source_lines (s, desc);
704 if (line < 1 || line > s->nlines)
707 error ("Line number %d out of range; %s has %d lines.",
708 line, s->filename, s->nlines);
711 if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
714 perror_with_name (s->filename);
717 stream = fdopen (desc, "r");
724 last_line_listed = current_source_line;
725 printf_filtered ("%d\t", current_source_line++);
728 if (c < 040 && c != '\t' && c != '\n')
729 printf_filtered ("^%c", c + 0100);
731 printf_filtered ("^?");
733 printf_filtered ("%c", c);
734 } while (c != '\n' && (c = fgetc (stream)) >= 0);
744 Print a list of files and line numbers which a user may choose from
745 in order to list a function which was specified ambiguously
746 (as with `list classname::overloadedfuncname', for example).
747 The vector in SALS provides the filenames and line numbers.
750 ambiguous_line_spec (sals)
751 struct symtabs_and_lines *sals;
755 for (i = 0; i < sals->nelts; ++i)
756 printf("file: \"%s\", line number: %d\n",
757 sals->sals[i].symtab->filename, sals->sals[i].line);
762 list_command (arg, from_tty)
766 struct symtabs_and_lines sals, sals_end;
767 struct symtab_and_line sal, sal_end;
776 if (symtab_list == 0 && partial_symtab_list == 0)
777 error ("No symbol table is loaded. Use the \"file\" command.");
779 /* Pull in a current source symtab if necessary */
780 if (current_source_symtab == 0 &&
781 (arg == 0 || arg[0] == '+' || arg[0] == '-'))
782 select_source_symtab (0);
784 /* "l" or "l +" lists next ten lines. */
786 if (arg == 0 || !strcmp (arg, "+"))
788 if (current_source_symtab == 0)
789 error ("No default source file yet. Do \"help list\".");
790 print_source_lines (current_source_symtab, current_source_line,
791 current_source_line + lines_to_list (), 0);
795 /* "l -" lists previous ten lines, the ones before the ten just listed. */
796 if (!strcmp (arg, "-"))
798 if (current_source_symtab == 0)
799 error ("No default source file yet. Do \"help list\".");
800 print_source_lines (current_source_symtab,
801 max (first_line_listed - lines_to_list (), 1),
802 first_line_listed, 0);
806 /* Now if there is only one argument, decode it in SAL
808 If there are two arguments, decode them in SAL and SAL_END
809 and clear NO_END; however, if one of the arguments is blank,
810 set DUMMY_BEG or DUMMY_END to record that fact. */
817 sals = decode_line_1 (&arg1, 0, 0, 0);
819 if (! sals.nelts) return; /* C++ */
822 ambiguous_line_spec (&sals);
831 /* Record whether the BEG arg is all digits. */
833 for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
834 linenum_beg = (p == arg1);
836 while (*arg1 == ' ' || *arg1 == '\t')
842 while (*arg1 == ' ' || *arg1 == '\t')
849 sals_end = decode_line_1 (&arg1, 0, 0, 0);
851 sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
852 if (sals_end.nelts == 0)
854 if (sals_end.nelts > 1)
856 ambiguous_line_spec (&sals_end);
857 free (sals_end.sals);
860 sal_end = sals_end.sals[0];
861 free (sals_end.sals);
866 error ("Junk at end of line specification.");
868 if (!no_end && !dummy_beg && !dummy_end
869 && sal.symtab != sal_end.symtab)
870 error ("Specified start and end are in different files.");
871 if (dummy_beg && dummy_end)
872 error ("Two empty args do not say what lines to list.");
874 /* if line was specified by address,
875 first print exactly which line, and which file.
876 In this case, sal.symtab == 0 means address is outside
877 of all known source files, not that user failed to give a filename. */
881 error ("No source file for address 0x%x.", sal.pc);
882 sym = find_pc_function (sal.pc);
884 printf ("0x%x is in %s (%s, line %d).\n",
885 sal.pc, SYMBOL_NAME (sym), sal.symtab->filename, sal.line);
887 printf ("0x%x is in %s, line %d.\n",
888 sal.pc, sal.symtab->filename, sal.line);
891 /* If line was not specified by just a line number,
892 and it does not imply a symtab, it must be an undebuggable symbol
893 which means no source code. */
895 if (! linenum_beg && sal.symtab == 0)
896 error ("No line number known for %s.", arg);
898 /* If this command is repeated with RET,
899 turn it into the no-arg variant. */
904 if (dummy_beg && sal_end.symtab == 0)
905 error ("No default source file yet. Do \"help list\".");
907 print_source_lines (sal_end.symtab,
908 max (sal_end.line - (lines_to_list () - 1), 1),
909 sal_end.line + 1, 0);
910 else if (sal.symtab == 0)
911 error ("No default source file yet. Do \"help list\".");
913 print_source_lines (sal.symtab,
914 max (sal.line - (lines_to_list () / 2), 1),
915 sal.line + (lines_to_list() / 2), 0);
917 print_source_lines (sal.symtab, sal.line,
919 ? sal.line + lines_to_list ()
924 /* Print info on range of pc's in a specified line. */
927 line_info (arg, from_tty)
931 struct symtabs_and_lines sals;
932 struct symtab_and_line sal;
933 CORE_ADDR start_pc, end_pc;
938 sal.symtab = current_source_symtab;
939 sal.line = last_line_listed;
941 sals.sals = (struct symtab_and_line *)
942 xmalloc (sizeof (struct symtab_and_line));
947 sals = decode_line_spec_1 (arg, 0);
949 /* If this command is repeated with RET,
950 turn it into the no-arg variant. */
955 /* C++ More than one line may have been specified, as when the user
956 specifies an overloaded function name. Print info on them all. */
957 for (i = 0; i < sals.nelts; i++)
962 error ("No source file specified.");
965 && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
967 if (start_pc == end_pc)
968 printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n",
969 sal.line, sal.symtab->filename, start_pc);
971 printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n",
972 sal.line, sal.symtab->filename, start_pc, end_pc);
973 /* x/i should display this line's code. */
974 set_next_address (start_pc);
975 /* Repeating "info line" should do the following line. */
976 last_line_listed = sal.line + 1;
979 printf ("Line number %d is out of range for \"%s\".\n",
980 sal.line, sal.symtab->filename);
984 /* Commands to search the source file for a regexp. */
988 forward_search_command (regex, from_tty)
994 register FILE *stream;
995 int line = last_line_listed + 1;
998 msg = (char *) re_comp (regex);
1002 if (current_source_symtab == 0)
1003 select_source_symtab (0);
1005 /* Search from last_line_listed+1 in current_source_symtab */
1007 desc = open_source_file (current_source_symtab);
1009 perror_with_name (current_source_symtab->filename);
1011 if (current_source_symtab->line_charpos == 0)
1012 find_source_lines (current_source_symtab, desc);
1014 if (line < 1 || line > current_source_symtab->nlines)
1017 error ("Expression not found");
1020 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1023 perror_with_name (current_source_symtab->filename);
1026 stream = fdopen (desc, "r");
1029 /* FIXME!!! We walk right off the end of buf if we get a long line!!! */
1030 char buf[4096]; /* Should be reasonable??? */
1031 register char *p = buf;
1038 } while (c != '\n' && (c = getc (stream)) >= 0);
1040 /* we now have a source line in buf, null terminate and match */
1042 if (re_exec (buf) > 0)
1046 print_source_lines (current_source_symtab,
1048 current_source_line = max (line - lines_to_list () / 2, 1);
1054 printf ("Expression not found\n");
1060 reverse_search_command (regex, from_tty)
1066 register FILE *stream;
1067 int line = last_line_listed - 1;
1070 msg = (char *) re_comp (regex);
1074 if (current_source_symtab == 0)
1075 select_source_symtab (0);
1077 /* Search from last_line_listed-1 in current_source_symtab */
1079 desc = open_source_file (current_source_symtab);
1081 perror_with_name (current_source_symtab->filename);
1083 if (current_source_symtab->line_charpos == 0)
1084 find_source_lines (current_source_symtab, desc);
1086 if (line < 1 || line > current_source_symtab->nlines)
1089 error ("Expression not found");
1092 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1095 perror_with_name (current_source_symtab->filename);
1098 stream = fdopen (desc, "r");
1102 /* FIXME!!! We walk right off the end of buf if we get a long line!!! */
1103 char buf[4096]; /* Should be reasonable??? */
1104 register char *p = buf;
1111 } while (c != '\n' && (c = getc (stream)) >= 0);
1113 /* We now have a source line in buf; null terminate and match. */
1115 if (re_exec (buf) > 0)
1119 print_source_lines (current_source_symtab,
1121 current_source_line = max (line - lines_to_list () / 2, 1);
1125 if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
1128 perror_with_name (current_source_symtab->filename);
1132 printf ("Expression not found\n");
1138 _initialize_source ()
1140 current_source_symtab = 0;
1141 init_source_path ();
1143 add_com ("directory", class_files, directory_command,
1144 "Add directory DIR to beginning of search path for source files.\n\
1145 Forget cached info on source file locations and line positions.\n\
1146 DIR can also be $cwd for the current working directory, or $cdir for the\n\
1147 directory in which the source file was compiled into object code.\n\
1148 With no argument, reset the search path to $cdir:$cwd, the default.");
1150 add_cmd ("directories", no_class, show_directories,
1151 "Current search path for finding source files.\n\
1152 $cwd in the path means the current working directory.\n\
1153 $cdir in the path means the compilation directory of the source file.",
1156 add_info ("source", source_info,
1157 "Information about the current source file.");
1159 add_info ("line", line_info,
1160 "Core addresses of the code for a source line.\n\
1161 Line can be specified as\n\
1162 LINENUM, to list around that line in current file,\n\
1163 FILE:LINENUM, to list around that line in that file,\n\
1164 FUNCTION, to list around beginning of that function,\n\
1165 FILE:FUNCTION, to distinguish among like-named static functions.\n\
1166 Default is to describe the last source line that was listed.\n\n\
1167 This sets the default address for \"x\" to the line's first instruction\n\
1168 so that \"x/i\" suffices to start examining the machine code.\n\
1169 The address is also stored as the value of \"$_\".");
1171 add_com ("forward-search", class_files, forward_search_command,
1172 "Search for regular expression (see regex(3)) from last line listed.");
1173 add_com_alias ("search", "forward-search", class_files, 0);
1175 add_com ("reverse-search", class_files, reverse_search_command,
1176 "Search backward for regular expression (see regex(3)) from last line listed.");
1178 add_com ("list", class_files, list_command,
1179 "List specified function or line.\n\
1180 With no argument, lists ten more lines after or around previous listing.\n\
1181 \"list -\" lists the ten lines before a previous ten-line listing.\n\
1182 One argument specifies a line, and ten lines are listed around that line.\n\
1183 Two arguments with comma between specify starting and ending lines to list.\n\
1184 Lines can be specified in these ways:\n\
1185 LINENUM, to list around that line in current file,\n\
1186 FILE:LINENUM, to list around that line in that file,\n\
1187 FUNCTION, to list around beginning of that function,\n\
1188 FILE:FUNCTION, to distinguish among like-named static functions.\n\
1189 *ADDRESS, to list around the line containing that address.\n\
1190 With two args if one is empty it stands for ten lines away from the other arg.");
1191 add_com_alias ("l", "list", class_files, 0);