+ name->found_count = 0;
+}
+
+/* Yield a newly allocated file name consisting of FILE_NAME concatenated to
+ NAME, with an intervening slash if FILE_NAME does not already end in one. */
+char *
+new_name (const char *file_name, const char *name)
+{
+ size_t file_name_len = strlen (file_name);
+ size_t namesize = strlen (name) + 1;
+ int slash = file_name_len && ! ISSLASH (file_name[file_name_len - 1]);
+ char *buffer = xmalloc (file_name_len + slash + namesize);
+ memcpy (buffer, file_name, file_name_len);
+ buffer[file_name_len] = '/';
+ memcpy (buffer + file_name_len + slash, name, namesize);
+ return buffer;
+}
+
+/* Return nonzero if file NAME is excluded. */
+bool
+excluded_name (char const *name)
+{
+ return excluded_filename (excluded, name + FILE_SYSTEM_PREFIX_LEN (name));
+}
+\f
+/* Hash tables of strings. */
+
+/* Calculate the hash of a string. */
+static unsigned
+hash_string_hasher (void const *name, unsigned n_buckets)
+{
+ return hash_string (name, n_buckets);
+}
+
+/* Compare two strings for equality. */
+static bool
+hash_string_compare (void const *name1, void const *name2)
+{
+ return strcmp (name1, name2) == 0;
+}
+
+/* Return zero if TABLE contains a copy of STRING; otherwise, insert a
+ copy of STRING to TABLE and return 1. */
+static bool
+hash_string_insert (Hash_table **table, char const *string)
+{
+ Hash_table *t = *table;
+ char *s = xstrdup (string);
+ char *e;
+
+ if (! ((t
+ || (*table = t = hash_initialize (0, 0, hash_string_hasher,
+ hash_string_compare, 0)))
+ && (e = hash_insert (t, s))))
+ xalloc_die ();
+
+ if (e == s)
+ return 1;
+ else
+ {
+ free (s);
+ return 0;
+ }
+}
+
+/* Return 1 if TABLE contains STRING. */
+static bool
+hash_string_lookup (Hash_table const *table, char const *string)
+{
+ return table && hash_lookup (table, string);
+}
+\f
+/* Names to avoid dumping. */
+static Hash_table *avoided_name_table;
+
+/* Remember to not archive NAME. */
+void
+add_avoided_name (char const *name)
+{
+ hash_string_insert (&avoided_name_table, name);