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