chiark / gitweb /
Remove redundant initialization of `sub'.
[mLib] / atom.c
CommitLineData
c1c43500 1/* -*-c-*-
2 *
3 * $Id: atom.c,v 1.1 2001/01/20 11:50:16 mdw Exp $
4 *
5 * Atom management
6 *
7 * (c) 2000 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of the mLib utilities library.
13 *
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.
18 *
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.
23 *
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,
27 * MA 02111-1307, USA.
28 */
29
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: atom.c,v $
33 * Revision 1.1 2001/01/20 11:50:16 mdw
34 * Implementation of atom tables (for example, as found in X11).
35 *
36 */
37
38/*----- Header files ------------------------------------------------------*/
39
40#include <stdio.h>
41#include <string.h>
42
43#include "alloc.h"
44#include "atom.h"
45#include "hash.h"
46#include "sym.h"
47
48/*----- Static variables --------------------------------------------------*/
49
50static atom_table atoms;
51
52/*----- Handy macros ------------------------------------------------------*/
53
54#define ATOM_RESOLVE(t) do { \
55 if (t == ATOM_GLOBAL) \
56 t = &atoms; \
57 if (!t->t.t.v) \
58 atom_createtable(t); \
59} while (0)
60
61/*----- Main code ---------------------------------------------------------*/
62
63/* --- @atom_createtable@ --- *
64 *
65 * Arguments: @atom_table *t@ = pointer to an atom table
66 *
67 * Returns: ---
68 *
69 * Use: Initializes an atom table.
70 */
71
72void atom_createtable(atom_table *t)
73{
74 sym_create(&t->t);
75 t->g = 0;
76 t->gseq = 0;
77}
78
79/* --- @atom_destroytable@ --- *
80 *
81 * Arguments: @atom_table *t@ = pointer to an atom table
82 *
83 * Returns: ---
84 *
85 * Use: Destroys all of the atoms in an atom table. All of the atoms
86 * (including uninterned atoms) are freed. Any references to
87 * atoms from the table become invalid, and any association
88 * tables dependent on the atom table are unusable, except that
89 * they may be destroyed safely.
90 */
91
92void atom_destroytable(atom_table *t)
93{
94 atom *a, *aa;
95
96 ATOM_RESOLVE(t);
97 for (a = (atom *)t->g; a; a = aa) {
98 aa = (atom *)a->b.b.next;
99 x_free(t->t.t.a, a);
100 }
101 sym_destroy(&t->t);
102}
103
104/* --- @atom_intern@ --- *
105 *
106 * Arguments: @atom_table *t@ = pointer to an atom table
107 * @const char *p@ = pointer to the string to intern
108 *
109 * Returns: A pointer to the atom block for the given symbol string.
110 *
111 * Use: Interns an atom, returning the atom block. The string can be
112 * extracted from the atom by means of the @ATOM_NAME@ macro.
113 */
114
115atom *atom_intern(atom_table *t, const char *p)
116{
117 atom *a;
118 unsigned f;
119
120 ATOM_RESOLVE(t);
121 a = sym_find(&t->t, p, -1, sizeof(atom), &f);
122 if (!f)
123 a->f = 0;
124 return (a);
125}
126
127/* --- @atom_gensym@ --- *
128 *
129 * Arguments: @atom_table *t@ = pointer to a symbol table
130 *
131 * Returns: A pointer to a new atom block, not previously interned.
132 *
133 * Use: Creates a new, uninterned atom. This atom will never be
134 * returned by either @atom_intern@ or any other call to
135 * @atom_gensym@, while the symbol table exists.
136 */
137
138atom *atom_gensym(atom_table *t)
139{
140 atom *a;
141 char buf[64];
142 size_t sz;
143
144 ATOM_RESOLVE(t);
145 sprintf(buf, "*gen-%lu*", t->gseq++);
146 sz = strlen(buf) + 1;
147 a = x_alloc(t->t.t.a, sizeof(atom) + sz);
148 a->b.name = (char *)(a + 1);
149 memcpy(a->b.name, buf, sz);
150 a->b.len = sz;
151 CRC32(a->b.b.hash, 0, buf, sz);
152 a->f = ATOMF_GENSYM;
153 a->b.b.next = t->g;
154 t->g = &a->b.b;
155 return (a);
156}
157
158/* --- @atom_name@ --- *
159 *
160 * Arguments: @atom *a@ = pointer to an atom
161 *
162 * Returns: The atom's textual name.
163 *
164 * Use: Given an atom, returns the name with which it was interned
165 * (or a made-up name if it was created using @gensym@.
166 */
167
168const char *atom_name(const atom *a) { return ATOM_NAME(a); }
169
170/* --- @atom_len@ --- *
171 *
172 * Arguments: @atom *a@ = pointer to an atom
173 *
174 * Returns: The atom string's length.
175 *
176 * Use: Given an atom, return the length of its textual
177 * representation.
178 */
179
180size_t atom_len(const atom *a) { return ATOM_LEN(a); }
181
182/* --- @atom_hash@ --- *
183 *
184 * Arguments: @atom *a@ = pointer to an atom
185 *
186 * Returns: The atom's hash.
187 *
188 * Use: Given an atom, returns its hash.
189 */
190
191uint32 atom_hash(const atom *a) { return ATOM_HASH(a); }
192
193/* --- @atom_mkiter@ , @atom_next@ --- *
194 *
195 * Arguments: @atom_table *t@ = pointer to an atom table
196 * @atom_iter *i@ = pointer to an iterator structure
197 *
198 * Returns: Next atom, for @atom_next@; nothing for @atom_mkiter@.
199 *
200 * Use: Iterates over atoms (both interned and uninterned).
201 */
202
203void atom_mkiter(atom_iter *i, atom_table *t)
204{
205 ATOM_RESOLVE(t);
206 i->i.i.t = &t->t.t;
207 i->i.i.p = t->g;
208 i->i.i.i = 0;
209}
210
211atom *atom_next(atom_iter *i)
212{
213 atom *a;
214 SYM_NEXT(&i->i, a);
215 return (a);
216}
217
218/*----- That's all, folks -------------------------------------------------*/