?? source.c
字號:
/* Name is $cwd -- insert current directory name instead. */ int newlen; /* First, realloc the filename buffer if too short. */ len = strlen (current_directory); newlen = len + strlen (string) + 2; if (newlen > alloclen) { alloclen = newlen; filename = (char *) alloca (alloclen); } strcpy (filename, current_directory); } else { /* Normal file name in path -- just use it. */ strncpy (filename, p, len); filename[len] = 0; } /* Remove trailing slashes */ while (len > 0 && filename[len-1] == '/') filename[--len] = 0; strcat (filename+len, "/"); strcat (filename, string); fd = open (filename, mode, prot); if (fd >= 0) break; } done: if (filename_opened) if (fd < 0) *filename_opened = (char *) 0; else if (filename[0] == '/') *filename_opened = savestring (filename, strlen (filename)); else { /* Beware the // my son, the Emacs barfs, the botch that catch... */ *filename_opened = concat (current_directory, '/' == current_directory[strlen(current_directory)-1]? "": "/", filename, NULL); } return fd;}/* Open a source file given a symtab S. Returns a file descriptor or negative number for error. */static intopen_source_file (s) struct symtab *s;{ char *path = source_path; char *p; int result; char *fullname; /* Quick way out if we already know its full name */ if (s->fullname) { result = open (s->fullname, O_RDONLY); if (result >= 0) return result; /* Didn't work -- free old one, try again. */ mfree (s->objfile->md, s->fullname); s->fullname = NULL; } if (s->dirname != NULL) { /* Replace a path entry of $cdir with the compilation directory name */#define cdir_len 5 /* We cast strstr's result in case an ANSIhole has made it const, which produces a "required warning" when assigned to a nonconst. */ p = (char *)strstr (source_path, "$cdir"); if (p && (p == path || p[-1] == ':') && (p[cdir_len] == ':' || p[cdir_len] == '\0')) { int len; path = (char *) alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1); len = p - source_path; strncpy (path, source_path, len); /* Before $cdir */ strcpy (path + len, s->dirname); /* new stuff */ strcat (path + len, source_path + len + cdir_len); /* After $cdir */ } } result = openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname); if (result < 0) { /* Didn't work. Try using just the basename. */ p = basename (s->filename); if (p != s->filename) result = openp(path, 0, p, O_RDONLY,0, &s->fullname); } if (result >= 0) { fullname = s -> fullname; s -> fullname = mstrsave (s -> objfile -> md, s -> fullname); free (fullname); } return result;}/* 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. All set S->nlines to the number of such lines. */static voidfind_source_lines (s, desc) struct symtab *s; int desc;{ struct stat st; char c; register char *data, *p, *end; int nlines = 0; int lines_allocated = 1000; int *line_charpos; long exec_mtime; int size; line_charpos = (int *) xmmalloc (s -> objfile -> md, lines_allocated * sizeof (int)); if (fstat (desc, &st) < 0) perror_with_name (s->filename); if (exec_bfd) { exec_mtime = bfd_get_mtime(exec_bfd); if (exec_mtime && exec_mtime < st.st_mtime) printf_filtered ("Source file is more recent than executable.\n"); }#ifdef LSEEK_NOT_LINEAR /* Have to read it byte by byte to find out where the chars live */ line_charpos[0] = tell(desc); nlines = 1; while (myread(desc, &c, 1)>0) { if (c == '\n') { if (nlines == lines_allocated) { lines_allocated *= 2; line_charpos = (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, sizeof (int) * lines_allocated); } line_charpos[nlines++] = tell(desc); } }#else /* st_size might be a large type, but we only support source files whose size fits in an int. FIXME. */ size = (int) st.st_size;#ifdef BROKEN_LARGE_ALLOCA data = (char *) xmalloc (size); make_cleanup (free, data);#else data = (char *) alloca (size);#endif if (myread (desc, data, size) < 0) perror_with_name (s->filename); end = data + size; p = data; line_charpos[0] = 0; nlines = 1; while (p != end) { if (*p++ == '\n' /* A newline at the end does not start a new line. */ && p != end) { if (nlines == lines_allocated) { lines_allocated *= 2; line_charpos = (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, sizeof (int) * lines_allocated); } line_charpos[nlines++] = p - data; } }#endif s->nlines = nlines; s->line_charpos = (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, nlines * sizeof (int));}/* Return the character position of a line LINE in symtab S. Return 0 if anything is invalid. */intsource_line_charpos (s, line) struct symtab *s; int line;{ if (!s) return 0; if (!s->line_charpos || line <= 0) return 0; if (line > s->nlines) line = s->nlines; return s->line_charpos[line - 1];}/* Return the line number of character position POS in symtab S. */intsource_charpos_line (s, chr) register struct symtab *s; register int chr;{ register int line = 0; register int *lnp; if (s == 0 || s->line_charpos == 0) return 0; lnp = s->line_charpos; /* Files are usually short, so sequential search is Ok */ while (line < s->nlines && *lnp <= chr) { line++; lnp++; } if (line >= s->nlines) line = s->nlines; return line;}/* Get full pathname and line number positions for a symtab. Return nonzero if line numbers may have changed. Set *FULLNAME to actual name of the file as found by `openp', or to 0 if the file is not found. */intget_filename_and_charpos (s, fullname) struct symtab *s; char **fullname;{ register int desc, linenums_changed = 0; desc = open_source_file (s); if (desc < 0) { if (fullname) *fullname = NULL; return 0; } if (fullname) *fullname = s->fullname; if (s->line_charpos == 0) linenums_changed = 1; if (linenums_changed) find_source_lines (s, desc); close (desc); return linenums_changed;}/* 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. */intidentify_source_line (s, line, mid_statement) struct symtab *s; int line; int mid_statement;{ if (s->line_charpos == 0) get_filename_and_charpos (s, (char **)NULL); if (s->fullname == 0) return 0; printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname, line, s->line_charpos[line - 1], mid_statement ? "middle" : "beg", get_frame_pc (get_current_frame())); current_source_line = line; first_line_listed = line; last_line_listed = line; current_source_symtab = s; return 1;}/* Print source lines from the file of symtab S, starting with line number LINE and stopping before line number STOPLINE. */voidprint_source_lines (s, line, stopline, noerror) struct symtab *s; int line, stopline; int noerror;{ register int c; register int desc; register FILE *stream; int nlines = stopline - line; /* Regardless of whether we can open the file, set current_source_symtab. */ current_source_symtab = s; current_source_line = line; first_line_listed = line; desc = open_source_file (s); if (desc < 0) { if (noerror && line + 1 == stopline) { /* can't find the file - tell user where we are anyway */ current_source_symtab = s; current_source_line = line; first_line_listed = line; last_line_listed = line; printf_filtered ("%d\t(%s)\n", current_source_line++, s->filename); } else { if (! noerror) { char *name = alloca (strlen (s->filename) + 100); sprintf (name, "%s:%d", s->filename, line); print_sys_errmsg (name, errno); } } return; } if (s->line_charpos == 0) find_source_lines (s, desc); if (line < 1 || line > s->nlines) { close (desc); error ("Line number %d out of range; %s has %d lines.", line, s->filename, s->nlines); } if (lseek (desc, s->line_charpos[line - 1], 0) < 0) { close (desc); perror_with_name (s->filename); } stream = fdopen (desc, "r"); clearerr (stream); while (nlines-- > 0) { c = fgetc (stream); if (c == EOF) break; last_line_listed = current_source_line; printf_filtered ("%d\t", current_source_line++); do { if (c < 040 && c != '\t' && c != '\n' && c != '\r') printf_filtered ("^%c", c + 0100); else if (c == 0177) printf_filtered ("^?"); else printf_filtered ("%c", c); } while (c != '\n' && (c = fgetc (stream)) >= 0); } fclose (stream);}/* C++ Print a list of files and line numbers which a user may choose from in order to list a function which was specified ambiguously (as with `list classname::overloadedfuncname', for example). The vector in SALS provides the filenames and line numbers. */static voidambiguous_line_spec (sals) struct symtabs_and_lines *sals;{ int i; for (i = 0; i < sals->nelts; ++i) printf_filtered("file: \"%s\", line number: %d\n", sals->sals[i].symtab->filename, sals->sals[i].line);}static voidsetfile_command(arg, from_tty) char *arg; int from_tty;{ struct symtabs_and_lines sals; struct symtab_and_line sal; struct symbol *sym; char *arg1; int linenum_beg = 0; char *p; /* Pull in a current source symtab if necessary */ if (arg == 0 || arg[0] == 0) { if (current_source_symtab == 0) select_source_symtab(0); else printf("%s\n", current_source_symtab->filename); return; } arg1 = arg; sals = decode_line_1 (&arg1, 0, 0, 0); if (! sals.nelts) return; /* C++ */ if (sals.nelts > 1) { ambiguous_line_spec (&sals); free (sals.sals); return; } sal = sals.sals[0]; free (sals.sals); /* Record whether the BEG arg is all digits. */ for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; ++p) ; linenum_beg = (p == arg1); /* if line was specified by address, print exactly which line, and which file. In this case, sal.symtab == 0 means address is outside of all known source files, not that user failed to give a filename. */ if (*arg == '*') { if (sal.symtab == 0) error ("No source file for address 0x%x.", sal.pc); sym = find_pc_function (sal.pc); if (sym) printf ("0x%x is in %s (%s, line %d).\n", sal.pc, SYMBOL_NAME (sym), sal.symtab->filename, sal.line); else printf ("0x%x is in %s, line %d.\n", sal.pc, sal.symtab->filename, sal.line); } /* If line was not specified by just a line number, and it does not imply a symtab, it must be an undebuggable symbol which means no source code. */ if (sal.symtab == 0) { if (! linenum_beg) error ("No line number known for %s.", arg); else error ("No default source file yet. Do \"help list\"."); } else { current_source_symtab = sal.symtab; current_source_line = sal.line; first_line_listed = sal.line; }}#define PUSH_STACK_SIZE 32static struct { struct symtab *symtab; int line;} push_stack[PUSH_STACK_SIZE];static unsigned int push_stack_ptr;static voidpush_to_file_command (arg, from_tty) char *arg; int from_tty;{ struct symtab *cursym = current_source_symtab; int curline = current_source_line; register unsigned int i;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -