chiark / gitweb /
430f23b90507fc6c5449863f98274b9638ec4242
[mLib] / atom.h
1 /* -*-c-*-
2  *
3  * Atom management
4  *
5  * (c) 2000 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
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * mLib is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public 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
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 #ifndef MLIB_ATOM_H
29 #define MLIB_ATOM_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #ifndef MLIB_SYM_H
38 #  include "sym.h"
39 #endif
40
41 /*----- Data structures ---------------------------------------------------*/
42
43 typedef struct atom_table {
44   sym_table t;                          /* Symbol table of interned atoms */
45   hash_base *g;                         /* List of uninterned atoms */
46   unsigned long gseq;                   /* Sequence number for @gensym@ */
47 } atom_table;
48
49 typedef struct atom {
50   sym_base b;                           /* Base structure for symbol table */
51   unsigned f;                           /* Various useful flags */
52 } atom;
53
54 #define ATOMF_GENSYM 1u                 /* Atom is uninterned */
55
56 typedef struct { sym_iter i; } atom_iter;
57
58 /*----- Global magic ------------------------------------------------------*/
59
60 #define ATOM_GLOBAL 0
61
62 /*----- Functions provided ------------------------------------------------*/
63
64 /* --- @atom_createtable@ --- *
65  *
66  * Arguments:   @atom_table *t@ = pointer to an atom table
67  *
68  * Returns:     ---
69  *
70  * Use:         Initializes an atom table.
71  */
72
73 extern void atom_createtable(atom_table */*t*/);
74
75 /* --- @atom_destroytable@ --- *
76  *
77  * Arguments:   @atom_table *t@ = pointer to an atom table
78  *
79  * Returns:     ---
80  *
81  * Use:         Destroys all of the atoms in an atom table.  All of the atoms
82  *              (including uninterned atoms) are freed.  Any references to
83  *              atoms from the table become invalid, and any association
84  *              tables dependent on the atom table are unusable, except that
85  *              they may be destroyed safely.
86  */
87
88 extern void atom_destroytable(atom_table */*t*/);
89
90 /* --- @atom_intern@ --- *
91  *
92  * Arguments:   @atom_table *t@ = pointer to an atom table
93  *              @const char *p@ = pointer to the string to intern
94  *              @size_t n@ = size of the string (for @atom_nintern)
95  *
96  * Returns:     A pointer to the atom block for the given symbol string.
97  *
98  * Use:         Interns an atom, returning the atom block.  The string can be
99  *              extracted from the atom by means of the @ATOM_NAME@ macro.
100  */
101
102 #define INTERN(p) atom_intern(ATOM_GLOBAL, (p))
103
104 extern atom *atom_intern(atom_table */*t*/, const char */*p*/);
105 extern atom *atom_nintern(atom_table */*t*/,
106                           const char */*p*/, size_t /*n*/);
107
108 /* --- @atom_gensym@ --- *
109  *
110  * Arguments:   @atom_table *t@ = pointer to a symbol table
111  *
112  * Returns:     A pointer to a new atom block, not previously interned.
113  *
114  * Use:         Creates a new, uninterned atom.  This atom will never be
115  *              returned by either @atom_intern@ or any other call to
116  *              @atom_gensym@, while the symbol table exists.
117  */
118
119 #define GENSYM atom_gensym(ATOM_GLOBAL)
120
121 extern atom *atom_gensym(atom_table */*t*/);
122
123 /* --- @atom_name@ --- *
124  *
125  * Arguments:   @atom *a@ = pointer to an atom
126  *
127  * Returns:     The atom's textual name.
128  *
129  * Use:         Given an atom, returns the name with which it was interned
130  *              (or a made-up name if it was created using @gensym@.
131  */
132
133 #define ATOM_NAME(a) SYM_NAME(a)
134
135 extern const char *atom_name(const atom */*a*/);
136
137 /* --- @atom_len@ --- *
138  *
139  * Arguments:   @atom *a@ = pointer to an atom
140  *
141  * Returns:     The atom string's length.
142  *
143  * Use:         Given an atom, return the length of its textual
144  *              representation.
145  */
146
147 #define ATOM_LEN(a) SYM_LEN(a)
148
149 extern size_t atom_len(const atom */*a*/);
150
151 /* --- @atom_hash@ --- *
152  *
153  * Arguments:   @atom *a@ = pointer to an atom
154  *
155  * Returns:     The atom's hash.
156  *
157  * Use:         Given an atom, returns its hash.
158  */
159
160 #define ATOM_HASH(a) SYM_HASH(a)
161
162 extern uint32 atom_hash(const atom */*a*/);
163
164 /* --- @atom_mkiter@ , @atom_next@ --- *
165  *
166  * Arguments:   @atom_table *t@ = pointer to an atom table
167  *              @atom_iter *i@ = pointer to an iterator structure
168  *
169  * Returns:     Next atom, for @atom_next@; nothing for @atom_mkiter@.
170  *
171  * Use:         Iterates over atoms (both interned and uninterned).
172  */
173
174 extern void atom_mkiter(atom_iter */*i*/, atom_table */*t*/);
175 extern atom *atom_next(atom_iter */*i*/);
176
177 /*----- That's all, folks -------------------------------------------------*/
178
179 #ifdef __cplusplus
180   }
181 #endif
182
183 #endif