chiark / gitweb /
Infrastructure: Split the files into subdirectories.
[mLib] / struct / atom.h
diff --git a/struct/atom.h b/struct/atom.h
new file mode 100644 (file)
index 0000000..430f23b
--- /dev/null
@@ -0,0 +1,183 @@
+/* -*-c-*-
+ *
+ * Atom management
+ *
+ * (c) 2000 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the mLib utilities library.
+ *
+ * mLib is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * mLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with mLib; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef MLIB_ATOM_H
+#define MLIB_ATOM_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#ifndef MLIB_SYM_H
+#  include "sym.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct atom_table {
+  sym_table t;                         /* Symbol table of interned atoms */
+  hash_base *g;                                /* List of uninterned atoms */
+  unsigned long gseq;                  /* Sequence number for @gensym@ */
+} atom_table;
+
+typedef struct atom {
+  sym_base b;                          /* Base structure for symbol table */
+  unsigned f;                          /* Various useful flags */
+} atom;
+
+#define ATOMF_GENSYM 1u                        /* Atom is uninterned */
+
+typedef struct { sym_iter i; } atom_iter;
+
+/*----- Global magic ------------------------------------------------------*/
+
+#define ATOM_GLOBAL 0
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @atom_createtable@ --- *
+ *
+ * Arguments:  @atom_table *t@ = pointer to an atom table
+ *
+ * Returns:    ---
+ *
+ * Use:                Initializes an atom table.
+ */
+
+extern void atom_createtable(atom_table */*t*/);
+
+/* --- @atom_destroytable@ --- *
+ *
+ * Arguments:  @atom_table *t@ = pointer to an atom table
+ *
+ * Returns:    ---
+ *
+ * Use:                Destroys all of the atoms in an atom table.  All of the atoms
+ *             (including uninterned atoms) are freed.  Any references to
+ *             atoms from the table become invalid, and any association
+ *             tables dependent on the atom table are unusable, except that
+ *             they may be destroyed safely.
+ */
+
+extern void atom_destroytable(atom_table */*t*/);
+
+/* --- @atom_intern@ --- *
+ *
+ * Arguments:  @atom_table *t@ = pointer to an atom table
+ *             @const char *p@ = pointer to the string to intern
+ *             @size_t n@ = size of the string (for @atom_nintern)
+ *
+ * Returns:    A pointer to the atom block for the given symbol string.
+ *
+ * Use:                Interns an atom, returning the atom block.  The string can be
+ *             extracted from the atom by means of the @ATOM_NAME@ macro.
+ */
+
+#define INTERN(p) atom_intern(ATOM_GLOBAL, (p))
+
+extern atom *atom_intern(atom_table */*t*/, const char */*p*/);
+extern atom *atom_nintern(atom_table */*t*/,
+                         const char */*p*/, size_t /*n*/);
+
+/* --- @atom_gensym@ --- *
+ *
+ * Arguments:  @atom_table *t@ = pointer to a symbol table
+ *
+ * Returns:    A pointer to a new atom block, not previously interned.
+ *
+ * Use:                Creates a new, uninterned atom.  This atom will never be
+ *             returned by either @atom_intern@ or any other call to
+ *             @atom_gensym@, while the symbol table exists.
+ */
+
+#define GENSYM atom_gensym(ATOM_GLOBAL)
+
+extern atom *atom_gensym(atom_table */*t*/);
+
+/* --- @atom_name@ --- *
+ *
+ * Arguments:  @atom *a@ = pointer to an atom
+ *
+ * Returns:    The atom's textual name.
+ *
+ * Use:                Given an atom, returns the name with which it was interned
+ *             (or a made-up name if it was created using @gensym@.
+ */
+
+#define ATOM_NAME(a) SYM_NAME(a)
+
+extern const char *atom_name(const atom */*a*/);
+
+/* --- @atom_len@ --- *
+ *
+ * Arguments:  @atom *a@ = pointer to an atom
+ *
+ * Returns:    The atom string's length.
+ *
+ * Use:                Given an atom, return the length of its textual
+ *             representation.
+ */
+
+#define ATOM_LEN(a) SYM_LEN(a)
+
+extern size_t atom_len(const atom */*a*/);
+
+/* --- @atom_hash@ --- *
+ *
+ * Arguments:  @atom *a@ = pointer to an atom
+ *
+ * Returns:    The atom's hash.
+ *
+ * Use:                Given an atom, returns its hash.
+ */
+
+#define ATOM_HASH(a) SYM_HASH(a)
+
+extern uint32 atom_hash(const atom */*a*/);
+
+/* --- @atom_mkiter@ , @atom_next@ --- *
+ *
+ * Arguments:  @atom_table *t@ = pointer to an atom table
+ *             @atom_iter *i@ = pointer to an iterator structure
+ *
+ * Returns:    Next atom, for @atom_next@; nothing for @atom_mkiter@.
+ *
+ * Use:                Iterates over atoms (both interned and uninterned).
+ */
+
+extern void atom_mkiter(atom_iter */*i*/, atom_table */*t*/);
+extern atom *atom_next(atom_iter */*i*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif