Wolfgang Thallergcc16 merge934c3885 months agoHistory
270 lines · 6.1 KB · C
RawDownload
/* source.c - Keep track of source files.    Copyright (C) 2000-2026 Free Software Foundation, Inc.    This file is part of GNU Binutils.    This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3 of the License, or   (at your option) any later version.    This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.    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., 51 Franklin Street - Fifth Floor, Boston, MA   02110-1301, USA.  */ #include "gprof.h"#include "libiberty.h"#include "filenames.h"#include "search_list.h"#include "source.h" #define EXT_ANNO "-ann"		/* Postfix of annotated files.  */ /* Default option values.  */bool create_annotation_files = false; Search_List src_search_list = {0, 0};Source_File *first_src_file = 0;  Source_File *source_file_lookup_path (const char *path){  Source_File *sf;   for (sf = first_src_file; sf; sf = sf->next)    {      if (FILENAME_CMP (path, sf->name) == 0)	break;    }   if (!sf)    {      /* Create a new source file descriptor.  */      sf = (Source_File *) xmalloc (sizeof (*sf));       memset (sf, 0, sizeof (*sf));       sf->name = xstrdup (path);      sf->next = first_src_file;      first_src_file = sf;    }   return sf;}  Source_File *source_file_lookup_name (const char *filename){  const char *fname;  Source_File *sf;   /* The user cannot know exactly how a filename will be stored in     the debugging info (e.g., ../include/foo.h     vs. /usr/include/foo.h).  So we simply compare the filename     component of a path only.  */  for (sf = first_src_file; sf; sf = sf->next)    {      fname = strrchr (sf->name, '/');       if (fname)	++fname;      else	fname = sf->name;       if (FILENAME_CMP (filename, fname) == 0)	break;    }   return sf;}  FILE *annotate_source (Source_File *sf, unsigned int max_width,     void (*annote) (char *, unsigned int, int, void *),     void *arg){  static bool first_file = true;  int i, line_num, nread;  bool new_line;  char buf[8192];  char *fname;  char *annotation, *name_only;  FILE *ifp, *ofp;  Search_List_Elem *sle = src_search_list.head;   /* Open input file.  If open fails, walk along search-list until     open succeeds or reaching end of list.  */  fname = (char *) sf->name;   if (IS_ABSOLUTE_PATH (sf->name))    sle = 0;			/* Don't use search list for absolute paths.  */   name_only = 0;  while (true)    {      DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n",			     sf->name, fname));       ifp = fopen (fname, FOPEN_RB);      if (fname != sf->name)	free (fname);      if (ifp)	break;       if (!sle && !name_only)	{	  name_only = strrchr (sf->name, '/');#ifdef HAVE_DOS_BASED_FILE_SYSTEM	  {	    char *bslash = strrchr (sf->name, '\\');	    if (name_only == NULL || (bslash != NULL && bslash > name_only))	      name_only = bslash;	    if (name_only == NULL && sf->name[0] != '\0' && sf->name[1] == ':')	      name_only = (char *)sf->name + 1;	  }#endif	  if (name_only)	    {	      /* Try search-list again, but this time with name only.  */	      ++name_only;	      sle = src_search_list.head;	    }	}       if (sle)	{	  fname = xmalloc (strlen (sle->path) + 3			   + strlen (name_only ? name_only : sf->name));	  strcpy (fname, sle->path);#ifdef HAVE_DOS_BASED_FILE_SYSTEM	  /* d:foo is not the same thing as d:/foo!  */	  if (fname[strlen (fname) - 1] == ':')	    strcat (fname, ".");#endif	  strcat (fname, "/"); 	  if (name_only)	    strcat (fname, name_only);	  else	    strcat (fname, sf->name); 	  sle = sle->next;	}      else	{	  if (errno == ENOENT)	    fprintf (stderr, _("%s: could not locate `%s'\n"),		     whoami, sf->name);	  else	    perror (sf->name); 	  return 0;	}    }   ofp = stdout;   if (create_annotation_files)    {      /* Try to create annotated source file.  */      const char *filename;       /* Create annotation files in the current working directory.  */      filename = strrchr (sf->name, '/');#ifdef HAVE_DOS_BASED_FILE_SYSTEM	{	  char *bslash = strrchr (sf->name, '\\');	  if (filename == NULL || (bslash != NULL && bslash > filename))	    filename = bslash;	  if (filename == NULL && sf->name[0] != '\0' && sf->name[1] == ':')	    filename = sf->name + 1;	}#endif      if (filename)	++filename;      else	filename = sf->name;       fname = xmalloc (strlen (filename) + strlen (EXT_ANNO) + 1);      strcpy (fname, filename);      strcat (fname, EXT_ANNO);#ifdef __MSDOS__      {	/* foo.cpp-ann can overwrite foo.cpp due to silent truncation of	   file names on 8+3 filesystems.  Their `stat' better be good...  */	struct stat buf1, buf2; 	if (stat (filename, &buf1) == 0	    && stat (fname, &buf2) == 0	    && buf1.st_ino == buf2.st_ino)	  {	    char *dot = strrchr (fname, '.'); 	    if (!dot)	      dot = fname + strlen (filename);	    strcpy (dot, ".ann");	  }      }#endif      ofp = fopen (fname, "w");       if (!ofp)	{	  perror (fname);	  free (fname);	  return 0;	}      free (fname);    }   /* Print file names if output goes to stdout     and there are more than one source file.  */  if (ofp == stdout)    {      if (first_file)	first_file = false;      else	fputc ('\n', ofp);       if (first_output)	first_output = false;      else	fprintf (ofp, "\f\n");       fprintf (ofp, _("*** File %s:\n"), sf->name);    }   annotation = (char *) xmalloc (max_width + 1);  line_num = 1;  new_line = true;   while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0)    {      for (i = 0; i < nread; ++i)	{	  if (new_line)	    {	      (*annote) (annotation, max_width, line_num, arg);	      fputs (annotation, ofp);	      ++line_num;	    } 	  new_line = (buf[i] == '\n');	  fputc (buf[i], ofp);	}    }   free (annotation);  fclose (ifp);  return ofp;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t