/* Set up combined include path chain for the preprocessor.
   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.

   Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.

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 2, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "machmode.h"
#include "target.h"
#include "tm.h"
#include "cpplib.h"
#include "prefix.h"
#include "intl.h"
#include "c-incpath.h"
#include "cppdefault.h"
/* APPLE LOCAL headermaps 3871393 */ 
#include "errors.h"

/* Windows does not natively support inodes, and neither does MSDOS.
   Cygwin's emulation can generate non-unique inodes, so don't use it.
   VMS has non-numeric inodes.  */
#ifdef VMS
# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
#else
# if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__
#  define INO_T_EQ(A, B) 0
# else
#  define INO_T_EQ(A, B) ((A) == (B))
# endif
# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
#endif

static void add_env_var_paths (const char *, int);
static void add_standard_paths (const char *, const char *, int);
static void free_path (struct cpp_dir *, int);
static void merge_include_chains (cpp_reader *, int);
static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
					   struct cpp_dir *,
					   struct cpp_dir *, int);

/* Include chains heads and tails.  */
static struct cpp_dir *heads[4];
static struct cpp_dir *tails[4];
static bool quote_ignores_source_dir;
enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };

/* Free an element of the include chain, possibly giving a reason.  */
static void
free_path (struct cpp_dir *path, int reason)
{
  switch (reason)
    {
    case REASON_DUP:
    case REASON_DUP_SYS:
      fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
      if (reason == REASON_DUP_SYS)
	fprintf (stderr,
 _("  as it is a non-system directory that duplicates a system directory\n"));
      break;

    case REASON_NOENT:
      fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
	       path->name);
      break;

    case REASON_QUIET:
    default:
      break;
    }

  free (path->name);
  free (path);
}

/* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
   append all the names to the search path CHAIN.  */
static void
add_env_var_paths (const char *env_var, int chain)
{
  char *p, *q, *path;

  GET_ENVIRONMENT (q, env_var);

  if (!q)
    return;

  for (p = q; *q; p = q + 1)
    {
      q = p;
      while (*q != 0 && *q != PATH_SEPARATOR)
	q++;

      if (p == q)
	path = xstrdup (".");
      else
	{
	  path = xmalloc (q - p + 1);
	  memcpy (path, p, q - p);
	  path[q - p] = '\0';
	}

      add_path (path, chain, chain == SYSTEM, false);
    }
}

/* Append the standard include chain defined in cppdefault.c.  */
static void
add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
{
  const struct default_include *p;
  size_t len;

  if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
    {
      /* Look for directories that start with the standard prefix.
	 "Translate" them, i.e. replace /usr/local/lib/gcc... with
	 IPREFIX and search them first.  */
      for (p = cpp_include_defaults; p->fname; p++)
	{
	  if (!p->cplusplus || cxx_stdinc)
	    {
	      /* Should we be translating sysrooted dirs too?  Assume
		 that iprefix and sysroot are mutually exclusive, for
		 now.  */
	      if (sysroot && p->add_sysroot)
		continue;
	      if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
		{
		  char *str = concat (iprefix, p->fname + len, NULL);
		  add_path (str, SYSTEM, p->cxx_aware, false);
		}
	    }
	}
    }

  for (p = cpp_include_defaults; p->fname; p++)
    {
      if (!p->cplusplus || cxx_stdinc)
	{
	  char *str;

	  /* Should this directory start with the sysroot?  */
	  if (sysroot && p->add_sysroot)
	    str = concat (sysroot, p->fname, NULL);
	  else
	    str = update_path (p->fname, p->component);

	  add_path (str, SYSTEM, p->cxx_aware, false);
	}
    }
}


/* APPLE LOCAL begin headermaps 3871393 */ 
/* Private function that hashes the contents of the null-terminated
   string in a case-insensitive way.  For use by headermaps only.  */

static inline 
uint32 hmap_hash_string (const char *str)
{
  const char *sp;
  unsigned hash_code = 0;

  for (sp = str; *sp; sp++)
    hash_code += TOLOWER (*(const unsigned char *)sp) * 13;
  return hash_code;
}

/* Private function that case-insensitively compares the null-
   terminated string STR1 with the null-terminated string STR2.
   Returns 1 if equal, 0 if not.  For use by headermaps only.  */

static inline unsigned 
hmap_compare_strings (const char *str1, const char *str2)
{
  const char *s1p;
  const char *s2p;

  for (s1p = str1, s2p = str2; *s1p && *s2p; s1p++, s2p++)
    {
      if (TOLOWER (*s1p) != TOLOWER (*s2p))
	return 0;
    }
  return (*s1p == '\0' && *s2p == '\0');
}

/* Attempts to load a headermap from the file at path FILEPATH, and
   returns a pointer to the loaded data.  Returns NULL if for any
   reason the headermap cannot be loaded.  This function is silent if
   the given file does not appear to be a headermap; this is useful
   for checking whether or not it in fact is.  */

static struct hmap_header_map *
hmap_load_header_map (const char *filepath)
{
  struct hmap_header_map *headermap = NULL;

  if (filepath != NULL && filepath[0] != '\0')
    {
      FILE *        f;
      struct stat   f_info;

      /* Try to open the file for reading. */
      f = fopen (filepath, "rb");
      if (f != NULL)
	{
	  /* If it is a regular file and if it is large enough to be a header-
	     map, see if it really is one. */
	  if (fstat (fileno (f), &f_info) == 0 && S_ISREG(f_info.st_mode)
      /* APPLE LOCAL begin LLVM */
	    && (unsigned) f_info.st_size >= sizeof(struct hmap_header_map))
      /* APPLE LOCAL end LLVM */
	    {
	      unsigned   headermap_size = f_info.st_size;

	      headermap = (struct hmap_header_map *) xmalloc (headermap_size);
	      if (fread (headermap, 1, headermap_size, f) != headermap_size)
		{
		  /* For some reason we could not read the entire file. */
		  fprintf (stderr,
		    "warning: could not read \"%s\" (%s)\n",
		    filepath, xstrerror (errno));
		  free (headermap);
		  headermap = NULL;
		}
	      if (headermap->version == 1 && headermap->_reserved == 0)
		{
		  /* It might be a headermap. */
		  if (headermap->magic == HMAP_OPPOSITE_ENDIANNESS_MAGIC)
		    {
		      /* It's a headermap, but has the wrong endianness. */
		      fprintf (stderr,
			"warning: headermap \"%s\" has incompatible endianness\n",
			filepath);
		      free (headermap);
		      headermap = NULL;
		    }
		  else if (headermap->magic != HMAP_SAME_ENDIANNESS_MAGIC)
		    {
		      /* It's not a headermap after all. */
		      free (headermap);
		      headermap = NULL;
		    }
		}
	      else
		{
		   /* It's not a headermap after all. */
		   free (headermap);
		   headermap = NULL;
		}
	    }
	  fclose (f);
        }
    }
  return headermap;
}

/* Returns a pointer to a malloced string that contains the real pathname
   to the file, given the DIR that represents the headermap and given the
   name to be looked up.  This function looks in the headermap associated
   with DIR, if any.  If there is no headermap associated with DIR, or if
   it does not contain FILENAME, this function returns NULL.  The CONSTRUCT
   field of a cpp_dir that represents a headermap points to this function. */

static char *
hmap_construct_pathname (const char *filename, cpp_dir *dir)
{
  if (dir->header_map)
    {
      struct hmap_header_map *headermap;
      const char *strings;
      struct hmap_bucket *buckets;
      uint32 bucket_mask;
      uint32 i;
      uint32 key_offset;

      headermap = (struct hmap_header_map *)dir->header_map;
      strings = ((const char *)headermap) + headermap->strings_offset;
      buckets = headermap->buckets;
      bucket_mask = headermap->capacity-1;
      i = hmap_hash_string (filename) & bucket_mask;
      while ((key_offset = buckets[i].key) != HMAP_NOT_A_KEY)
	{
	  if (hmap_compare_strings (filename, strings+key_offset))
	    {
	      char *result_path;
	      unsigned prefix_length;
	      unsigned suffix_length;

	      prefix_length = strlen(strings + buckets[i].value.prefix);
	      suffix_length = strlen(strings + buckets[i].value.suffix);
	      result_path = xmalloc(prefix_length + suffix_length + 1);
	      memcpy(result_path,
		     strings + buckets[i].value.prefix,
		     prefix_length);
	      memcpy(result_path + prefix_length,
		     strings + buckets[i].value.suffix,
		     suffix_length);
	      result_path[prefix_length + suffix_length] = '\0';
	      return result_path;
	    }
	  i = (i + 1) & bucket_mask;
	}
      /* didn't find header in header map -- return NULL.  */
      return NULL;
    }
  else
    return NULL;
}
/* APPLE LOCAL end headermaps 3871393 */ 


/* For each duplicate path in chain HEAD, keep just the first one.
   Remove each path in chain HEAD that also exists in chain SYSTEM.
   Set the NEXT pointer of the last path in the resulting chain to
   JOIN, unless it duplicates JOIN in which case the last path is
   removed.  Return the head of the resulting chain.  Any of HEAD,
   JOIN and SYSTEM can be NULL.  */

static struct cpp_dir *
remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
		   struct cpp_dir *system, struct cpp_dir *join,
		   int verbose)
{
  struct cpp_dir **pcur, *tmp, *cur;
  struct stat st;

  for (pcur = &head; *pcur; )
    {
      int reason = REASON_QUIET;

      cur = *pcur;

      if (stat (cur->name, &st))
	{
	  /* Dirs that don't exist are silently ignored, unless verbose.  */
	  if (errno != ENOENT)
	    cpp_errno (pfile, CPP_DL_ERROR, cur->name);
	  else
	    {
	      /* If -Wmissing-include-dirs is given, warn.  */
	      cpp_options *opts = cpp_get_options (pfile);
	      if (opts->warn_missing_include_dirs && cur->user_supplied_p)
		cpp_errno (pfile, CPP_DL_WARNING, cur->name);
	      reason = REASON_NOENT;
	    }
	}
      else if (!S_ISDIR (st.st_mode))
	/* APPLE LOCAL begin headermaps 3871393 */
	{
	  /* Only check for headermap if this is a regular file and if there
	     is no path-constructor function in CUR. */
	  if (S_ISREG (st.st_mode) && !cur->construct)
	    {
	      /* Try to load the file as a headermap.  We will get back NULL
	         if this fails, and there won't be any warnings/errors emitted
	         unless the load function is fairly sure it's dealing with a
	         headermap file that is malformed.  */
	      struct hmap_header_map *header_map;

	      header_map = hmap_load_header_map (cur->name);
	      if (header_map)
		{
		  /* Successfully loaded a headermap.  Store a pointer to it
		     and set up the construct function pointer in cur.  */
		  cur->header_map = header_map;
		  cur->construct = hmap_construct_pathname;
		  pcur = &cur->next;
		  continue;
		}
	    }

	    /* If we fall through to here, it's some other kind of file.  */
	    cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
				 "%s: not a directory", cur->name);
	}
        /* APPLE LOCAL end headermaps 3871393 */
      else
	{
	  INO_T_COPY (cur->ino, st.st_ino);
	  cur->dev  = st.st_dev;

	  /* Remove this one if it is in the system chain.  */
	  reason = REASON_DUP_SYS;
	  for (tmp = system; tmp; tmp = tmp->next)
           if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev
               && cur->construct == tmp->construct)
	      break;

	  if (!tmp)
	    {
	      /* Duplicate of something earlier in the same chain?  */
	      reason = REASON_DUP;
	      for (tmp = head; tmp != cur; tmp = tmp->next)
               if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev
                   && cur->construct == tmp->construct)
		  break;

	      if (tmp == cur
		  /* Last in the chain and duplicate of JOIN?  */
		  && !(cur->next == NULL && join
		       && INO_T_EQ (cur->ino, join->ino)
                      && cur->dev == join->dev
                      && cur->construct == join->construct))
		{
		  /* Unique, so keep this directory.  */
		  pcur = &cur->next;
		  continue;
		}
	    }
	}

      /* Remove this entry from the chain.  */
      *pcur = cur->next;
      free_path (cur, verbose ? reason: REASON_QUIET);
    }

  *pcur = join;
  return head;
}

/* Merge the four include chains together in the order quote, bracket,
   system, after.  Remove duplicate dirs (as determined by
   INO_T_EQ()).

   We can't just merge the lists and then uniquify them because then
   we may lose directories from the <> search path that should be
   there; consider -iquote foo -iquote bar -Ifoo -Iquux.  It is
   however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if
   written -iquote bar -Ifoo -Iquux.  */

static void
merge_include_chains (cpp_reader *pfile, int verbose)
{
  /* Join the SYSTEM and AFTER chains.  Remove duplicates in the
     resulting SYSTEM chain.  */
  if (heads[SYSTEM])
    tails[SYSTEM]->next = heads[AFTER];
  else
    heads[SYSTEM] = heads[AFTER];
  heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);

  /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
     join it to SYSTEM.  */
  heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
				      heads[SYSTEM], verbose);

  /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
     join it to BRACKET.  */
  heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
				    heads[BRACKET], verbose);

  /* If verbose, print the list of dirs to search.  */
  if (verbose)
    {
      struct cpp_dir *p;

      fprintf (stderr, _("#include \"...\" search starts here:\n"));
      for (p = heads[QUOTE];; p = p->next)
	{
	  if (p == heads[BRACKET])
	    fprintf (stderr, _("#include <...> search starts here:\n"));
	  if (!p)
	    break;
	  /* APPLE LOCAL begin 5033355 */
	  if (p->construct == 0)
	    fprintf (stderr, " %s\n", p->name);
	  else if (p->construct == hmap_construct_pathname)
	    fprintf (stderr, " %s (headermap)\n", p->name);
	  else
	    fprintf (stderr, " %s (framework directory)\n", p->name);
	  /* APPLE LOCAL end 5033355 */
	}
      fprintf (stderr, _("End of search list.\n"));
    }
}

/* Use given -I paths for #include "..." but not #include <...>, and
   don't search the directory of the present file for #include "...".
   (Note that -I. -I- is not the same as the default setup; -I. uses
   the compiler's working dir.)  */
void
split_quote_chain (void)
{
  heads[QUOTE] = heads[BRACKET];
  tails[QUOTE] = tails[BRACKET];
  heads[BRACKET] = NULL;
  tails[BRACKET] = NULL;
  /* This is NOT redundant.  */
  quote_ignores_source_dir = true;
}

/* Add P to the chain specified by CHAIN.  */

void
add_cpp_dir_path (cpp_dir *p, int chain)
{
  if (tails[chain])
    tails[chain]->next = p;
  else
    heads[chain] = p;
  tails[chain] = p;
}

/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
   NUL-terminated.  */
void
add_path (char *path, int chain, int cxx_aware, bool user_supplied_p)
{
  cpp_dir *p;

#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
  /* Convert all backslashes to slashes.  The native CRT stat()
     function does not recognize a directory that ends in a backslash
     (unless it is a drive root dir, such "c:\").  Forward slashes,
     trailing or otherwise, cause no problems for stat().  */
  char* c;
  for (c = path; *c; c++)
    if (*c == '\\') *c = '/';
#endif

  p = xmalloc (sizeof (cpp_dir));
  p->next = NULL;
  p->name = path;
  if (chain == SYSTEM || chain == AFTER)
    p->sysp = 1 + !cxx_aware;
  else
    p->sysp = 0;
  p->construct = 0;
  p->user_supplied_p = user_supplied_p;

  add_cpp_dir_path (p, chain);
}

/* Exported function to handle include chain merging, duplicate
   removal, and registration with cpplib.  */
void
register_include_chains (cpp_reader *pfile, const char *sysroot,
			 const char *iprefix, int stdinc, int cxx_stdinc,
			 int verbose)
{
  static const char *const lang_env_vars[] =
    { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
      "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
  cpp_options *cpp_opts = cpp_get_options (pfile);
  size_t idx = (cpp_opts->objc ? 2: 0);

  if (cpp_opts->cplusplus)
    idx++;
  else
    cxx_stdinc = false;

  /* CPATH and language-dependent environment variables may add to the
     include chain.  */
  add_env_var_paths ("CPATH", BRACKET);
  add_env_var_paths (lang_env_vars[idx], SYSTEM);
  
  target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);

  /* Finally chain on the standard directories.  */
  if (stdinc)
    add_standard_paths (sysroot, iprefix, cxx_stdinc);

  target_c_incpath.extra_includes (sysroot, iprefix, stdinc);

  merge_include_chains (pfile, verbose);

  cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
			  quote_ignores_source_dir);
}
#if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES)
static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED,
					   const char *iprefix ATTRIBUTE_UNUSED,
					   int stdinc ATTRIBUTE_UNUSED)
{
}
#endif

#ifndef TARGET_EXTRA_INCLUDES
#define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int
#endif
#ifndef TARGET_EXTRA_PRE_INCLUDES
#define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int
#endif

struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES };

