1025598e |
1 | .\" -*-nroff-*- |
2 | .de VS |
3 | .sp 1 |
4 | .RS |
5 | .nf |
6 | .ft B |
7 | .. |
8 | .de VE |
9 | .ft R |
10 | .fi |
11 | .RE |
12 | .sp 1 |
13 | .. |
fbf20b5b |
14 | .TH atom 3 "21 January 2001" "Straylight/Edgeware" "mLib utilities library" |
1025598e |
15 | .SH NAME |
16 | atom \- atom table manager |
17 | .\" @atom_createtable |
18 | .\" @atom_destroytable |
19 | .\" @atom_intern |
20 | .\" @atom_nintern |
21 | .\" @atom_gensym |
22 | .\" @atom_name |
23 | .\" @atom_len |
24 | .\" @atom_hash |
25 | .\" @atom_mkiter |
26 | .\" @atom_next |
27 | .\" |
28 | .\" @ATOM_GLOBAL |
29 | .\" @INTERN |
30 | .\" @GENSYM |
31 | .\" @ATOM_NAME |
32 | .\" @ATOM_LEN |
33 | .\" @ATOM_HASH |
34 | .\" |
35 | .SH SYNOPSIS |
36 | .nf |
37 | .B "#include <mLib/atom.h>" |
38 | |
39 | .BI "void atom_createtable(atom_table *" t ); |
40 | .BI "void atom_destroytable(atom_table *" t ); |
41 | |
42 | .BI "atom *atom_intern(atom_table *" t ", const char *" p ); |
43 | .BI "atom *atom_nintern(atom_table *" t ", const char *" p ", size_t " n ); |
44 | .BI "atom *atom_gensym(atom_table *" t ); |
45 | .BI "atom *INTERN(const char *" p ); |
46 | .BI "atom *GENSYM;" |
47 | |
48 | .BI "const char *atom_name(const atom *" a ); |
49 | .BI "size_t atom_len(const atom *" a ); |
50 | .BI "uint32 atom_hash(const atom *" a ); |
51 | .BI "const char *ATOM_NAME(const atom *" a ); |
52 | .BI "size_t ATOM_LEN(const atom *" a ); |
53 | .BI "uint32 ATOM_HASH(const atom *" a ); |
54 | |
55 | .BI "void atom_mkiter(atom_iter *" i ", atom_table *" t ); |
56 | .BI "atom *atom_next(atom_iter *" i ); |
57 | |
58 | .BI "extern atom_table *ATOM_GLOBAL;" |
59 | .fi |
60 | .SH DESCRIPTION |
61 | The |
62 | .B atom |
63 | functions and macros implement a data type similar to immutable strings, |
64 | with an additional property: that the addresses of two atoms from the |
65 | same table are equal if and only if they contain the same text. Atom |
66 | strings don't have to be null-terminated, although the interface is |
67 | simpler if you know that all of your atoms are null-terminated. It's |
68 | also possible to make |
69 | .IR "uninterned atoms" : |
70 | see below. |
71 | .PP |
72 | If a necessary memory allocation fails during an atom operation, the |
73 | exception |
74 | .B EXC_NOMEM |
75 | is raised. |
76 | .PP |
77 | Atoms are useful for speeding up string comparisons, and for saving |
78 | memory when many possibly-identical strings need storing. |
79 | .PP |
80 | There is a global atom table, named |
81 | .BR ATOM_GLOBAL , |
82 | available for general use. You can initialize your own atom table if |
83 | either you want to ensure that the atoms are not shared with some other |
84 | table, or if you want to be able to free the atoms later. Private atom |
85 | tables have the type |
86 | .BR atom_table ; |
87 | initialize it using the function |
88 | .B atom_createtable |
89 | and free it when you're finished using |
90 | .BR atom_destroytable . |
91 | .SS "Creating atoms from strings" |
92 | The process of making atoms from strings is called |
93 | .IR interning . |
94 | The function |
95 | .B atom_nintern |
96 | takes an atom table, a string, and a length, and returns an atom with |
97 | the same text. If your string is null-terminated, you can instead use |
98 | .B atom_intern |
99 | which has no length argument; if, in addition, you want to use the |
100 | global atom table, you can use the single-argument |
101 | .B INTERN |
102 | macro, which takes just a null-terminated string. |
103 | .PP |
104 | A terminating null byte is always appended to an atom name. This is not |
105 | considered to be a part of the name itself, and does not contribute to |
106 | the atom's length as reported by the |
107 | .B ATOM_LEN |
108 | macro. |
109 | .SS "Uninterned atoms" |
110 | You can make an atom which is guaranteed to be distinct from every other |
111 | atom, and has no sensible text string, by calling |
112 | .BR atom_gensym , |
113 | passing it the address of your atom table. The macro |
114 | .B GENSYM |
115 | (which doesn't look like a function, and has no parentheses following |
116 | it!) will return a unique atom from the global table. Uninterned atoms |
117 | have a generated name of the form |
118 | .RB ` *gen- \fInnn * ' |
119 | where |
120 | .I nnn |
121 | is an atom-table-specific sequence number. This text is there as a |
122 | debugging convenience, and doesn't mean that the uninterned atom has the |
123 | same address as an interned atom with the same text. |
124 | .SS "Other enquiries about atoms" |
125 | Atoms can be interrogated to find their names and hashes. The macro |
126 | .B ATOM_NAME |
127 | returns a pointer to the atom's name (its text); |
128 | .B ATOM_LEN |
129 | returns the length of the atom's name, excluding the terminating null; |
130 | and |
131 | .B ATOM_HASH |
132 | returns the atom's hash value, which is useful if you want to use the |
133 | atom as a key in some other structure. There are lower-case function |
134 | versions of these, which have the same effect. There is little point in |
135 | using the functions. |
136 | .SS "Enumerating atoms" |
137 | You can iterate over the atoms in an atom table. The |
138 | .B atom_mkiter |
139 | function initializes an iterator object to iterate over a particular |
140 | atom table; |
141 | .B atom_next |
142 | returns the next atom from the iterator. Atoms are not returned in any |
143 | particular order. |
144 | .SH SEE ALSO |
145 | .BR assoc (3), |
146 | .BR hash (3), |
147 | .BR mLib (3). |
148 | .SH AUTHOR |
9b5ac6ff |
149 | Mark Wooding, <mdw@distorted.org.uk> |