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; }
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; }
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; }
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; }
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 */ }
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); }
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; }
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; }
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 */ } }