-\f
-/* Atoms: reference-counted constant strings. */
-
-/* An atom. */
-struct atom
- {
- struct hmap_node node; /* Hash map node. */
- char *string; /* String value. */
- unsigned ref_count; /* Number of references. */
- };
-
-/* Hash table of atoms. */
-static struct hmap atoms = HMAP_INITIALIZER (atoms);
-
-static void free_atom (struct atom *atom);
-static void free_all_atoms (void);
-
-/* Creates and returns an atom for STRING. */
-static struct atom *
-atom_create (const char *string)
-{
- static bool initialized;
- struct atom *atom;
- size_t hash;
-
- assert (string != NULL);
-
- if (!initialized)
- {
- initialized = true;
- atexit (free_all_atoms);
- }
-
- hash = hash_string (string, 0);
- HMAP_FOR_EACH_WITH_HASH (atom, struct atom, node, hash, &atoms)
- if (!strcmp (atom->string, string))
- {
- atom->ref_count++;
- return atom;
- }
-
- atom = xmalloc (sizeof *atom);
- atom->string = xstrdup (string);
- atom->ref_count = 1;
- hmap_insert (&atoms, &atom->node, hash);
- return atom;
-}
-
-/* Destroys ATOM. */
-static void
-atom_destroy (struct atom *atom)
-{
- if (atom != NULL)
- {
- assert (atom->ref_count > 0);
- atom->ref_count--;
- if (atom->ref_count == 0)
- {
- hmap_delete (&atoms, &atom->node);
- free_atom (atom);
- }
- }
-}
-
-/* Returns the string associated with ATOM. */
-static const char *
-atom_to_string (const struct atom *atom)
-{
- return atom->string;
-}
-
-static void
-free_atom (struct atom *atom)
-{
- free (atom->string);
- free (atom);
-}
-
-static void
-free_all_atoms (void)
-{
- struct atom *atom, *next;
-
- HMAP_FOR_EACH_SAFE (atom, next, struct atom, node, &atoms)
- free_atom (atom);
-}