3 .\" Manual for atom interning
5 .\" (c) 2001, 2005, 2009, 2023, 2024 Straylight/Edgeware
8 .\"----- Licensing notice ---------------------------------------------------
10 .\" This file is part of the mLib utilities library.
12 .\" mLib is free software: you can redistribute it and/or modify it under
13 .\" the terms of the GNU Library General Public License as published by
14 .\" the Free Software Foundation; either version 2 of the License, or (at
15 .\" your option) any later version.
17 .\" mLib is distributed in the hope that it will be useful, but WITHOUT
18 .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 .\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 .\" License for more details.
22 .\" You should have received a copy of the GNU Library General Public
23 .\" License along with mLib. If not, write to the Free Software
24 .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 .\"--------------------------------------------------------------------------
28 .so ../defs.man \" @@@PRE@@@
30 .\"--------------------------------------------------------------------------
31 .TH atom 3mLib "21 January 2001" "Straylight/Edgeware" "mLib utilities library"
33 .\" @atom_destroytable
50 .\"--------------------------------------------------------------------------
52 atom \- atom table manager
57 .B "#include <mLib/atom.h>"
59 .B "typedef struct { ...\& } atom_table;"
60 .B "typedef struct { ...\& } atom;"
62 .BI "void atom_createtable(atom_table *" t );
63 .BI "void atom_destroytable(atom_table *" t );
65 .BI "atom *atom_intern(atom_table *" t ", const char *" p );
66 .BI "atom *atom_nintern(atom_table *" t ", const char *" p ", size_t " n );
67 .BI "atom *atom_gensym(atom_table *" t );
68 .BI "atom *INTERN(const char *" p );
71 .BI "const char *atom_name(const atom *" a );
72 .BI "size_t atom_len(const atom *" a );
73 .BI "uint32 atom_hash(const atom *" a );
74 .BI "const char *ATOM_NAME(const atom *" a );
75 .BI "size_t ATOM_LEN(const atom *" a );
76 .BI "uint32 ATOM_HASH(const atom *" a );
78 .BI "void atom_mkiter(atom_iter *" i ", atom_table *" t );
79 .BI "atom *atom_next(atom_iter *" i );
81 .BI "extern atom_table *ATOM_GLOBAL;"
84 .\"--------------------------------------------------------------------------
88 functions and macros implement a data type similar to immutable strings,
89 with an additional property: that the addresses of two atoms from the
90 same table are equal if and only if they contain the same text. Atom
91 strings don't have to be null-terminated, although the interface is
92 simpler if you know that all of your atoms are null-terminated. It's
94 .IR "uninterned atoms" :
97 If a necessary memory allocation fails during an atom operation, the
102 Atoms are useful for speeding up string comparisons, and for saving
103 memory when many possibly-identical strings need storing.
105 There is a global atom table, named
107 available for general use. You can initialize your own atom table if
108 either you want to ensure that the atoms are not shared with some other
109 table, or if you want to be able to free the atoms later. Private atom
112 initialize it using the function
114 and free it when you're finished using
115 .BR atom_destroytable .
117 .SS "Creating atoms from strings"
118 The process of making atoms from strings is called
122 takes an atom table, a string, and a length, and returns an atom with
123 the same text. If your string is null-terminated, you can instead use
125 which has no length argument; if, in addition, you want to use the
126 global atom table, you can use the single-argument
128 macro, which takes just a null-terminated string.
130 A terminating null byte is always appended to an atom name. This is not
131 considered to be a part of the name itself, and does not contribute to
132 the atom's length as reported by the
136 .SS "Uninterned atoms"
137 You can make an atom which is guaranteed to be distinct from every other
138 atom, and has no sensible text string, by calling
140 passing it the address of your atom table. The macro
142 (which doesn't look like a function, and has no parentheses following
143 it!) will return a unique atom from the global table. Uninterned atoms
144 have a generated name of the form
145 .RB ` *gen- \fInnn * '
148 is an atom-table-specific sequence number. This text is there as a
149 debugging convenience, and doesn't mean that the uninterned atom has the
150 same address as an interned atom with the same text.
152 .SS "Other enquiries about atoms"
153 Atoms can be interrogated to find their names and hashes. The macro
155 returns a pointer to the atom's name (its text);
157 returns the length of the atom's name, excluding the terminating null;
160 returns the atom's hash value, which is useful if you want to use the
161 atom as a key in some other structure. There are lower-case function
162 versions of these, which have the same effect. There is little point in
165 .SS "Enumerating atoms"
166 You can iterate over the atoms in an atom table. The
168 function initializes an iterator object to iterate over a particular
171 returns the next atom from the iterator. Atoms are not returned in any
174 .\"--------------------------------------------------------------------------
181 .\"--------------------------------------------------------------------------
184 Mark Wooding, <mdw@distorted.org.uk>
186 .\"----- That's all, folks --------------------------------------------------