/* List lines of source files for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "symtab.h"
#include "filenames.h" /* for DOSish file names */
#include "completer.h"
#include "ui-out.h"
-#include <readline/readline.h>
-
-#ifdef CRLF_SOURCE_FILES
-
-/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
- host use \r\n rather than just \n. Defining CRLF_SOURCE_FILES is
- much faster than defining LSEEK_NOT_LINEAR. */
+#include "readline/readline.h"
#ifndef O_BINARY
#define O_BINARY 0
#define OPEN_MODE (O_RDONLY | O_BINARY)
#define FDOPEN_MODE FOPEN_RB
-#else /* ! defined (CRLF_SOURCE_FILES) */
-
-#define OPEN_MODE O_RDONLY
-#define FDOPEN_MODE FOPEN_RT
-
-#endif /* ! defined (CRLF_SOURCE_FILES) */
-
/* Prototypes for exported functions. */
void _initialize_source (void);
static void line_info (char *, int);
-static void ambiguous_line_spec (struct symtabs_and_lines *);
-
static void source_info (char *, int);
static void show_directories (char *, int);
things are wrapping, but that would be a fair amount of work. */
int lines_to_list = 10;
+static void
+show_lines_to_list (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Number of source lines gdb will list by default is %s.\n"),
+ value);
+}
/* Line number of last line printed. Default for various commands.
current_source_line is usually, but not always, the same as this. */
struct symtab_and_line
get_current_source_symtab_and_line (void)
{
- struct symtab_and_line cursal;
+ struct symtab_and_line cursal = { };
cursal.symtab = current_source_symtab;
cursal.line = current_source_line;
struct symtab_and_line cursal;
if (!have_full_symbols () && !have_partial_symbols ())
- error ("No symbol table is loaded. Use the \"file\" command.");
+ error (_("No symbol table is loaded. Use the \"file\" command."));
/* Pull in a current source symtab if necessary */
if (current_source_symtab == 0)
struct symtab_and_line
set_current_source_symtab_and_line (const struct symtab_and_line *sal)
{
- struct symtab_and_line cursal;
+ struct symtab_and_line cursal = { };
cursal.symtab = current_source_symtab;
cursal.line = current_source_line;
{
for (s = ofp->symtabs; s; s = s->next)
{
- char *name = s->filename;
+ const char *name = s->filename;
int len = strlen (name);
- if (!(len > 2 && (DEPRECATED_STREQ (&name[len - 2], ".h"))))
- {
- current_source_symtab = s;
- }
+ if (!(len > 2 && strcmp(&name[len - 2], ".h") == 0))
+ current_source_symtab = s;
}
}
if (current_source_symtab)
{
for (ps = ofp->psymtabs; ps != NULL; ps = ps->next)
{
- char *name = ps->filename;
+ const char *name = ps->filename;
int len = strlen (name);
- if (!(len > 2 && (DEPRECATED_STREQ (&name[len - 2], ".h"))))
- {
- cs_pst = ps;
- }
+ if (!(len > 2 && strcmp (&name[len - 2], ".h") == 0))
+ cs_pst = ps;
}
}
if (cs_pst)
if (cs_pst->readin)
{
internal_error (__FILE__, __LINE__,
- "select_source_symtab: "
- "readin pst found and no symtabs.");
+ _("select_source_symtab: "
+ "readin pst found and no symtabs."));
}
else
{
if (current_source_symtab)
return;
- error ("Can't find a default source file");
+ error (_("Can't find a default source file"));
}
\f
static void
{
if (s->line_charpos != NULL)
{
- xmfree (objfile->md, s->line_charpos);
+ xfree (s->line_charpos);
s->line_charpos = NULL;
}
if (s->fullname != NULL)
{
- xmfree (objfile->md, s->fullname);
+ xfree (s->fullname);
s->fullname = NULL;
}
}
/* FIXME, this goes to "delete dir"... */
if (dirname == 0)
{
- if (from_tty && query ("Reinitialize source path to empty? "))
+ if (from_tty && query (_("Reinitialize source path to empty? ")))
{
xfree (source_path);
init_source_path ();
name = tilde_expand (name);
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
else if (IS_ABSOLUTE_PATH (name) && p == name + 2) /* "d:" => "d:." */
- name = concat (name, ".", NULL);
+ name = concat (name, ".", (char *)NULL);
#endif
else if (!IS_ABSOLUTE_PATH (name) && name[0] != '$')
- name = concat (current_directory, SLASH_STRING, name, NULL);
+ name = concat (current_directory, SLASH_STRING, name, (char *)NULL);
else
name = savestring (name, p - name);
make_cleanup (xfree, name);
print_sys_errmsg (name, save_errno);
}
else if ((st.st_mode & S_IFMT) != S_IFDIR)
- warning ("%s is not a directory.", name);
+ warning (_("%s is not a directory."), name);
}
append:
c = old[prefix];
old[prefix] = '\0';
- temp = concat (old, tinybuf, name, NULL);
+ temp = concat (old, tinybuf, name, (char *)NULL);
old[prefix] = c;
- *which_path = concat (temp, "", &old[prefix], NULL);
+ *which_path = concat (temp, "", &old[prefix], (char *)NULL);
prefix = strlen (temp);
xfree (temp);
}
else
{
- *which_path = concat (name, (old[0] ? tinybuf : old), old, NULL);
+ *which_path = concat (name, (old[0] ? tinybuf : old),
+ old, (char *)NULL);
prefix = strlen (name);
}
xfree (old);
if (!s)
{
- printf_filtered ("No current source file.\n");
+ printf_filtered (_("No current source file.\n"));
return;
}
- printf_filtered ("Current source file is %s\n", s->filename);
+ printf_filtered (_("Current source file is %s\n"), s->filename);
if (s->dirname)
- printf_filtered ("Compilation directory is %s\n", s->dirname);
+ printf_filtered (_("Compilation directory is %s\n"), s->dirname);
if (s->fullname)
- printf_filtered ("Located in %s\n", s->fullname);
+ printf_filtered (_("Located in %s\n"), s->fullname);
if (s->nlines)
- printf_filtered ("Contains %d line%s.\n", s->nlines,
+ printf_filtered (_("Contains %d line%s.\n"), s->nlines,
s->nlines == 1 ? "" : "s");
- printf_filtered ("Source language is %s.\n", language_str (s->language));
- printf_filtered ("Compiled with %s debugging format.\n", s->debugformat);
- printf_filtered ("%s preprocessor macro info.\n",
+ printf_filtered (_("Source language is %s.\n"), language_str (s->language));
+ printf_filtered (_("Compiled with %s debugging format.\n"), s->debugformat);
+ printf_filtered (_("%s preprocessor macro info.\n"),
s->macro_table ? "Includes" : "Does not include");
}
\f
/* Open a file named STRING, searching path PATH (dir names sep by some char)
using mode MODE and protection bits PROT in the calls to open.
- If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
+ OPTS specifies the function behaviour in specific cases.
+
+ If OPF_TRY_CWD_FIRST, try to open ./STRING before searching PATH.
(ie pretend the first element of PATH is "."). This also indicates
that a slash in STRING disables searching of the path (this is
so that "exec-file ./foo" or "symbol-file ./foo" insures that you
get that particular version of foo or an error message).
+ If OPTS has OPF_SEARCH_IN_PATH set, absolute names will also be
+ searched in path (we usually want this for source files but not for
+ executables).
+
If FILENAME_OPENED is non-null, set it to a newly allocated string naming
the actual file opened (this string will always start with a "/"). We
have to take special pains to avoid doubling the "/" between the directory
/* >>>> This should only allow files of certain types,
>>>> eg executable, non-directory */
int
-openp (const char *path, int try_cwd_first, const char *string,
+openp (const char *path, int opts, const char *string,
int mode, int prot,
char **filename_opened)
{
if (!path)
path = ".";
-#if defined(_WIN32) || defined(__CYGWIN__)
mode |= O_BINARY;
-#endif
- if (try_cwd_first || IS_ABSOLUTE_PATH (string))
+ if ((opts & OPF_TRY_CWD_FIRST) || IS_ABSOLUTE_PATH (string))
{
int i;
fd = -1;
}
- for (i = 0; string[i]; i++)
- if (IS_DIR_SEPARATOR (string[i]))
- goto done;
+ if (!(opts & OPF_SEARCH_IN_PATH))
+ for (i = 0; string[i]; i++)
+ if (IS_DIR_SEPARATOR (string[i]))
+ goto done;
}
+ /* /foo => foo, to avoid multiple slashes that Emacs doesn't like. */
+ while (IS_DIR_SEPARATOR(string[0]))
+ string++;
+
/* ./foo => foo */
while (string[0] == '.' && IS_DIR_SEPARATOR (string[1]))
string += 2;
strcat (filename, string);
if (is_regular_file (filename))
- {
- fd = open (filename, mode);
- if (fd >= 0)
- break;
- }
+ {
+ fd = open (filename, mode);
+ if (fd >= 0)
+ break;
+ }
}
done:
/* Beware the // my son, the Emacs barfs, the botch that catch... */
char *f = concat (current_directory,
- IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
- ? "" : SLASH_STRING,
- filename, NULL);
+ IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
+ ? "" : SLASH_STRING,
+ filename, (char *)NULL);
*filename_opened = xfullpath (f);
xfree (f);
}
If the file was found, this function returns 1, and FULL_PATHNAME is
set to the fully-qualified pathname.
- Else, this functions returns 0, and FULL_PATHNAME is set to NULL.
- */
+ Else, this functions returns 0, and FULL_PATHNAME is set to NULL. */
int
source_full_path_of (char *filename, char **full_pathname)
{
int fd;
- fd = openp (source_path, 1, filename, O_RDONLY, 0, full_pathname);
+ fd = openp (source_path, OPF_TRY_CWD_FIRST | OPF_SEARCH_IN_PATH, filename,
+ O_RDONLY, 0, full_pathname);
if (fd < 0)
{
*full_pathname = NULL;
return 1;
}
+/* This function is capable of finding the absolute path to a
+ source file, and opening it, provided you give it an
+ OBJFILE and FILENAME. Both the DIRNAME and FULLNAME are only
+ added suggestions on where to find the file.
-/* Open a source file given a symtab S. Returns a file descriptor or
- negative number for error. */
+ OBJFILE should be the objfile associated with a psymtab or symtab.
+ FILENAME should be the filename to open.
+ DIRNAME is the compilation directory of a particular source file.
+ Only some debug formats provide this info.
+ FULLNAME can be the last known absolute path to the file in question.
+
+ On Success
+ A valid file descriptor is returned. ( the return value is positive )
+ FULLNAME is set to the absolute path to the file just opened.
+ On Failure
+ A non valid file descriptor is returned. ( the return value is negitive )
+ FULLNAME is set to NULL. */
int
-open_source_file (struct symtab *s)
+find_and_open_source (struct objfile *objfile,
+ const char *filename,
+ const char *dirname,
+ char **fullname)
{
char *path = source_path;
const char *p;
int result;
- char *fullname;
/* Quick way out if we already know its full name */
- if (s->fullname)
+ if (*fullname)
{
- result = open (s->fullname, OPEN_MODE);
+ result = open (*fullname, OPEN_MODE);
if (result >= 0)
return result;
/* Didn't work -- free old one, try again. */
- xmfree (s->objfile->md, s->fullname);
- s->fullname = NULL;
+ xfree (*fullname);
+ *fullname = NULL;
}
- if (s->dirname != NULL)
+ if (dirname != NULL)
{
/* Replace a path entry of $cdir with the compilation directory name */
#define cdir_len 5
int len;
path = (char *)
- alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
+ alloca (strlen (source_path) + 1 + strlen (dirname) + 1);
len = p - source_path;
strncpy (path, source_path, len); /* Before $cdir */
- strcpy (path + len, s->dirname); /* new stuff */
+ strcpy (path + len, dirname); /* new stuff */
strcat (path + len, source_path + len + cdir_len); /* After $cdir */
}
}
- result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
+ result = openp (path, OPF_SEARCH_IN_PATH, filename, OPEN_MODE, 0, fullname);
if (result < 0)
{
/* Didn't work. Try using just the basename. */
- p = lbasename (s->filename);
- if (p != s->filename)
- result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
+ p = lbasename (filename);
+ if (p != filename)
+ result = openp (path, OPF_SEARCH_IN_PATH, p, OPEN_MODE, 0, fullname);
}
if (result >= 0)
{
- fullname = s->fullname;
- s->fullname = mstrsave (s->objfile->md, s->fullname);
- xfree (fullname);
+ char *tmp_fullname;
+ tmp_fullname = *fullname;
+ *fullname = xstrdup (tmp_fullname);
+ xfree (tmp_fullname);
}
return result;
}
-/* Return the path to the source file associated with symtab. Returns NULL
- if no symtab. */
+/* Open a source file given a symtab S. Returns a file descriptor or
+ negative number for error.
+
+ This function is a convience function to find_and_open_source. */
+int
+open_source_file (struct symtab *s)
+{
+ if (!s)
+ return -1;
+
+ return find_and_open_source (s->objfile, s->filename, s->dirname,
+ &s->fullname);
+}
+
+/* Finds the fullname that a symtab represents.
+
+ If this functions finds the fullname, it will save it in ps->fullname
+ and it will also return the value.
+
+ If this function fails to find the file that this symtab represents,
+ NULL will be returned and ps->fullname will be set to NULL. */
char *
-symtab_to_filename (struct symtab *s)
+symtab_to_fullname (struct symtab *s)
{
- int fd;
+ int r;
if (!s)
return NULL;
- /* If we've seen the file before, just return fullname. */
+ /* Don't check s->fullname here, the file could have been
+ deleted/moved/..., look for it again */
+ r = find_and_open_source (s->objfile, s->filename, s->dirname,
+ &s->fullname);
- if (s->fullname)
- return s->fullname;
+ if (r)
+ {
+ close (r);
+ return s->fullname;
+ }
- /* Try opening the file to setup fullname */
+ return NULL;
+}
- fd = open_source_file (s);
- if (fd < 0)
- return s->filename; /* File not found. Just use short name */
+/* Finds the fullname that a partial_symtab represents.
- /* Found the file. Cleanup and return the full name */
+ If this functions finds the fullname, it will save it in ps->fullname
+ and it will also return the value.
- close (fd);
- return s->fullname;
+ If this function fails to find the file that this partial_symtab represents,
+ NULL will be returned and ps->fullname will be set to NULL. */
+char *
+psymtab_to_fullname (struct partial_symtab *ps)
+{
+ int r;
+
+ if (!ps)
+ return NULL;
+
+ /* Don't check ps->fullname here, the file could have been
+ deleted/moved/..., look for it again */
+ r = find_and_open_source (ps->objfile, ps->filename, ps->dirname,
+ &ps->fullname);
+
+ if (r)
+ {
+ close (r);
+ return ps->fullname;
+ }
+
+ return NULL;
}
\f
-
/* Create and initialize the table S->line_charpos that records
the positions of the lines in the source file, which is assumed
to be open on descriptor DESC.
long mtime = 0;
int size;
- line_charpos = (int *) xmmalloc (s->objfile->md,
- lines_allocated * sizeof (int));
+ line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
if (fstat (desc, &st) < 0)
perror_with_name (s->filename);
mtime = bfd_get_mtime (exec_bfd);
if (mtime && mtime < st.st_mtime)
- {
- warning ("Source file is more recent than executable.\n");
- }
+ warning (_("Source file is more recent than executable."));
#ifdef LSEEK_NOT_LINEAR
{
{
lines_allocated *= 2;
line_charpos =
- (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
- sizeof (int) * lines_allocated);
+ (int *) xrealloc ((char *) line_charpos,
+ sizeof (int) * lines_allocated);
}
line_charpos[nlines++] = lseek (desc, 0, SEEK_CUR);
}
{
lines_allocated *= 2;
line_charpos =
- (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
- sizeof (int) * lines_allocated);
+ (int *) xrealloc ((char *) line_charpos,
+ sizeof (int) * lines_allocated);
}
line_charpos[nlines++] = p - data;
}
#endif /* lseek linear. */
s->nlines = nlines;
s->line_charpos =
- (int *) xmrealloc (s->objfile->md, (char *) line_charpos,
- nlines * sizeof (int));
+ (int *) xrealloc ((char *) line_charpos, nlines * sizeof (int));
}
if (line < 1 || line > s->nlines)
{
close (desc);
- error ("Line number %d out of range; %s has %d lines.",
+ error (_("Line number %d out of range; %s has %d lines."),
line, s->filename, s->nlines);
}
}
else if (c == 0177)
ui_out_text (uiout, "^?");
-#ifdef CRLF_SOURCE_FILES
else if (c == '\r')
{
/* Skip a \r character, but only before a \n. */
if (c1 != EOF)
ungetc (c1, stream);
}
-#endif
else
{
sprintf (buf, "%c", c);
if (sal.symtab == 0)
{
- printf_filtered ("No line number information available");
+ printf_filtered (_("No line number information available"));
if (sal.pc != 0)
{
/* This is useful for "info line *0x7f34". If we can't tell the
/* Is there any case in which we get here, and have an address
which the user would want to see? If we have debugging symbols
and no line numbers? */
- printf_filtered ("Line number %d is out of range for \"%s\".\n",
+ printf_filtered (_("Line number %d is out of range for \"%s\".\n"),
sal.line, sal.symtab->filename);
}
xfree (sals.sals);
msg = (char *) re_comp (regex);
if (msg)
- error ("%s", msg);
+ error (("%s"), msg);
if (current_source_symtab == 0)
select_source_symtab (0);
if (line < 1 || line > current_source_symtab->nlines)
{
close (desc);
- error ("Expression not found");
+ error (_("Expression not found"));
}
if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
}
while (c != '\n' && (c = getc (stream)) >= 0);
-#ifdef CRLF_SOURCE_FILES
/* Remove the \r, if any, at the end of the line, otherwise
regular expressions that end with $ or \n won't work. */
if (p - buf > 1 && p[-2] == '\r')
p--;
p[-1] = '\n';
}
-#endif
/* we now have a source line in buf, null terminate and match */
*p = 0;
line++;
}
- printf_filtered ("Expression not found\n");
+ printf_filtered (_("Expression not found\n"));
fclose (stream);
}
msg = (char *) re_comp (regex);
if (msg)
- error ("%s", msg);
+ error (("%s"), msg);
if (current_source_symtab == 0)
select_source_symtab (0);
if (line < 1 || line > current_source_symtab->nlines)
{
close (desc);
- error ("Expression not found");
+ error (_("Expression not found"));
}
if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
}
while (c != '\n' && (c = getc (stream)) >= 0);
-#ifdef CRLF_SOURCE_FILES
/* Remove the \r, if any, at the end of the line, otherwise
regular expressions that end with $ or \n won't work. */
if (p - buf > 1 && p[-2] == '\r')
p--;
p[-1] = '\n';
}
-#endif
/* We now have a source line in buf; null terminate and match. */
*p = 0;
}
}
- printf_filtered ("Expression not found\n");
+ printf_filtered (_("Expression not found\n"));
fclose (stream);
return;
}
just an approximation. */
re_set_syntax (RE_SYNTAX_GREP);
- c = add_cmd ("directory", class_files, directory_command,
- "Add directory DIR to beginning of search path for source files.\n\
+ c = add_cmd ("directory", class_files, directory_command, _("\
+Add directory DIR to beginning of search path for source files.\n\
Forget cached info on source file locations and line positions.\n\
DIR can also be $cwd for the current working directory, or $cdir for the\n\
directory in which the source file was compiled into object code.\n\
-With no argument, reset the search path to $cdir:$cwd, the default.",
+With no argument, reset the search path to $cdir:$cwd, the default."),
&cmdlist);
if (dbx_commands)
set_cmd_completer (c, filename_completer);
- add_cmd ("directories", no_class, show_directories,
- "Current search path for finding source files.\n\
+ add_cmd ("directories", no_class, show_directories, _("\
+Current search path for finding source files.\n\
$cwd in the path means the current working directory.\n\
-$cdir in the path means the compilation directory of the source file.",
+$cdir in the path means the compilation directory of the source file."),
&showlist);
if (xdb_commands)
{
add_com_alias ("D", "directory", class_files, 0);
- add_cmd ("ld", no_class, show_directories,
- "Current search path for finding source files.\n\
+ add_cmd ("ld", no_class, show_directories, _("\
+Current search path for finding source files.\n\
$cwd in the path means the current working directory.\n\
-$cdir in the path means the compilation directory of the source file.",
+$cdir in the path means the compilation directory of the source file."),
&cmdlist);
}
add_info ("source", source_info,
- "Information about the current source file.");
+ _("Information about the current source file."));
- add_info ("line", line_info,
- concat ("Core addresses of the code for a source line.\n\
+ add_info ("line", line_info, _("\
+Core addresses of the code for a source line.\n\
Line can be specified as\n\
LINENUM, to list around that line in current file,\n\
FILE:LINENUM, to list around that line in that file,\n\
FUNCTION, to list around beginning of that function,\n\
FILE:FUNCTION, to distinguish among like-named static functions.\n\
-", "\
Default is to describe the last source line that was listed.\n\n\
This sets the default address for \"x\" to the line's first instruction\n\
so that \"x/i\" suffices to start examining the machine code.\n\
-The address is also stored as the value of \"$_\".", NULL));
+The address is also stored as the value of \"$_\"."));
- add_com ("forward-search", class_files, forward_search_command,
- "Search for regular expression (see regex(3)) from last line listed.\n\
-The matching line number is also stored as the value of \"$_\".");
+ add_com ("forward-search", class_files, forward_search_command, _("\
+Search for regular expression (see regex(3)) from last line listed.\n\
+The matching line number is also stored as the value of \"$_\"."));
add_com_alias ("search", "forward-search", class_files, 0);
- add_com ("reverse-search", class_files, reverse_search_command,
- "Search backward for regular expression (see regex(3)) from last line listed.\n\
-The matching line number is also stored as the value of \"$_\".");
+ add_com ("reverse-search", class_files, reverse_search_command, _("\
+Search backward for regular expression (see regex(3)) from last line listed.\n\
+The matching line number is also stored as the value of \"$_\"."));
if (xdb_commands)
{
add_com_alias ("?", "reverse-search", class_files, 0);
}
- add_show_from_set
- (add_set_cmd ("listsize", class_support, var_uinteger,
- (char *) &lines_to_list,
- "Set number of source lines gdb will list by default.",
- &setlist),
- &showlist);
+ add_setshow_integer_cmd ("listsize", class_support, &lines_to_list, _("\
+Set number of source lines gdb will list by default."), _("\
+Show number of source lines gdb will list by default."), NULL,
+ NULL,
+ show_lines_to_list,
+ &setlist, &showlist);
}