Fix typos and thinkos reported by Sun Ming (and one reported by John).
[deliverable/binutils-gdb.git] / gdb / source.c
1 /* List lines of source files for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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. */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "expression.h"
23 #include "language.h"
24 #include "command.h"
25 #include "gdbcmd.h"
26 #include "frame.h"
27
28 #ifdef USG
29 #include <sys/types.h>
30 #endif
31
32 #include <string.h>
33 #include <sys/param.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include "gdbcore.h"
37 #include "regex.h"
38 #include "symfile.h"
39 #include "objfiles.h"
40
41 /* Prototypes for local functions. */
42
43 static int
44 open_source_file PARAMS ((struct symtab *));
45
46 static int
47 get_filename_and_charpos PARAMS ((struct symtab *, char **));
48
49 static void
50 reverse_search_command PARAMS ((char *, int));
51
52 static void
53 forward_search_command PARAMS ((char *, int));
54
55 static void
56 line_info PARAMS ((char *, int));
57
58 static void
59 list_command PARAMS ((char *, int));
60
61 static void
62 ambiguous_line_spec PARAMS ((struct symtabs_and_lines *));
63
64 static void
65 source_info PARAMS ((char *, int));
66
67 static void
68 show_directories PARAMS ((char *, int));
69
70 static void
71 find_source_lines PARAMS ((struct symtab *, int));
72
73 /* If we use this declaration, it breaks because of fucking ANSI "const" stuff
74 on some systems. We just have to not declare it at all, have it default
75 to int, and possibly botch on a few systems. Thanks, ANSIholes... */
76 /* extern char *strstr(); */
77
78 /* Path of directories to search for source files.
79 Same format as the PATH environment variable's value. */
80
81 char *source_path;
82
83 /* Symtab of default file for listing lines of. */
84
85 struct symtab *current_source_symtab;
86
87 /* Default next line to list. */
88
89 int current_source_line;
90
91 /* Default number of lines to print with commands like "list".
92 This is based on guessing how many long (i.e. more than chars_per_line
93 characters) lines there will be. To be completely correct, "list"
94 and friends should be rewritten to count characters and see where
95 things are wrapping, but that would be a fair amount of work. */
96
97 int lines_to_list = 10;
98
99 /* Line number of last line printed. Default for various commands.
100 current_source_line is usually, but not always, the same as this. */
101
102 static int last_line_listed;
103
104 /* First line number listed by last listing command. */
105
106 static int first_line_listed;
107
108 \f
109 /* Set the source file default for the "list" command, specifying a
110 symtab. Sigh. Behavior specification: If it is called with a
111 non-zero argument, that is the symtab to select. If it is not,
112 first lookup "main"; if it exists, use the symtab and line it
113 defines. If not, take the last symtab in the symtab lists (if it
114 exists) or the last symtab in the psymtab lists (if *it* exists). If
115 none of this works, report an error. */
116
117 void
118 select_source_symtab (s)
119 register struct symtab *s;
120 {
121 struct symtabs_and_lines sals;
122 struct symtab_and_line sal;
123 struct partial_symtab *ps;
124 struct partial_symtab *cs_pst = 0;
125 struct objfile *ofp;
126
127 if (s)
128 {
129 current_source_symtab = s;
130 current_source_line = 1;
131 return;
132 }
133
134 /* Make the default place to list be the function `main'
135 if one exists. */
136 if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL))
137 {
138 sals = decode_line_spec ("main", 1);
139 sal = sals.sals[0];
140 free (sals.sals);
141 current_source_symtab = sal.symtab;
142 current_source_line = max (sal.line - (lines_to_list - 1), 1);
143 if (current_source_symtab)
144 return;
145 }
146
147 /* All right; find the last file in the symtab list (ignoring .h's). */
148
149 current_source_line = 1;
150
151 for (ofp = object_files; ofp != NULL; ofp = ofp -> next)
152 {
153 for (s = ofp -> symtabs; s; s = s->next)
154 {
155 char *name = s -> filename;
156 int len = strlen (name);
157 if (! (len > 2 && (strcmp (&name[len - 2], ".h") == 0)))
158 {
159 current_source_symtab = s;
160 }
161 }
162 }
163 if (current_source_symtab)
164 return;
165
166 /* Howabout the partial symbol tables? */
167
168 for (ofp = object_files; ofp != NULL; ofp = ofp -> next)
169 {
170 for (ps = ofp -> psymtabs; ps != NULL; ps = ps -> next)
171 {
172 char *name = ps -> filename;
173 int len = strlen (name);
174 if (! (len > 2 && (strcmp (&name[len - 2], ".h") == 0)))
175 {
176 cs_pst = ps;
177 }
178 }
179 }
180 if (cs_pst)
181 {
182 if (cs_pst -> readin)
183 {
184 fatal ("Internal: select_source_symtab: readin pst found and no symtabs.");
185 }
186 else
187 {
188 current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
189 }
190 }
191
192 if (current_source_symtab)
193 return;
194
195 error ("Can't find a default source file");
196 }
197 \f
198 static void
199 show_directories (ignore, from_tty)
200 char *ignore;
201 int from_tty;
202 {
203 printf_filtered ("Source directories searched: %s\n", source_path);
204 }
205
206 /* Forget what we learned about line positions in source files,
207 and which directories contain them;
208 must check again now since files may be found in
209 a different directory now. */
210
211 void
212 forget_cached_source_info ()
213 {
214 register struct symtab *s;
215 register struct objfile *objfile;
216
217 for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
218 {
219 for (s = objfile -> symtabs; s != NULL; s = s -> next)
220 {
221 if (s -> line_charpos != NULL)
222 {
223 mfree (objfile -> md, s -> line_charpos);
224 s -> line_charpos = NULL;
225 }
226 if (s -> fullname != NULL)
227 {
228 mfree (objfile -> md, s -> fullname);
229 s -> fullname = NULL;
230 }
231 }
232 }
233 }
234
235 void
236 init_source_path ()
237 {
238 source_path = savestring ("$cdir:$cwd", /* strlen of it */ 10);
239 forget_cached_source_info ();
240 }
241
242 /* Add zero or more directories to the front of the source path. */
243
244 void
245 directory_command (dirname, from_tty)
246 char *dirname;
247 int from_tty;
248 {
249 dont_repeat ();
250 /* FIXME, this goes to "delete dir"... */
251 if (dirname == 0)
252 {
253 if (query ("Reinitialize source path to empty? ", ""))
254 {
255 free (source_path);
256 init_source_path ();
257 }
258 }
259 else
260 mod_path (dirname, &source_path);
261 if (from_tty)
262 show_directories ((char *)0, from_tty);
263 forget_cached_source_info ();
264 }
265
266 /* Add zero or more directories to the front of an arbitrary path. */
267
268 void
269 mod_path (dirname, which_path)
270 char *dirname;
271 char **which_path;
272 {
273 char *old = *which_path;
274 int prefix = 0;
275
276 if (dirname == 0)
277 return;
278
279 dirname = strsave (dirname);
280 make_cleanup (free, dirname);
281
282 do
283 {
284 char *name = dirname;
285 register char *p;
286 struct stat st;
287
288 {
289 char *colon = strchr (name, ':');
290 char *space = strchr (name, ' ');
291 char *tab = strchr (name, '\t');
292 if (colon == 0 && space == 0 && tab == 0)
293 p = dirname = name + strlen (name);
294 else
295 {
296 p = 0;
297 if (colon != 0 && (p == 0 || colon < p))
298 p = colon;
299 if (space != 0 && (p == 0 || space < p))
300 p = space;
301 if (tab != 0 && (p == 0 || tab < p))
302 p = tab;
303 dirname = p + 1;
304 while (*dirname == ':' || *dirname == ' ' || *dirname == '\t')
305 ++dirname;
306 }
307 }
308
309 if (p[-1] == '/')
310 /* Sigh. "foo/" => "foo" */
311 --p;
312 *p = '\0';
313
314 while (p[-1] == '.')
315 {
316 if (p - name == 1)
317 {
318 /* "." => getwd (). */
319 name = current_directory;
320 goto append;
321 }
322 else if (p[-2] == '/')
323 {
324 if (p - name == 2)
325 {
326 /* "/." => "/". */
327 *--p = '\0';
328 goto append;
329 }
330 else
331 {
332 /* "...foo/." => "...foo". */
333 p -= 2;
334 *p = '\0';
335 continue;
336 }
337 }
338 else
339 break;
340 }
341
342 if (name[0] == '~')
343 name = tilde_expand (name);
344 else if (name[0] != '/' && name[0] != '$')
345 name = concat (current_directory, "/", name, NULL);
346 else
347 name = savestring (name, p - name);
348 make_cleanup (free, name);
349
350 /* Unless it's a variable, check existence. */
351 if (name[0] != '$') {
352 if (stat (name, &st) < 0)
353 perror_with_name (name);
354 if ((st.st_mode & S_IFMT) != S_IFDIR)
355 error ("%s is not a directory.", name);
356 }
357
358 append:
359 {
360 register unsigned int len = strlen (name);
361
362 p = *which_path;
363 while (1)
364 {
365 if (!strncmp (p, name, len)
366 && (p[len] == '\0' || p[len] == ':'))
367 {
368 /* Found it in the search path, remove old copy */
369 if (p > *which_path)
370 p--; /* Back over leading colon */
371 if (prefix > p - *which_path)
372 goto skip_dup; /* Same dir twice in one cmd */
373 strcpy (p, &p[len+1]); /* Copy from next \0 or : */
374 }
375 p = strchr (p, ':');
376 if (p != 0)
377 ++p;
378 else
379 break;
380 }
381 if (p == 0)
382 {
383 /* 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. */
384 if (prefix)
385 {
386 char *temp, c;
387
388 c = old[prefix];
389 old[prefix] = '\0';
390 temp = concat (old, ":", name, NULL);
391 old[prefix] = c;
392 *which_path = concat (temp, "", &old[prefix], NULL);
393 prefix = strlen (temp);
394 free (temp);
395 }
396 else
397 {
398 *which_path = concat (name, (old[0]? ":" : old), old, NULL);
399 prefix = strlen (name);
400 }
401 free (old);
402 old = *which_path;
403 }
404 }
405 skip_dup: ;
406 } while (*dirname != '\0');
407 }
408
409
410 static void
411 source_info (ignore, from_tty)
412 char *ignore;
413 int from_tty;
414 {
415 register struct symtab *s = current_source_symtab;
416
417 if (!s)
418 {
419 printf_filtered("No current source file.\n");
420 return;
421 }
422 printf_filtered ("Current source file is %s\n", s->filename);
423 if (s->dirname)
424 printf_filtered ("Compilation directory is %s\n", s->dirname);
425 if (s->fullname)
426 printf_filtered ("Located in %s\n", s->fullname);
427 if (s->nlines)
428 printf_filtered ("Contains %d lines\n", s->nlines);
429
430 printf_filtered("Source language %s.\n", language_str (s->language));
431 }
432
433
434 \f
435 /* Open a file named STRING, searching path PATH (dir names sep by colons)
436 using mode MODE and protection bits PROT in the calls to open.
437 If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
438 (ie pretend the first element of PATH is ".")
439 If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
440 the actual file opened (this string will always start with a "/". We
441 have to take special pains to avoid doubling the "/" between the directory
442 and the file, sigh! Emacs gets confuzzed by this when we print the
443 source file name!!!
444
445 If a file is found, return the descriptor.
446 Otherwise, return -1, with errno set for the last name we tried to open. */
447
448 /* >>>> This should only allow files of certain types,
449 >>>> eg executable, non-directory */
450 int
451 openp (path, try_cwd_first, string, mode, prot, filename_opened)
452 char *path;
453 int try_cwd_first;
454 char *string;
455 int mode;
456 int prot;
457 char **filename_opened;
458 {
459 register int fd;
460 register char *filename;
461 register char *p, *p1;
462 register int len;
463 int alloclen;
464
465 if (!path)
466 path = ".";
467
468 /* ./foo => foo */
469 while (string[0] == '.' && string[1] == '/')
470 string += 2;
471
472 if (try_cwd_first || string[0] == '/')
473 {
474 filename = string;
475 fd = open (filename, mode, prot);
476 if (fd >= 0 || string[0] == '/')
477 goto done;
478 }
479
480 alloclen = strlen (path) + strlen (string) + 2;
481 filename = (char *) alloca (alloclen);
482 fd = -1;
483 for (p = path; p; p = p1 ? p1 + 1 : 0)
484 {
485 p1 = (char *) strchr (p, ':');
486 if (p1)
487 len = p1 - p;
488 else
489 len = strlen (p);
490
491 if (len == 4 && p[0] == '$' && p[1] == 'c'
492 && p[2] == 'w' && p[3] == 'd') {
493 /* Name is $cwd -- insert current directory name instead. */
494 int newlen;
495
496 /* First, realloc the filename buffer if too short. */
497 len = strlen (current_directory);
498 newlen = len + strlen (string) + 2;
499 if (newlen > alloclen) {
500 alloclen = newlen;
501 filename = (char *) alloca (alloclen);
502 }
503 strcpy (filename, current_directory);
504 } else {
505 /* Normal file name in path -- just use it. */
506 strncpy (filename, p, len);
507 filename[len] = 0;
508 }
509
510 /* Remove trailing slashes */
511 while (len > 0 && filename[len-1] == '/')
512 filename[--len] = 0;
513
514 strcat (filename+len, "/");
515 strcat (filename, string);
516
517 fd = open (filename, mode, prot);
518 if (fd >= 0) break;
519 }
520
521 done:
522 if (filename_opened)
523 if (fd < 0)
524 *filename_opened = (char *) 0;
525 else if (filename[0] == '/')
526 *filename_opened = savestring (filename, strlen (filename));
527 else
528 {
529 /* Beware the // my son, the Emacs barfs, the botch that catch... */
530
531 *filename_opened = concat (current_directory,
532 '/' == current_directory[strlen(current_directory)-1]? "": "/",
533 filename, NULL);
534 }
535
536 return fd;
537 }
538
539 /* Open a source file given a symtab S. Returns a file descriptor
540 or negative number for error. */
541
542 static int
543 open_source_file (s)
544 struct symtab *s;
545 {
546 char *path = source_path;
547 char *p;
548 int result;
549 char *fullname;
550
551 /* Quick way out if we already know its full name */
552 if (s->fullname)
553 {
554 result = open (s->fullname, O_RDONLY);
555 if (result >= 0)
556 return result;
557 /* Didn't work -- free old one, try again. */
558 mfree (s->objfile->md, s->fullname);
559 s->fullname = NULL;
560 }
561
562 if (s->dirname != NULL)
563 {
564 /* Replace a path entry of $cdir with the compilation directory name */
565 #define cdir_len 5
566 /* We cast strstr's result in case an ANSIhole has made it const,
567 which produces a "required warning" when assigned to a nonconst. */
568 p = (char *)strstr (source_path, "$cdir");
569 if (p && (p == path || p[-1] == ':')
570 && (p[cdir_len] == ':' || p[cdir_len] == '\0')) {
571 int len;
572
573 path = (char *)
574 alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
575 len = p - source_path;
576 strncpy (path, source_path, len); /* Before $cdir */
577 strcpy (path + len, s->dirname); /* new stuff */
578 strcat (path + len, source_path + len + cdir_len); /* After $cdir */
579 }
580 }
581
582 result = openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname);
583 if (result < 0)
584 {
585 /* Didn't work. Try using just the basename. */
586 p = basename (s->filename);
587 if (p != s->filename)
588 result = openp(path, 0, p, O_RDONLY,0, &s->fullname);
589 }
590 if (result >= 0)
591 {
592 fullname = s -> fullname;
593 s -> fullname = mstrsave (s -> objfile -> md, s -> fullname);
594 free (fullname);
595 }
596 return result;
597 }
598
599 \f
600 /* Create and initialize the table S->line_charpos that records
601 the positions of the lines in the source file, which is assumed
602 to be open on descriptor DESC.
603 All set S->nlines to the number of such lines. */
604
605 static void
606 find_source_lines (s, desc)
607 struct symtab *s;
608 int desc;
609 {
610 struct stat st;
611 register char *data, *p, *end;
612 int nlines = 0;
613 int lines_allocated = 1000;
614 int *line_charpos;
615 long exec_mtime;
616 int size;
617
618 line_charpos = (int *) xmmalloc (s -> objfile -> md,
619 lines_allocated * sizeof (int));
620 if (fstat (desc, &st) < 0)
621 perror_with_name (s->filename);
622
623 if (exec_bfd) {
624 exec_mtime = bfd_get_mtime(exec_bfd);
625 if (exec_mtime && exec_mtime < st.st_mtime)
626 printf_filtered ("Source file is more recent than executable.\n");
627 }
628
629 /* st_size might be a large type, but we only support source files whose
630 size fits in an int. FIXME. */
631 size = (int) st.st_size;
632
633 #ifdef BROKEN_LARGE_ALLOCA
634 data = (char *) xmalloc (size);
635 make_cleanup (free, data);
636 #else
637 data = (char *) alloca (size);
638 #endif
639 if (myread (desc, data, size) < 0)
640 perror_with_name (s->filename);
641 end = data + size;
642 p = data;
643 line_charpos[0] = 0;
644 nlines = 1;
645 while (p != end)
646 {
647 if (*p++ == '\n'
648 /* A newline at the end does not start a new line. */
649 && p != end)
650 {
651 if (nlines == lines_allocated)
652 {
653 lines_allocated *= 2;
654 line_charpos =
655 (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
656 sizeof (int) * lines_allocated);
657 }
658 line_charpos[nlines++] = p - data;
659 }
660 }
661 s->nlines = nlines;
662 s->line_charpos =
663 (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
664 nlines * sizeof (int));
665 }
666
667 /* Return the character position of a line LINE in symtab S.
668 Return 0 if anything is invalid. */
669
670 #if 0 /* Currently unused */
671
672 int
673 source_line_charpos (s, line)
674 struct symtab *s;
675 int line;
676 {
677 if (!s) return 0;
678 if (!s->line_charpos || line <= 0) return 0;
679 if (line > s->nlines)
680 line = s->nlines;
681 return s->line_charpos[line - 1];
682 }
683
684 /* Return the line number of character position POS in symtab S. */
685
686 int
687 source_charpos_line (s, chr)
688 register struct symtab *s;
689 register int chr;
690 {
691 register int line = 0;
692 register int *lnp;
693
694 if (s == 0 || s->line_charpos == 0) return 0;
695 lnp = s->line_charpos;
696 /* Files are usually short, so sequential search is Ok */
697 while (line < s->nlines && *lnp <= chr)
698 {
699 line++;
700 lnp++;
701 }
702 if (line >= s->nlines)
703 line = s->nlines;
704 return line;
705 }
706
707 #endif /* 0 */
708
709 \f
710 /* Get full pathname and line number positions for a symtab.
711 Return nonzero if line numbers may have changed.
712 Set *FULLNAME to actual name of the file as found by `openp',
713 or to 0 if the file is not found. */
714
715 static int
716 get_filename_and_charpos (s, fullname)
717 struct symtab *s;
718 char **fullname;
719 {
720 register int desc, linenums_changed = 0;
721
722 desc = open_source_file (s);
723 if (desc < 0)
724 {
725 if (fullname)
726 *fullname = NULL;
727 return 0;
728 }
729 if (fullname)
730 *fullname = s->fullname;
731 if (s->line_charpos == 0) linenums_changed = 1;
732 if (linenums_changed) find_source_lines (s, desc);
733 close (desc);
734 return linenums_changed;
735 }
736
737 /* Print text describing the full name of the source file S
738 and the line number LINE and its corresponding character position.
739 The text starts with two Ctrl-z so that the Emacs-GDB interface
740 can easily find it.
741
742 MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
743
744 Return 1 if successful, 0 if could not find the file. */
745
746 int
747 identify_source_line (s, line, mid_statement)
748 struct symtab *s;
749 int line;
750 int mid_statement;
751 {
752 if (s->line_charpos == 0)
753 get_filename_and_charpos (s, (char **)NULL);
754 if (s->fullname == 0)
755 return 0;
756 printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname,
757 line, s->line_charpos[line - 1],
758 mid_statement ? "middle" : "beg",
759 get_frame_pc (get_current_frame()));
760 current_source_line = line;
761 first_line_listed = line;
762 last_line_listed = line;
763 current_source_symtab = s;
764 return 1;
765 }
766 \f
767 /* Print source lines from the file of symtab S,
768 starting with line number LINE and stopping before line number STOPLINE. */
769
770 void
771 print_source_lines (s, line, stopline, noerror)
772 struct symtab *s;
773 int line, stopline;
774 int noerror;
775 {
776 register int c;
777 register int desc;
778 register FILE *stream;
779 int nlines = stopline - line;
780
781 /* Regardless of whether we can open the file, set current_source_symtab. */
782 current_source_symtab = s;
783 current_source_line = line;
784 first_line_listed = line;
785
786 desc = open_source_file (s);
787 if (desc < 0)
788 {
789 if (! noerror) {
790 char *name = alloca (strlen (s->filename) + 100);
791 sprintf (name, "%s:%d", s->filename, line);
792 print_sys_errmsg (name, errno);
793 }
794 return;
795 }
796
797 if (s->line_charpos == 0)
798 find_source_lines (s, desc);
799
800 if (line < 1 || line > s->nlines)
801 {
802 close (desc);
803 error ("Line number %d out of range; %s has %d lines.",
804 line, s->filename, s->nlines);
805 }
806
807 if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
808 {
809 close (desc);
810 perror_with_name (s->filename);
811 }
812
813 stream = fdopen (desc, "r");
814 clearerr (stream);
815
816 while (nlines-- > 0)
817 {
818 c = fgetc (stream);
819 if (c == EOF) break;
820 last_line_listed = current_source_line;
821 printf_filtered ("%d\t", current_source_line++);
822 do
823 {
824 if (c < 040 && c != '\t' && c != '\n')
825 printf_filtered ("^%c", c + 0100);
826 else if (c == 0177)
827 printf_filtered ("^?");
828 else
829 printf_filtered ("%c", c);
830 } while (c != '\n' && (c = fgetc (stream)) >= 0);
831 }
832
833 fclose (stream);
834 }
835 \f
836
837
838 /*
839 C++
840 Print a list of files and line numbers which a user may choose from
841 in order to list a function which was specified ambiguously
842 (as with `list classname::overloadedfuncname', for example).
843 The vector in SALS provides the filenames and line numbers.
844 */
845 static void
846 ambiguous_line_spec (sals)
847 struct symtabs_and_lines *sals;
848 {
849 int i;
850
851 for (i = 0; i < sals->nelts; ++i)
852 printf_filtered("file: \"%s\", line number: %d\n",
853 sals->sals[i].symtab->filename, sals->sals[i].line);
854 }
855
856
857 static void
858 list_command (arg, from_tty)
859 char *arg;
860 int from_tty;
861 {
862 struct symtabs_and_lines sals, sals_end;
863 struct symtab_and_line sal, sal_end;
864 struct symbol *sym;
865 char *arg1;
866 int no_end = 1;
867 int dummy_end = 0;
868 int dummy_beg = 0;
869 int linenum_beg = 0;
870 char *p;
871
872 if (!have_full_symbols () && !have_partial_symbols())
873 error ("No symbol table is loaded. Use the \"file\" command.");
874
875 /* Pull in a current source symtab if necessary */
876 if (current_source_symtab == 0 &&
877 (arg == 0 || arg[0] == '+' || arg[0] == '-'))
878 select_source_symtab (0);
879
880 /* "l" or "l +" lists next ten lines. */
881
882 if (arg == 0 || !strcmp (arg, "+"))
883 {
884 if (current_source_symtab == 0)
885 error ("No default source file yet. Do \"help list\".");
886 print_source_lines (current_source_symtab, current_source_line,
887 current_source_line + lines_to_list, 0);
888 return;
889 }
890
891 /* "l -" lists previous ten lines, the ones before the ten just listed. */
892 if (!strcmp (arg, "-"))
893 {
894 if (current_source_symtab == 0)
895 error ("No default source file yet. Do \"help list\".");
896 print_source_lines (current_source_symtab,
897 max (first_line_listed - lines_to_list, 1),
898 first_line_listed, 0);
899 return;
900 }
901
902 /* Now if there is only one argument, decode it in SAL
903 and set NO_END.
904 If there are two arguments, decode them in SAL and SAL_END
905 and clear NO_END; however, if one of the arguments is blank,
906 set DUMMY_BEG or DUMMY_END to record that fact. */
907
908 arg1 = arg;
909 if (*arg1 == ',')
910 dummy_beg = 1;
911 else
912 {
913 sals = decode_line_1 (&arg1, 0, 0, 0);
914
915 if (! sals.nelts) return; /* C++ */
916 if (sals.nelts > 1)
917 {
918 ambiguous_line_spec (&sals);
919 free (sals.sals);
920 return;
921 }
922
923 sal = sals.sals[0];
924 free (sals.sals);
925 }
926
927 /* Record whether the BEG arg is all digits. */
928
929 for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
930 linenum_beg = (p == arg1);
931
932 while (*arg1 == ' ' || *arg1 == '\t')
933 arg1++;
934 if (*arg1 == ',')
935 {
936 no_end = 0;
937 arg1++;
938 while (*arg1 == ' ' || *arg1 == '\t')
939 arg1++;
940 if (*arg1 == 0)
941 dummy_end = 1;
942 else
943 {
944 if (dummy_beg)
945 sals_end = decode_line_1 (&arg1, 0, 0, 0);
946 else
947 sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
948 if (sals_end.nelts == 0)
949 return;
950 if (sals_end.nelts > 1)
951 {
952 ambiguous_line_spec (&sals_end);
953 free (sals_end.sals);
954 return;
955 }
956 sal_end = sals_end.sals[0];
957 free (sals_end.sals);
958 }
959 }
960
961 if (*arg1)
962 error ("Junk at end of line specification.");
963
964 if (!no_end && !dummy_beg && !dummy_end
965 && sal.symtab != sal_end.symtab)
966 error ("Specified start and end are in different files.");
967 if (dummy_beg && dummy_end)
968 error ("Two empty args do not say what lines to list.");
969
970 /* if line was specified by address,
971 first print exactly which line, and which file.
972 In this case, sal.symtab == 0 means address is outside
973 of all known source files, not that user failed to give a filename. */
974 if (*arg == '*')
975 {
976 if (sal.symtab == 0)
977 error ("No source file for address %s.", local_hex_string(sal.pc));
978 sym = find_pc_function (sal.pc);
979 if (sym)
980 {
981 printf_filtered ("%s is in ", local_hex_string(sal.pc));
982 fprint_symbol (stdout, SYMBOL_NAME (sym));
983 printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
984 }
985 else
986 printf_filtered ("%s is at %s:%d.\n",
987 local_hex_string(sal.pc),
988 sal.symtab->filename, sal.line);
989 }
990
991 /* If line was not specified by just a line number,
992 and it does not imply a symtab, it must be an undebuggable symbol
993 which means no source code. */
994
995 if (! linenum_beg && sal.symtab == 0)
996 error ("No line number known for %s.", arg);
997
998 /* If this command is repeated with RET,
999 turn it into the no-arg variant. */
1000
1001 if (from_tty)
1002 *arg = 0;
1003
1004 if (dummy_beg && sal_end.symtab == 0)
1005 error ("No default source file yet. Do \"help list\".");
1006 if (dummy_beg)
1007 print_source_lines (sal_end.symtab,
1008 max (sal_end.line - (lines_to_list - 1), 1),
1009 sal_end.line + 1, 0);
1010 else if (sal.symtab == 0)
1011 error ("No default source file yet. Do \"help list\".");
1012 else if (no_end)
1013 print_source_lines (sal.symtab,
1014 max (sal.line - (lines_to_list / 2), 1),
1015 sal.line + (lines_to_list / 2), 0);
1016 else
1017 print_source_lines (sal.symtab, sal.line,
1018 (dummy_end
1019 ? sal.line + lines_to_list
1020 : sal_end.line + 1),
1021 0);
1022 }
1023 \f
1024 /* Print info on range of pc's in a specified line. */
1025
1026 static void
1027 line_info (arg, from_tty)
1028 char *arg;
1029 int from_tty;
1030 {
1031 struct symtabs_and_lines sals;
1032 struct symtab_and_line sal;
1033 CORE_ADDR start_pc, end_pc;
1034 int i;
1035
1036 if (arg == 0)
1037 {
1038 sal.symtab = current_source_symtab;
1039 sal.line = last_line_listed;
1040 sals.nelts = 1;
1041 sals.sals = (struct symtab_and_line *)
1042 xmalloc (sizeof (struct symtab_and_line));
1043 sals.sals[0] = sal;
1044 }
1045 else
1046 {
1047 sals = decode_line_spec_1 (arg, 0);
1048
1049 /* If this command is repeated with RET,
1050 turn it into the no-arg variant. */
1051 if (from_tty)
1052 *arg = 0;
1053 }
1054
1055 /* C++ More than one line may have been specified, as when the user
1056 specifies an overloaded function name. Print info on them all. */
1057 for (i = 0; i < sals.nelts; i++)
1058 {
1059 sal = sals.sals[i];
1060
1061 if (sal.symtab == 0)
1062 error ("No source file specified.");
1063
1064 if (sal.line > 0
1065 && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
1066 {
1067 if (start_pc == end_pc)
1068 printf_filtered ("Line %d of \"%s\" is at pc %s but contains no code.\n",
1069 sal.line, sal.symtab->filename, local_hex_string(start_pc));
1070 else
1071 {
1072 printf_filtered ("Line %d of \"%s\" starts at pc %s",
1073 sal.line, sal.symtab->filename,
1074 local_hex_string(start_pc));
1075 printf_filtered (" and ends at %s.\n",
1076 local_hex_string(end_pc));
1077 }
1078 /* x/i should display this line's code. */
1079 set_next_address (start_pc);
1080 /* Repeating "info line" should do the following line. */
1081 last_line_listed = sal.line + 1;
1082 }
1083 else
1084 printf_filtered ("Line number %d is out of range for \"%s\".\n",
1085 sal.line, sal.symtab->filename);
1086 }
1087 }
1088 \f
1089 /* Commands to search the source file for a regexp. */
1090
1091 /* ARGSUSED */
1092 static void
1093 forward_search_command (regex, from_tty)
1094 char *regex;
1095 int from_tty;
1096 {
1097 register int c;
1098 register int desc;
1099 register FILE *stream;
1100 int line = last_line_listed + 1;
1101 char *msg;
1102
1103 msg = (char *) re_comp (regex);
1104 if (msg)
1105 error (msg);
1106
1107 if (current_source_symtab == 0)
1108 select_source_symtab (0);
1109
1110 /* Search from last_line_listed+1 in current_source_symtab */
1111
1112 desc = open_source_file (current_source_symtab);
1113 if (desc < 0)
1114 perror_with_name (current_source_symtab->filename);
1115
1116 if (current_source_symtab->line_charpos == 0)
1117 find_source_lines (current_source_symtab, desc);
1118
1119 if (line < 1 || line > current_source_symtab->nlines)
1120 {
1121 close (desc);
1122 error ("Expression not found");
1123 }
1124
1125 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1126 {
1127 close (desc);
1128 perror_with_name (current_source_symtab->filename);
1129 }
1130
1131 stream = fdopen (desc, "r");
1132 clearerr (stream);
1133 while (1) {
1134 /* FIXME!!! We walk right off the end of buf if we get a long line!!! */
1135 char buf[4096]; /* Should be reasonable??? */
1136 register char *p = buf;
1137
1138 c = getc (stream);
1139 if (c == EOF)
1140 break;
1141 do {
1142 *p++ = c;
1143 } while (c != '\n' && (c = getc (stream)) >= 0);
1144
1145 /* we now have a source line in buf, null terminate and match */
1146 *p = 0;
1147 if (re_exec (buf) > 0)
1148 {
1149 /* Match! */
1150 fclose (stream);
1151 print_source_lines (current_source_symtab,
1152 line, line+1, 0);
1153 current_source_line = max (line - lines_to_list / 2, 1);
1154 return;
1155 }
1156 line++;
1157 }
1158
1159 printf_filtered ("Expression not found\n");
1160 fclose (stream);
1161 }
1162
1163 /* ARGSUSED */
1164 static void
1165 reverse_search_command (regex, from_tty)
1166 char *regex;
1167 int from_tty;
1168 {
1169 register int c;
1170 register int desc;
1171 register FILE *stream;
1172 int line = last_line_listed - 1;
1173 char *msg;
1174
1175 msg = (char *) re_comp (regex);
1176 if (msg)
1177 error (msg);
1178
1179 if (current_source_symtab == 0)
1180 select_source_symtab (0);
1181
1182 /* Search from last_line_listed-1 in current_source_symtab */
1183
1184 desc = open_source_file (current_source_symtab);
1185 if (desc < 0)
1186 perror_with_name (current_source_symtab->filename);
1187
1188 if (current_source_symtab->line_charpos == 0)
1189 find_source_lines (current_source_symtab, desc);
1190
1191 if (line < 1 || line > current_source_symtab->nlines)
1192 {
1193 close (desc);
1194 error ("Expression not found");
1195 }
1196
1197 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1198 {
1199 close (desc);
1200 perror_with_name (current_source_symtab->filename);
1201 }
1202
1203 stream = fdopen (desc, "r");
1204 clearerr (stream);
1205 while (line > 1)
1206 {
1207 /* FIXME!!! We walk right off the end of buf if we get a long line!!! */
1208 char buf[4096]; /* Should be reasonable??? */
1209 register char *p = buf;
1210
1211 c = getc (stream);
1212 if (c == EOF)
1213 break;
1214 do {
1215 *p++ = c;
1216 } while (c != '\n' && (c = getc (stream)) >= 0);
1217
1218 /* We now have a source line in buf; null terminate and match. */
1219 *p = 0;
1220 if (re_exec (buf) > 0)
1221 {
1222 /* Match! */
1223 fclose (stream);
1224 print_source_lines (current_source_symtab,
1225 line, line+1, 0);
1226 current_source_line = max (line - lines_to_list / 2, 1);
1227 return;
1228 }
1229 line--;
1230 if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
1231 {
1232 fclose (stream);
1233 perror_with_name (current_source_symtab->filename);
1234 }
1235 }
1236
1237 printf_filtered ("Expression not found\n");
1238 fclose (stream);
1239 return;
1240 }
1241 \f
1242 void
1243 _initialize_source ()
1244 {
1245 current_source_symtab = 0;
1246 init_source_path ();
1247
1248 add_com ("directory", class_files, directory_command,
1249 "Add directory DIR to beginning of search path for source files.\n\
1250 Forget cached info on source file locations and line positions.\n\
1251 DIR can also be $cwd for the current working directory, or $cdir for the\n\
1252 directory in which the source file was compiled into object code.\n\
1253 With no argument, reset the search path to $cdir:$cwd, the default.");
1254
1255 add_cmd ("directories", no_class, show_directories,
1256 "Current search path for finding source files.\n\
1257 $cwd in the path means the current working directory.\n\
1258 $cdir in the path means the compilation directory of the source file.",
1259 &showlist);
1260
1261 add_info ("source", source_info,
1262 "Information about the current source file.");
1263
1264 add_info ("line", line_info,
1265 "Core addresses of the code for a source line.\n\
1266 Line can be specified as\n\
1267 LINENUM, to list around that line in current file,\n\
1268 FILE:LINENUM, to list around that line in that file,\n\
1269 FUNCTION, to list around beginning of that function,\n\
1270 FILE:FUNCTION, to distinguish among like-named static functions.\n\
1271 Default is to describe the last source line that was listed.\n\n\
1272 This sets the default address for \"x\" to the line's first instruction\n\
1273 so that \"x/i\" suffices to start examining the machine code.\n\
1274 The address is also stored as the value of \"$_\".");
1275
1276 add_com ("forward-search", class_files, forward_search_command,
1277 "Search for regular expression (see regex(3)) from last line listed.");
1278 add_com_alias ("search", "forward-search", class_files, 0);
1279
1280 add_com ("reverse-search", class_files, reverse_search_command,
1281 "Search backward for regular expression (see regex(3)) from last line listed.");
1282
1283 add_com ("list", class_files, list_command,
1284 "List specified function or line.\n\
1285 With no argument, lists ten more lines after or around previous listing.\n\
1286 \"list -\" lists the ten lines before a previous ten-line listing.\n\
1287 One argument specifies a line, and ten lines are listed around that line.\n\
1288 Two arguments with comma between specify starting and ending lines to list.\n\
1289 Lines can be specified in these ways:\n\
1290 LINENUM, to list around that line in current file,\n\
1291 FILE:LINENUM, to list around that line in that file,\n\
1292 FUNCTION, to list around beginning of that function,\n\
1293 FILE:FUNCTION, to distinguish among like-named static functions.\n\
1294 *ADDRESS, to list around the line containing that address.\n\
1295 With two args if one is empty it stands for ten lines away from the other arg.");
1296 add_com_alias ("l", "list", class_files, 0);
1297
1298 add_show_from_set
1299 (add_set_cmd ("listsize", class_support, var_uinteger,
1300 (char *)&lines_to_list,
1301 "Set number of source lines gdb will list by default.",
1302 &setlist),
1303 &showlist);
1304 }
This page took 0.06825 seconds and 4 git commands to generate.