.\" -*-nroff-*- .de VS .sp 1 .RS .nf .ft B .. .de VE .ft R .fi .RE .sp 1 .. .TH atom 3 "21 January 2001" "Straylight/Edgeware" "mLib utilities library" .SH NAME atom \- atom table manager .\" @atom_createtable .\" @atom_destroytable .\" @atom_intern .\" @atom_nintern .\" @atom_gensym .\" @atom_name .\" @atom_len .\" @atom_hash .\" @atom_mkiter .\" @atom_next .\" .\" @ATOM_GLOBAL .\" @INTERN .\" @GENSYM .\" @ATOM_NAME .\" @ATOM_LEN .\" @ATOM_HASH .\" .SH SYNOPSIS .nf .B "#include " .BI "void atom_createtable(atom_table *" t ); .BI "void atom_destroytable(atom_table *" t ); .BI "atom *atom_intern(atom_table *" t ", const char *" p ); .BI "atom *atom_nintern(atom_table *" t ", const char *" p ", size_t " n ); .BI "atom *atom_gensym(atom_table *" t ); .BI "atom *INTERN(const char *" p ); .BI "atom *GENSYM;" .BI "const char *atom_name(const atom *" a ); .BI "size_t atom_len(const atom *" a ); .BI "uint32 atom_hash(const atom *" a ); .BI "const char *ATOM_NAME(const atom *" a ); .BI "size_t ATOM_LEN(const atom *" a ); .BI "uint32 ATOM_HASH(const atom *" a ); .BI "void atom_mkiter(atom_iter *" i ", atom_table *" t ); .BI "atom *atom_next(atom_iter *" i ); .BI "extern atom_table *ATOM_GLOBAL;" .fi .SH DESCRIPTION The .B atom functions and macros implement a data type similar to immutable strings, with an additional property: that the addresses of two atoms from the same table are equal if and only if they contain the same text. Atom strings don't have to be null-terminated, although the interface is simpler if you know that all of your atoms are null-terminated. It's also possible to make .IR "uninterned atoms" : see below. .PP If a necessary memory allocation fails during an atom operation, the exception .B EXC_NOMEM is raised. .PP Atoms are useful for speeding up string comparisons, and for saving memory when many possibly-identical strings need storing. .PP There is a global atom table, named .BR ATOM_GLOBAL , available for general use. You can initialize your own atom table if either you want to ensure that the atoms are not shared with some other table, or if you want to be able to free the atoms later. Private atom tables have the type .BR atom_table ; initialize it using the function .B atom_createtable and free it when you're finished using .BR atom_destroytable . .SS "Creating atoms from strings" The process of making atoms from strings is called .IR interning . The function .B atom_nintern takes an atom table, a string, and a length, and returns an atom with the same text. If your string is null-terminated, you can instead use .B atom_intern which has no length argument; if, in addition, you want to use the global atom table, you can use the single-argument .B INTERN macro, which takes just a null-terminated string. .PP A terminating null byte is always appended to an atom name. This is not considered to be a part of the name itself, and does not contribute to the atom's length as reported by the .B ATOM_LEN macro. .SS "Uninterned atoms" You can make an atom which is guaranteed to be distinct from every other atom, and has no sensible text string, by calling .BR atom_gensym , passing it the address of your atom table. The macro .B GENSYM (which doesn't look like a function, and has no parentheses following it!) will return a unique atom from the global table. Uninterned atoms have a generated name of the form .RB ` *gen- \fInnn * ' where .I nnn is an atom-table-specific sequence number. This text is there as a debugging convenience, and doesn't mean that the uninterned atom has the same address as an interned atom with the same text. .SS "Other enquiries about atoms" Atoms can be interrogated to find their names and hashes. The macro .B ATOM_NAME returns a pointer to the atom's name (its text); .B ATOM_LEN returns the length of the atom's name, excluding the terminating null; and .B ATOM_HASH returns the atom's hash value, which is useful if you want to use the atom as a key in some other structure. There are lower-case function versions of these, which have the same effect. There is little point in using the functions. .SS "Enumerating atoms" You can iterate over the atoms in an atom table. The .B atom_mkiter function initializes an iterator object to iterate over a particular atom table; .B atom_next returns the next atom from the iterator. Atoms are not returned in any particular order. .SH SEE ALSO .BR assoc (3), .BR hash (3), .BR mLib (3). .SH AUTHOR Mark Wooding,