1bbe1b32bSmrg/*
2bbe1b32bSmrg * font server atom manipulations
3bbe1b32bSmrg */
4bbe1b32bSmrg/*
5bbe1b32bSmrgCopyright 1987, 1998  The Open Group
6bbe1b32bSmrg
7bbe1b32bSmrgPermission to use, copy, modify, distribute, and sell this software and its
8bbe1b32bSmrgdocumentation for any purpose is hereby granted without fee, provided that
9bbe1b32bSmrgthe above copyright notice appear in all copies and that both that
10bbe1b32bSmrgcopyright notice and this permission notice appear in supporting
11bbe1b32bSmrgdocumentation.
12bbe1b32bSmrg
13bbe1b32bSmrgThe above copyright notice and this permission notice shall be included in
14bbe1b32bSmrgall copies or substantial portions of the Software.
15bbe1b32bSmrg
16bbe1b32bSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bbe1b32bSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bbe1b32bSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19bbe1b32bSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20bbe1b32bSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21bbe1b32bSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22bbe1b32bSmrg
23bbe1b32bSmrgExcept as contained in this notice, the name of The Open Group shall not be
24bbe1b32bSmrgused in advertising or otherwise to promote the sale, use or other dealings
25bbe1b32bSmrgin this Software without prior written authorization from The Open Group.
26bbe1b32bSmrg * Copyright 1990, 1991 Network Computing Devices;
27bbe1b32bSmrg * Portions Copyright 1987 by Digital Equipment Corporation
28bbe1b32bSmrg *
29bbe1b32bSmrg * Permission to use, copy, modify, distribute, and sell this software and its
30bbe1b32bSmrg * documentation for any purpose is hereby granted without fee, provided that
31bbe1b32bSmrg * the above copyright notice appear in all copies and that both that
32bbe1b32bSmrg * copyright notice and this permission notice appear in supporting
33bbe1b32bSmrg * documentation, and that the names of Network Computing Devices,
34bbe1b32bSmrg * or Digital not be used in advertising or
35bbe1b32bSmrg * publicity pertaining to distribution of the software without specific,
36bbe1b32bSmrg * written prior permission.  Network Computing Devices, or Digital
37bbe1b32bSmrg * make no representations about the
38bbe1b32bSmrg * suitability of this software for any purpose.  It is provided "as is"
39bbe1b32bSmrg * without express or implied warranty.
40bbe1b32bSmrg *
41bbe1b32bSmrg * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
42bbe1b32bSmrg * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
43bbe1b32bSmrg * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
44bbe1b32bSmrg * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
45bbe1b32bSmrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
46bbe1b32bSmrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
47bbe1b32bSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
48bbe1b32bSmrg *
49bbe1b32bSmrg */
50ce6676dbSmrg
5134f90d55Smrg#include "config.h"
52bbe1b32bSmrg
53bbe1b32bSmrg#include "misc.h"
54bbe1b32bSmrg#include "fsresource.h"
55bbe1b32bSmrg#include "difs.h"
56bbe1b32bSmrg
57bbe1b32bSmrg#define InitialTableSize 100
58bbe1b32bSmrg#define	FSA_LAST_PREDEFINED	0 /* only None is predefined */
59bbe1b32bSmrg
60bbe1b32bSmrgtypedef struct _Node {
61bbe1b32bSmrg    struct _Node *left,
62bbe1b32bSmrg               *right;
63bbe1b32bSmrg    Atom        a;
64bbe1b32bSmrg    unsigned int fingerPrint;
65bbe1b32bSmrg    char       *string;
66bbe1b32bSmrg}           NodeRec, *NodePtr;
67bbe1b32bSmrg
68bbe1b32bSmrgstatic Atom lastAtom = None;
69bbe1b32bSmrgstatic NodePtr atomRoot = (NodePtr) NULL;
70bbe1b32bSmrgstatic unsigned long tableLength;
71bbe1b32bSmrgstatic NodePtr *nodeTable;
72bbe1b32bSmrg
73bbe1b32bSmrgAtom
7434f90d55SmrgMakeAtom(const char *string, unsigned int len, Bool makeit)
75bbe1b32bSmrg{
76bbe1b32bSmrg    register NodePtr *np;
77bbe1b32bSmrg    unsigned    i;
78bbe1b32bSmrg    int         comp;
79bbe1b32bSmrg    register unsigned int fp = 0;
80bbe1b32bSmrg
81bbe1b32bSmrg    np = &atomRoot;
82bbe1b32bSmrg    for (i = 0; i < (len + 1) / 2; i++) {
83bbe1b32bSmrg	fp = fp * 27 + string[i];
84bbe1b32bSmrg	fp = fp * 27 + string[len - 1 - i];
85bbe1b32bSmrg    }
86bbe1b32bSmrg    while (*np != (NodePtr) NULL) {
87bbe1b32bSmrg	if (fp < (*np)->fingerPrint)
88bbe1b32bSmrg	    np = &((*np)->left);
89bbe1b32bSmrg	else if (fp > (*np)->fingerPrint)
90bbe1b32bSmrg	    np = &((*np)->right);
91bbe1b32bSmrg	else {			/* now start testing the strings */
9234f90d55Smrg	    comp = strncmp(string, (*np)->string, len);
93bbe1b32bSmrg	    if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string))))
94bbe1b32bSmrg		np = &((*np)->left);
95bbe1b32bSmrg	    else if (comp > 0)
96bbe1b32bSmrg		np = &((*np)->right);
97bbe1b32bSmrg	    else
98bbe1b32bSmrg		return (*np)->a;
99bbe1b32bSmrg	}
100bbe1b32bSmrg    }
101bbe1b32bSmrg    if (makeit) {
102bbe1b32bSmrg	register NodePtr nd;
103bbe1b32bSmrg
104e1db7cd1Smrg	nd = (NodePtr) FSalloc(sizeof(NodeRec));
105bbe1b32bSmrg	if (!nd)
106bbe1b32bSmrg	    return BAD_RESOURCE;
107bbe1b32bSmrg#if FSA_LAST_PREDEFINED > 0
108bbe1b32bSmrg	if (lastAtom < FSA_LAST_PREDEFINED) {
109bbe1b32bSmrg	    nd->string = string;
110bbe1b32bSmrg	} else
111bbe1b32bSmrg#endif
112bbe1b32bSmrg	{
113e1db7cd1Smrg	    nd->string = (char *) FSalloc(len + 1);
114bbe1b32bSmrg	    if (!nd->string) {
115e1db7cd1Smrg		FSfree(nd);
116bbe1b32bSmrg		return BAD_RESOURCE;
117bbe1b32bSmrg	    }
11834f90d55Smrg	    strncpy(nd->string, string, len);
119bbe1b32bSmrg	    nd->string[len] = 0;
120bbe1b32bSmrg	}
121bbe1b32bSmrg	if ((lastAtom + 1) >= tableLength) {
122bbe1b32bSmrg	    NodePtr    *table;
123bbe1b32bSmrg
124e1db7cd1Smrg	    table = (NodePtr *) FSreallocarray(nodeTable, tableLength,
125e1db7cd1Smrg                                               (2 * sizeof(NodePtr)));
126bbe1b32bSmrg	    if (!table) {
127bbe1b32bSmrg		if (nd->string != string)
128e1db7cd1Smrg		    FSfree(nd->string);
129e1db7cd1Smrg		FSfree(nd);
130bbe1b32bSmrg		return BAD_RESOURCE;
131bbe1b32bSmrg	    }
132bbe1b32bSmrg	    tableLength <<= 1;
133bbe1b32bSmrg	    nodeTable = table;
134bbe1b32bSmrg	}
135bbe1b32bSmrg	*np = nd;
136bbe1b32bSmrg	nd->left = nd->right = (NodePtr) NULL;
137bbe1b32bSmrg	nd->fingerPrint = fp;
138bbe1b32bSmrg	nd->a = (++lastAtom);
139bbe1b32bSmrg	*(nodeTable + lastAtom) = nd;
140bbe1b32bSmrg	return nd->a;
141bbe1b32bSmrg    } else
142bbe1b32bSmrg	return None;
143bbe1b32bSmrg}
144bbe1b32bSmrg
145bbe1b32bSmrgint
146bbe1b32bSmrgValidAtom(Atom atom)
147bbe1b32bSmrg{
148bbe1b32bSmrg    return (atom != None) && (atom <= lastAtom);
149bbe1b32bSmrg}
150bbe1b32bSmrg
15140c5823bSmrgconst char *
152bbe1b32bSmrgNameForAtom(Atom atom)
153bbe1b32bSmrg{
154bbe1b32bSmrg    NodePtr     node;
155bbe1b32bSmrg
156bbe1b32bSmrg    if (atom > lastAtom)
157ce6676dbSmrg	return NULL;
158bbe1b32bSmrg    if ((node = nodeTable[atom]) == (NodePtr) NULL)
159ce6676dbSmrg	return NULL;
160bbe1b32bSmrg    return node->string;
161bbe1b32bSmrg}
162bbe1b32bSmrg
163bbe1b32bSmrgstatic void
164bbe1b32bSmrgatom_error(void)
165bbe1b32bSmrg{
166bbe1b32bSmrg    FatalError("initializing atoms\n");
167bbe1b32bSmrg}
168bbe1b32bSmrg
169bbe1b32bSmrgstatic void
170bbe1b32bSmrgfree_atom(NodePtr patom)
171bbe1b32bSmrg{
172bbe1b32bSmrg    if (patom->left)
173bbe1b32bSmrg	free_atom(patom->left);
174bbe1b32bSmrg    if (patom->right)
175bbe1b32bSmrg	free_atom(patom->right);
176bbe1b32bSmrg    if (patom->a > FSA_LAST_PREDEFINED)
177e1db7cd1Smrg	FSfree(patom->string);
178e1db7cd1Smrg    FSfree(patom);
179bbe1b32bSmrg}
180bbe1b32bSmrg
181bbe1b32bSmrgstatic void
182bbe1b32bSmrgfree_all_atoms(void)
183bbe1b32bSmrg{
184bbe1b32bSmrg    if (atomRoot == (NodePtr) NULL)
185bbe1b32bSmrg	return;
186bbe1b32bSmrg    free_atom(atomRoot);
187bbe1b32bSmrg    atomRoot = (NodePtr) NULL;
188e1db7cd1Smrg    FSfree(nodeTable);
189bbe1b32bSmrg    nodeTable = (NodePtr *) NULL;
190bbe1b32bSmrg    lastAtom = None;
191bbe1b32bSmrg}
192bbe1b32bSmrg
193bbe1b32bSmrgvoid
194bbe1b32bSmrgInitAtoms(void)
195bbe1b32bSmrg{
196bbe1b32bSmrg    free_all_atoms();
197bbe1b32bSmrg    tableLength = InitialTableSize;
198e1db7cd1Smrg    nodeTable = (NodePtr *) FSallocarray(InitialTableSize, sizeof(NodePtr));
199bbe1b32bSmrg    if (!nodeTable)
200bbe1b32bSmrg	atom_error();
201bbe1b32bSmrg    nodeTable[None] = (NodePtr) NULL;
202bbe1b32bSmrg    lastAtom = FSA_LAST_PREDEFINED;
203bbe1b32bSmrg}
204