/* Dependency generator for Makefile fragments.
   Copyright (C) 2000, 2001, 2003, 2007, 2008, 2009
   Free Software Foundation, Inc.
   Contributed by Zack Weinberg, Mar 2000

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, 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; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.

 In other words, you are welcome to use, share and improve this program.
 You are forbidden to forbid anyone else to use, share and improve
 what you give them.   Help stamp out software-hoarding!  */

#include "config.h"
#include "system.h"
#include "mkdeps.h"

/* Keep this structure local to this file, so clients don't find it
   easy to start making assumptions.  */
struct deps
{
  const char **targetv;
  unsigned int ntargets;	/* number of slots actually occupied */
  unsigned int targets_size;	/* amt of allocated space - in words */

  const char **depv;
  unsigned int ndeps;
  unsigned int deps_size;

  const char **vpathv;
  size_t *vpathlv;
  unsigned int nvpaths;
  unsigned int vpaths_size;
};

static const char *munge (const char *);

/* Given a filename, quote characters in that filename which are
   significant to Make.  Note that it's not possible to quote all such
   characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
   not properly handled.  It isn't possible to get this right in any
   current version of Make.  (??? Still true?  Old comment referred to
   3.76.1.)  */

static const char *
munge (const char *filename)
{
  int len;
  const char *p, *q;
  char *dst, *buffer;

  for (p = filename, len = 0; *p; p++, len++)
    {
      switch (*p)
	{
	case ' ':
	case '\t':
	  /* GNU make uses a weird quoting scheme for white space.
	     A space or tab preceded by 2N+1 backslashes represents
	     N backslashes followed by space; a space or tab
	     preceded by 2N backslashes represents N backslashes at
	     the end of a file name; and backslashes in other
	     contexts should not be doubled.  */
	  for (q = p - 1; filename <= q && *q == '\\';  q--)
	    len++;
	  len++;
	  break;

	case '$':
	  /* '$' is quoted by doubling it.  */
	  len++;
	  break;

	case '#':
	  /* '#' is quoted with a backslash.  */
	  len++;
	  break;
	}
    }

  /* Now we know how big to make the buffer.  */
  buffer = XNEWVEC (char, len + 1);

  for (p = filename, dst = buffer; *p; p++, dst++)
    {
      switch (*p)
	{
	case ' ':
	case '\t':
	  for (q = p - 1; filename <= q && *q == '\\';  q--)
	    *dst++ = '\\';
	  *dst++ = '\\';
	  break;

	case '$':
	  *dst++ = '$';
	  break;

	case '#':
	  *dst++ = '\\';
	  break;

	default:
	  /* nothing */;
	}
      *dst = *p;
    }

  *dst = '\0';
  return buffer;
}

/* If T begins with any of the partial pathnames listed in d->vpathv,
   then advance T to point beyond that pathname.  */
static const char *
apply_vpath (struct deps *d, const char *t)
{
  if (d->vpathv)
    {
      unsigned int i;
      for (i = 0; i < d->nvpaths; i++)
	{
	  if (!strncmp (d->vpathv[i], t, d->vpathlv[i]))
	    {
	      const char *p = t + d->vpathlv[i];
	      if (!IS_DIR_SEPARATOR (*p))
		goto not_this_one;

	      /* Do not simplify $(vpath)/../whatever.  ??? Might not
		 be necessary. */
	      if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
		goto not_this_one;

	      /* found a match */
	      t = t + d->vpathlv[i] + 1;
	      break;
	    }
	not_this_one:;
	}
    }

  /* Remove leading ./ in any case.  */
  while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
    {
      t += 2;
      /* If we removed a leading ./, then also remove any /s after the
	 first.  */
      while (IS_DIR_SEPARATOR (t[0]))
	++t;
    }

  return t;
}

/* Public routines.  */

struct deps *
deps_init (void)
{
  return XCNEW (struct deps);
}

void
deps_free (struct deps *d)
{
  unsigned int i;

  if (d->targetv)
    {
      for (i = 0; i < d->ntargets; i++)
	free ((void *) d->targetv[i]);
      free (d->targetv);
    }

  if (d->depv)
    {
      for (i = 0; i < d->ndeps; i++)
	free ((void *) d->depv[i]);
      free (d->depv);
    }

  if (d->vpathv)
    {
      for (i = 0; i < d->nvpaths; i++)
	free ((void *) d->vpathv[i]);
      free (d->vpathv);
      free (d->vpathlv);
    }

  free (d);
}

/* Adds a target T.  We make a copy, so it need not be a permanent
   string.  QUOTE is true if the string should be quoted.  */
void
deps_add_target (struct deps *d, const char *t, int quote)
{
  if (d->ntargets == d->targets_size)
    {
      d->targets_size = d->targets_size * 2 + 4;
      d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size);
    }

  t = apply_vpath (d, t);
  if (quote)
    t = munge (t);  /* Also makes permanent copy.  */
  else
    t = xstrdup (t);

  d->targetv[d->ntargets++] = t;
}

/* Sets the default target if none has been given already.  An empty
   string as the default target in interpreted as stdin.  The string
   is quoted for MAKE.  */
void
deps_add_default_target (struct deps *d, const char *tgt)
{
  /* Only if we have no targets.  */
  if (d->ntargets)
    return;

  if (tgt[0] == '\0')
    deps_add_target (d, "-", 1);
  else
    {
#ifndef TARGET_OBJECT_SUFFIX
# define TARGET_OBJECT_SUFFIX ".o"
#endif
      const char *start = lbasename (tgt);
      char *o = (char *) alloca (strlen (start)
                                 + strlen (TARGET_OBJECT_SUFFIX) + 1);
      char *suffix;

      strcpy (o, start);

      suffix = strrchr (o, '.');
      if (!suffix)
        suffix = o + strlen (o);
      strcpy (suffix, TARGET_OBJECT_SUFFIX);

      deps_add_target (d, o, 1);
    }
}

void
deps_add_dep (struct deps *d, const char *t)
{
  t = munge (apply_vpath (d, t));  /* Also makes permanent copy.  */

  if (d->ndeps == d->deps_size)
    {
      d->deps_size = d->deps_size * 2 + 8;
      d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size);
    }
  d->depv[d->ndeps++] = t;
}

void
deps_add_vpath (struct deps *d, const char *vpath)
{
  const char *elem, *p;
  char *copy;
  size_t len;

  for (elem = vpath; *elem; elem = p)
    {
      for (p = elem; *p && *p != ':'; p++);
      len = p - elem;
      copy = XNEWVEC (char, len + 1);
      memcpy (copy, elem, len);
      copy[len] = '\0';
      if (*p == ':')
	p++;

      if (d->nvpaths == d->vpaths_size)
	{
	  d->vpaths_size = d->vpaths_size * 2 + 8;
	  d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size);
	  d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size);
	}
      d->vpathv[d->nvpaths] = copy;
      d->vpathlv[d->nvpaths] = len;
      d->nvpaths++;
    }
}

void
deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
{
  unsigned int size, i, column;

  column = 0;
  if (colmax && colmax < 34)
    colmax = 34;

  for (i = 0; i < d->ntargets; i++)
    {
      size = strlen (d->targetv[i]);
      column += size;
      if (i)
	{
	  if (colmax && column > colmax)
	    {
	      fputs (" \\\n ", fp);
	      column = 1 + size;
	    }
	  else
	    {
	      putc (' ', fp);
	      column++;
	    }
	}
      fputs (d->targetv[i], fp);
    }

  putc (':', fp);
  column++;

  for (i = 0; i < d->ndeps; i++)
    {
      size = strlen (d->depv[i]);
      column += size;
      if (colmax && column > colmax)
	{
	  fputs (" \\\n ", fp);
	  column = 1 + size;
	}
      else
	{
	  putc (' ', fp);
	  column++;
	}
      fputs (d->depv[i], fp);
    }
  putc ('\n', fp);
}

void
deps_phony_targets (const struct deps *d, FILE *fp)
{
  unsigned int i;

  for (i = 1; i < d->ndeps; i++)
    {
      putc ('\n', fp);
      fputs (d->depv[i], fp);
      putc (':', fp);
      putc ('\n', fp);
    }
}

/* Write out a deps buffer to a file, in a form that can be read back
   with deps_restore.  Returns nonzero on error, in which case the
   error number will be in errno.  */

int
deps_save (struct deps *deps, FILE *f)
{
  unsigned int i;

  /* The cppreader structure contains makefile dependences.  Write out this
     structure.  */

  /* The number of dependences.  */
  if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
      return -1;
  /* The length of each dependence followed by the string.  */
  for (i = 0; i < deps->ndeps; i++)
    {
      size_t num_to_write = strlen (deps->depv[i]);
      if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
          return -1;
      if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
          return -1;
    }

  return 0;
}

/* Read back dependency information written with deps_save into
   the deps buffer.  The third argument may be NULL, in which case
   the dependency information is just skipped, or it may be a filename,
   in which case that filename is skipped.  */

int
deps_restore (struct deps *deps, FILE *fd, const char *self)
{
  unsigned int i, count;
  size_t num_to_read;
  size_t buf_size = 512;
  char *buf = XNEWVEC (char, buf_size);

  /* Number of dependences.  */
  if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
    return -1;

  /* The length of each dependence string, followed by the string.  */
  for (i = 0; i < count; i++)
    {
      /* Read in # bytes in string.  */
      if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
	return -1;
      if (buf_size < num_to_read + 1)
	{
	  buf_size = num_to_read + 1 + 127;
	  buf = XRESIZEVEC (char, buf, buf_size);
	}
      if (fread (buf, 1, num_to_read, fd) != num_to_read)
	return -1;
      buf[num_to_read] = '\0';

      /* Generate makefile dependencies from .pch if -nopch-deps.  */
      if (self != NULL && strcmp (buf, self) != 0)
        deps_add_dep (deps, buf);
    }

  free (buf);
  return 0;
}
