]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/source.c
import gdb-1999-09-21
[thirdparty/binutils-gdb.git] / gdb / source.c
CommitLineData
c906108c 1/* List lines of source files for GDB, the GNU debugger.
7be570e7 2 Copyright 1986-1989, 1991-1999 Free Software Foundation, Inc.
c906108c 3
c5aa993b 4 This file is part of GDB.
c906108c 5
c5aa993b
JM
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
c906108c 10
c5aa993b
JM
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
c906108c 15
c5aa993b
JM
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
c906108c
SS
20
21#include "defs.h"
22#include "symtab.h"
23#include "expression.h"
24#include "language.h"
25#include "command.h"
c2c6d25f 26#include "source.h"
c906108c
SS
27#include "gdbcmd.h"
28#include "frame.h"
29#include "value.h"
30
31#include <sys/types.h>
32#include "gdb_string.h"
33#include "gdb_stat.h"
34#include <fcntl.h>
c906108c
SS
35#include "gdbcore.h"
36#include "gnu-regex.h"
37#include "symfile.h"
38#include "objfiles.h"
39#include "annotate.h"
40#include "gdbtypes.h"
41
42#ifdef CRLF_SOURCE_FILES
43
44/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
45 host use \r\n rather than just \n. Defining CRLF_SOURCE_FILES is
46 much faster than defining LSEEK_NOT_LINEAR. */
47
48#ifndef O_BINARY
49#define O_BINARY 0
50#endif
51
52#define OPEN_MODE (O_RDONLY | O_BINARY)
53#define FDOPEN_MODE FOPEN_RB
54
55#else /* ! defined (CRLF_SOURCE_FILES) */
56
57#define OPEN_MODE O_RDONLY
58#define FDOPEN_MODE FOPEN_RT
59
60#endif /* ! defined (CRLF_SOURCE_FILES) */
61
c906108c
SS
62/* Prototypes for exported functions. */
63
64void _initialize_source PARAMS ((void));
65
66/* Prototypes for local functions. */
67
68static int get_filename_and_charpos PARAMS ((struct symtab *, char **));
69
70static void reverse_search_command PARAMS ((char *, int));
71
72static void forward_search_command PARAMS ((char *, int));
73
74static void line_info PARAMS ((char *, int));
75
76static void list_command PARAMS ((char *, int));
77
78static void ambiguous_line_spec PARAMS ((struct symtabs_and_lines *));
79
80static void source_info PARAMS ((char *, int));
81
82static void show_directories PARAMS ((char *, int));
83
84/* Path of directories to search for source files.
85 Same format as the PATH environment variable's value. */
86
87char *source_path;
88
89/* Symtab of default file for listing lines of. */
90
91struct symtab *current_source_symtab;
92
93/* Default next line to list. */
94
95int current_source_line;
96
97/* Default number of lines to print with commands like "list".
98 This is based on guessing how many long (i.e. more than chars_per_line
99 characters) lines there will be. To be completely correct, "list"
100 and friends should be rewritten to count characters and see where
101 things are wrapping, but that would be a fair amount of work. */
102
103int lines_to_list = 10;
104
105/* Line number of last line printed. Default for various commands.
106 current_source_line is usually, but not always, the same as this. */
107
108static int last_line_listed;
109
110/* First line number listed by last listing command. */
111
112static int first_line_listed;
113
114/* Saves the name of the last source file visited and a possible error code.
115 Used to prevent repeating annoying "No such file or directories" msgs */
116
117static struct symtab *last_source_visited = NULL;
118static int last_source_error = 0;
c906108c 119\f
c5aa993b 120
c906108c
SS
121/* Set the source file default for the "list" command to be S.
122
123 If S is NULL, and we don't have a default, find one. This
124 should only be called when the user actually tries to use the
125 default, since we produce an error if we can't find a reasonable
126 default. Also, since this can cause symbols to be read, doing it
127 before we need to would make things slower than necessary. */
128
129void
130select_source_symtab (s)
131 register struct symtab *s;
132{
133 struct symtabs_and_lines sals;
134 struct symtab_and_line sal;
135 struct partial_symtab *ps;
136 struct partial_symtab *cs_pst = 0;
137 struct objfile *ofp;
c5aa993b 138
c906108c
SS
139 if (s)
140 {
141 current_source_symtab = s;
142 current_source_line = 1;
143 return;
144 }
145
146 if (current_source_symtab)
147 return;
148
149 /* Make the default place to list be the function `main'
150 if one exists. */
151 if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL))
152 {
153 sals = decode_line_spec ("main", 1);
154 sal = sals.sals[0];
155 free (sals.sals);
156 current_source_symtab = sal.symtab;
157 current_source_line = max (sal.line - (lines_to_list - 1), 1);
158 if (current_source_symtab)
c5aa993b 159 return;
c906108c 160 }
c5aa993b 161
c906108c
SS
162 /* All right; find the last file in the symtab list (ignoring .h's). */
163
164 current_source_line = 1;
165
c5aa993b 166 for (ofp = object_files; ofp != NULL; ofp = ofp->next)
c906108c 167 {
c5aa993b 168 for (s = ofp->symtabs; s; s = s->next)
c906108c 169 {
c5aa993b 170 char *name = s->filename;
c906108c 171 int len = strlen (name);
c5aa993b 172 if (!(len > 2 && (STREQ (&name[len - 2], ".h"))))
c906108c
SS
173 {
174 current_source_symtab = s;
175 }
176 }
177 }
178 if (current_source_symtab)
179 return;
180
181 /* Howabout the partial symbol tables? */
182
c5aa993b 183 for (ofp = object_files; ofp != NULL; ofp = ofp->next)
c906108c 184 {
c5aa993b 185 for (ps = ofp->psymtabs; ps != NULL; ps = ps->next)
c906108c 186 {
c5aa993b 187 char *name = ps->filename;
c906108c 188 int len = strlen (name);
c5aa993b 189 if (!(len > 2 && (STREQ (&name[len - 2], ".h"))))
c906108c
SS
190 {
191 cs_pst = ps;
192 }
193 }
194 }
195 if (cs_pst)
196 {
c5aa993b 197 if (cs_pst->readin)
c906108c 198 {
96baa820 199 internal_error ("select_source_symtab: readin pst found and no symtabs.");
c906108c
SS
200 }
201 else
202 {
203 current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
204 }
205 }
206 if (current_source_symtab)
207 return;
208
209 error ("Can't find a default source file");
210}
211\f
212static void
213show_directories (ignore, from_tty)
214 char *ignore;
215 int from_tty;
216{
217 puts_filtered ("Source directories searched: ");
218 puts_filtered (source_path);
219 puts_filtered ("\n");
220}
221
222/* Forget what we learned about line positions in source files, and
223 which directories contain them; must check again now since files
224 may be found in a different directory now. */
225
226void
227forget_cached_source_info ()
228{
229 register struct symtab *s;
230 register struct objfile *objfile;
231
c5aa993b 232 for (objfile = object_files; objfile != NULL; objfile = objfile->next)
c906108c 233 {
c5aa993b 234 for (s = objfile->symtabs; s != NULL; s = s->next)
c906108c 235 {
c5aa993b 236 if (s->line_charpos != NULL)
c906108c 237 {
c5aa993b
JM
238 mfree (objfile->md, s->line_charpos);
239 s->line_charpos = NULL;
c906108c 240 }
c5aa993b 241 if (s->fullname != NULL)
c906108c 242 {
c5aa993b
JM
243 mfree (objfile->md, s->fullname);
244 s->fullname = NULL;
c906108c
SS
245 }
246 }
247 }
248}
249
250void
251init_source_path ()
252{
253 char buf[20];
254
255 sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR);
256 source_path = strsave (buf);
257 forget_cached_source_info ();
258}
259
260/* Add zero or more directories to the front of the source path. */
c5aa993b 261
c906108c
SS
262void
263directory_command (dirname, from_tty)
264 char *dirname;
265 int from_tty;
266{
267 dont_repeat ();
268 /* FIXME, this goes to "delete dir"... */
269 if (dirname == 0)
270 {
43ff13b4 271 if (from_tty && query ("Reinitialize source path to empty? "))
c906108c
SS
272 {
273 free (source_path);
274 init_source_path ();
275 }
276 }
277 else
278 {
279 mod_path (dirname, &source_path);
280 last_source_visited = NULL;
281 }
282 if (from_tty)
c5aa993b 283 show_directories ((char *) 0, from_tty);
c906108c
SS
284 forget_cached_source_info ();
285}
286
287/* Add zero or more directories to the front of an arbitrary path. */
288
289void
290mod_path (dirname, which_path)
291 char *dirname;
292 char **which_path;
293{
294 char *old = *which_path;
295 int prefix = 0;
296
297 if (dirname == 0)
298 return;
299
300 dirname = strsave (dirname);
301 make_cleanup (free, dirname);
302
303 do
304 {
305 char *name = dirname;
306 register char *p;
307 struct stat st;
308
309 {
310 char *separator = strchr (name, DIRNAME_SEPARATOR);
311 char *space = strchr (name, ' ');
312 char *tab = strchr (name, '\t');
313
c5aa993b 314 if (separator == 0 && space == 0 && tab == 0)
c906108c
SS
315 p = dirname = name + strlen (name);
316 else
317 {
318 p = 0;
319 if (separator != 0 && (p == 0 || separator < p))
320 p = separator;
321 if (space != 0 && (p == 0 || space < p))
322 p = space;
323 if (tab != 0 && (p == 0 || tab < p))
324 p = tab;
325 dirname = p + 1;
326 while (*dirname == DIRNAME_SEPARATOR
327 || *dirname == ' '
328 || *dirname == '\t')
329 ++dirname;
330 }
331 }
332
7be570e7
JM
333 if (!(SLASH_P (*name) && p <= name + 1) /* "/" */
334#if defined(_WIN32) || defined(__MSDOS__)
335 /* On MS-DOS and MS-Windows, h:\ is different from h: */
336 && !(!SLASH_P (*name) && ROOTED_P (name) && p <= name + 3) /* d:/ */
337#endif
338 && SLASH_P (p[-1]))
c906108c
SS
339 /* Sigh. "foo/" => "foo" */
340 --p;
c906108c
SS
341 *p = '\0';
342
7be570e7 343 while (p > name && p[-1] == '.')
c906108c
SS
344 {
345 if (p - name == 1)
346 {
347 /* "." => getwd (). */
348 name = current_directory;
349 goto append;
350 }
7be570e7 351 else if (p > name + 1 && SLASH_P (p[-2]))
c906108c
SS
352 {
353 if (p - name == 2)
354 {
355 /* "/." => "/". */
356 *--p = '\0';
357 goto append;
358 }
359 else
360 {
361 /* "...foo/." => "...foo". */
362 p -= 2;
363 *p = '\0';
364 continue;
365 }
366 }
367 else
368 break;
369 }
370
371 if (name[0] == '~')
372 name = tilde_expand (name);
7be570e7
JM
373#if defined(_WIN32) || defined(__MSDOS__)
374 else if (ROOTED_P (name) && p == name + 2) /* "d:" => "d:." */
375 name = concat (name, ".", NULL);
376#endif
c5aa993b
JM
377 else if (!ROOTED_P (name) && name[0] != '$')
378 name = concat (current_directory, SLASH_STRING, name, NULL);
c906108c
SS
379 else
380 name = savestring (name, p - name);
381 make_cleanup (free, name);
382
383 /* Unless it's a variable, check existence. */
c5aa993b
JM
384 if (name[0] != '$')
385 {
386 /* These are warnings, not errors, since we don't want a
387 non-existent directory in a .gdbinit file to stop processing
388 of the .gdbinit file.
389
390 Whether they get added to the path is more debatable. Current
391 answer is yes, in case the user wants to go make the directory
392 or whatever. If the directory continues to not exist/not be
393 a directory/etc, then having them in the path should be
394 harmless. */
395 if (stat (name, &st) < 0)
396 {
397 int save_errno = errno;
398 fprintf_unfiltered (gdb_stderr, "Warning: ");
399 print_sys_errmsg (name, save_errno);
400 }
401 else if ((st.st_mode & S_IFMT) != S_IFDIR)
402 warning ("%s is not a directory.", name);
403 }
c906108c
SS
404
405 append:
406 {
407 register unsigned int len = strlen (name);
408
409 p = *which_path;
410 while (1)
411 {
7be570e7
JM
412 /* FIXME: strncmp loses in interesting ways on MS-DOS and
413 MS-Windows because of case-insensitivity and two different
414 but functionally identical slash characters. We need a
415 special filesystem-dependent file-name comparison function.
416
417 Actually, even on Unix I would use realpath() or its work-
418 alike before comparing. Then all the code above which
419 removes excess slashes and dots could simply go away. */
c906108c
SS
420 if (!strncmp (p, name, len)
421 && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR))
422 {
423 /* Found it in the search path, remove old copy */
424 if (p > *which_path)
c5aa993b 425 p--; /* Back over leading separator */
c906108c
SS
426 if (prefix > p - *which_path)
427 goto skip_dup; /* Same dir twice in one cmd */
c5aa993b 428 strcpy (p, &p[len + 1]); /* Copy from next \0 or : */
c906108c
SS
429 }
430 p = strchr (p, DIRNAME_SEPARATOR);
431 if (p != 0)
432 ++p;
433 else
434 break;
435 }
436 if (p == 0)
437 {
438 char tinybuf[2];
439
440 tinybuf[0] = DIRNAME_SEPARATOR;
441 tinybuf[1] = '\0';
442
c5aa993b 443 /* 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. */
c906108c
SS
444 if (prefix)
445 {
446 char *temp, c;
447
448 c = old[prefix];
449 old[prefix] = '\0';
450 temp = concat (old, tinybuf, name, NULL);
451 old[prefix] = c;
452 *which_path = concat (temp, "", &old[prefix], NULL);
453 prefix = strlen (temp);
454 free (temp);
455 }
456 else
457 {
458 *which_path = concat (name, (old[0] ? tinybuf : old), old, NULL);
459 prefix = strlen (name);
460 }
461 free (old);
462 old = *which_path;
463 }
464 }
c5aa993b
JM
465 skip_dup:;
466 }
467 while (*dirname != '\0');
c906108c
SS
468}
469
470
471static void
472source_info (ignore, from_tty)
473 char *ignore;
474 int from_tty;
475{
476 register struct symtab *s = current_source_symtab;
477
478 if (!s)
479 {
c5aa993b 480 printf_filtered ("No current source file.\n");
c906108c
SS
481 return;
482 }
483 printf_filtered ("Current source file is %s\n", s->filename);
484 if (s->dirname)
485 printf_filtered ("Compilation directory is %s\n", s->dirname);
486 if (s->fullname)
487 printf_filtered ("Located in %s\n", s->fullname);
488 if (s->nlines)
489 printf_filtered ("Contains %d line%s.\n", s->nlines,
490 s->nlines == 1 ? "" : "s");
491
492 printf_filtered ("Source language is %s.\n", language_str (s->language));
493 printf_filtered ("Compiled with %s debugging format.\n", s->debugformat);
494}
c5aa993b 495\f
c906108c
SS
496
497
c906108c
SS
498/* Open a file named STRING, searching path PATH (dir names sep by some char)
499 using mode MODE and protection bits PROT in the calls to open.
500
501 If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
502 (ie pretend the first element of PATH is "."). This also indicates
503 that a slash in STRING disables searching of the path (this is
504 so that "exec-file ./foo" or "symbol-file ./foo" insures that you
505 get that particular version of foo or an error message).
506
507 If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
508 the actual file opened (this string will always start with a "/". We
509 have to take special pains to avoid doubling the "/" between the directory
510 and the file, sigh! Emacs gets confuzzed by this when we print the
511 source file name!!!
512
513 If a file is found, return the descriptor.
514 Otherwise, return -1, with errno set for the last name we tried to open. */
515
516/* >>>> This should only allow files of certain types,
c5aa993b 517 >>>> eg executable, non-directory */
c906108c
SS
518int
519openp (path, try_cwd_first, string, mode, prot, filename_opened)
520 char *path;
521 int try_cwd_first;
522 char *string;
523 int mode;
524 int prot;
525 char **filename_opened;
526{
527 register int fd;
528 register char *filename;
529 register char *p, *p1;
530 register int len;
531 int alloclen;
532
533 if (!path)
534 path = ".";
535
536#ifdef _WIN32
537 mode |= O_BINARY;
538#endif
539
b83266a0 540 if (try_cwd_first || ROOTED_P (string))
c906108c
SS
541 {
542 int i;
543 filename = string;
544 fd = open (filename, mode, prot);
545 if (fd >= 0)
546 goto done;
547 for (i = 0; string[i]; i++)
548 if (SLASH_P (string[i]))
549 goto done;
550 }
551
552 /* ./foo => foo */
553 while (string[0] == '.' && SLASH_P (string[1]))
554 string += 2;
555
556 alloclen = strlen (path) + strlen (string) + 2;
557 filename = (char *) alloca (alloclen);
558 fd = -1;
559 for (p = path; p; p = p1 ? p1 + 1 : 0)
560 {
561 p1 = (char *) strchr (p, DIRNAME_SEPARATOR);
562 if (p1)
563 len = p1 - p;
564 else
565 len = strlen (p);
566
567 if (len == 4 && p[0] == '$' && p[1] == 'c'
c5aa993b
JM
568 && p[2] == 'w' && p[3] == 'd')
569 {
570 /* Name is $cwd -- insert current directory name instead. */
571 int newlen;
572
573 /* First, realloc the filename buffer if too short. */
574 len = strlen (current_directory);
575 newlen = len + strlen (string) + 2;
576 if (newlen > alloclen)
577 {
578 alloclen = newlen;
579 filename = (char *) alloca (alloclen);
580 }
581 strcpy (filename, current_directory);
582 }
583 else
584 {
585 /* Normal file name in path -- just use it. */
586 strncpy (filename, p, len);
587 filename[len] = 0;
c906108c 588 }
c906108c
SS
589
590 /* Remove trailing slashes */
c5aa993b 591 while (len > 0 && SLASH_P (filename[len - 1]))
c906108c
SS
592 filename[--len] = 0;
593
c5aa993b 594 strcat (filename + len, SLASH_STRING);
c906108c
SS
595 strcat (filename, string);
596
597 fd = open (filename, mode);
c5aa993b
JM
598 if (fd >= 0)
599 break;
c906108c
SS
600 }
601
c5aa993b 602done:
c906108c
SS
603 if (filename_opened)
604 {
605 if (fd < 0)
606 *filename_opened = (char *) 0;
607 else if (ROOTED_P (filename))
608 *filename_opened = savestring (filename, strlen (filename));
609 else
610 {
611 /* Beware the // my son, the Emacs barfs, the botch that catch... */
c5aa993b
JM
612
613 *filename_opened = concat (current_directory,
7be570e7 614 SLASH_P (current_directory[strlen (current_directory) - 1])
c5aa993b 615 ? "" : SLASH_STRING,
c906108c 616 filename, NULL);
c5aa993b 617 }
c906108c
SS
618 }
619#ifdef MPW
620 /* This is a debugging hack that can go away when all combinations
621 of Mac and Unix names are handled reasonably. */
622 {
623 extern int debug_openp;
624
625 if (debug_openp)
626 {
c5aa993b
JM
627 printf ("openp on %s, path %s mode %d prot %d\n returned %d",
628 string, path, mode, prot, fd);
c906108c 629 if (*filename_opened)
c5aa993b
JM
630 printf (" (filename is %s)", *filename_opened);
631 printf ("\n");
c906108c
SS
632 }
633 }
634#endif /* MPW */
635
636 return fd;
637}
638
c5aa993b 639
c906108c
SS
640/* This is essentially a convenience, for clients that want the behaviour
641 of openp, using source_path, but that really don't want the file to be
642 opened but want instead just to know what the full pathname is (as
643 qualified against source_path).
644
645 The current working directory is searched first.
646
647 If the file was found, this function returns 1, and FULL_PATHNAME is
648 set to the fully-qualified pathname.
649
650 Else, this functions returns 0, and FULL_PATHNAME is set to NULL.
c5aa993b 651 */
c906108c
SS
652int
653source_full_path_of (filename, full_pathname)
c5aa993b
JM
654 char *filename;
655 char **full_pathname;
c906108c 656{
c5aa993b 657 int fd;
c906108c
SS
658
659 fd = openp (source_path, 1, filename, O_RDONLY, 0, full_pathname);
660 if (fd < 0)
661 {
662 *full_pathname = NULL;
663 return 0;
664 }
665
666 close (fd);
667 return 1;
668}
669
670
671/* Open a source file given a symtab S. Returns a file descriptor or
672 negative number for error. */
673
674int
675open_source_file (s)
676 struct symtab *s;
677{
678 char *path = source_path;
679 char *p;
680 int result;
681 char *fullname;
682
683 /* Quick way out if we already know its full name */
c5aa993b 684 if (s->fullname)
c906108c
SS
685 {
686 result = open (s->fullname, OPEN_MODE);
687 if (result >= 0)
c5aa993b 688 return result;
c906108c
SS
689 /* Didn't work -- free old one, try again. */
690 mfree (s->objfile->md, s->fullname);
691 s->fullname = NULL;
692 }
693
694 if (s->dirname != NULL)
695 {
696 /* Replace a path entry of $cdir with the compilation directory name */
697#define cdir_len 5
698 /* We cast strstr's result in case an ANSIhole has made it const,
c5aa993b
JM
699 which produces a "required warning" when assigned to a nonconst. */
700 p = (char *) strstr (source_path, "$cdir");
c906108c 701 if (p && (p == path || p[-1] == DIRNAME_SEPARATOR)
c5aa993b 702 && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0'))
c906108c
SS
703 {
704 int len;
705
706 path = (char *)
707 alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
708 len = p - source_path;
c5aa993b
JM
709 strncpy (path, source_path, len); /* Before $cdir */
710 strcpy (path + len, s->dirname); /* new stuff */
711 strcat (path + len, source_path + len + cdir_len); /* After $cdir */
c906108c
SS
712 }
713 }
714
715 result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
716 if (result < 0)
717 {
718 /* Didn't work. Try using just the basename. */
719 p = basename (s->filename);
720 if (p != s->filename)
721 result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
722 }
723#ifdef MPW
724 if (result < 0)
725 {
726 /* Didn't work. Try using just the MPW basename. */
727 p = (char *) mpw_basename (s->filename);
728 if (p != s->filename)
729 result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
730 }
731 if (result < 0)
732 {
733 /* Didn't work. Try using the mixed Unix/MPW basename. */
734 p = (char *) mpw_mixed_basename (s->filename);
735 if (p != s->filename)
736 result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
737 }
738#endif /* MPW */
739
740 if (result >= 0)
741 {
742 fullname = s->fullname;
743 s->fullname = mstrsave (s->objfile->md, s->fullname);
744 free (fullname);
745 }
746 return result;
747}
748
749/* Return the path to the source file associated with symtab. Returns NULL
750 if no symtab. */
751
752char *
753symtab_to_filename (s)
754 struct symtab *s;
755{
756 int fd;
757
758 if (!s)
759 return NULL;
760
761 /* If we've seen the file before, just return fullname. */
762
763 if (s->fullname)
764 return s->fullname;
765
766 /* Try opening the file to setup fullname */
767
768 fd = open_source_file (s);
769 if (fd < 0)
770 return s->filename; /* File not found. Just use short name */
771
772 /* Found the file. Cleanup and return the full name */
773
774 close (fd);
775 return s->fullname;
776}
c906108c 777\f
c5aa993b 778
c906108c
SS
779/* Create and initialize the table S->line_charpos that records
780 the positions of the lines in the source file, which is assumed
781 to be open on descriptor DESC.
782 All set S->nlines to the number of such lines. */
783
784void
785find_source_lines (s, desc)
786 struct symtab *s;
787 int desc;
788{
789 struct stat st;
790 register char *data, *p, *end;
791 int nlines = 0;
792 int lines_allocated = 1000;
793 int *line_charpos;
794 long mtime = 0;
795 int size;
796
c5aa993b 797 line_charpos = (int *) xmmalloc (s->objfile->md,
c906108c
SS
798 lines_allocated * sizeof (int));
799 if (fstat (desc, &st) < 0)
800 perror_with_name (s->filename);
801
802 if (s && s->objfile && s->objfile->obfd)
c5aa993b 803 mtime = bfd_get_mtime (s->objfile->obfd);
c906108c 804 else if (exec_bfd)
c5aa993b 805 mtime = bfd_get_mtime (exec_bfd);
c906108c
SS
806
807 if (mtime && mtime < st.st_mtime)
808 {
809 if (tui_version)
810 printf_filtered ("\n");
c5aa993b 811 warning ("Source file is more recent than executable.\n");
c906108c
SS
812 }
813
814#ifdef LSEEK_NOT_LINEAR
815 {
816 char c;
817
818 /* Have to read it byte by byte to find out where the chars live */
819
820 line_charpos[0] = lseek (desc, 0, SEEK_CUR);
821 nlines = 1;
c5aa993b 822 while (myread (desc, &c, 1) > 0)
c906108c 823 {
c5aa993b 824 if (c == '\n')
c906108c 825 {
c5aa993b 826 if (nlines == lines_allocated)
c906108c
SS
827 {
828 lines_allocated *= 2;
829 line_charpos =
c5aa993b 830 (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
c906108c
SS
831 sizeof (int) * lines_allocated);
832 }
833 line_charpos[nlines++] = lseek (desc, 0, SEEK_CUR);
834 }
835 }
836 }
837#else /* lseek linear. */
838 {
839 struct cleanup *old_cleanups;
840
841 /* st_size might be a large type, but we only support source files whose
842 size fits in an int. */
843 size = (int) st.st_size;
844
845 /* Use malloc, not alloca, because this may be pretty large, and we may
846 run into various kinds of limits on stack size. */
847 data = (char *) xmalloc (size);
848 old_cleanups = make_cleanup (free, data);
849
850 /* Reassign `size' to result of read for systems where \r\n -> \n. */
851 size = myread (desc, data, size);
852 if (size < 0)
853 perror_with_name (s->filename);
854 end = data + size;
855 p = data;
856 line_charpos[0] = 0;
857 nlines = 1;
858 while (p != end)
859 {
860 if (*p++ == '\n'
c5aa993b 861 /* A newline at the end does not start a new line. */
c906108c
SS
862 && p != end)
863 {
864 if (nlines == lines_allocated)
865 {
866 lines_allocated *= 2;
867 line_charpos =
c5aa993b 868 (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
c906108c
SS
869 sizeof (int) * lines_allocated);
870 }
871 line_charpos[nlines++] = p - data;
872 }
873 }
874 do_cleanups (old_cleanups);
875 }
876#endif /* lseek linear. */
877 s->nlines = nlines;
878 s->line_charpos =
c5aa993b
JM
879 (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
880 nlines * sizeof (int));
c906108c
SS
881
882}
883
884/* Return the character position of a line LINE in symtab S.
885 Return 0 if anything is invalid. */
886
c5aa993b 887#if 0 /* Currently unused */
c906108c
SS
888
889int
890source_line_charpos (s, line)
891 struct symtab *s;
892 int line;
893{
c5aa993b
JM
894 if (!s)
895 return 0;
896 if (!s->line_charpos || line <= 0)
897 return 0;
c906108c
SS
898 if (line > s->nlines)
899 line = s->nlines;
900 return s->line_charpos[line - 1];
901}
902
903/* Return the line number of character position POS in symtab S. */
904
905int
906source_charpos_line (s, chr)
c5aa993b
JM
907 register struct symtab *s;
908 register int chr;
c906108c
SS
909{
910 register int line = 0;
911 register int *lnp;
c5aa993b
JM
912
913 if (s == 0 || s->line_charpos == 0)
914 return 0;
c906108c
SS
915 lnp = s->line_charpos;
916 /* Files are usually short, so sequential search is Ok */
c5aa993b 917 while (line < s->nlines && *lnp <= chr)
c906108c
SS
918 {
919 line++;
920 lnp++;
921 }
922 if (line >= s->nlines)
923 line = s->nlines;
924 return line;
925}
926
c5aa993b 927#endif /* 0 */
c906108c 928\f
c5aa993b 929
c906108c
SS
930/* Get full pathname and line number positions for a symtab.
931 Return nonzero if line numbers may have changed.
932 Set *FULLNAME to actual name of the file as found by `openp',
933 or to 0 if the file is not found. */
934
935static int
936get_filename_and_charpos (s, fullname)
937 struct symtab *s;
938 char **fullname;
939{
940 register int desc, linenums_changed = 0;
c5aa993b 941
c906108c
SS
942 desc = open_source_file (s);
943 if (desc < 0)
944 {
945 if (fullname)
946 *fullname = NULL;
947 return 0;
c5aa993b 948 }
c906108c
SS
949 if (fullname)
950 *fullname = s->fullname;
c5aa993b
JM
951 if (s->line_charpos == 0)
952 linenums_changed = 1;
953 if (linenums_changed)
954 find_source_lines (s, desc);
c906108c
SS
955 close (desc);
956 return linenums_changed;
957}
958
959/* Print text describing the full name of the source file S
960 and the line number LINE and its corresponding character position.
961 The text starts with two Ctrl-z so that the Emacs-GDB interface
962 can easily find it.
963
964 MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
965
966 Return 1 if successful, 0 if could not find the file. */
967
968int
969identify_source_line (s, line, mid_statement, pc)
970 struct symtab *s;
971 int line;
972 int mid_statement;
973 CORE_ADDR pc;
974{
975 if (s->line_charpos == 0)
c5aa993b 976 get_filename_and_charpos (s, (char **) NULL);
c906108c
SS
977 if (s->fullname == 0)
978 return 0;
979 if (line > s->nlines)
980 /* Don't index off the end of the line_charpos array. */
981 return 0;
982 annotate_source (s->fullname, line, s->line_charpos[line - 1],
983 mid_statement, pc);
984
985 current_source_line = line;
986 first_line_listed = line;
987 last_line_listed = line;
988 current_source_symtab = s;
989 return 1;
990}
c906108c 991\f
c5aa993b 992
c906108c
SS
993/* Print source lines from the file of symtab S,
994 starting with line number LINE and stopping before line number STOPLINE. */
995
c5aa993b 996static void print_source_lines_base PARAMS ((struct symtab * s, int line, int stopline, int noerror));
c906108c
SS
997static void
998print_source_lines_base (s, line, stopline, noerror)
999 struct symtab *s;
7a292a7a
SS
1000 int line;
1001 int stopline;
c906108c
SS
1002 int noerror;
1003{
1004 register int c;
1005 register int desc;
1006 register FILE *stream;
1007 int nlines = stopline - line;
1008
1009 /* Regardless of whether we can open the file, set current_source_symtab. */
1010 current_source_symtab = s;
1011 current_source_line = line;
1012 first_line_listed = line;
1013
c5aa993b
JM
1014 /* Only prints "No such file or directory" once */
1015 if ((s != last_source_visited) || (!last_source_error))
1016 {
1017 last_source_visited = s;
1018 desc = open_source_file (s);
1019 }
1020 else
1021 {
1022 desc = last_source_error;
1023 noerror = 1;
1024 }
c906108c
SS
1025
1026 if (desc < 0)
1027 {
1028 last_source_error = desc;
1029
c5aa993b
JM
1030 if (!noerror)
1031 {
c906108c
SS
1032 char *name = alloca (strlen (s->filename) + 100);
1033 sprintf (name, "%d\t%s", line, s->filename);
1034 print_sys_errmsg (name, errno);
1035 }
1036 else
1037 printf_filtered ("%d\tin %s\n", line, s->filename);
1038
1039 return;
1040 }
1041
1042 last_source_error = 0;
1043
1044 if (s->line_charpos == 0)
1045 find_source_lines (s, desc);
1046
1047 if (line < 1 || line > s->nlines)
1048 {
1049 close (desc);
1050 error ("Line number %d out of range; %s has %d lines.",
1051 line, s->filename, s->nlines);
1052 }
1053
1054 if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
1055 {
1056 close (desc);
1057 perror_with_name (s->filename);
1058 }
1059
1060 stream = fdopen (desc, FDOPEN_MODE);
1061 clearerr (stream);
1062
1063 while (nlines-- > 0)
1064 {
1065 c = fgetc (stream);
c5aa993b
JM
1066 if (c == EOF)
1067 break;
c906108c
SS
1068 last_line_listed = current_source_line;
1069 printf_filtered ("%d\t", current_source_line++);
1070 do
1071 {
1072 if (c < 040 && c != '\t' && c != '\n' && c != '\r')
1073 printf_filtered ("^%c", c + 0100);
1074 else if (c == 0177)
1075 printf_filtered ("^?");
1076#ifdef CRLF_SOURCE_FILES
1077 else if (c == '\r')
1078 {
1079 /* Just skip \r characters. */
1080 }
1081#endif
1082 else
1083 printf_filtered ("%c", c);
c5aa993b
JM
1084 }
1085 while (c != '\n' && (c = fgetc (stream)) >= 0);
c906108c
SS
1086 }
1087
1088 fclose (stream);
1089}
1090\f
1091/* Show source lines from the file of symtab S, starting with line
1092 number LINE and stopping before line number STOPLINE. If this is the
1093 not the command line version, then the source is shown in the source
1094 window otherwise it is simply printed */
1095
c5aa993b 1096void
c906108c 1097print_source_lines (s, line, stopline, noerror)
c5aa993b
JM
1098 struct symtab *s;
1099 int line, stopline, noerror;
c906108c
SS
1100{
1101#if defined(TUI)
c5aa993b
JM
1102 if (!tui_version ||
1103 m_winPtrIsNull (srcWin) || !srcWin->generic.isVisible)
1104 print_source_lines_base (s, line, stopline, noerror);
c906108c
SS
1105 else
1106 {
c5aa993b 1107 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
c906108c
SS
1108 extern void tui_vAddWinToLayout PARAMS ((va_list));
1109 extern void tui_vUpdateSourceWindowsWithLine PARAMS ((va_list));
1110
c5aa993b
JM
1111 /* Regardless of whether we can open the file,
1112 set current_source_symtab. */
1113 current_source_symtab = s;
1114 current_source_line = line;
1115 first_line_listed = line;
c906108c 1116
c5aa993b
JM
1117 /* make sure that the source window is displayed */
1118 tuiDo ((TuiOpaqueFuncPtr) tui_vAddWinToLayout, SRC_WIN);
c906108c 1119
c5aa993b
JM
1120 tuiDo ((TuiOpaqueFuncPtr) tui_vUpdateSourceWindowsWithLine, s, line);
1121 tuiDo ((TuiOpaqueFuncPtr) tui_vUpdateLocatorFilename, s->filename);
1122 }
c906108c 1123#else
c5aa993b 1124 print_source_lines_base (s, line, stopline, noerror);
c906108c
SS
1125#endif
1126}
1127\f
1128
1129
1130/* Print a list of files and line numbers which a user may choose from
c5aa993b
JM
1131 in order to list a function which was specified ambiguously (as with
1132 `list classname::overloadedfuncname', for example). The vector in
1133 SALS provides the filenames and line numbers. */
c906108c
SS
1134
1135static void
1136ambiguous_line_spec (sals)
1137 struct symtabs_and_lines *sals;
1138{
1139 int i;
1140
1141 for (i = 0; i < sals->nelts; ++i)
c5aa993b
JM
1142 printf_filtered ("file: \"%s\", line number: %d\n",
1143 sals->sals[i].symtab->filename, sals->sals[i].line);
c906108c
SS
1144}
1145
1146static void
1147list_command (arg, from_tty)
1148 char *arg;
1149 int from_tty;
1150{
1151 struct symtabs_and_lines sals, sals_end;
1152 struct symtab_and_line sal, sal_end;
1153 struct symbol *sym;
1154 char *arg1;
1155 int no_end = 1;
1156 int dummy_end = 0;
1157 int dummy_beg = 0;
1158 int linenum_beg = 0;
1159 char *p;
1160
c5aa993b 1161 if (!have_full_symbols () && !have_partial_symbols ())
c906108c
SS
1162 error ("No symbol table is loaded. Use the \"file\" command.");
1163
1164 /* Pull in a current source symtab if necessary */
1165 if (current_source_symtab == 0 &&
1166 (arg == 0 || arg[0] == '+' || arg[0] == '-'))
1167 select_source_symtab (0);
1168
1169 /* "l" or "l +" lists next ten lines. */
1170
1171 if (arg == 0 || STREQ (arg, "+"))
1172 {
1173 if (current_source_symtab == 0)
1174 error ("No default source file yet. Do \"help list\".");
1175 print_source_lines (current_source_symtab, current_source_line,
1176 current_source_line + lines_to_list, 0);
1177 return;
1178 }
1179
1180 /* "l -" lists previous ten lines, the ones before the ten just listed. */
1181 if (STREQ (arg, "-"))
1182 {
1183 if (current_source_symtab == 0)
1184 error ("No default source file yet. Do \"help list\".");
1185 print_source_lines (current_source_symtab,
1186 max (first_line_listed - lines_to_list, 1),
1187 first_line_listed, 0);
1188 return;
1189 }
1190
1191 /* Now if there is only one argument, decode it in SAL
1192 and set NO_END.
1193 If there are two arguments, decode them in SAL and SAL_END
1194 and clear NO_END; however, if one of the arguments is blank,
1195 set DUMMY_BEG or DUMMY_END to record that fact. */
1196
1197 arg1 = arg;
1198 if (*arg1 == ',')
1199 dummy_beg = 1;
1200 else
1201 {
1202 sals = decode_line_1 (&arg1, 0, 0, 0, 0);
1203
c5aa993b
JM
1204 if (!sals.nelts)
1205 return; /* C++ */
c906108c
SS
1206 if (sals.nelts > 1)
1207 {
1208 ambiguous_line_spec (&sals);
1209 free (sals.sals);
1210 return;
1211 }
1212
1213 sal = sals.sals[0];
1214 free (sals.sals);
1215 }
1216
1217 /* Record whether the BEG arg is all digits. */
1218
1219 for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
1220 linenum_beg = (p == arg1);
1221
1222 while (*arg1 == ' ' || *arg1 == '\t')
1223 arg1++;
1224 if (*arg1 == ',')
1225 {
1226 no_end = 0;
1227 arg1++;
1228 while (*arg1 == ' ' || *arg1 == '\t')
1229 arg1++;
1230 if (*arg1 == 0)
1231 dummy_end = 1;
1232 else
1233 {
1234 if (dummy_beg)
1235 sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
1236 else
1237 sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
c5aa993b 1238 if (sals_end.nelts == 0)
c906108c
SS
1239 return;
1240 if (sals_end.nelts > 1)
1241 {
1242 ambiguous_line_spec (&sals_end);
1243 free (sals_end.sals);
1244 return;
1245 }
1246 sal_end = sals_end.sals[0];
1247 free (sals_end.sals);
1248 }
1249 }
1250
1251 if (*arg1)
1252 error ("Junk at end of line specification.");
1253
1254 if (!no_end && !dummy_beg && !dummy_end
1255 && sal.symtab != sal_end.symtab)
1256 error ("Specified start and end are in different files.");
1257 if (dummy_beg && dummy_end)
1258 error ("Two empty args do not say what lines to list.");
c5aa993b 1259
c906108c
SS
1260 /* if line was specified by address,
1261 first print exactly which line, and which file.
1262 In this case, sal.symtab == 0 means address is outside
1263 of all known source files, not that user failed to give a filename. */
1264 if (*arg == '*')
1265 {
1266 if (sal.symtab == 0)
1267 /* FIXME-32x64--assumes sal.pc fits in long. */
1268 error ("No source file for address %s.",
c5aa993b 1269 local_hex_string ((unsigned long) sal.pc));
c906108c
SS
1270 sym = find_pc_function (sal.pc);
1271 if (sym)
1272 {
1273 print_address_numeric (sal.pc, 1, gdb_stdout);
1274 printf_filtered (" is in ");
1275 fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
1276 printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
1277 }
1278 else
1279 {
1280 print_address_numeric (sal.pc, 1, gdb_stdout);
1281 printf_filtered (" is at %s:%d.\n",
1282 sal.symtab->filename, sal.line);
1283 }
1284 }
1285
1286 /* If line was not specified by just a line number,
1287 and it does not imply a symtab, it must be an undebuggable symbol
1288 which means no source code. */
1289
c5aa993b 1290 if (!linenum_beg && sal.symtab == 0)
c906108c
SS
1291 error ("No line number known for %s.", arg);
1292
1293 /* If this command is repeated with RET,
1294 turn it into the no-arg variant. */
1295
1296 if (from_tty)
1297 *arg = 0;
1298
1299 if (dummy_beg && sal_end.symtab == 0)
1300 error ("No default source file yet. Do \"help list\".");
1301 if (dummy_beg)
1302 print_source_lines (sal_end.symtab,
1303 max (sal_end.line - (lines_to_list - 1), 1),
1304 sal_end.line + 1, 0);
1305 else if (sal.symtab == 0)
1306 error ("No default source file yet. Do \"help list\".");
1307 else if (no_end)
7a292a7a 1308 {
d4f3574e
SS
1309 int first_line = sal.line - lines_to_list / 2;
1310
1311 if (first_line < 1) first_line = 1;
1312
1313 print_source_lines (sal.symtab, first_line, first_line + lines_to_list,
1314 0);
7a292a7a 1315 }
c906108c
SS
1316 else
1317 print_source_lines (sal.symtab, sal.line,
1318 (dummy_end
1319 ? sal.line + lines_to_list
1320 : sal_end.line + 1),
1321 0);
1322}
1323\f
1324/* Print info on range of pc's in a specified line. */
1325
1326static void
1327line_info (arg, from_tty)
1328 char *arg;
1329 int from_tty;
1330{
1331 struct symtabs_and_lines sals;
1332 struct symtab_and_line sal;
1333 CORE_ADDR start_pc, end_pc;
1334 int i;
1335
c5aa993b 1336 INIT_SAL (&sal); /* initialize to zeroes */
c906108c
SS
1337
1338 if (arg == 0)
1339 {
1340 sal.symtab = current_source_symtab;
1341 sal.line = last_line_listed;
1342 sals.nelts = 1;
1343 sals.sals = (struct symtab_and_line *)
1344 xmalloc (sizeof (struct symtab_and_line));
1345 sals.sals[0] = sal;
1346 }
1347 else
1348 {
1349 sals = decode_line_spec_1 (arg, 0);
c5aa993b 1350
c906108c
SS
1351 dont_repeat ();
1352 }
1353
1354 /* C++ More than one line may have been specified, as when the user
1355 specifies an overloaded function name. Print info on them all. */
1356 for (i = 0; i < sals.nelts; i++)
1357 {
1358 sal = sals.sals[i];
c5aa993b 1359
c906108c
SS
1360 if (sal.symtab == 0)
1361 {
1362 printf_filtered ("No line number information available");
1363 if (sal.pc != 0)
1364 {
1365 /* This is useful for "info line *0x7f34". If we can't tell the
c5aa993b
JM
1366 user about a source line, at least let them have the symbolic
1367 address. */
c906108c
SS
1368 printf_filtered (" for address ");
1369 wrap_here (" ");
1370 print_address (sal.pc, gdb_stdout);
1371 }
1372 else
1373 printf_filtered (".");
1374 printf_filtered ("\n");
1375 }
1376 else if (sal.line > 0
1377 && find_line_pc_range (sal, &start_pc, &end_pc))
1378 {
1379 if (start_pc == end_pc)
1380 {
1381 printf_filtered ("Line %d of \"%s\"",
1382 sal.line, sal.symtab->filename);
1383 wrap_here (" ");
1384 printf_filtered (" is at address ");
1385 print_address (start_pc, gdb_stdout);
1386 wrap_here (" ");
1387 printf_filtered (" but contains no code.\n");
1388 }
1389 else
1390 {
1391 printf_filtered ("Line %d of \"%s\"",
1392 sal.line, sal.symtab->filename);
1393 wrap_here (" ");
1394 printf_filtered (" starts at address ");
1395 print_address (start_pc, gdb_stdout);
1396 wrap_here (" ");
1397 printf_filtered (" and ends at ");
1398 print_address (end_pc, gdb_stdout);
1399 printf_filtered (".\n");
1400 }
1401
1402 /* x/i should display this line's code. */
1403 set_next_address (start_pc);
1404
1405 /* Repeating "info line" should do the following line. */
1406 last_line_listed = sal.line + 1;
1407
1408 /* If this is the only line, show the source code. If it could
1409 not find the file, don't do anything special. */
1410 if (annotation_level && sals.nelts == 1)
1411 identify_source_line (sal.symtab, sal.line, 0, start_pc);
1412 }
1413 else
1414 /* Is there any case in which we get here, and have an address
1415 which the user would want to see? If we have debugging symbols
1416 and no line numbers? */
1417 printf_filtered ("Line number %d is out of range for \"%s\".\n",
1418 sal.line, sal.symtab->filename);
1419 }
1420 free (sals.sals);
1421}
1422\f
1423/* Commands to search the source file for a regexp. */
1424
1425/* ARGSUSED */
1426static void
1427forward_search_command (regex, from_tty)
1428 char *regex;
1429 int from_tty;
1430{
1431 register int c;
1432 register int desc;
1433 register FILE *stream;
1434 int line;
1435 char *msg;
1436
1437#if defined(TUI)
1438 /*
c5aa993b
JM
1439 ** If this is the TUI, search from the first line displayed in
1440 ** the source window, otherwise, search from last_line_listed+1
1441 ** in current_source_symtab
1442 */
c906108c
SS
1443 if (!tui_version)
1444 line = last_line_listed;
1445 else
1446 {
1447 if (srcWin->generic.isVisible && srcWin->generic.contentSize > 0)
c5aa993b
JM
1448 line = ((TuiWinContent)
1449 srcWin->generic.content)[0]->whichElement.source.lineOrAddr.lineNo;
c906108c 1450 else
c5aa993b
JM
1451 {
1452 printf_filtered ("No source displayed.\nExpression not found.\n");
1453 return;
1454 }
c906108c
SS
1455 }
1456 line++;
1457#else
1458 line = last_line_listed + 1;
1459#endif
1460
1461 msg = (char *) re_comp (regex);
1462 if (msg)
1463 error (msg);
1464
1465 if (current_source_symtab == 0)
1466 select_source_symtab (0);
1467
1468 desc = open_source_file (current_source_symtab);
1469 if (desc < 0)
1470 perror_with_name (current_source_symtab->filename);
1471
1472 if (current_source_symtab->line_charpos == 0)
1473 find_source_lines (current_source_symtab, desc);
1474
1475 if (line < 1 || line > current_source_symtab->nlines)
1476 {
1477 close (desc);
1478 error ("Expression not found");
1479 }
1480
1481 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1482 {
1483 close (desc);
1484 perror_with_name (current_source_symtab->filename);
1485 }
1486
1487 stream = fdopen (desc, FDOPEN_MODE);
1488 clearerr (stream);
c5aa993b
JM
1489 while (1)
1490 {
1491 static char *buf = NULL;
1492 register char *p;
1493 int cursize, newsize;
1494
1495 cursize = 256;
1496 buf = xmalloc (cursize);
1497 p = buf;
1498
1499 c = getc (stream);
1500 if (c == EOF)
1501 break;
1502 do
c906108c 1503 {
c5aa993b
JM
1504 *p++ = c;
1505 if (p - buf == cursize)
1506 {
1507 newsize = cursize + cursize / 2;
1508 buf = xrealloc (buf, newsize);
1509 p = buf + cursize;
1510 cursize = newsize;
1511 }
c906108c 1512 }
c5aa993b 1513 while (c != '\n' && (c = getc (stream)) >= 0);
c906108c 1514
7be570e7
JM
1515#ifdef CRLF_SOURCE_FILES
1516 /* Remove the \r, if any, at the end of the line, otherwise
1517 regular expressions that end with $ or \n won't work. */
1518 if (p - buf > 1 && p[-2] == '\r')
1519 {
1520 p--;
1521 p[-1] = '\n';
1522 }
1523#endif
1524
c5aa993b
JM
1525 /* we now have a source line in buf, null terminate and match */
1526 *p = 0;
1527 if (re_exec (buf) > 0)
1528 {
1529 /* Match! */
1530 fclose (stream);
1531 if (tui_version)
1532 print_source_lines_base (current_source_symtab, line, line + 1, 0);
1533 print_source_lines (current_source_symtab, line, line + 1, 0);
1534 set_internalvar (lookup_internalvar ("_"),
1535 value_from_longest (builtin_type_int,
1536 (LONGEST) line));
1537 current_source_line = max (line - lines_to_list / 2, 1);
1538 return;
1539 }
1540 line++;
1541 }
c906108c
SS
1542
1543 printf_filtered ("Expression not found\n");
1544 fclose (stream);
1545}
1546
1547/* ARGSUSED */
1548static void
1549reverse_search_command (regex, from_tty)
1550 char *regex;
1551 int from_tty;
1552{
1553 register int c;
1554 register int desc;
1555 register FILE *stream;
1556 int line;
1557 char *msg;
1558#if defined(TUI)
1559 /*
c5aa993b
JM
1560 ** If this is the TUI, search from the first line displayed in
1561 ** the source window, otherwise, search from last_line_listed-1
1562 ** in current_source_symtab
1563 */
c906108c
SS
1564 if (!tui_version)
1565 line = last_line_listed;
1566 else
1567 {
1568 if (srcWin->generic.isVisible && srcWin->generic.contentSize > 0)
c5aa993b
JM
1569 line = ((TuiWinContent)
1570 srcWin->generic.content)[0]->whichElement.source.lineOrAddr.lineNo;
c906108c 1571 else
c5aa993b
JM
1572 {
1573 printf_filtered ("No source displayed.\nExpression not found.\n");
1574 return;
1575 }
c906108c
SS
1576 }
1577 line--;
1578#else
1579 line = last_line_listed - 1;
1580#endif
1581
1582 msg = (char *) re_comp (regex);
1583 if (msg)
1584 error (msg);
1585
1586 if (current_source_symtab == 0)
1587 select_source_symtab (0);
1588
1589 desc = open_source_file (current_source_symtab);
1590 if (desc < 0)
1591 perror_with_name (current_source_symtab->filename);
1592
1593 if (current_source_symtab->line_charpos == 0)
1594 find_source_lines (current_source_symtab, desc);
1595
1596 if (line < 1 || line > current_source_symtab->nlines)
1597 {
1598 close (desc);
1599 error ("Expression not found");
1600 }
1601
1602 if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
1603 {
1604 close (desc);
1605 perror_with_name (current_source_symtab->filename);
1606 }
1607
1608 stream = fdopen (desc, FDOPEN_MODE);
1609 clearerr (stream);
1610 while (line > 1)
1611 {
1612/* FIXME!!! We walk right off the end of buf if we get a long line!!! */
1613 char buf[4096]; /* Should be reasonable??? */
1614 register char *p = buf;
1615
1616 c = getc (stream);
1617 if (c == EOF)
1618 break;
c5aa993b
JM
1619 do
1620 {
1621 *p++ = c;
1622 }
1623 while (c != '\n' && (c = getc (stream)) >= 0);
c906108c 1624
7be570e7
JM
1625#ifdef CRLF_SOURCE_FILES
1626 /* Remove the \r, if any, at the end of the line, otherwise
1627 regular expressions that end with $ or \n won't work. */
1628 if (p - buf > 1 && p[-2] == '\r')
1629 {
1630 p--;
1631 p[-1] = '\n';
1632 }
1633#endif
1634
c906108c
SS
1635 /* We now have a source line in buf; null terminate and match. */
1636 *p = 0;
1637 if (re_exec (buf) > 0)
1638 {
1639 /* Match! */
1640 fclose (stream);
c5aa993b
JM
1641 if (tui_version)
1642 print_source_lines_base (current_source_symtab, line, line + 1, 0);
1643 print_source_lines (current_source_symtab, line, line + 1, 0);
c906108c
SS
1644 set_internalvar (lookup_internalvar ("_"),
1645 value_from_longest (builtin_type_int,
1646 (LONGEST) line));
1647 current_source_line = max (line - lines_to_list / 2, 1);
1648 return;
1649 }
1650 line--;
1651 if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
1652 {
1653 fclose (stream);
1654 perror_with_name (current_source_symtab->filename);
1655 }
1656 }
1657
1658 printf_filtered ("Expression not found\n");
1659 fclose (stream);
1660 return;
1661}
1662\f
1663void
1664_initialize_source ()
1665{
1666 struct cmd_list_element *c;
1667 current_source_symtab = 0;
1668 init_source_path ();
1669
1670 /* The intention is to use POSIX Basic Regular Expressions.
1671 Always use the GNU regex routine for consistency across all hosts.
1672 Our current GNU regex.c does not have all the POSIX features, so this is
1673 just an approximation. */
1674 re_set_syntax (RE_SYNTAX_GREP);
1675
1676 c = add_cmd ("directory", class_files, directory_command,
c5aa993b 1677 "Add directory DIR to beginning of search path for source files.\n\
c906108c
SS
1678Forget cached info on source file locations and line positions.\n\
1679DIR can also be $cwd for the current working directory, or $cdir for the\n\
1680directory in which the source file was compiled into object code.\n\
1681With no argument, reset the search path to $cdir:$cwd, the default.",
1682 &cmdlist);
1683
1684 if (dbx_commands)
c5aa993b 1685 add_com_alias ("use", "directory", class_files, 0);
c906108c
SS
1686
1687 c->completer = filename_completer;
1688
1689 add_cmd ("directories", no_class, show_directories,
1690 "Current search path for finding source files.\n\
1691$cwd in the path means the current working directory.\n\
1692$cdir in the path means the compilation directory of the source file.",
1693 &showlist);
1694
1695 if (xdb_commands)
1696 {
c5aa993b 1697 add_com_alias ("D", "directory", class_files, 0);
c906108c 1698 add_cmd ("ld", no_class, show_directories,
c5aa993b 1699 "Current search path for finding source files.\n\
c906108c
SS
1700$cwd in the path means the current working directory.\n\
1701$cdir in the path means the compilation directory of the source file.",
c5aa993b 1702 &cmdlist);
c906108c
SS
1703 }
1704
1705 add_info ("source", source_info,
1706 "Information about the current source file.");
1707
1708 add_info ("line", line_info,
1709 concat ("Core addresses of the code for a source line.\n\
1710Line can be specified as\n\
1711 LINENUM, to list around that line in current file,\n\
1712 FILE:LINENUM, to list around that line in that file,\n\
1713 FUNCTION, to list around beginning of that function,\n\
1714 FILE:FUNCTION, to distinguish among like-named static functions.\n\
1715", "\
1716Default is to describe the last source line that was listed.\n\n\
1717This sets the default address for \"x\" to the line's first instruction\n\
1718so that \"x/i\" suffices to start examining the machine code.\n\
1719The address is also stored as the value of \"$_\".", NULL));
1720
1721 add_com ("forward-search", class_files, forward_search_command,
1722 "Search for regular expression (see regex(3)) from last line listed.\n\
1723The matching line number is also stored as the value of \"$_\".");
1724 add_com_alias ("search", "forward-search", class_files, 0);
1725
1726 add_com ("reverse-search", class_files, reverse_search_command,
1727 "Search backward for regular expression (see regex(3)) from last line listed.\n\
1728The matching line number is also stored as the value of \"$_\".");
1729
1730 if (xdb_commands)
1731 {
c5aa993b
JM
1732 add_com_alias ("/", "forward-search", class_files, 0);
1733 add_com_alias ("?", "reverse-search", class_files, 0);
c906108c
SS
1734 }
1735
1736 add_com ("list", class_files, list_command,
1737 concat ("List specified function or line.\n\
1738With no argument, lists ten more lines after or around previous listing.\n\
1739\"list -\" lists the ten lines before a previous ten-line listing.\n\
1740One argument specifies a line, and ten lines are listed around that line.\n\
1741Two arguments with comma between specify starting and ending lines to list.\n\
1742", "\
1743Lines can be specified in these ways:\n\
1744 LINENUM, to list around that line in current file,\n\
1745 FILE:LINENUM, to list around that line in that file,\n\
1746 FUNCTION, to list around beginning of that function,\n\
1747 FILE:FUNCTION, to distinguish among like-named static functions.\n\
1748 *ADDRESS, to list around the line containing that address.\n\
1749With two args if one is empty it stands for ten lines away from the other arg.", NULL));
1750
1751 if (!xdb_commands)
1752 add_com_alias ("l", "list", class_files, 1);
1753 else
1754 add_com_alias ("v", "list", class_files, 1);
1755
1756 if (dbx_commands)
1757 add_com_alias ("file", "list", class_files, 1);
1758
1759 add_show_from_set
1760 (add_set_cmd ("listsize", class_support, var_uinteger,
c5aa993b
JM
1761 (char *) &lines_to_list,
1762 "Set number of source lines gdb will list by default.",
c906108c
SS
1763 &setlist),
1764 &showlist);
1765}