/* Relative (relocatable) prefix support.
   Copyright (C) 1987-2021 Free Software Foundation, Inc.

This file is part of libiberty.

GCC 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 2, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA.  */

/*

@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, @
  const char *@var{bin_prefix}, const char *@var{prefix})

Given three paths @var{progname}, @var{bin_prefix}, @var{prefix},
return the path that is in the same position relative to
@var{progname}'s directory as @var{prefix} is relative to
@var{bin_prefix}.  That is, a string starting with the directory
portion of @var{progname}, followed by a relative pathname of the
difference between @var{bin_prefix} and @var{prefix}.

If @var{progname} does not contain any directory separators,
@code{make_relative_prefix} will search @env{PATH} to find a program
named @var{progname}.  Also, if @var{progname} is a symbolic link,
the symbolic link will be resolved.

For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta},
@var{prefix} is @code{/alpha/beta/gamma/omega/}, and @var{progname} is
@code{/red/green/blue/gcc}, then this function will return
@code{/red/green/blue/../../omega/}.

The return value is normally allocated via @code{malloc}.  If no
relative prefix can be found, return @code{NULL}.

@end deftypefn

*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#include <string.h>

#include "ansidecl.h"
#include "libiberty.h"

#ifndef R_OK
#define R_OK 4
#define W_OK 2
#define X_OK 1
#endif

#ifndef DIR_SEPARATOR
#  define DIR_SEPARATOR '/'
#endif

#if defined (_WIN32) || defined (__MSDOS__) \
    || defined (__DJGPP__) || defined (__OS2__)
#  define HAVE_DOS_BASED_FILE_SYSTEM
#  define HAVE_HOST_EXECUTABLE_SUFFIX
#  define HOST_EXECUTABLE_SUFFIX ".exe"
#  ifndef DIR_SEPARATOR_2 
#    define DIR_SEPARATOR_2 '\\'
#  endif
#  define PATH_SEPARATOR ';'
#else
#  define PATH_SEPARATOR ':'
#endif

#ifndef DIR_SEPARATOR_2
#  define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
#else
#  define IS_DIR_SEPARATOR(ch) \
	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
#endif

#define DIR_UP ".."

static char *save_string (const char *, int);
static char **split_directories	(const char *, int *);
static void free_split_directories (char **);

static char *
save_string (const char *s, int len)
{
  char *result = (char *) malloc (len + 1);

  memcpy (result, s, len);
  result[len] = 0;
  return result;
}

/* Split a filename into component directories.  */

static char **
split_directories (const char *name, int *ptr_num_dirs)
{
  int num_dirs = 0;
  char **dirs;
  const char *p, *q;
  int ch;

  if (!*name)
    return NULL;

  /* Count the number of directories.  Special case MSDOS disk names as part
     of the initial directory.  */
  p = name;
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
  if (name[1] == ':' && IS_DIR_SEPARATOR (name[2]))
    {
      p += 3;
      num_dirs++;
    }
#endif /* HAVE_DOS_BASED_FILE_SYSTEM */

  while ((ch = *p++) != '\0')
    {
      if (IS_DIR_SEPARATOR (ch))
	{
	  num_dirs++;
	  while (IS_DIR_SEPARATOR (*p))
	    p++;
	}
    }

  dirs = (char **) malloc (sizeof (char *) * (num_dirs + 2));
  if (dirs == NULL)
    return NULL;

  /* Now copy the directory parts.  */
  num_dirs = 0;
  p = name;
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
  if (name[1] == ':' && IS_DIR_SEPARATOR (name[2]))
    {
      dirs[num_dirs++] = save_string (p, 3);
      if (dirs[num_dirs - 1] == NULL)
	{
	  free (dirs);
	  return NULL;
	}
      p += 3;
    }
#endif /* HAVE_DOS_BASED_FILE_SYSTEM */

  q = p;
  while ((ch = *p++) != '\0')
    {
      if (IS_DIR_SEPARATOR (ch))
	{
	  while (IS_DIR_SEPARATOR (*p))
	    p++;

	  dirs[num_dirs++] = save_string (q, p - q);
	  if (dirs[num_dirs - 1] == NULL)
	    {
	      dirs[num_dirs] = NULL;
	      free_split_directories (dirs);
	      return NULL;
	    }
	  q = p;
	}
    }

  if (p - 1 - q > 0)
    dirs[num_dirs++] = save_string (q, p - 1 - q);
  dirs[num_dirs] = NULL;

  if (dirs[num_dirs - 1] == NULL)
    {
      free_split_directories (dirs);
      return NULL;
    }

  if (ptr_num_dirs)
    *ptr_num_dirs = num_dirs;
  return dirs;
}

/* Release storage held by split directories.  */

static void
free_split_directories (char **dirs)
{
  int i = 0;

  if (dirs != NULL)
    {
      while (dirs[i] != NULL)
	free (dirs[i++]);

      free ((char *) dirs);
    }
}

/* Given three strings PROGNAME, BIN_PREFIX, PREFIX, return a string that gets
   to PREFIX starting with the directory portion of PROGNAME and a relative
   pathname of the difference between BIN_PREFIX and PREFIX.

   For example, if BIN_PREFIX is /alpha/beta/gamma/gcc/delta, PREFIX is
   /alpha/beta/gamma/omega/, and PROGNAME is /red/green/blue/gcc, then this
   function will return /red/green/blue/../../omega/.

   If no relative prefix can be found, return NULL.  */

static char *
make_relative_prefix_1 (const char *progname, const char *bin_prefix,
			const char *prefix, const int resolve_links)
{
  char **prog_dirs = NULL, **bin_dirs = NULL, **prefix_dirs = NULL;
  int prog_num, bin_num, prefix_num;
  int i, n, common;
  int needed_len;
  char *ret = NULL, *ptr, *full_progname;
  char *alloc_ptr = NULL;

  if (progname == NULL || bin_prefix == NULL || prefix == NULL)
    return NULL;

  /* If there is no full pathname, try to find the program by checking in each
     of the directories specified in the PATH environment variable.  */
  if (lbasename (progname) == progname)
    {
      char *temp;

      temp = getenv ("PATH");
      if (temp)
	{
	  char *startp, *endp, *nstore;
	  size_t prefixlen = strlen (temp) + 1;
	  size_t len;
	  if (prefixlen < 2)
	    prefixlen = 2;

	  len = prefixlen + strlen (progname) + 1;
#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
	  len += strlen (HOST_EXECUTABLE_SUFFIX);
#endif
	  if (len < MAX_ALLOCA_SIZE)
	    nstore = (char *) alloca (len);
	  else
	    alloc_ptr = nstore = (char *) malloc (len);

	  startp = endp = temp;
	  while (1)
	    {
	      if (*endp == PATH_SEPARATOR || *endp == 0)
		{
		  if (endp == startp)
		    {
		      nstore[0] = '.';
		      nstore[1] = DIR_SEPARATOR;
		      nstore[2] = '\0';
		    }
		  else
		    {
		      memcpy (nstore, startp, endp - startp);
		      if (! IS_DIR_SEPARATOR (endp[-1]))
			{
			  nstore[endp - startp] = DIR_SEPARATOR;
			  nstore[endp - startp + 1] = 0;
			}
		      else
			nstore[endp - startp] = 0;
		    }
		  strcat (nstore, progname);
		  if (! access (nstore, X_OK)
#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
                      || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
#endif
		      )
		    {
#if defined (HAVE_SYS_STAT_H) && defined (S_ISREG)
		      struct stat st;
		      if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode))
#endif
			{
			  progname = nstore;
			  break;
			}
		    }

		  if (*endp == 0)
		    break;
		  endp = startp = endp + 1;
		}
	      else
		endp++;
	    }
	}
    }

  if (resolve_links)
    full_progname = lrealpath (progname);
  else
    full_progname = strdup (progname);
  if (full_progname == NULL)
    goto bailout;

  prog_dirs = split_directories (full_progname, &prog_num);
  free (full_progname);
  if (prog_dirs == NULL)
    goto bailout;

  bin_dirs = split_directories (bin_prefix, &bin_num);
  if (bin_dirs == NULL)
    goto bailout;

  /* Remove the program name from comparison of directory names.  */
  prog_num--;

  /* If we are still installed in the standard location, we don't need to
     specify relative directories.  Also, if argv[0] still doesn't contain
     any directory specifiers after the search above, then there is not much
     we can do.  */
  if (prog_num == bin_num)
    {
      for (i = 0; i < bin_num; i++)
	{
	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
	    break;
	}

      if (prog_num <= 0 || i == bin_num)
	goto bailout;
    }

  prefix_dirs = split_directories (prefix, &prefix_num);
  if (prefix_dirs == NULL)
    goto bailout;

  /* Find how many directories are in common between bin_prefix & prefix.  */
  n = (prefix_num < bin_num) ? prefix_num : bin_num;
  for (common = 0; common < n; common++)
    {
      if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
	break;
    }

  /* If there are no common directories, there can be no relative prefix.  */
  if (common == 0)
    goto bailout;

  /* Two passes: first figure out the size of the result string, and
     then construct it.  */
  needed_len = 0;
  for (i = 0; i < prog_num; i++)
    needed_len += strlen (prog_dirs[i]);
  needed_len += sizeof (DIR_UP) * (bin_num - common);
  for (i = common; i < prefix_num; i++)
    needed_len += strlen (prefix_dirs[i]);
  needed_len += 1; /* Trailing NUL.  */

  ret = (char *) malloc (needed_len);
  if (ret == NULL)
    goto bailout;

  /* Build up the pathnames in argv[0].  */
  *ret = '\0';
  for (i = 0; i < prog_num; i++)
    strcat (ret, prog_dirs[i]);

  /* Now build up the ..'s.  */
  ptr = ret + strlen(ret);
  for (i = common; i < bin_num; i++)
    {
      strcpy (ptr, DIR_UP);
      ptr += sizeof (DIR_UP) - 1;
      *(ptr++) = DIR_SEPARATOR;
    }
  *ptr = '\0';

  /* Put in directories to move over to prefix.  */
  for (i = common; i < prefix_num; i++)
    strcat (ret, prefix_dirs[i]);

 bailout:
  free_split_directories (prog_dirs);
  free_split_directories (bin_dirs);
  free_split_directories (prefix_dirs);
  free (alloc_ptr);

  return ret;
}


/* Do the full job, including symlink resolution.
   This path will find files installed in the same place as the
   program even when a soft link has been made to the program
   from somwhere else. */

char *
make_relative_prefix (const char *progname, const char *bin_prefix,
		      const char *prefix)
{
  return make_relative_prefix_1 (progname, bin_prefix, prefix, 1);
}

/* Make the relative pathname without attempting to resolve any links.
   '..' etc may also be left in the pathname.
   This will find the files the user meant the program to find if the
   installation is patched together with soft links. */

char *
make_relative_prefix_ignore_links (const char *progname,
				   const char *bin_prefix,
				   const char *prefix)
{
  return make_relative_prefix_1 (progname, bin_prefix, prefix, 0);
}

