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