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