예제 #1
0
static string *subdir_match(str_list_type subdirs, string * matches)
{
    string *ret = XTALLOC1(string);
    unsigned len = 1;
    unsigned m;

    for (m = 0; matches[m]; m++) {
        size_t loc;
        unsigned e;
        string s = xstrdup(matches[m]);
        for (loc = strlen(s); loc > 0 && !IS_DIR_SEP(s[loc - 1]); loc--);
        while (loc > 0 && IS_DIR_SEP(s[loc - 1])) {
            loc--;
        }
        s[loc] = 0;             /* wipe out basename */

        for (e = 0; e < STR_LIST_LENGTH(subdirs); e++) {
            string subdir = STR_LIST_ELT(subdirs, e);
            size_t subdir_len = strlen(subdir);
            while (subdir_len > 0 && IS_DIR_SEP(subdir[subdir_len - 1])) {
                subdir_len--;
                subdir[subdir_len] = 0; /* remove trailing slashes from subdir spec */
            }
            if (FILESTRCASEEQ(subdir, s + loc - subdir_len)) {
                /* matched, save this one.  */
                XRETALLOC(ret, len + 1, string);
                ret[len - 1] = matches[m];
                len++;
            }
        }
        free(s);
    }
    ret[len - 1] = NULL;
    return ret;
}
예제 #2
0
void
str_list_add P2C(str_list_type *, l,  string, s)
{
  STR_LIST_LENGTH (*l)++;
  XRETALLOC (STR_LIST (*l), STR_LIST_LENGTH (*l), string);
  STR_LIST_LAST_ELT (*l) = s;
}
예제 #3
0
static void
cache (kpathsea kpse, const_string key,  str_llist_type *value)
{
  kpse->cache_length++;
  XRETALLOC (kpse->the_cache, kpse->cache_length, cache_entry);
  kpse->the_cache[kpse->cache_length - 1].key = xstrdup (key);
  kpse->the_cache[kpse->cache_length - 1].value = value;
}
예제 #4
0
static void
cache P2C(const_string, key,  str_llist_type *, value)
{
  cache_length++;
  XRETALLOC (the_cache, cache_length, cache_entry);
  the_cache[cache_length - 1].key = xstrdup (key);
  the_cache[cache_length - 1].value = value;
}
예제 #5
0
void
xputenv P2C(const_string, var_name,  const_string, value)
{
  static const_string *saved_env_items;
  static unsigned saved_len;
  string old_item = NULL;
  string new_item = concat3 (var_name, "=", value);

#ifndef SMART_PUTENV
  /* Check if we have saved anything yet.  */
  if (!saved_env_items)
    {
      saved_env_items = XTALLOC1 (const_string);
      saved_env_items[0] = var_name;
      saved_len = 1;
    }
  else
    {
      /* Check if we've assigned VAR_NAME before.  */
      unsigned i;
      unsigned len = strlen (var_name);
      for (i = 0; i < saved_len && !old_item; i++)
        {
          if (STREQ (saved_env_items[i], var_name))
            {
              old_item = getenv (var_name);
              assert (old_item);
              old_item -= (len + 1);  /* Back up to the `NAME='.  */
            }
        }
      
      if (!old_item)
        {
          /* If we haven't seen VAR_NAME before, save it.  Assume it is
             in safe storage.  */
          saved_len++;
          XRETALLOC (saved_env_items, saved_len, const_string);
          saved_env_items[saved_len - 1] = var_name;
        }
    }
#endif /* not SMART_PUTENV */

  /* As far as I can see there's no way to distinguish between the
     various errors; putenv doesn't have errno values.  */
  if (putenv (new_item) < 0)
    FATAL1 ("putenv (%s) failed", new_item);
  
#ifndef SMART_PUTENV
  /* Can't free `new_item' because its contained value is now in
     `environ', but we can free `old_item', since it's been replaced.  */
  if (old_item)
    free (old_item);
#endif /* not SMART_PUTENV */
}
예제 #6
0
void
str_list_concat P2C(str_list_type *, target,  str_list_type, more)
{
  unsigned e;
  unsigned prev_len = STR_LIST_LENGTH (*target);

  STR_LIST_LENGTH (*target) += STR_LIST_LENGTH (more);
  XRETALLOC (STR_LIST (*target), STR_LIST_LENGTH (*target), string);
  
  for (e = 0; e < STR_LIST_LENGTH (more); e++)
    STR_LIST_ELT (*target, prev_len + e) = STR_LIST_ELT (more, e);
}
예제 #7
0
static void
expanding P2C(const_string, var,  boolean, xp)
{
  unsigned e;
  for (e = 0; e < expansion_len; e++) {
    if (STREQ (expansions[e].var, var)) {
      expansions[e].expanding = xp;
      return;
    }
  }

  /* New variable, add it to the list.  */
  expansion_len++;
  XRETALLOC (expansions, expansion_len, expansion_type);
  expansions[expansion_len - 1].var = xstrdup (var);
  expansions[expansion_len - 1].expanding = xp;
}
예제 #8
0
static void
expanding (kpathsea kpse, const_string var, boolean xp)
{
  unsigned e;
  for (e = 0; e < kpse->expansion_len; e++) {
    if (STREQ (kpse->expansions[e].var, var)) {
      kpse->expansions[e].expanding = xp;
      return;
    }
  }

  /* New variable, add it to the list.  */
  kpse->expansion_len++;
  XRETALLOC (kpse->expansions, kpse->expansion_len, expansion_type);
  kpse->expansions[kpse->expansion_len - 1].var = xstrdup (var);
  kpse->expansions[kpse->expansion_len - 1].expanding = xp;
}
예제 #9
0
void
xputenv P2C(const_string, var_name,  const_string, value)
{
  string old_item = NULL;
  string new_item = concat3 (var_name, "=", value);
  unsigned name_len = strlen (var_name);

#ifndef SMART_PUTENV

  static const_string *saved_env_items = NULL;
  static unsigned saved_len;
  boolean found = false;

  /* Check if we have saved anything yet.  */
  if (!saved_env_items)
    {
      saved_env_items = XTALLOC1 (const_string);
      saved_env_items[0] = var_name;
      saved_len = 1;
    }
  else
    {
      /* Check if we've assigned VAR_NAME before.  */
      unsigned i;
      for (i = 0; i < saved_len && !found; i++)
        {
          if (STREQ (saved_env_items[i], var_name))
            {
              found = true;
              old_item = getenv (var_name);
#ifdef WIN32
	      /* win32 putenv() removes the variable if called with
		 "VAR=". So we have to cope with this case. Distinction
		 is not made between the value being "" or the variable
		 not set. */
	      if (old_item)
		old_item -= (name_len + 1);
#else
              assert (old_item);
              /* Back up to the `NAME=' in the environment before the
                 value that getenv returns.  */
              old_item -= (name_len + 1);
#endif
            }
        }

      if (!found)
        {
          /* If we haven't seen VAR_NAME before, save it.  Assume it is
             in safe storage.  */
          saved_len++;
          XRETALLOC (saved_env_items, saved_len, const_string);
          saved_env_items[saved_len - 1] = var_name;
        }
    }
#endif /* not SMART_PUTENV */

  /* If the old and the new values are identical, don't do anything.
     This is both more memory-efficient and safer as far as our
     assumptions (about how putenv is implemented in libc) go.  */
  if (!old_item || !STREQ (old_item, new_item))
    {
      char *new_val;
      /* As far as I can see there's no way to distinguish between the
         various errors; putenv doesn't have errno values.  */
      if (putenv (new_item) < 0)
        FATAL1 ("putenv (%s) failed", new_item);

      /* If their putenv copied `new_item', we can free it.  */
      new_val = getenv (var_name);
      if (new_val && new_val - name_len - 1 != new_item)
        free (new_item);

#ifndef SMART_PUTENV
      /* Can't free `new_item' because its contained value is now in
         `environ', but we can free `old_item', since it's been replaced.  */
#ifndef WIN32
      /* ... except on Win32, where old_item points to garbage.
         Or at least non free-able memory. Or at least, that's what
         BoundsChecker says... FP, 06/10/98) */
      if (old_item)
        free (old_item);
#endif
#endif /* not SMART_PUTENV */
    }
}