3 * $Id: atom.c,v 1.4 2003/12/15 20:53:47 mdw Exp $
7 * (c) 2000 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of the mLib utilities library.
14 * mLib is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
19 * mLib is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with mLib; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 /*----- Revision history --------------------------------------------------*
33 * Revision 1.4 2003/12/15 20:53:47 mdw
34 * Add global unihash table; use universal hashing instead of CRC.
36 * Revision 1.3 2001/01/25 21:13:15 mdw
37 * New function allowing an atom's length to be specified at intern time.
39 * Revision 1.2 2001/01/21 19:04:51 mdw
40 * Include `crc32.h' for @CRC32@ macro.
42 * Revision 1.1 2001/01/20 11:50:16 mdw
43 * Implementation of atom tables (for example, as found in X11).
47 /*----- Header files ------------------------------------------------------*/
58 /*----- Static variables --------------------------------------------------*/
60 static atom_table atoms
;
62 /*----- Handy macros ------------------------------------------------------*/
64 #define ATOM_RESOLVE(t) do { \
65 if (t == ATOM_GLOBAL) \
68 atom_createtable(t); \
71 /*----- Main code ---------------------------------------------------------*/
73 /* --- @atom_createtable@ --- *
75 * Arguments: @atom_table *t@ = pointer to an atom table
79 * Use: Initializes an atom table.
82 void atom_createtable(atom_table
*t
)
89 /* --- @atom_destroytable@ --- *
91 * Arguments: @atom_table *t@ = pointer to an atom table
95 * Use: Destroys all of the atoms in an atom table. All of the atoms
96 * (including uninterned atoms) are freed. Any references to
97 * atoms from the table become invalid, and any association
98 * tables dependent on the atom table are unusable, except that
99 * they may be destroyed safely.
102 void atom_destroytable(atom_table
*t
)
107 for (a
= (atom
*)t
->g
; a
; a
= aa
) {
108 aa
= (atom
*)a
->b
.b
.next
;
114 /* --- @atom_intern@, @atom_nintern@ --- *
116 * Arguments: @atom_table *t@ = pointer to an atom table
117 * @const char *p@ = pointer to the string to intern
118 * @size_t n@ = size of the string (for @atom_nintern)
120 * Returns: A pointer to the atom block for the given symbol string.
122 * Use: Interns an atom, returning the atom block. The string can be
123 * extracted from the atom by means of the @ATOM_NAME@ macro.
126 atom
*atom_intern(atom_table
*t
, const char *p
)
132 a
= sym_find(&t
->t
, p
, -1, sizeof(atom
), &f
);
138 atom
*atom_nintern(atom_table
*t
, const char *p
, size_t n
)
144 a
= sym_find(&t
->t
, p
, n
, sizeof(atom
), &f
);
150 /* --- @atom_gensym@ --- *
152 * Arguments: @atom_table *t@ = pointer to a symbol table
154 * Returns: A pointer to a new atom block, not previously interned.
156 * Use: Creates a new, uninterned atom. This atom will never be
157 * returned by either @atom_intern@ or any other call to
158 * @atom_gensym@, while the symbol table exists.
161 atom
*atom_gensym(atom_table
*t
)
168 sprintf(buf
, "*gen-%lu*", t
->gseq
++);
169 sz
= strlen(buf
) + 1;
170 a
= x_alloc(t
->t
.t
.a
, sizeof(atom
) + sz
);
171 a
->b
.name
= (char *)(a
+ 1);
172 memcpy(a
->b
.name
, buf
, sz
);
174 a
->b
.b
.hash
= UNIHASH(&unihash_global
, buf
, sz
);
181 /* --- @atom_name@ --- *
183 * Arguments: @atom *a@ = pointer to an atom
185 * Returns: The atom's textual name.
187 * Use: Given an atom, returns the name with which it was interned
188 * (or a made-up name if it was created using @gensym@.
191 const char *atom_name(const atom
*a
) { return ATOM_NAME(a
); }
193 /* --- @atom_len@ --- *
195 * Arguments: @atom *a@ = pointer to an atom
197 * Returns: The atom string's length.
199 * Use: Given an atom, return the length of its textual
203 size_t atom_len(const atom
*a
) { return ATOM_LEN(a
); }
205 /* --- @atom_hash@ --- *
207 * Arguments: @atom *a@ = pointer to an atom
209 * Returns: The atom's hash.
211 * Use: Given an atom, returns its hash.
214 uint32
atom_hash(const atom
*a
) { return ATOM_HASH(a
); }
216 /* --- @atom_mkiter@ , @atom_next@ --- *
218 * Arguments: @atom_table *t@ = pointer to an atom table
219 * @atom_iter *i@ = pointer to an iterator structure
221 * Returns: Next atom, for @atom_next@; nothing for @atom_mkiter@.
223 * Use: Iterates over atoms (both interned and uninterned).
226 void atom_mkiter(atom_iter
*i
, atom_table
*t
)
234 atom
*atom_next(atom_iter
*i
)
241 /*----- That's all, folks -------------------------------------------------*/