/* List lines of source files for GDB, the GNU debugger.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "completer.h"
#include "ui-out.h"
#include "readline/readline.h"
+#include "common/enum-flags.h"
+#include <algorithm>
#define OPEN_MODE (O_RDONLY | O_BINARY)
#define FDOPEN_MODE FOPEN_RB
and friends should be rewritten to count characters and see where
things are wrapping, but that would be a fair amount of work. */
-int lines_to_list = 10;
+static 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)
xfree (sals.sals);
current_source_pspace = sal.pspace;
current_source_symtab = sal.symtab;
- current_source_line = max (sal.line - (lines_to_list - 1), 1);
+ current_source_line = std::max (sal.line - (lines_to_list - 1), 1);
if (current_source_symtab)
return;
}
}
\f
-/* Return True if the file NAME exists and is a regular file. */
+/* Return True if the file NAME exists and is a regular file.
+ If the result is false then *ERRNO_PTR is set to a useful value assuming
+ we're expecting a regular file. */
+
static int
-is_regular_file (const char *name)
+is_regular_file (const char *name, int *errno_ptr)
{
struct stat st;
const int status = stat (name, &st);
on obscure systems where stat does not work as expected. */
if (status != 0)
- return (errno != ENOENT);
+ {
+ if (errno != ENOENT)
+ return 1;
+ *errno_ptr = ENOENT;
+ return 0;
+ }
- return S_ISREG (st.st_mode);
+ if (S_ISREG (st.st_mode))
+ return 1;
+
+ if (S_ISDIR (st.st_mode))
+ *errno_ptr = EISDIR;
+ else
+ *errno_ptr = EINVAL;
+ return 0;
}
/* Open a file named STRING, searching path PATH (dir names sep by some char)
struct cleanup *back_to;
int ix;
char *dir;
+ /* The errno set for the last name we tried to open (and
+ failed). */
+ int last_errno = 0;
/* The open syscall MODE parameter is not specified. */
gdb_assert ((mode & O_CREAT) == 0);
if ((opts & OPF_TRY_CWD_FIRST) || IS_ABSOLUTE_PATH (string))
{
- int i;
+ int i, reg_file_errno;
- if (is_regular_file (string))
+ if (is_regular_file (string, ®_file_errno))
{
- filename = alloca (strlen (string) + 1);
+ filename = (char *) alloca (strlen (string) + 1);
strcpy (filename, string);
fd = gdb_open_cloexec (filename, mode, 0);
if (fd >= 0)
goto done;
+ last_errno = errno;
}
else
{
filename = NULL;
fd = -1;
+ last_errno = reg_file_errno;
}
if (!(opts & OPF_SEARCH_IN_PATH))
string += 2;
alloclen = strlen (path) + strlen (string) + 2;
- filename = alloca (alloclen);
+ filename = (char *) alloca (alloclen);
fd = -1;
+ last_errno = ENOENT;
dir_vec = dirnames_to_char_ptr_vec (path);
back_to = make_cleanup_free_char_ptr_vec (dir_vec);
for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, dir); ++ix)
{
size_t len = strlen (dir);
+ int reg_file_errno;
if (strcmp (dir, "$cwd") == 0)
{
if (newlen > alloclen)
{
alloclen = newlen;
- filename = alloca (alloclen);
+ filename = (char *) alloca (alloclen);
}
strcpy (filename, current_directory);
}
if (newlen > alloclen)
{
alloclen = newlen;
- filename = alloca (alloclen);
+ filename = (char *) alloca (alloclen);
}
strcpy (filename, tilde_expanded);
xfree (tilde_expanded);
strcat (filename + len, SLASH_STRING);
strcat (filename, string);
- if (is_regular_file (filename))
+ if (is_regular_file (filename, ®_file_errno))
{
fd = gdb_open_cloexec (filename, mode, 0);
if (fd >= 0)
break;
+ last_errno = errno;
}
+ else
+ last_errno = reg_file_errno;
}
do_cleanups (back_to);
*filename_opened = gdb_abspath (filename);
}
+ errno = last_errno;
return fd;
}
if (SYMTAB_DIRNAME (s) == NULL || IS_ABSOLUTE_PATH (s->filename))
fullname = xstrdup (s->filename);
else
- fullname = concat (SYMTAB_DIRNAME (s), SLASH_STRING, s->filename,
- NULL);
+ fullname = concat (SYMTAB_DIRNAME (s), SLASH_STRING,
+ s->filename, (char *) NULL);
back_to = make_cleanup (xfree, fullname);
s->fullname = rewrite_source_path (fullname);
static void
print_source_lines_base (struct symtab *s, int line, int stopline,
- enum print_source_lines_flags flags)
+ print_source_lines_flags flags)
{
int c;
int desc;
/* If printing of source lines is disabled, just print file and line
number. */
- if (ui_out_test_flags (uiout, ui_source_list))
+ if (uiout->test_flags (ui_source_list))
{
/* Only prints "No such file or directory" once. */
if ((s != last_source_visited) || (!last_source_error))
else
{
desc = last_source_error;
- flags |= PRINT_SOURCE_LINES_NOERROR;
+ flags |= PRINT_SOURCE_LINES_NOERROR;
noprint = 1;
}
{
const char *filename = symtab_to_filename_for_display (s);
int len = strlen (filename) + 100;
- char *name = alloca (len);
+ char *name = (char *) alloca (len);
xsnprintf (name, len, "%d\t%s", line, filename);
print_sys_errmsg (name, errno);
}
else
{
- ui_out_field_int (uiout, "line", line);
- ui_out_text (uiout, "\tin ");
+ uiout->field_int ("line", line);
+ uiout->text ("\tin ");
/* CLI expects only the "file" field. TUI expects only the
"fullname" field (and TUI does break if "file" is printed).
MI expects both fields. ui_source_list is set only for CLI,
not for TUI. */
- if (ui_out_is_mi_like_p (uiout)
- || ui_out_test_flags (uiout, ui_source_list))
- ui_out_field_string (uiout, "file",
- symtab_to_filename_for_display (s));
- if (ui_out_is_mi_like_p (uiout)
- || !ui_out_test_flags (uiout, ui_source_list))
+ if (uiout->is_mi_like_p () || uiout->test_flags (ui_source_list))
+ uiout->field_string ("file", symtab_to_filename_for_display (s));
+ if (uiout->is_mi_like_p () || !uiout->test_flags (ui_source_list))
{
const char *s_fullname = symtab_to_fullname (s);
char *local_fullname;
/* ui_out_field_string may free S_FULLNAME by calling
open_source_file for it again. See e.g.,
tui_field_string->tui_show_source. */
- local_fullname = alloca (strlen (s_fullname) + 1);
+ local_fullname = (char *) alloca (strlen (s_fullname) + 1);
strcpy (local_fullname, s_fullname);
- ui_out_field_string (uiout, "fullname", local_fullname);
+ uiout->field_string ("fullname", local_fullname);
}
- ui_out_text (uiout, "\n");
+ uiout->text ("\n");
}
return;
last_line_listed = current_source_line;
if (flags & PRINT_SOURCE_LINES_FILENAME)
{
- ui_out_text (uiout, symtab_to_filename_for_display (s));
- ui_out_text (uiout, ":");
+ uiout->text (symtab_to_filename_for_display (s));
+ uiout->text (":");
}
xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++);
- ui_out_text (uiout, buf);
+ uiout->text (buf);
do
{
if (c < 040 && c != '\t' && c != '\n' && c != '\r')
{
xsnprintf (buf, sizeof (buf), "^%c", c + 0100);
- ui_out_text (uiout, buf);
+ uiout->text (buf);
}
else if (c == 0177)
- ui_out_text (uiout, "^?");
+ uiout->text ("^?");
else if (c == '\r')
{
/* Skip a \r character, but only before a \n. */
else
{
xsnprintf (buf, sizeof (buf), "%c", c);
- ui_out_text (uiout, buf);
+ uiout->text (buf);
}
}
while (c != '\n' && (c = fgetc (stream)) >= 0);
void
print_source_lines (struct symtab *s, int line, int stopline,
- enum print_source_lines_flags flags)
+ print_source_lines_flags flags)
{
print_source_lines_base (s, line, stopline, flags);
}
int cursize, newsize;
cursize = 256;
- buf = xmalloc (cursize);
+ buf = (char *) xmalloc (cursize);
p = buf;
c = fgetc (stream);
if (p - buf == cursize)
{
newsize = cursize + cursize / 2;
- buf = xrealloc (buf, newsize);
+ buf = (char *) xrealloc (buf, newsize);
p = buf + cursize;
cursize = newsize;
}
do_cleanups (cleanups);
print_source_lines (current_source_symtab, line, line + 1, 0);
set_internalvar_integer (lookup_internalvar ("_"), line);
- current_source_line = max (line - lines_to_list / 2, 1);
+ current_source_line = std::max (line - lines_to_list / 2, 1);
return;
}
line++;
do_cleanups (cleanups);
print_source_lines (current_source_symtab, line, line + 1, 0);
set_internalvar_integer (lookup_internalvar ("_"), line);
- current_source_line = max (line - lines_to_list / 2, 1);
+ current_source_line = std::max (line - lines_to_list / 2, 1);
return;
}
line--;