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