chiark / gitweb /
@@@ tty mess
[mLib] / struct / atom.3.in
1 .\" -*-nroff-*-
2 .\"
3 .\" Manual for atom interning
4 .\"
5 .\" (c) 2001, 2005, 2009, 2023, 2024 Straylight/Edgeware
6 .\"
7 .
8 .\"----- Licensing notice ---------------------------------------------------
9 .\"
10 .\" This file is part of the mLib utilities library.
11 .\"
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.
16 .\"
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.
21 .\"
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,
25 .\" USA.
26 .
27 .\"--------------------------------------------------------------------------
28 .so ../defs.man \" @@@PRE@@@
29 .
30 .\"--------------------------------------------------------------------------
31 .TH atom 3mLib "21 January 2001" "Straylight/Edgeware" "mLib utilities library"
32 .\" @atom_createtable
33 .\" @atom_destroytable
34 .\" @atom_intern
35 .\" @atom_nintern
36 .\" @atom_gensym
37 .\" @atom_name
38 .\" @atom_len
39 .\" @atom_hash
40 .\" @atom_mkiter
41 .\" @atom_next
42 .
43 .\" @ATOM_GLOBAL
44 .\" @INTERN
45 .\" @GENSYM
46 .\" @ATOM_NAME
47 .\" @ATOM_LEN
48 .\" @ATOM_HASH
49 .
50 .\"--------------------------------------------------------------------------
51 .SH NAME
52 atom \- atom table manager
53 .
54 .SH SYNOPSIS
55 .
56 .nf
57 .B "#include <mLib/atom.h>"
58 .PP
59 .B "typedef struct { ...\& } atom_table;"
60 .B "typedef struct { ...\& } atom;"
61 .PP
62 .BI "void atom_createtable(atom_table *" t );
63 .BI "void atom_destroytable(atom_table *" t );
64 .PP
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 );
69 .BI "atom *GENSYM;"
70 .PP
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 );
77 .PP
78 .BI "void atom_mkiter(atom_iter *" i ", atom_table *" t );
79 .BI "atom *atom_next(atom_iter *" i );
80 .PP
81 .BI "extern atom_table *ATOM_GLOBAL;"
82 .fi
83 .
84 .\"--------------------------------------------------------------------------
85 .SH DESCRIPTION
86 The
87 .B atom
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
93 also possible to make
94 .IR "uninterned atoms" :
95 see below.
96 .PP
97 If a necessary memory allocation fails during an atom operation, the
98 exception
99 .B EXC_NOMEM
100 is raised.
101 .PP
102 Atoms are useful for speeding up string comparisons, and for saving
103 memory when many possibly-identical strings need storing.
104 .PP
105 There is a global atom table, named
106 .BR ATOM_GLOBAL ,
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
110 tables have the type
111 .BR atom_table ;
112 initialize it using the function
113 .B atom_createtable
114 and free it when you're finished using
115 .BR atom_destroytable .
116 .
117 .SS "Creating atoms from strings"
118 The process of making atoms from strings is called
119 .IR interning .
120 The function
121 .B atom_nintern
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
124 .B atom_intern
125 which has no length argument; if, in addition, you want to use the
126 global atom table, you can use the single-argument
127 .B INTERN
128 macro, which takes just a null-terminated string.
129 .PP
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
133 .B ATOM_LEN
134 macro.
135 .
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
139 .BR atom_gensym ,
140 passing it the address of your atom table.  The macro
141 .B GENSYM
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 * '
146 where
147 .I nnn
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.
151 .
152 .SS "Other enquiries about atoms"
153 Atoms can be interrogated to find their names and hashes.  The macro
154 .B ATOM_NAME
155 returns a pointer to the atom's name (its text);
156 .B ATOM_LEN
157 returns the length of the atom's name, excluding the terminating null;
158 and
159 .B ATOM_HASH
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
163 using the functions.
164 .
165 .SS "Enumerating atoms"
166 You can iterate over the atoms in an atom table.  The
167 .B atom_mkiter
168 function initializes an iterator object to iterate over a particular
169 atom table;
170 .B atom_next
171 returns the next atom from the iterator.  Atoms are not returned in any
172 particular order.
173 .
174 .\"--------------------------------------------------------------------------
175 .SH SEE ALSO
176 .
177 .BR assoc (3),
178 .BR hash (3),
179 .BR mLib (3).
180 .
181 .\"--------------------------------------------------------------------------
182 .SH AUTHOR
183 .
184 Mark Wooding, <mdw@distorted.org.uk>
185 .
186 .\"----- That's all, folks --------------------------------------------------