Ejemplo n.º 1
0
static void
convert_suffix_rule (const char *target, const char *source,
                     struct commands *cmds)
{
  const char **names, **percents;
  struct dep *deps;

  names = xmalloc (sizeof (const char *));
  percents = xmalloc (sizeof (const char *));

  if (target == 0)
    {
      /* Special case: TARGET being nil means we are defining a '.X.a' suffix
         rule; the target pattern is always '(%.o)'.  */
#ifdef VMS
      *names = strcache_add_len ("(%.obj)", 7);
#else
      *names = strcache_add_len ("(%.o)", 5);
#endif
      *percents = *names + 1;
    }
  else
    {
      /* Construct the target name.  */
      unsigned int len = strlen (target);
      char *p = alloca (1 + len + 1);
      p[0] = '%';
      memcpy (p + 1, target, len + 1);
      *names = strcache_add_len (p, len + 1);
      *percents = *names;
    }

  if (source == 0)
    deps = 0;
  else
    {
      /* Construct the dependency name.  */
      unsigned int len = strlen (source);
      char *p = alloca (1 + len + 1);
      p[0] = '%';
      memcpy (p + 1, source, len + 1);
      deps = alloc_dep ();
      deps->name = strcache_add_len (p, len + 1);
    }

  create_pattern_rule (names, percents, 1, 0, deps, cmds, 0);
}
Ejemplo n.º 2
0
/* Dependency or file strcache allocation / recording. */
static const char *
incdep_dep_strcache (struct incdep *cur, const char *str, int len)
{
  const char *ret;
  if (cur->worker_tid == -1)
    {
      /* Make sure the string is terminated before we hand it to
         strcache_add_len so it does have to make a temporary copy
         of it on the stack. */
      char ch = str[len];
      ((char *)str)[len] = '\0';
      ret = strcache_add_len (str, len);
      ((char *)str)[len] = ch;
    }
  else
    {
      /* Add it out the strcache of the thread. */
      ret = strcache2_add (&incdep_dep_strcaches[cur->worker_tid], str, len);
      ret = (const char *)strcache2_get_entry(&incdep_dep_strcaches[cur->worker_tid], ret);
    }
  return ret;
}
Ejemplo n.º 3
0
void
set_file_variables (struct file *file)
{
    struct dep *d;
    const char *at, *percent, *star, *less;

#ifndef	NO_ARCHIVES
    /* If the target is an archive member `lib(member)',
       then $@ is `lib' and $% is `member'.  */

    if (ar_name (file->name))
    {
        unsigned int len;
        const char *cp;
        char *p;

        cp = strchr (file->name, '(');
        p = alloca (cp - file->name + 1);
        memcpy (p, file->name, cp - file->name);
        p[cp - file->name] = '\0';
        at = p;
        len = strlen (cp + 1);
        p = alloca (len);
        memcpy (p, cp + 1, len - 1);
        p[len - 1] = '\0';
        percent = p;
    }
    else
#endif	/* NO_ARCHIVES.  */
    {
        at = file->name;
        percent = "";
    }

    /* $* is the stem from an implicit or static pattern rule.  */
    if (file->stem == 0)
    {
        /* In Unix make, $* is set to the target name with
        any suffix in the .SUFFIXES list stripped off for
         explicit rules.  We store this in the `stem' member.  */
        const char *name;
        unsigned int len;

#ifndef	NO_ARCHIVES
        if (ar_name (file->name))
        {
            name = strchr (file->name, '(') + 1;
            len = strlen (name) - 1;
        }
        else
#endif
        {
            name = file->name;
            len = strlen (name);
        }

        for (d = enter_file (strcache_add (".SUFFIXES"))->deps; d ; d = d->next)
        {
            unsigned int slen = strlen (dep_name (d));
            if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
            {
                file->stem = strcache_add_len (name, len - slen);
                break;
            }
        }
        if (d == 0)
            file->stem = "";
    }
    star = file->stem;

    /* $< is the first not order-only dependency.  */
    less = "";
    for (d = file->deps; d != 0; d = d->next)
        if (!d->ignore_mtime)
        {
            if (!d->need_2nd_expansion)
                less = dep_name (d);
            break;
        }

    if (file->cmds == default_file->cmds)
        /* This file got its commands from .DEFAULT.
           In this case $< is the same as $@.  */
        less = at;

#define	DEFINE_VARIABLE(name, len, value) \
  (void) define_variable_for_file (name,len,value,o_automatic,0,file)

    /* Define the variables.  */

    DEFINE_VARIABLE ("<", 1, less);
    DEFINE_VARIABLE ("*", 1, star);
    DEFINE_VARIABLE ("@", 1, at);
    DEFINE_VARIABLE ("%", 1, percent);

    /* Compute the values for $^, $+, $?, and $|.  */

    {
        static char *plus_value=0, *bar_value=0, *qmark_value=0;
        static unsigned int plus_max=0, bar_max=0, qmark_max=0;

        unsigned int qmark_len, plus_len, bar_len;
        char *cp;
        char *caret_value;
        char *qp;
        char *bp;
        unsigned int len;

        struct hash_table dep_hash;
        void **slot;

        /* Compute first the value for $+, which is supposed to contain
           duplicate dependencies as they were listed in the makefile.  */

        plus_len = 0;
        bar_len = 0;
        for (d = file->deps; d != 0; d = d->next)
        {
            if (!d->need_2nd_expansion)
            {
                if (d->ignore_mtime)
                    bar_len += strlen (dep_name (d)) + 1;
                else
                    plus_len += strlen (dep_name (d)) + 1;
            }
        }

        if (bar_len == 0)
            bar_len++;

        if (plus_len == 0)
            plus_len++;

        if (plus_len > plus_max)
            plus_value = xrealloc (plus_value, plus_max = plus_len);

        cp = plus_value;

        qmark_len = plus_len + 1;	/* Will be this or less.  */
        for (d = file->deps; d != 0; d = d->next)
            if (! d->ignore_mtime && ! d->need_2nd_expansion)
            {
                const char *c = dep_name (d);

#ifndef	NO_ARCHIVES
                if (ar_name (c))
                {
                    c = strchr (c, '(') + 1;
                    len = strlen (c) - 1;
                }
                else
#endif
                    len = strlen (c);

                memcpy (cp, c, len);
                cp += len;
                *cp++ = FILE_LIST_SEPARATOR;
                if (! (d->changed || always_make_flag))
                    qmark_len -= len + 1;	/* Don't space in $? for this one.  */
            }

        /* Kill the last space and define the variable.  */

        cp[cp > plus_value ? -1 : 0] = '\0';
        DEFINE_VARIABLE ("+", 1, plus_value);

        /* Compute the values for $^, $?, and $|.  */

        cp = caret_value = plus_value; /* Reuse the buffer; it's big enough.  */

        if (qmark_len > qmark_max)
            qmark_value = xrealloc (qmark_value, qmark_max = qmark_len);
        qp = qmark_value;

        if (bar_len > bar_max)
            bar_value = xrealloc (bar_value, bar_max = bar_len);
        bp = bar_value;

        /* Make sure that no dependencies are repeated in $^, $?, and $|.  It
           would be natural to combine the next two loops but we can't do it
           because of a situation where we have two dep entries, the first
           is order-only and the second is normal (see below).  */

        hash_init (&dep_hash, 500, dep_hash_1, dep_hash_2, dep_hash_cmp);

        for (d = file->deps; d != 0; d = d->next)
        {
            if (d->need_2nd_expansion)
                continue;

            slot = hash_find_slot (&dep_hash, d);
            if (HASH_VACANT (*slot))
                hash_insert_at (&dep_hash, d, slot);
            else
            {
                /* Check if the two prerequisites have different ignore_mtime.
                   If so then we need to "upgrade" one that is order-only.  */

                struct dep* hd = (struct dep*) *slot;

                if (d->ignore_mtime != hd->ignore_mtime)
                    d->ignore_mtime = hd->ignore_mtime = 0;
            }
        }

        for (d = file->deps; d != 0; d = d->next)
        {
            const char *c;

            if (d->need_2nd_expansion || hash_find_item (&dep_hash, d) != d)
                continue;

            c = dep_name (d);
#ifndef	NO_ARCHIVES
            if (ar_name (c))
            {
                c = strchr (c, '(') + 1;
                len = strlen (c) - 1;
            }
            else
#endif
                len = strlen (c);

            if (d->ignore_mtime)
            {
                memcpy (bp, c, len);
                bp += len;
                *bp++ = FILE_LIST_SEPARATOR;
            }
            else
            {
                memcpy (cp, c, len);
                cp += len;
                *cp++ = FILE_LIST_SEPARATOR;
                if (d->changed || always_make_flag)
                {
                    memcpy (qp, c, len);
                    qp += len;
                    *qp++ = FILE_LIST_SEPARATOR;
                }
            }
        }

        hash_free (&dep_hash, 0);

        /* Kill the last spaces and define the variables.  */

        cp[cp > caret_value ? -1 : 0] = '\0';
        DEFINE_VARIABLE ("^", 1, caret_value);

        qp[qp > qmark_value ? -1 : 0] = '\0';
        DEFINE_VARIABLE ("?", 1, qmark_value);

        bp[bp > bar_value ? -1 : 0] = '\0';
        DEFINE_VARIABLE ("|", 1, bar_value);
    }

#undef	DEFINE_VARIABLE
}