119370Spst/* List lines of source files for GDB, the GNU debugger.
298944Sobrien   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
3130803Smarcel   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
419370Spst   Free Software Foundation, Inc.
519370Spst
698944Sobrien   This file is part of GDB.
719370Spst
898944Sobrien   This program is free software; you can redistribute it and/or modify
998944Sobrien   it under the terms of the GNU General Public License as published by
1098944Sobrien   the Free Software Foundation; either version 2 of the License, or
1198944Sobrien   (at your option) any later version.
1219370Spst
1398944Sobrien   This program is distributed in the hope that it will be useful,
1498944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien   GNU General Public License for more details.
1719370Spst
1898944Sobrien   You should have received a copy of the GNU General Public License
1998944Sobrien   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2219370Spst
2319370Spst#include "defs.h"
2419370Spst#include "symtab.h"
2519370Spst#include "expression.h"
2619370Spst#include "language.h"
2719370Spst#include "command.h"
2898944Sobrien#include "source.h"
2919370Spst#include "gdbcmd.h"
3019370Spst#include "frame.h"
3119370Spst#include "value.h"
3219370Spst
3319370Spst#include <sys/types.h>
3419370Spst#include "gdb_string.h"
3519370Spst#include "gdb_stat.h"
3619370Spst#include <fcntl.h>
3719370Spst#include "gdbcore.h"
3898944Sobrien#include "gdb_regex.h"
3919370Spst#include "symfile.h"
4019370Spst#include "objfiles.h"
4119370Spst#include "annotate.h"
4219370Spst#include "gdbtypes.h"
4398944Sobrien#include "linespec.h"
4498944Sobrien#include "filenames.h"		/* for DOSish file names */
4598944Sobrien#include "completer.h"
4698944Sobrien#include "ui-out.h"
47130803Smarcel#include "readline/readline.h"
4819370Spst
4946283Sdfr#ifdef CRLF_SOURCE_FILES
5046283Sdfr
5146283Sdfr/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
5246283Sdfr   host use \r\n rather than just \n.  Defining CRLF_SOURCE_FILES is
5346283Sdfr   much faster than defining LSEEK_NOT_LINEAR.  */
5446283Sdfr
5546283Sdfr#ifndef O_BINARY
5646283Sdfr#define O_BINARY 0
5746283Sdfr#endif
5846283Sdfr
5946283Sdfr#define OPEN_MODE (O_RDONLY | O_BINARY)
6046283Sdfr#define FDOPEN_MODE FOPEN_RB
6146283Sdfr
6246283Sdfr#else /* ! defined (CRLF_SOURCE_FILES) */
6346283Sdfr
6446283Sdfr#define OPEN_MODE O_RDONLY
6546283Sdfr#define FDOPEN_MODE FOPEN_RT
6646283Sdfr
6746283Sdfr#endif /* ! defined (CRLF_SOURCE_FILES) */
6846283Sdfr
6946283Sdfr/* Prototypes for exported functions. */
7046283Sdfr
7198944Sobrienvoid _initialize_source (void);
7246283Sdfr
7319370Spst/* Prototypes for local functions. */
7419370Spst
7598944Sobrienstatic int get_filename_and_charpos (struct symtab *, char **);
7619370Spst
7798944Sobrienstatic void reverse_search_command (char *, int);
7819370Spst
7998944Sobrienstatic void forward_search_command (char *, int);
8019370Spst
8198944Sobrienstatic void line_info (char *, int);
8219370Spst
8398944Sobrienstatic void source_info (char *, int);
8419370Spst
8598944Sobrienstatic void show_directories (char *, int);
8619370Spst
8719370Spst/* Path of directories to search for source files.
8819370Spst   Same format as the PATH environment variable's value.  */
8919370Spst
9019370Spstchar *source_path;
9119370Spst
9219370Spst/* Symtab of default file for listing lines of.  */
9319370Spst
94130803Smarcelstatic struct symtab *current_source_symtab;
9519370Spst
9619370Spst/* Default next line to list.  */
9719370Spst
98130803Smarcelstatic int current_source_line;
9919370Spst
10019370Spst/* Default number of lines to print with commands like "list".
10119370Spst   This is based on guessing how many long (i.e. more than chars_per_line
10219370Spst   characters) lines there will be.  To be completely correct, "list"
10319370Spst   and friends should be rewritten to count characters and see where
10419370Spst   things are wrapping, but that would be a fair amount of work.  */
10519370Spst
10619370Spstint lines_to_list = 10;
10719370Spst
10819370Spst/* Line number of last line printed.  Default for various commands.
10919370Spst   current_source_line is usually, but not always, the same as this.  */
11019370Spst
11119370Spststatic int last_line_listed;
11219370Spst
11319370Spst/* First line number listed by last listing command.  */
11419370Spst
11519370Spststatic int first_line_listed;
11619370Spst
11746283Sdfr/* Saves the name of the last source file visited and a possible error code.
11846283Sdfr   Used to prevent repeating annoying "No such file or directories" msgs */
11946283Sdfr
12046283Sdfrstatic struct symtab *last_source_visited = NULL;
12146283Sdfrstatic int last_source_error = 0;
12298944Sobrien
123130803Smarcel/* Return the first line listed by print_source_lines.
124130803Smarcel   Used by command interpreters to request listing from
125130803Smarcel   a previous point. */
12646283Sdfr
127130803Smarcelint
128130803Smarcelget_first_line_listed (void)
129130803Smarcel{
130130803Smarcel  return first_line_listed;
131130803Smarcel}
132130803Smarcel
133130803Smarcel/* Return the default number of lines to print with commands like the
134130803Smarcel   cli "list".  The caller of print_source_lines must use this to
135130803Smarcel   calculate the end line and use it in the call to print_source_lines
136130803Smarcel   as it does not automatically use this value. */
137130803Smarcel
138130803Smarcelint
139130803Smarcelget_lines_to_list (void)
140130803Smarcel{
141130803Smarcel  return lines_to_list;
142130803Smarcel}
143130803Smarcel
144130803Smarcel/* Return the current source file for listing and next line to list.
145130803Smarcel   NOTE: The returned sal pc and end fields are not valid. */
146130803Smarcel
147130803Smarcelstruct symtab_and_line
148130803Smarcelget_current_source_symtab_and_line (void)
149130803Smarcel{
150130803Smarcel  struct symtab_and_line cursal;
151130803Smarcel
152130803Smarcel  cursal.symtab = current_source_symtab;
153130803Smarcel  cursal.line = current_source_line;
154130803Smarcel  cursal.pc = 0;
155130803Smarcel  cursal.end = 0;
156130803Smarcel
157130803Smarcel  return cursal;
158130803Smarcel}
159130803Smarcel
160130803Smarcel/* If the current source file for listing is not set, try and get a default.
161130803Smarcel   Usually called before get_current_source_symtab_and_line() is called.
162130803Smarcel   It may err out if a default cannot be determined.
163130803Smarcel   We must be cautious about where it is called, as it can recurse as the
164130803Smarcel   process of determining a new default may call the caller!
165130803Smarcel   Use get_current_source_symtab_and_line only to get whatever
166130803Smarcel   we have without erroring out or trying to get a default. */
167130803Smarcel
168130803Smarcelvoid
169130803Smarcelset_default_source_symtab_and_line (void)
170130803Smarcel{
171130803Smarcel  struct symtab_and_line cursal;
172130803Smarcel
173130803Smarcel  if (!have_full_symbols () && !have_partial_symbols ())
174130803Smarcel    error ("No symbol table is loaded.  Use the \"file\" command.");
175130803Smarcel
176130803Smarcel  /* Pull in a current source symtab if necessary */
177130803Smarcel  if (current_source_symtab == 0)
178130803Smarcel    select_source_symtab (0);
179130803Smarcel}
180130803Smarcel
181130803Smarcel/* Return the current default file for listing and next line to list
182130803Smarcel   (the returned sal pc and end fields are not valid.)
183130803Smarcel   and set the current default to whatever is in SAL.
184130803Smarcel   NOTE: The returned sal pc and end fields are not valid. */
185130803Smarcel
186130803Smarcelstruct symtab_and_line
187130803Smarcelset_current_source_symtab_and_line (const struct symtab_and_line *sal)
188130803Smarcel{
189130803Smarcel  struct symtab_and_line cursal;
190130803Smarcel
191130803Smarcel  cursal.symtab = current_source_symtab;
192130803Smarcel  cursal.line = current_source_line;
193130803Smarcel
194130803Smarcel  current_source_symtab = sal->symtab;
195130803Smarcel  current_source_line = sal->line;
196130803Smarcel  cursal.pc = 0;
197130803Smarcel  cursal.end = 0;
198130803Smarcel
199130803Smarcel  return cursal;
200130803Smarcel}
201130803Smarcel
202130803Smarcel/* Reset any information stored about a default file and line to print. */
203130803Smarcel
204130803Smarcelvoid
205130803Smarcelclear_current_source_symtab_and_line (void)
206130803Smarcel{
207130803Smarcel  current_source_symtab = 0;
208130803Smarcel  current_source_line = 0;
209130803Smarcel}
210130803Smarcel
21119370Spst/* Set the source file default for the "list" command to be S.
21219370Spst
21319370Spst   If S is NULL, and we don't have a default, find one.  This
21419370Spst   should only be called when the user actually tries to use the
21519370Spst   default, since we produce an error if we can't find a reasonable
21619370Spst   default.  Also, since this can cause symbols to be read, doing it
21719370Spst   before we need to would make things slower than necessary.  */
21819370Spst
21919370Spstvoid
220130803Smarcelselect_source_symtab (struct symtab *s)
22119370Spst{
22219370Spst  struct symtabs_and_lines sals;
22319370Spst  struct symtab_and_line sal;
22419370Spst  struct partial_symtab *ps;
22519370Spst  struct partial_symtab *cs_pst = 0;
22619370Spst  struct objfile *ofp;
22798944Sobrien
22819370Spst  if (s)
22919370Spst    {
23019370Spst      current_source_symtab = s;
23119370Spst      current_source_line = 1;
23219370Spst      return;
23319370Spst    }
23419370Spst
23519370Spst  if (current_source_symtab)
23619370Spst    return;
23719370Spst
23819370Spst  /* Make the default place to list be the function `main'
23919370Spst     if one exists.  */
240130803Smarcel  if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0, NULL))
24119370Spst    {
24298944Sobrien      sals = decode_line_spec (main_name (), 1);
24319370Spst      sal = sals.sals[0];
24498944Sobrien      xfree (sals.sals);
24519370Spst      current_source_symtab = sal.symtab;
24619370Spst      current_source_line = max (sal.line - (lines_to_list - 1), 1);
24719370Spst      if (current_source_symtab)
24898944Sobrien	return;
24919370Spst    }
25098944Sobrien
25119370Spst  /* All right; find the last file in the symtab list (ignoring .h's).  */
25219370Spst
25319370Spst  current_source_line = 1;
25419370Spst
25598944Sobrien  for (ofp = object_files; ofp != NULL; ofp = ofp->next)
25619370Spst    {
25798944Sobrien      for (s = ofp->symtabs; s; s = s->next)
25819370Spst	{
25998944Sobrien	  char *name = s->filename;
26019370Spst	  int len = strlen (name);
261130803Smarcel	  if (!(len > 2 && (DEPRECATED_STREQ (&name[len - 2], ".h"))))
26219370Spst	    {
26319370Spst	      current_source_symtab = s;
26419370Spst	    }
26519370Spst	}
26619370Spst    }
26719370Spst  if (current_source_symtab)
26819370Spst    return;
26919370Spst
27019370Spst  /* Howabout the partial symbol tables? */
27119370Spst
27298944Sobrien  for (ofp = object_files; ofp != NULL; ofp = ofp->next)
27319370Spst    {
27498944Sobrien      for (ps = ofp->psymtabs; ps != NULL; ps = ps->next)
27519370Spst	{
27698944Sobrien	  char *name = ps->filename;
27719370Spst	  int len = strlen (name);
278130803Smarcel	  if (!(len > 2 && (DEPRECATED_STREQ (&name[len - 2], ".h"))))
27919370Spst	    {
28019370Spst	      cs_pst = ps;
28119370Spst	    }
28219370Spst	}
28319370Spst    }
28419370Spst  if (cs_pst)
28519370Spst    {
28698944Sobrien      if (cs_pst->readin)
28719370Spst	{
28898944Sobrien	  internal_error (__FILE__, __LINE__,
28998944Sobrien			  "select_source_symtab: "
29098944Sobrien			  "readin pst found and no symtabs.");
29119370Spst	}
29219370Spst      else
29319370Spst	{
29419370Spst	  current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
29519370Spst	}
29619370Spst    }
29746283Sdfr  if (current_source_symtab)
29846283Sdfr    return;
29919370Spst
30019370Spst  error ("Can't find a default source file");
30119370Spst}
30219370Spst
30319370Spststatic void
30498944Sobrienshow_directories (char *ignore, int from_tty)
30519370Spst{
30619370Spst  puts_filtered ("Source directories searched: ");
30719370Spst  puts_filtered (source_path);
30819370Spst  puts_filtered ("\n");
30919370Spst}
31019370Spst
31119370Spst/* Forget what we learned about line positions in source files, and
31219370Spst   which directories contain them; must check again now since files
31319370Spst   may be found in a different directory now.  */
31419370Spst
31519370Spstvoid
31698944Sobrienforget_cached_source_info (void)
31719370Spst{
318130803Smarcel  struct symtab *s;
319130803Smarcel  struct objfile *objfile;
32098944Sobrien  struct partial_symtab *pst;
32119370Spst
32298944Sobrien  for (objfile = object_files; objfile != NULL; objfile = objfile->next)
32319370Spst    {
32498944Sobrien      for (s = objfile->symtabs; s != NULL; s = s->next)
32519370Spst	{
32698944Sobrien	  if (s->line_charpos != NULL)
32719370Spst	    {
32898944Sobrien	      xmfree (objfile->md, s->line_charpos);
32998944Sobrien	      s->line_charpos = NULL;
33019370Spst	    }
33198944Sobrien	  if (s->fullname != NULL)
33219370Spst	    {
33398944Sobrien	      xmfree (objfile->md, s->fullname);
33498944Sobrien	      s->fullname = NULL;
33519370Spst	    }
33619370Spst	}
33798944Sobrien
33898944Sobrien      ALL_OBJFILE_PSYMTABS (objfile, pst)
33998944Sobrien      {
34098944Sobrien	if (pst->fullname != NULL)
34198944Sobrien	  {
34298944Sobrien	    xfree (pst->fullname);
34398944Sobrien	    pst->fullname = NULL;
34498944Sobrien	  }
34598944Sobrien      }
34619370Spst    }
34719370Spst}
34819370Spst
34919370Spstvoid
35098944Sobrieninit_source_path (void)
35119370Spst{
35219370Spst  char buf[20];
35319370Spst
35419370Spst  sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR);
35598944Sobrien  source_path = xstrdup (buf);
35619370Spst  forget_cached_source_info ();
35719370Spst}
35819370Spst
359130803Smarcelvoid
360130803Smarcelinit_last_source_visited (void)
361130803Smarcel{
362130803Smarcel  last_source_visited = NULL;
363130803Smarcel}
364130803Smarcel
36519370Spst/* Add zero or more directories to the front of the source path.  */
36698944Sobrien
36719370Spstvoid
36898944Sobriendirectory_command (char *dirname, int from_tty)
36919370Spst{
37019370Spst  dont_repeat ();
37119370Spst  /* FIXME, this goes to "delete dir"... */
37219370Spst  if (dirname == 0)
37319370Spst    {
37498944Sobrien      if (from_tty && query ("Reinitialize source path to empty? "))
37519370Spst	{
37698944Sobrien	  xfree (source_path);
37719370Spst	  init_source_path ();
37819370Spst	}
37919370Spst    }
38019370Spst  else
38146283Sdfr    {
38246283Sdfr      mod_path (dirname, &source_path);
38346283Sdfr      last_source_visited = NULL;
38446283Sdfr    }
38519370Spst  if (from_tty)
38698944Sobrien    show_directories ((char *) 0, from_tty);
38719370Spst  forget_cached_source_info ();
38819370Spst}
38919370Spst
39019370Spst/* Add zero or more directories to the front of an arbitrary path.  */
39119370Spst
39219370Spstvoid
39398944Sobrienmod_path (char *dirname, char **which_path)
39419370Spst{
395130803Smarcel  add_path (dirname, which_path, 1);
396130803Smarcel}
397130803Smarcel
398130803Smarcel/* Workhorse of mod_path.  Takes an extra argument to determine
399130803Smarcel   if dirname should be parsed for separators that indicate multiple
400130803Smarcel   directories.  This allows for interfaces that pre-parse the dirname
401130803Smarcel   and allow specification of traditional separator characters such
402130803Smarcel   as space or tab. */
403130803Smarcel
404130803Smarcelvoid
405130803Smarceladd_path (char *dirname, char **which_path, int parse_separators)
406130803Smarcel{
40719370Spst  char *old = *which_path;
40819370Spst  int prefix = 0;
40919370Spst
41019370Spst  if (dirname == 0)
41119370Spst    return;
41219370Spst
41398944Sobrien  dirname = xstrdup (dirname);
41498944Sobrien  make_cleanup (xfree, dirname);
41519370Spst
41619370Spst  do
41719370Spst    {
41819370Spst      char *name = dirname;
419130803Smarcel      char *p;
42019370Spst      struct stat st;
42119370Spst
42219370Spst      {
423130803Smarcel	char *separator = NULL;
424130803Smarcel	char *space = NULL;
425130803Smarcel	char *tab = NULL;
42619370Spst
427130803Smarcel	if (parse_separators)
428130803Smarcel	  {
429130803Smarcel	    separator = strchr (name, DIRNAME_SEPARATOR);
430130803Smarcel	    space = strchr (name, ' ');
431130803Smarcel	    tab = strchr (name, '\t');
432130803Smarcel	  }
433130803Smarcel
43498944Sobrien	if (separator == 0 && space == 0 && tab == 0)
43519370Spst	  p = dirname = name + strlen (name);
43619370Spst	else
43719370Spst	  {
43819370Spst	    p = 0;
43919370Spst	    if (separator != 0 && (p == 0 || separator < p))
44019370Spst	      p = separator;
44119370Spst	    if (space != 0 && (p == 0 || space < p))
44219370Spst	      p = space;
44319370Spst	    if (tab != 0 && (p == 0 || tab < p))
44419370Spst	      p = tab;
44519370Spst	    dirname = p + 1;
44619370Spst	    while (*dirname == DIRNAME_SEPARATOR
44719370Spst		   || *dirname == ' '
44819370Spst		   || *dirname == '\t')
44919370Spst	      ++dirname;
45019370Spst	  }
45119370Spst      }
45219370Spst
45398944Sobrien      if (!(IS_DIR_SEPARATOR (*name) && p <= name + 1)	 /* "/" */
45498944Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM
45598944Sobrien      /* On MS-DOS and MS-Windows, h:\ is different from h: */
45698944Sobrien	  && !(p == name + 3 && name[1] == ':') 	 /* "d:/" */
45798944Sobrien#endif
45898944Sobrien	  && IS_DIR_SEPARATOR (p[-1]))
45919370Spst	/* Sigh. "foo/" => "foo" */
46019370Spst	--p;
46119370Spst      *p = '\0';
46219370Spst
46398944Sobrien      while (p > name && p[-1] == '.')
46419370Spst	{
46519370Spst	  if (p - name == 1)
46619370Spst	    {
46719370Spst	      /* "." => getwd ().  */
46819370Spst	      name = current_directory;
46919370Spst	      goto append;
47019370Spst	    }
47198944Sobrien	  else if (p > name + 1 && IS_DIR_SEPARATOR (p[-2]))
47219370Spst	    {
47319370Spst	      if (p - name == 2)
47419370Spst		{
47519370Spst		  /* "/." => "/".  */
47619370Spst		  *--p = '\0';
47719370Spst		  goto append;
47819370Spst		}
47919370Spst	      else
48019370Spst		{
48119370Spst		  /* "...foo/." => "...foo".  */
48219370Spst		  p -= 2;
48319370Spst		  *p = '\0';
48419370Spst		  continue;
48519370Spst		}
48619370Spst	    }
48719370Spst	  else
48819370Spst	    break;
48919370Spst	}
49019370Spst
49119370Spst      if (name[0] == '~')
49219370Spst	name = tilde_expand (name);
49398944Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM
49498944Sobrien      else if (IS_ABSOLUTE_PATH (name) && p == name + 2) /* "d:" => "d:." */
49598944Sobrien	name = concat (name, ".", NULL);
49698944Sobrien#endif
49798944Sobrien      else if (!IS_ABSOLUTE_PATH (name) && name[0] != '$')
49898944Sobrien	name = concat (current_directory, SLASH_STRING, name, NULL);
49919370Spst      else
50019370Spst	name = savestring (name, p - name);
50198944Sobrien      make_cleanup (xfree, name);
50219370Spst
50319370Spst      /* Unless it's a variable, check existence.  */
50498944Sobrien      if (name[0] != '$')
50598944Sobrien	{
50698944Sobrien	  /* These are warnings, not errors, since we don't want a
50798944Sobrien	     non-existent directory in a .gdbinit file to stop processing
50898944Sobrien	     of the .gdbinit file.
50919370Spst
51098944Sobrien	     Whether they get added to the path is more debatable.  Current
51198944Sobrien	     answer is yes, in case the user wants to go make the directory
51298944Sobrien	     or whatever.  If the directory continues to not exist/not be
51398944Sobrien	     a directory/etc, then having them in the path should be
51498944Sobrien	     harmless.  */
51598944Sobrien	  if (stat (name, &st) < 0)
51698944Sobrien	    {
51798944Sobrien	      int save_errno = errno;
51898944Sobrien	      fprintf_unfiltered (gdb_stderr, "Warning: ");
51998944Sobrien	      print_sys_errmsg (name, save_errno);
52098944Sobrien	    }
52198944Sobrien	  else if ((st.st_mode & S_IFMT) != S_IFDIR)
52298944Sobrien	    warning ("%s is not a directory.", name);
52398944Sobrien	}
52419370Spst
52519370Spst    append:
52619370Spst      {
527130803Smarcel	unsigned int len = strlen (name);
52819370Spst
52919370Spst	p = *which_path;
53019370Spst	while (1)
53119370Spst	  {
53298944Sobrien	    /* FIXME: strncmp loses in interesting ways on MS-DOS and
53398944Sobrien	       MS-Windows because of case-insensitivity and two different
53498944Sobrien	       but functionally identical slash characters.  We need a
53598944Sobrien	       special filesystem-dependent file-name comparison function.
53698944Sobrien
53798944Sobrien	       Actually, even on Unix I would use realpath() or its work-
53898944Sobrien	       alike before comparing.  Then all the code above which
53998944Sobrien	       removes excess slashes and dots could simply go away.  */
54019370Spst	    if (!strncmp (p, name, len)
54119370Spst		&& (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR))
54219370Spst	      {
54319370Spst		/* Found it in the search path, remove old copy */
54419370Spst		if (p > *which_path)
54598944Sobrien		  p--;		/* Back over leading separator */
54619370Spst		if (prefix > p - *which_path)
54719370Spst		  goto skip_dup;	/* Same dir twice in one cmd */
54898944Sobrien		strcpy (p, &p[len + 1]);	/* Copy from next \0 or  : */
54919370Spst	      }
55019370Spst	    p = strchr (p, DIRNAME_SEPARATOR);
55119370Spst	    if (p != 0)
55219370Spst	      ++p;
55319370Spst	    else
55419370Spst	      break;
55519370Spst	  }
55619370Spst	if (p == 0)
55719370Spst	  {
55819370Spst	    char tinybuf[2];
55919370Spst
56019370Spst	    tinybuf[0] = DIRNAME_SEPARATOR;
56119370Spst	    tinybuf[1] = '\0';
56219370Spst
563130803Smarcel	    /* If we have already tacked on a name(s) in this command, be sure they stay
564130803Smarcel	       on the front as we tack on some more.  */
56519370Spst	    if (prefix)
56619370Spst	      {
56719370Spst		char *temp, c;
56819370Spst
56919370Spst		c = old[prefix];
57019370Spst		old[prefix] = '\0';
57119370Spst		temp = concat (old, tinybuf, name, NULL);
57219370Spst		old[prefix] = c;
57319370Spst		*which_path = concat (temp, "", &old[prefix], NULL);
57419370Spst		prefix = strlen (temp);
57598944Sobrien		xfree (temp);
57619370Spst	      }
57719370Spst	    else
57819370Spst	      {
57919370Spst		*which_path = concat (name, (old[0] ? tinybuf : old), old, NULL);
58019370Spst		prefix = strlen (name);
58119370Spst	      }
58298944Sobrien	    xfree (old);
58319370Spst	    old = *which_path;
58419370Spst	  }
58519370Spst      }
58698944Sobrien    skip_dup:;
58798944Sobrien    }
58898944Sobrien  while (*dirname != '\0');
58919370Spst}
59019370Spst
59119370Spst
59219370Spststatic void
59398944Sobriensource_info (char *ignore, int from_tty)
59419370Spst{
595130803Smarcel  struct symtab *s = current_source_symtab;
59619370Spst
59719370Spst  if (!s)
59819370Spst    {
59998944Sobrien      printf_filtered ("No current source file.\n");
60019370Spst      return;
60119370Spst    }
60219370Spst  printf_filtered ("Current source file is %s\n", s->filename);
60319370Spst  if (s->dirname)
60419370Spst    printf_filtered ("Compilation directory is %s\n", s->dirname);
60519370Spst  if (s->fullname)
60619370Spst    printf_filtered ("Located in %s\n", s->fullname);
60719370Spst  if (s->nlines)
60819370Spst    printf_filtered ("Contains %d line%s.\n", s->nlines,
60919370Spst		     s->nlines == 1 ? "" : "s");
61019370Spst
61146283Sdfr  printf_filtered ("Source language is %s.\n", language_str (s->language));
61246283Sdfr  printf_filtered ("Compiled with %s debugging format.\n", s->debugformat);
613130803Smarcel  printf_filtered ("%s preprocessor macro info.\n",
614130803Smarcel                   s->macro_table ? "Includes" : "Does not include");
61519370Spst}
61698944Sobrien
61719370Spst
618130803Smarcel/* Return True if the file NAME exists and is a regular file */
619130803Smarcelstatic int
620130803Smarcelis_regular_file (const char *name)
621130803Smarcel{
622130803Smarcel  struct stat st;
623130803Smarcel  const int status = stat (name, &st);
62419370Spst
625130803Smarcel  /* Stat should never fail except when the file does not exist.
626130803Smarcel     If stat fails, analyze the source of error and return True
627130803Smarcel     unless the file does not exist, to avoid returning false results
628130803Smarcel     on obscure systems where stat does not work as expected.
629130803Smarcel   */
630130803Smarcel  if (status != 0)
631130803Smarcel    return (errno != ENOENT);
632130803Smarcel
633130803Smarcel  return S_ISREG (st.st_mode);
634130803Smarcel}
635130803Smarcel
63619370Spst/* Open a file named STRING, searching path PATH (dir names sep by some char)
63719370Spst   using mode MODE and protection bits PROT in the calls to open.
63819370Spst
63919370Spst   If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
64019370Spst   (ie pretend the first element of PATH is ".").  This also indicates
64119370Spst   that a slash in STRING disables searching of the path (this is
64219370Spst   so that "exec-file ./foo" or "symbol-file ./foo" insures that you
64319370Spst   get that particular version of foo or an error message).
64419370Spst
64598944Sobrien   If FILENAME_OPENED is non-null, set it to a newly allocated string naming
646130803Smarcel   the actual file opened (this string will always start with a "/").  We
64719370Spst   have to take special pains to avoid doubling the "/" between the directory
64819370Spst   and the file, sigh!  Emacs gets confuzzed by this when we print the
64919370Spst   source file name!!!
65019370Spst
65119370Spst   If a file is found, return the descriptor.
65219370Spst   Otherwise, return -1, with errno set for the last name we tried to open.  */
65319370Spst
65419370Spst/*  >>>> This should only allow files of certain types,
655130803Smarcel    >>>>  eg executable, non-directory */
65619370Spstint
65798944Sobrienopenp (const char *path, int try_cwd_first, const char *string,
65898944Sobrien       int mode, int prot,
65998944Sobrien       char **filename_opened)
66019370Spst{
661130803Smarcel  int fd;
662130803Smarcel  char *filename;
66398944Sobrien  const char *p;
66498944Sobrien  const char *p1;
665130803Smarcel  int len;
66619370Spst  int alloclen;
66719370Spst
66819370Spst  if (!path)
66919370Spst    path = ".";
67019370Spst
67198944Sobrien#if defined(_WIN32) || defined(__CYGWIN__)
67219370Spst  mode |= O_BINARY;
67319370Spst#endif
67419370Spst
67598944Sobrien  if (try_cwd_first || IS_ABSOLUTE_PATH (string))
67619370Spst    {
67719370Spst      int i;
678130803Smarcel
679130803Smarcel      if (is_regular_file (string))
680130803Smarcel	{
681130803Smarcel	  filename = alloca (strlen (string) + 1);
682130803Smarcel	  strcpy (filename, string);
683130803Smarcel	  fd = open (filename, mode, prot);
684130803Smarcel	  if (fd >= 0)
685130803Smarcel	    goto done;
686130803Smarcel	}
687130803Smarcel      else
688130803Smarcel	{
689130803Smarcel	  filename = NULL;
690130803Smarcel	  fd = -1;
691130803Smarcel	}
692130803Smarcel
69319370Spst      for (i = 0; string[i]; i++)
69498944Sobrien	if (IS_DIR_SEPARATOR (string[i]))
69519370Spst	  goto done;
69619370Spst    }
69719370Spst
69819370Spst  /* ./foo => foo */
69998944Sobrien  while (string[0] == '.' && IS_DIR_SEPARATOR (string[1]))
70019370Spst    string += 2;
70119370Spst
70219370Spst  alloclen = strlen (path) + strlen (string) + 2;
70398944Sobrien  filename = alloca (alloclen);
70419370Spst  fd = -1;
70519370Spst  for (p = path; p; p = p1 ? p1 + 1 : 0)
70619370Spst    {
70798944Sobrien      p1 = strchr (p, DIRNAME_SEPARATOR);
70819370Spst      if (p1)
70919370Spst	len = p1 - p;
71019370Spst      else
71119370Spst	len = strlen (p);
71219370Spst
71319370Spst      if (len == 4 && p[0] == '$' && p[1] == 'c'
71498944Sobrien	  && p[2] == 'w' && p[3] == 'd')
71598944Sobrien	{
71698944Sobrien	  /* Name is $cwd -- insert current directory name instead.  */
71798944Sobrien	  int newlen;
71819370Spst
71998944Sobrien	  /* First, realloc the filename buffer if too short. */
72098944Sobrien	  len = strlen (current_directory);
72198944Sobrien	  newlen = len + strlen (string) + 2;
72298944Sobrien	  if (newlen > alloclen)
72398944Sobrien	    {
72498944Sobrien	      alloclen = newlen;
72598944Sobrien	      filename = alloca (alloclen);
72698944Sobrien	    }
72798944Sobrien	  strcpy (filename, current_directory);
72819370Spst	}
72998944Sobrien      else
73098944Sobrien	{
73198944Sobrien	  /* Normal file name in path -- just use it.  */
73298944Sobrien	  strncpy (filename, p, len);
73398944Sobrien	  filename[len] = 0;
73498944Sobrien	}
73519370Spst
73619370Spst      /* Remove trailing slashes */
73798944Sobrien      while (len > 0 && IS_DIR_SEPARATOR (filename[len - 1]))
73819370Spst	filename[--len] = 0;
73919370Spst
74098944Sobrien      strcat (filename + len, SLASH_STRING);
74119370Spst      strcat (filename, string);
74219370Spst
743130803Smarcel      if (is_regular_file (filename))
744130803Smarcel      {
745130803Smarcel        fd = open (filename, mode);
746130803Smarcel        if (fd >= 0)
747130803Smarcel          break;
748130803Smarcel      }
74919370Spst    }
75019370Spst
75198944Sobriendone:
75219370Spst  if (filename_opened)
75319370Spst    {
754130803Smarcel      /* If a file was opened, canonicalize its filename. Use xfullpath
755130803Smarcel         rather than gdb_realpath to avoid resolving the basename part
756130803Smarcel         of filenames when the associated file is a symbolic link. This
757130803Smarcel         fixes a potential inconsistency between the filenames known to
758130803Smarcel         GDB and the filenames it prints in the annotations.  */
75919370Spst      if (fd < 0)
76098944Sobrien	*filename_opened = NULL;
76198944Sobrien      else if (IS_ABSOLUTE_PATH (filename))
762130803Smarcel	*filename_opened = xfullpath (filename);
76319370Spst      else
76419370Spst	{
76519370Spst	  /* Beware the // my son, the Emacs barfs, the botch that catch... */
76698944Sobrien
76798944Sobrien	  char *f = concat (current_directory,
76898944Sobrien           IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
76998944Sobrien				     ? "" : SLASH_STRING,
77019370Spst				     filename, NULL);
771130803Smarcel	  *filename_opened = xfullpath (f);
77298944Sobrien	  xfree (f);
77398944Sobrien	}
77419370Spst    }
77519370Spst
77619370Spst  return fd;
77719370Spst}
77819370Spst
77998944Sobrien
78046283Sdfr/* This is essentially a convenience, for clients that want the behaviour
78146283Sdfr   of openp, using source_path, but that really don't want the file to be
78246283Sdfr   opened but want instead just to know what the full pathname is (as
78346283Sdfr   qualified against source_path).
78446283Sdfr
78546283Sdfr   The current working directory is searched first.
78646283Sdfr
78746283Sdfr   If the file was found, this function returns 1, and FULL_PATHNAME is
78846283Sdfr   set to the fully-qualified pathname.
78946283Sdfr
79046283Sdfr   Else, this functions returns 0, and FULL_PATHNAME is set to NULL.
79198944Sobrien */
79246283Sdfrint
79398944Sobriensource_full_path_of (char *filename, char **full_pathname)
79446283Sdfr{
79598944Sobrien  int fd;
79646283Sdfr
79746283Sdfr  fd = openp (source_path, 1, filename, O_RDONLY, 0, full_pathname);
79846283Sdfr  if (fd < 0)
79946283Sdfr    {
80046283Sdfr      *full_pathname = NULL;
80146283Sdfr      return 0;
80246283Sdfr    }
80346283Sdfr
80446283Sdfr  close (fd);
80546283Sdfr  return 1;
80646283Sdfr}
80746283Sdfr
80846283Sdfr
80919370Spst/* Open a source file given a symtab S.  Returns a file descriptor or
81019370Spst   negative number for error.  */
81119370Spst
81246283Sdfrint
81398944Sobrienopen_source_file (struct symtab *s)
81419370Spst{
81519370Spst  char *path = source_path;
81698944Sobrien  const char *p;
81719370Spst  int result;
81819370Spst  char *fullname;
81919370Spst
82019370Spst  /* Quick way out if we already know its full name */
82198944Sobrien  if (s->fullname)
82219370Spst    {
82346283Sdfr      result = open (s->fullname, OPEN_MODE);
82419370Spst      if (result >= 0)
82598944Sobrien	return result;
82619370Spst      /* Didn't work -- free old one, try again. */
82798944Sobrien      xmfree (s->objfile->md, s->fullname);
82819370Spst      s->fullname = NULL;
82919370Spst    }
83019370Spst
83119370Spst  if (s->dirname != NULL)
83219370Spst    {
83319370Spst      /* Replace a path entry of  $cdir  with the compilation directory name */
83419370Spst#define	cdir_len	5
83519370Spst      /* We cast strstr's result in case an ANSIhole has made it const,
83698944Sobrien         which produces a "required warning" when assigned to a nonconst. */
83798944Sobrien      p = (char *) strstr (source_path, "$cdir");
83819370Spst      if (p && (p == path || p[-1] == DIRNAME_SEPARATOR)
83998944Sobrien	  && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0'))
84019370Spst	{
84119370Spst	  int len;
84219370Spst
84319370Spst	  path = (char *)
84419370Spst	    alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
84519370Spst	  len = p - source_path;
84698944Sobrien	  strncpy (path, source_path, len);	/* Before $cdir */
84798944Sobrien	  strcpy (path + len, s->dirname);	/* new stuff */
84898944Sobrien	  strcat (path + len, source_path + len + cdir_len);	/* After $cdir */
84919370Spst	}
85019370Spst    }
85119370Spst
85246283Sdfr  result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
85319370Spst  if (result < 0)
85419370Spst    {
85519370Spst      /* Didn't work.  Try using just the basename. */
85698944Sobrien      p = lbasename (s->filename);
85719370Spst      if (p != s->filename)
85846283Sdfr	result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
85919370Spst    }
86019370Spst
86119370Spst  if (result >= 0)
86219370Spst    {
86319370Spst      fullname = s->fullname;
86419370Spst      s->fullname = mstrsave (s->objfile->md, s->fullname);
86598944Sobrien      xfree (fullname);
86619370Spst    }
86719370Spst  return result;
86819370Spst}
86919370Spst
87019370Spst/* Return the path to the source file associated with symtab.  Returns NULL
87119370Spst   if no symtab.  */
87219370Spst
87319370Spstchar *
87498944Sobriensymtab_to_filename (struct symtab *s)
87519370Spst{
87619370Spst  int fd;
87719370Spst
87819370Spst  if (!s)
87919370Spst    return NULL;
88019370Spst
88119370Spst  /* If we've seen the file before, just return fullname. */
88219370Spst
88319370Spst  if (s->fullname)
88419370Spst    return s->fullname;
88519370Spst
88619370Spst  /* Try opening the file to setup fullname */
88719370Spst
88819370Spst  fd = open_source_file (s);
88919370Spst  if (fd < 0)
89019370Spst    return s->filename;		/* File not found.  Just use short name */
89119370Spst
89219370Spst  /* Found the file.  Cleanup and return the full name */
89319370Spst
89419370Spst  close (fd);
89519370Spst  return s->fullname;
89619370Spst}
89798944Sobrien
89819370Spst
89919370Spst/* Create and initialize the table S->line_charpos that records
90019370Spst   the positions of the lines in the source file, which is assumed
90119370Spst   to be open on descriptor DESC.
90219370Spst   All set S->nlines to the number of such lines.  */
90319370Spst
90446283Sdfrvoid
90598944Sobrienfind_source_lines (struct symtab *s, int desc)
90619370Spst{
90719370Spst  struct stat st;
908130803Smarcel  char *data, *p, *end;
90919370Spst  int nlines = 0;
91019370Spst  int lines_allocated = 1000;
91119370Spst  int *line_charpos;
91246283Sdfr  long mtime = 0;
91319370Spst  int size;
91419370Spst
91598944Sobrien  line_charpos = (int *) xmmalloc (s->objfile->md,
91619370Spst				   lines_allocated * sizeof (int));
91719370Spst  if (fstat (desc, &st) < 0)
91819370Spst    perror_with_name (s->filename);
91919370Spst
92046283Sdfr  if (s && s->objfile && s->objfile->obfd)
92198944Sobrien    mtime = bfd_get_mtime (s->objfile->obfd);
92246283Sdfr  else if (exec_bfd)
92398944Sobrien    mtime = bfd_get_mtime (exec_bfd);
92446283Sdfr
92546283Sdfr  if (mtime && mtime < st.st_mtime)
92619370Spst    {
92798944Sobrien      warning ("Source file is more recent than executable.\n");
92819370Spst    }
92919370Spst
93019370Spst#ifdef LSEEK_NOT_LINEAR
93119370Spst  {
93219370Spst    char c;
93319370Spst
93419370Spst    /* Have to read it byte by byte to find out where the chars live */
93519370Spst
93619370Spst    line_charpos[0] = lseek (desc, 0, SEEK_CUR);
93719370Spst    nlines = 1;
93898944Sobrien    while (myread (desc, &c, 1) > 0)
93919370Spst      {
94098944Sobrien	if (c == '\n')
94119370Spst	  {
94298944Sobrien	    if (nlines == lines_allocated)
94319370Spst	      {
94419370Spst		lines_allocated *= 2;
94519370Spst		line_charpos =
94698944Sobrien		  (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
94719370Spst				     sizeof (int) * lines_allocated);
94819370Spst	      }
94919370Spst	    line_charpos[nlines++] = lseek (desc, 0, SEEK_CUR);
95019370Spst	  }
95119370Spst      }
95219370Spst  }
95319370Spst#else /* lseek linear.  */
95419370Spst  {
95519370Spst    struct cleanup *old_cleanups;
95619370Spst
95719370Spst    /* st_size might be a large type, but we only support source files whose
95819370Spst       size fits in an int.  */
95919370Spst    size = (int) st.st_size;
96019370Spst
96119370Spst    /* Use malloc, not alloca, because this may be pretty large, and we may
96219370Spst       run into various kinds of limits on stack size.  */
96319370Spst    data = (char *) xmalloc (size);
96498944Sobrien    old_cleanups = make_cleanup (xfree, data);
96519370Spst
96646283Sdfr    /* Reassign `size' to result of read for systems where \r\n -> \n.  */
96746283Sdfr    size = myread (desc, data, size);
96846283Sdfr    if (size < 0)
96919370Spst      perror_with_name (s->filename);
97019370Spst    end = data + size;
97119370Spst    p = data;
97219370Spst    line_charpos[0] = 0;
97319370Spst    nlines = 1;
97419370Spst    while (p != end)
97519370Spst      {
97619370Spst	if (*p++ == '\n'
97798944Sobrien	/* A newline at the end does not start a new line.  */
97819370Spst	    && p != end)
97919370Spst	  {
98019370Spst	    if (nlines == lines_allocated)
98119370Spst	      {
98219370Spst		lines_allocated *= 2;
98319370Spst		line_charpos =
98498944Sobrien		  (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
98519370Spst				     sizeof (int) * lines_allocated);
98619370Spst	      }
98719370Spst	    line_charpos[nlines++] = p - data;
98819370Spst	  }
98919370Spst      }
99019370Spst    do_cleanups (old_cleanups);
99119370Spst  }
99219370Spst#endif /* lseek linear.  */
99319370Spst  s->nlines = nlines;
99419370Spst  s->line_charpos =
99598944Sobrien    (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
99698944Sobrien		       nlines * sizeof (int));
99719370Spst
99819370Spst}
99919370Spst
100019370Spst/* Return the character position of a line LINE in symtab S.
100119370Spst   Return 0 if anything is invalid.  */
100219370Spst
100398944Sobrien#if 0				/* Currently unused */
100419370Spst
100519370Spstint
100698944Sobriensource_line_charpos (struct symtab *s, int line)
100719370Spst{
100898944Sobrien  if (!s)
100998944Sobrien    return 0;
101098944Sobrien  if (!s->line_charpos || line <= 0)
101198944Sobrien    return 0;
101219370Spst  if (line > s->nlines)
101319370Spst    line = s->nlines;
101419370Spst  return s->line_charpos[line - 1];
101519370Spst}
101619370Spst
101719370Spst/* Return the line number of character position POS in symtab S.  */
101819370Spst
101919370Spstint
1020130803Smarcelsource_charpos_line (struct symtab *s, int chr)
102119370Spst{
1022130803Smarcel  int line = 0;
1023130803Smarcel  int *lnp;
102498944Sobrien
102598944Sobrien  if (s == 0 || s->line_charpos == 0)
102698944Sobrien    return 0;
102719370Spst  lnp = s->line_charpos;
102819370Spst  /* Files are usually short, so sequential search is Ok */
102998944Sobrien  while (line < s->nlines && *lnp <= chr)
103019370Spst    {
103119370Spst      line++;
103219370Spst      lnp++;
103319370Spst    }
103419370Spst  if (line >= s->nlines)
103519370Spst    line = s->nlines;
103619370Spst  return line;
103719370Spst}
103819370Spst
103998944Sobrien#endif /* 0 */
104098944Sobrien
104119370Spst
104219370Spst/* Get full pathname and line number positions for a symtab.
104319370Spst   Return nonzero if line numbers may have changed.
104419370Spst   Set *FULLNAME to actual name of the file as found by `openp',
104519370Spst   or to 0 if the file is not found.  */
104619370Spst
104719370Spststatic int
104898944Sobrienget_filename_and_charpos (struct symtab *s, char **fullname)
104919370Spst{
1050130803Smarcel  int desc, linenums_changed = 0;
105198944Sobrien
105219370Spst  desc = open_source_file (s);
105319370Spst  if (desc < 0)
105419370Spst    {
105519370Spst      if (fullname)
105619370Spst	*fullname = NULL;
105719370Spst      return 0;
105898944Sobrien    }
105919370Spst  if (fullname)
106019370Spst    *fullname = s->fullname;
106198944Sobrien  if (s->line_charpos == 0)
106298944Sobrien    linenums_changed = 1;
106398944Sobrien  if (linenums_changed)
106498944Sobrien    find_source_lines (s, desc);
106519370Spst  close (desc);
106619370Spst  return linenums_changed;
106719370Spst}
106819370Spst
106919370Spst/* Print text describing the full name of the source file S
107019370Spst   and the line number LINE and its corresponding character position.
107119370Spst   The text starts with two Ctrl-z so that the Emacs-GDB interface
107219370Spst   can easily find it.
107319370Spst
107419370Spst   MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
107519370Spst
107619370Spst   Return 1 if successful, 0 if could not find the file.  */
107719370Spst
107819370Spstint
107998944Sobrienidentify_source_line (struct symtab *s, int line, int mid_statement,
108098944Sobrien		      CORE_ADDR pc)
108119370Spst{
108219370Spst  if (s->line_charpos == 0)
108398944Sobrien    get_filename_and_charpos (s, (char **) NULL);
108419370Spst  if (s->fullname == 0)
108519370Spst    return 0;
108619370Spst  if (line > s->nlines)
108719370Spst    /* Don't index off the end of the line_charpos array.  */
108819370Spst    return 0;
108919370Spst  annotate_source (s->fullname, line, s->line_charpos[line - 1],
109019370Spst		   mid_statement, pc);
109119370Spst
109219370Spst  current_source_line = line;
109319370Spst  first_line_listed = line;
109419370Spst  last_line_listed = line;
109519370Spst  current_source_symtab = s;
109619370Spst  return 1;
109719370Spst}
109898944Sobrien
109946283Sdfr
110019370Spst/* Print source lines from the file of symtab S,
110146283Sdfr   starting with line number LINE and stopping before line number STOPLINE. */
110219370Spst
110398944Sobrienstatic void print_source_lines_base (struct symtab *s, int line, int stopline,
110498944Sobrien				     int noerror);
110546283Sdfrstatic void
110698944Sobrienprint_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
110719370Spst{
1108130803Smarcel  int c;
1109130803Smarcel  int desc;
1110130803Smarcel  FILE *stream;
111119370Spst  int nlines = stopline - line;
111219370Spst
111319370Spst  /* Regardless of whether we can open the file, set current_source_symtab. */
111419370Spst  current_source_symtab = s;
111519370Spst  current_source_line = line;
111619370Spst  first_line_listed = line;
111719370Spst
111898944Sobrien  /* If printing of source lines is disabled, just print file and line number */
111998944Sobrien  if (ui_out_test_flags (uiout, ui_source_list))
112046283Sdfr    {
112198944Sobrien      /* Only prints "No such file or directory" once */
112298944Sobrien      if ((s != last_source_visited) || (!last_source_error))
112398944Sobrien	{
112498944Sobrien	  last_source_visited = s;
112598944Sobrien	  desc = open_source_file (s);
112698944Sobrien	}
112798944Sobrien      else
112898944Sobrien	{
112998944Sobrien	  desc = last_source_error;
113098944Sobrien	  noerror = 1;
113198944Sobrien	}
113246283Sdfr    }
113346283Sdfr  else
113446283Sdfr    {
113598944Sobrien      desc = -1;
113646283Sdfr      noerror = 1;
113746283Sdfr    }
113846283Sdfr
113919370Spst  if (desc < 0)
114019370Spst    {
114146283Sdfr      last_source_error = desc;
114246283Sdfr
114398944Sobrien      if (!noerror)
114498944Sobrien	{
114546283Sdfr	  char *name = alloca (strlen (s->filename) + 100);
114646283Sdfr	  sprintf (name, "%d\t%s", line, s->filename);
114746283Sdfr	  print_sys_errmsg (name, errno);
114846283Sdfr	}
114946283Sdfr      else
115098944Sobrien	ui_out_field_int (uiout, "line", line);
115198944Sobrien      ui_out_text (uiout, "\tin ");
115298944Sobrien      ui_out_field_string (uiout, "file", s->filename);
115398944Sobrien      ui_out_text (uiout, "\n");
115446283Sdfr
115519370Spst      return;
115619370Spst    }
115719370Spst
115846283Sdfr  last_source_error = 0;
115946283Sdfr
116019370Spst  if (s->line_charpos == 0)
116119370Spst    find_source_lines (s, desc);
116219370Spst
116319370Spst  if (line < 1 || line > s->nlines)
116419370Spst    {
116519370Spst      close (desc);
116619370Spst      error ("Line number %d out of range; %s has %d lines.",
116719370Spst	     line, s->filename, s->nlines);
116819370Spst    }
116919370Spst
117019370Spst  if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
117119370Spst    {
117219370Spst      close (desc);
117319370Spst      perror_with_name (s->filename);
117419370Spst    }
117519370Spst
117646283Sdfr  stream = fdopen (desc, FDOPEN_MODE);
117719370Spst  clearerr (stream);
117819370Spst
117919370Spst  while (nlines-- > 0)
118019370Spst    {
118198944Sobrien      char buf[20];
118298944Sobrien
118319370Spst      c = fgetc (stream);
118498944Sobrien      if (c == EOF)
118598944Sobrien	break;
118619370Spst      last_line_listed = current_source_line;
118798944Sobrien      sprintf (buf, "%d\t", current_source_line++);
118898944Sobrien      ui_out_text (uiout, buf);
118919370Spst      do
119019370Spst	{
119119370Spst	  if (c < 040 && c != '\t' && c != '\n' && c != '\r')
119298944Sobrien	    {
119398944Sobrien	      sprintf (buf, "^%c", c + 0100);
119498944Sobrien	      ui_out_text (uiout, buf);
119598944Sobrien	    }
119619370Spst	  else if (c == 0177)
119798944Sobrien	    ui_out_text (uiout, "^?");
119846283Sdfr#ifdef CRLF_SOURCE_FILES
119946283Sdfr	  else if (c == '\r')
120046283Sdfr	    {
120198944Sobrien	      /* Skip a \r character, but only before a \n.  */
120298944Sobrien	      int c1 = fgetc (stream);
120398944Sobrien
120498944Sobrien	      if (c1 != '\n')
120598944Sobrien		printf_filtered ("^%c", c + 0100);
120698944Sobrien	      if (c1 != EOF)
120798944Sobrien		ungetc (c1, stream);
120846283Sdfr	    }
120946283Sdfr#endif
121019370Spst	  else
121198944Sobrien	    {
121298944Sobrien	      sprintf (buf, "%c", c);
121398944Sobrien	      ui_out_text (uiout, buf);
121498944Sobrien	    }
121598944Sobrien	}
121698944Sobrien      while (c != '\n' && (c = fgetc (stream)) >= 0);
121719370Spst    }
121819370Spst
121919370Spst  fclose (stream);
122019370Spst}
122119370Spst
122246283Sdfr/* Show source lines from the file of symtab S, starting with line
122346283Sdfr   number LINE and stopping before line number STOPLINE.  If this is the
122446283Sdfr   not the command line version, then the source is shown in the source
122546283Sdfr   window otherwise it is simply printed */
122619370Spst
122798944Sobrienvoid
122898944Sobrienprint_source_lines (struct symtab *s, int line, int stopline, int noerror)
122946283Sdfr{
123098944Sobrien  print_source_lines_base (s, line, stopline, noerror);
123146283Sdfr}
123246283Sdfr
123319370Spst/* Print info on range of pc's in a specified line.  */
123419370Spst
123519370Spststatic void
123698944Sobrienline_info (char *arg, int from_tty)
123719370Spst{
123819370Spst  struct symtabs_and_lines sals;
123919370Spst  struct symtab_and_line sal;
124019370Spst  CORE_ADDR start_pc, end_pc;
124119370Spst  int i;
124219370Spst
1243130803Smarcel  init_sal (&sal);		/* initialize to zeroes */
124446283Sdfr
124519370Spst  if (arg == 0)
124619370Spst    {
124719370Spst      sal.symtab = current_source_symtab;
124819370Spst      sal.line = last_line_listed;
124919370Spst      sals.nelts = 1;
125019370Spst      sals.sals = (struct symtab_and_line *)
125119370Spst	xmalloc (sizeof (struct symtab_and_line));
125219370Spst      sals.sals[0] = sal;
125319370Spst    }
125419370Spst  else
125519370Spst    {
125619370Spst      sals = decode_line_spec_1 (arg, 0);
125798944Sobrien
125819370Spst      dont_repeat ();
125919370Spst    }
126019370Spst
126119370Spst  /* C++  More than one line may have been specified, as when the user
126219370Spst     specifies an overloaded function name. Print info on them all. */
126319370Spst  for (i = 0; i < sals.nelts; i++)
126419370Spst    {
126519370Spst      sal = sals.sals[i];
126698944Sobrien
126719370Spst      if (sal.symtab == 0)
126819370Spst	{
126919370Spst	  printf_filtered ("No line number information available");
127019370Spst	  if (sal.pc != 0)
127119370Spst	    {
127219370Spst	      /* This is useful for "info line *0x7f34".  If we can't tell the
127398944Sobrien	         user about a source line, at least let them have the symbolic
127498944Sobrien	         address.  */
127519370Spst	      printf_filtered (" for address ");
127619370Spst	      wrap_here ("  ");
127719370Spst	      print_address (sal.pc, gdb_stdout);
127819370Spst	    }
127919370Spst	  else
128019370Spst	    printf_filtered (".");
128119370Spst	  printf_filtered ("\n");
128219370Spst	}
128319370Spst      else if (sal.line > 0
128419370Spst	       && find_line_pc_range (sal, &start_pc, &end_pc))
128519370Spst	{
128619370Spst	  if (start_pc == end_pc)
128719370Spst	    {
128819370Spst	      printf_filtered ("Line %d of \"%s\"",
128919370Spst			       sal.line, sal.symtab->filename);
129019370Spst	      wrap_here ("  ");
129119370Spst	      printf_filtered (" is at address ");
129219370Spst	      print_address (start_pc, gdb_stdout);
129319370Spst	      wrap_here ("  ");
129419370Spst	      printf_filtered (" but contains no code.\n");
129519370Spst	    }
129619370Spst	  else
129719370Spst	    {
129819370Spst	      printf_filtered ("Line %d of \"%s\"",
129919370Spst			       sal.line, sal.symtab->filename);
130019370Spst	      wrap_here ("  ");
130119370Spst	      printf_filtered (" starts at address ");
130219370Spst	      print_address (start_pc, gdb_stdout);
130319370Spst	      wrap_here ("  ");
130419370Spst	      printf_filtered (" and ends at ");
130519370Spst	      print_address (end_pc, gdb_stdout);
130619370Spst	      printf_filtered (".\n");
130719370Spst	    }
130819370Spst
130919370Spst	  /* x/i should display this line's code.  */
131019370Spst	  set_next_address (start_pc);
131119370Spst
131219370Spst	  /* Repeating "info line" should do the following line.  */
131319370Spst	  last_line_listed = sal.line + 1;
131419370Spst
131519370Spst	  /* If this is the only line, show the source code.  If it could
131619370Spst	     not find the file, don't do anything special.  */
131719370Spst	  if (annotation_level && sals.nelts == 1)
131819370Spst	    identify_source_line (sal.symtab, sal.line, 0, start_pc);
131919370Spst	}
132019370Spst      else
132119370Spst	/* Is there any case in which we get here, and have an address
132219370Spst	   which the user would want to see?  If we have debugging symbols
132319370Spst	   and no line numbers?  */
132419370Spst	printf_filtered ("Line number %d is out of range for \"%s\".\n",
132519370Spst			 sal.line, sal.symtab->filename);
132619370Spst    }
132798944Sobrien  xfree (sals.sals);
132819370Spst}
132919370Spst
133019370Spst/* Commands to search the source file for a regexp.  */
133119370Spst
133219370Spststatic void
133398944Sobrienforward_search_command (char *regex, int from_tty)
133419370Spst{
1335130803Smarcel  int c;
1336130803Smarcel  int desc;
1337130803Smarcel  FILE *stream;
133846283Sdfr  int line;
133919370Spst  char *msg;
134019370Spst
134146283Sdfr  line = last_line_listed + 1;
134246283Sdfr
134319370Spst  msg = (char *) re_comp (regex);
134419370Spst  if (msg)
1345130803Smarcel    error ("%s", msg);
134619370Spst
134719370Spst  if (current_source_symtab == 0)
134819370Spst    select_source_symtab (0);
134919370Spst
135019370Spst  desc = open_source_file (current_source_symtab);
135119370Spst  if (desc < 0)
135219370Spst    perror_with_name (current_source_symtab->filename);
135319370Spst
135419370Spst  if (current_source_symtab->line_charpos == 0)
135519370Spst    find_source_lines (current_source_symtab, desc);
135619370Spst
135719370Spst  if (line < 1 || line > current_source_symtab->nlines)
135819370Spst    {
135919370Spst      close (desc);
136019370Spst      error ("Expression not found");
136119370Spst    }
136219370Spst
136319370Spst  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
136419370Spst    {
136519370Spst      close (desc);
136619370Spst      perror_with_name (current_source_symtab->filename);
136719370Spst    }
136819370Spst
136946283Sdfr  stream = fdopen (desc, FDOPEN_MODE);
137019370Spst  clearerr (stream);
137198944Sobrien  while (1)
137298944Sobrien    {
137398944Sobrien      static char *buf = NULL;
1374130803Smarcel      char *p;
137598944Sobrien      int cursize, newsize;
137619370Spst
137798944Sobrien      cursize = 256;
137898944Sobrien      buf = xmalloc (cursize);
137998944Sobrien      p = buf;
138019370Spst
138198944Sobrien      c = getc (stream);
138298944Sobrien      if (c == EOF)
138398944Sobrien	break;
138498944Sobrien      do
138519370Spst	{
138698944Sobrien	  *p++ = c;
138798944Sobrien	  if (p - buf == cursize)
138898944Sobrien	    {
138998944Sobrien	      newsize = cursize + cursize / 2;
139098944Sobrien	      buf = xrealloc (buf, newsize);
139198944Sobrien	      p = buf + cursize;
139298944Sobrien	      cursize = newsize;
139398944Sobrien	    }
139419370Spst	}
139598944Sobrien      while (c != '\n' && (c = getc (stream)) >= 0);
139619370Spst
139798944Sobrien#ifdef CRLF_SOURCE_FILES
139898944Sobrien      /* Remove the \r, if any, at the end of the line, otherwise
139998944Sobrien         regular expressions that end with $ or \n won't work.  */
140098944Sobrien      if (p - buf > 1 && p[-2] == '\r')
140198944Sobrien	{
140298944Sobrien	  p--;
140398944Sobrien	  p[-1] = '\n';
140498944Sobrien	}
140598944Sobrien#endif
140619370Spst
140798944Sobrien      /* we now have a source line in buf, null terminate and match */
140898944Sobrien      *p = 0;
140998944Sobrien      if (re_exec (buf) > 0)
141098944Sobrien	{
141198944Sobrien	  /* Match! */
141298944Sobrien	  fclose (stream);
141398944Sobrien	  print_source_lines (current_source_symtab, line, line + 1, 0);
141498944Sobrien	  set_internalvar (lookup_internalvar ("_"),
141598944Sobrien			   value_from_longest (builtin_type_int,
141698944Sobrien					       (LONGEST) line));
141798944Sobrien	  current_source_line = max (line - lines_to_list / 2, 1);
141898944Sobrien	  return;
141998944Sobrien	}
142098944Sobrien      line++;
142198944Sobrien    }
142298944Sobrien
142319370Spst  printf_filtered ("Expression not found\n");
142419370Spst  fclose (stream);
142519370Spst}
142619370Spst
142719370Spststatic void
142898944Sobrienreverse_search_command (char *regex, int from_tty)
142919370Spst{
1430130803Smarcel  int c;
1431130803Smarcel  int desc;
1432130803Smarcel  FILE *stream;
143346283Sdfr  int line;
143419370Spst  char *msg;
143598944Sobrien
143646283Sdfr  line = last_line_listed - 1;
143719370Spst
143819370Spst  msg = (char *) re_comp (regex);
143919370Spst  if (msg)
1440130803Smarcel    error ("%s", msg);
144119370Spst
144219370Spst  if (current_source_symtab == 0)
144319370Spst    select_source_symtab (0);
144419370Spst
144519370Spst  desc = open_source_file (current_source_symtab);
144619370Spst  if (desc < 0)
144719370Spst    perror_with_name (current_source_symtab->filename);
144819370Spst
144919370Spst  if (current_source_symtab->line_charpos == 0)
145019370Spst    find_source_lines (current_source_symtab, desc);
145119370Spst
145219370Spst  if (line < 1 || line > current_source_symtab->nlines)
145319370Spst    {
145419370Spst      close (desc);
145519370Spst      error ("Expression not found");
145619370Spst    }
145719370Spst
145819370Spst  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
145919370Spst    {
146019370Spst      close (desc);
146119370Spst      perror_with_name (current_source_symtab->filename);
146219370Spst    }
146319370Spst
146446283Sdfr  stream = fdopen (desc, FDOPEN_MODE);
146519370Spst  clearerr (stream);
146619370Spst  while (line > 1)
146719370Spst    {
146819370Spst/* FIXME!!!  We walk right off the end of buf if we get a long line!!! */
146919370Spst      char buf[4096];		/* Should be reasonable??? */
1470130803Smarcel      char *p = buf;
147119370Spst
147219370Spst      c = getc (stream);
147319370Spst      if (c == EOF)
147419370Spst	break;
147598944Sobrien      do
147698944Sobrien	{
147798944Sobrien	  *p++ = c;
147898944Sobrien	}
147998944Sobrien      while (c != '\n' && (c = getc (stream)) >= 0);
148019370Spst
148198944Sobrien#ifdef CRLF_SOURCE_FILES
148298944Sobrien      /* Remove the \r, if any, at the end of the line, otherwise
148398944Sobrien         regular expressions that end with $ or \n won't work.  */
148498944Sobrien      if (p - buf > 1 && p[-2] == '\r')
148598944Sobrien	{
148698944Sobrien	  p--;
148798944Sobrien	  p[-1] = '\n';
148898944Sobrien	}
148998944Sobrien#endif
149098944Sobrien
149119370Spst      /* We now have a source line in buf; null terminate and match.  */
149219370Spst      *p = 0;
149319370Spst      if (re_exec (buf) > 0)
149419370Spst	{
149519370Spst	  /* Match! */
149619370Spst	  fclose (stream);
149798944Sobrien	  print_source_lines (current_source_symtab, line, line + 1, 0);
149819370Spst	  set_internalvar (lookup_internalvar ("_"),
149919370Spst			   value_from_longest (builtin_type_int,
150019370Spst					       (LONGEST) line));
150119370Spst	  current_source_line = max (line - lines_to_list / 2, 1);
150219370Spst	  return;
150319370Spst	}
150419370Spst      line--;
150519370Spst      if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
150619370Spst	{
150719370Spst	  fclose (stream);
150819370Spst	  perror_with_name (current_source_symtab->filename);
150919370Spst	}
151019370Spst    }
151119370Spst
151219370Spst  printf_filtered ("Expression not found\n");
151319370Spst  fclose (stream);
151419370Spst  return;
151519370Spst}
151619370Spst
151719370Spstvoid
151898944Sobrien_initialize_source (void)
151919370Spst{
152019370Spst  struct cmd_list_element *c;
152119370Spst  current_source_symtab = 0;
152219370Spst  init_source_path ();
152319370Spst
152419370Spst  /* The intention is to use POSIX Basic Regular Expressions.
152519370Spst     Always use the GNU regex routine for consistency across all hosts.
152619370Spst     Our current GNU regex.c does not have all the POSIX features, so this is
152719370Spst     just an approximation.  */
152819370Spst  re_set_syntax (RE_SYNTAX_GREP);
152919370Spst
153019370Spst  c = add_cmd ("directory", class_files, directory_command,
153198944Sobrien	       "Add directory DIR to beginning of search path for source files.\n\
153219370SpstForget cached info on source file locations and line positions.\n\
153319370SpstDIR can also be $cwd for the current working directory, or $cdir for the\n\
153419370Spstdirectory in which the source file was compiled into object code.\n\
153519370SpstWith no argument, reset the search path to $cdir:$cwd, the default.",
153619370Spst	       &cmdlist);
153746283Sdfr
153846283Sdfr  if (dbx_commands)
153998944Sobrien    add_com_alias ("use", "directory", class_files, 0);
154046283Sdfr
1541130803Smarcel  set_cmd_completer (c, filename_completer);
154219370Spst
154319370Spst  add_cmd ("directories", no_class, show_directories,
154419370Spst	   "Current search path for finding source files.\n\
154519370Spst$cwd in the path means the current working directory.\n\
154619370Spst$cdir in the path means the compilation directory of the source file.",
154719370Spst	   &showlist);
154819370Spst
154946283Sdfr  if (xdb_commands)
155046283Sdfr    {
155198944Sobrien      add_com_alias ("D", "directory", class_files, 0);
155246283Sdfr      add_cmd ("ld", no_class, show_directories,
155398944Sobrien	       "Current search path for finding source files.\n\
155446283Sdfr$cwd in the path means the current working directory.\n\
155546283Sdfr$cdir in the path means the compilation directory of the source file.",
155698944Sobrien	       &cmdlist);
155746283Sdfr    }
155846283Sdfr
155919370Spst  add_info ("source", source_info,
156019370Spst	    "Information about the current source file.");
156119370Spst
156219370Spst  add_info ("line", line_info,
156319370Spst	    concat ("Core addresses of the code for a source line.\n\
156419370SpstLine can be specified as\n\
156519370Spst  LINENUM, to list around that line in current file,\n\
156619370Spst  FILE:LINENUM, to list around that line in that file,\n\
156719370Spst  FUNCTION, to list around beginning of that function,\n\
156819370Spst  FILE:FUNCTION, to distinguish among like-named static functions.\n\
156919370Spst", "\
157019370SpstDefault is to describe the last source line that was listed.\n\n\
157119370SpstThis sets the default address for \"x\" to the line's first instruction\n\
157219370Spstso that \"x/i\" suffices to start examining the machine code.\n\
157319370SpstThe address is also stored as the value of \"$_\".", NULL));
157419370Spst
157519370Spst  add_com ("forward-search", class_files, forward_search_command,
157619370Spst	   "Search for regular expression (see regex(3)) from last line listed.\n\
157719370SpstThe matching line number is also stored as the value of \"$_\".");
157819370Spst  add_com_alias ("search", "forward-search", class_files, 0);
157919370Spst
158019370Spst  add_com ("reverse-search", class_files, reverse_search_command,
158119370Spst	   "Search backward for regular expression (see regex(3)) from last line listed.\n\
158219370SpstThe matching line number is also stored as the value of \"$_\".");
158319370Spst
158446283Sdfr  if (xdb_commands)
158546283Sdfr    {
158698944Sobrien      add_com_alias ("/", "forward-search", class_files, 0);
158798944Sobrien      add_com_alias ("?", "reverse-search", class_files, 0);
158846283Sdfr    }
158946283Sdfr
159019370Spst  add_show_from_set
159119370Spst    (add_set_cmd ("listsize", class_support, var_uinteger,
159298944Sobrien		  (char *) &lines_to_list,
159398944Sobrien		  "Set number of source lines gdb will list by default.",
159419370Spst		  &setlist),
159519370Spst     &showlist);
159619370Spst}
1597