/* source.c - Keep track of source files.

   Copyright (C) 2000-2025 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;
}
