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

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