⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 source.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* 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 + -