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