X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsource.c;h=d070958e852213c73b8c7f41287e4d5309279842;hb=b669c95337903d39aa2254e8ea0405c0ac117d24;hp=575e46c2123e66a58eb20f3f227b881601e421cd;hpb=cbe5657196d0d3acbeca39973f93f333ecedacda;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/source.c b/gdb/source.c index 575e46c212..d070958e85 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -1,5 +1,5 @@ /* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986-2018 Free Software Foundation, Inc. + Copyright (C) 1986-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -45,6 +45,7 @@ #include "common/scoped_fd.h" #include #include "common/pathstuff.h" +#include "source-cache.h" #define OPEN_MODE (O_RDONLY | O_BINARY) #define FDOPEN_MODE FOPEN_RB @@ -232,20 +233,11 @@ clear_current_source_symtab_and_line (void) current_source_line = 0; } -/* Set the source file default for the "list" command to be S. - - If S is NULL, and we don't have a default, find one. This - should only be called when the user actually tries to use the - default, since we produce an error if we can't find a reasonable - default. Also, since this can cause symbols to be read, doing it - before we need to would make things slower than necessary. */ +/* See source.h. */ void select_source_symtab (struct symtab *s) { - struct objfile *ofp; - struct compunit_symtab *cu; - if (s) { current_source_symtab = s; @@ -277,29 +269,35 @@ select_source_symtab (struct symtab *s) current_source_line = 1; - ALL_FILETABS (ofp, cu, s) + for (objfile *ofp : current_program_space->objfiles ()) { - const char *name = s->filename; - int len = strlen (name); - - if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0 - || strcmp (name, "<>") == 0))) + for (compunit_symtab *cu : ofp->compunits ()) { - current_source_pspace = current_program_space; - current_source_symtab = s; + for (symtab *symtab : compunit_filetabs (cu)) + { + const char *name = symtab->filename; + int len = strlen (name); + + if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0 + || strcmp (name, "<>") == 0))) + { + current_source_pspace = current_program_space; + current_source_symtab = symtab; + } + } } } if (current_source_symtab) return; - ALL_OBJFILES (ofp) - { - if (ofp->sf) - s = ofp->sf->qf->find_last_source_symtab (ofp); - if (s) - current_source_symtab = s; - } + for (objfile *objfile : current_program_space->objfiles ()) + { + if (objfile->sf) + s = objfile->sf->qf->find_last_source_symtab (objfile); + if (s) + current_source_symtab = s; + } if (current_source_symtab) return; @@ -350,26 +348,25 @@ show_directories_command (struct ui_file *file, int from_tty, show_directories_1 (NULL, from_tty); } -/* Forget line positions and file names for the symtabs in a - particular objfile. */ +/* See source.h. */ void forget_cached_source_info_for_objfile (struct objfile *objfile) { - struct compunit_symtab *cu; - struct symtab *s; - - ALL_OBJFILE_FILETABS (objfile, cu, s) + for (compunit_symtab *cu : objfile->compunits ()) { - if (s->line_charpos != NULL) - { - xfree (s->line_charpos); - s->line_charpos = NULL; - } - if (s->fullname != NULL) + for (symtab *s : compunit_filetabs (cu)) { - xfree (s->fullname); - s->fullname = NULL; + if (s->line_charpos != NULL) + { + xfree (s->line_charpos); + s->line_charpos = NULL; + } + if (s->fullname != NULL) + { + xfree (s->fullname); + s->fullname = NULL; + } } } @@ -377,22 +374,20 @@ forget_cached_source_info_for_objfile (struct objfile *objfile) objfile->sf->qf->forget_cached_source_info (objfile); } -/* Forget what we learned about line positions in source files, and - which directories contain them; must check again now since files - may be found in a different directory now. */ +/* See source.h. */ void forget_cached_source_info (void) { struct program_space *pspace; - struct objfile *objfile; ALL_PSPACES (pspace) - ALL_PSPACE_OBJFILES (pspace, objfile) - { - forget_cached_source_info_for_objfile (objfile); - } + for (objfile *objfile : pspace->objfiles ()) + { + forget_cached_source_info_for_objfile (objfile); + } + g_source_cache.clear (); last_source_visited = NULL; } @@ -1224,14 +1219,7 @@ get_filename_and_charpos (struct symtab *s, char **fullname) find_source_lines (s, desc.get ()); } -/* Print text describing the full name of the source file S - and the line number LINE and its corresponding character position. - The text starts with two Ctrl-z so that the Emacs-GDB interface - can easily find it. - - MID_STATEMENT is nonzero if the PC is not at the beginning of that line. - - Return 1 if successful, 0 if could not find the file. */ +/* See source.h. */ int identify_source_line (struct symtab *s, int line, int mid_statement, @@ -1344,25 +1332,23 @@ print_source_lines_base (struct symtab *s, int line, int stopline, last_source_error = 0; - if (s->line_charpos == 0) - find_source_lines (s, desc.get ()); + /* If the user requested a sequence of lines that seems to go backward + (from high to low line numbers) then we don't print anything. */ + if (stopline <= line) + return; - if (line < 1 || line > s->nlines) + std::string lines; + if (!g_source_cache.get_source_lines (s, line, stopline - 1, &lines)) error (_("Line number %d out of range; %s has %d lines."), line, symtab_to_filename_for_display (s), s->nlines); - if (lseek (desc.get (), s->line_charpos[line - 1], 0) < 0) - perror_with_name (symtab_to_filename_for_display (s)); - - gdb_file_up stream = desc.to_file (FDOPEN_MODE); - clearerr (stream.get ()); - + const char *iter = lines.c_str (); while (nlines-- > 0) { char buf[20]; - c = fgetc (stream.get ()); - if (c == EOF) + c = *iter++; + if (c == '\0') break; last_line_listed = current_source_line; if (flags & PRINT_SOURCE_LINES_FILENAME) @@ -1374,7 +1360,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, uiout->text (buf); do { - if (c < 040 && c != '\t' && c != '\n' && c != '\r') + if (c < 040 && c != '\t' && c != '\n' && c != '\r' && c != '\033') { xsnprintf (buf, sizeof (buf), "^%c", c + 0100); uiout->text (buf); @@ -1384,12 +1370,8 @@ print_source_lines_base (struct symtab *s, int line, int stopline, else if (c == '\r') { /* Skip a \r character, but only before a \n. */ - int c1 = fgetc (stream.get ()); - - if (c1 != '\n') + if (*iter != '\n') printf_filtered ("^%c", c + 0100); - if (c1 != EOF) - ungetc (c1, stream.get ()); } else { @@ -1397,14 +1379,16 @@ print_source_lines_base (struct symtab *s, int line, int stopline, uiout->text (buf); } } - while (c != '\n' && (c = fgetc (stream.get ())) >= 0); + while (c != '\n' && (c = *iter++) != '\0'); + if (c == '\0') + break; } + if (!lines.empty() && lines.back () != '\n') + uiout->text ("\n"); } -/* Show source lines from the file of symtab S, starting with line - number LINE and stopping before line number STOPLINE. If this is - not the command line version, then the source is shown in the source - window otherwise it is simply printed. */ + +/* See source.h. */ void print_source_lines (struct symtab *s, int line, int stopline, @@ -1412,6 +1396,18 @@ print_source_lines (struct symtab *s, int line, int stopline, { print_source_lines_base (s, line, stopline, flags); } + +/* See source.h. */ + +void +print_source_lines (struct symtab *s, source_lines_range line_range, + print_source_lines_flags flags) +{ + print_source_lines_base (s, line_range.startline (), + line_range.stopline (), flags); +} + + /* Print info on range of pc's in a specified line. */ @@ -1598,6 +1594,8 @@ search_command_helper (const char *regex, int from_tty, bool forward) else { line--; + if (line < 1) + break; if (fseek (stream.get (), current_source_symtab->line_charpos[line - 1], 0) < 0) { @@ -1833,6 +1831,33 @@ set_substitute_path_command (const char *args, int from_tty) forget_cached_source_info (); } +/* See source.h. */ + +source_lines_range::source_lines_range (int startline, + source_lines_range::direction dir) +{ + if (dir == source_lines_range::FORWARD) + { + LONGEST end = static_cast (startline) + get_lines_to_list (); + + if (end > INT_MAX) + end = INT_MAX; + + m_startline = startline; + m_stopline = static_cast (end); + } + else + { + LONGEST start = static_cast (startline) - get_lines_to_list (); + + if (start < 1) + start = 1; + + m_startline = static_cast (start); + m_stopline = startline; + } +} + void _initialize_source (void)