824N/A/*
824N/A * dpsdict.c
824N/A *
824N/A * (c) Copyright 1988-1994 Adobe Systems Incorporated.
824N/A * All rights reserved.
824N/A *
824N/A * Permission to use, copy, modify, distribute, and sublicense this software
824N/A * and its documentation for any purpose and without fee is hereby granted,
824N/A * provided that the above copyright notices appear in all copies and that
824N/A * both those copyright notices and this permission notice appear in
824N/A * supporting documentation and that the name of Adobe Systems Incorporated
824N/A * not be used in advertising or publicity pertaining to distribution of the
824N/A * software without specific, written prior permission. No trademark license
824N/A * to use the Adobe trademarks is hereby granted. If the Adobe trademark
824N/A * "Display PostScript"(tm) is used to describe this software, its
824N/A * functionality or for any other purpose, such use shall be limited to a
824N/A * statement that this software works in conjunction with the Display
824N/A * PostScript system. Proper trademark attribution to reflect Adobe's
824N/A * ownership of the trademark shall be given whenever any such reference to
824N/A * the Display PostScript system is made.
824N/A *
824N/A * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
824N/A * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
824N/A * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
824N/A * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
824N/A * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
824N/A * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
824N/A * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
824N/A * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
824N/A * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
824N/A * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
824N/A *
824N/A * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
824N/A * Incorporated which may be registered in certain jurisdictions
824N/A *
824N/A * Author: Adobe Systems Incorporated
824N/A */
824N/A/* $XFree86$ */
824N/A
824N/A/***********/
824N/A/* Imports */
824N/A/***********/
824N/A
824N/A#include <stdlib.h>
824N/A#include <string.h>
824N/A
824N/A#include "dpsint.h"
824N/A
824N/A/********************/
824N/A/* Types */
824N/A/********************/
824N/A
824N/Atypedef struct _EntryRec {
824N/A struct _EntryRec *next;
824N/A char *name;
824N/A PSWDictValue value;
824N/A } EntryRec, *Entry;
824N/A
824N/A /* The concrete definition for a dictionary */
824N/A typedef struct _PSWDictRec {
824N/A integer nEntries;
824N/A Entry *entries;
824N/A } PSWDictRec;
824N/A
824N/Astatic PSWDict atoms;
824N/A
824N/A/**************************/
824N/A/* Procedure Declarations */
824N/A/**************************/
824N/A
824N/A/* Creates and returns a new dictionary. nEntries is a hint. */
824N/APSWDict DPSCreatePSWDict(integer nEntries)
824N/A{
824N/A PSWDict d = (PSWDict)DPScalloc(sizeof(PSWDictRec), 1);
824N/A d->nEntries = nEntries;
824N/A d->entries = (Entry *)DPScalloc(sizeof(EntryRec), d->nEntries);
824N/A return d;
824N/A}
824N/A
824N/A/* Destroys a dictionary */
824N/Avoid DPSDestroyPSWDict(PSWDict dict)
824N/A{
824N/A integer links = dict->nEntries;
824N/A Entry next;
824N/A Entry prev;
824N/A
824N/A while (links > 0)
824N/A {
824N/A next = (dict->entries)[links];
824N/A while (next != NIL)
824N/A {
824N/A prev = next;
824N/A next = next->next;
824N/A free (prev);
824N/A }
824N/A links--;
824N/A }
824N/A free(dict->entries);
824N/A free(dict);
824N/A}
824N/A
824N/Astatic integer Hash(char *name, integer nEntries)
824N/A{
824N/A register integer val = 0;
824N/A while (*name) val += *name++;
824N/A if (val < 0) val = -val;
824N/A return (val % nEntries);
824N/A}
824N/A
824N/Astatic Entry Probe(PSWDict d, integer x, char *name)
824N/A{
824N/A register Entry e;
824N/A for (e = (d->entries)[x]; e != NIL; e = e->next) {
824N/A if (strcmp(name, e->name) == 0) break;
824N/A }
824N/A return e;
824N/A}
824N/A
824N/Astatic Entry PrevProbe(Entry *prev, PSWDict d, integer x, char *name)
824N/A{
824N/A register Entry e;
824N/A *prev = NIL;
824N/A for (e = (d->entries)[x]; e != NIL; e = e->next) {
824N/A if (strcmp(name, e->name) == 0) break;
824N/A *prev = e;
824N/A }
824N/A return e;
824N/A}
824N/A
824N/A/* -1 => not found */
824N/APSWDictValue DPSWDictLookup(PSWDict dict, char *name)
824N/A{
824N/A Entry e;
824N/A e = Probe(dict, Hash(name, dict->nEntries), name);
824N/A if (e == NIL) return -1;
824N/A return e->value;
824N/A}
824N/A
824N/A/* 0 => normal return (not found)
824N/A -1 => found. If found, value is replaced. */
824N/APSWDictValue DPSWDictEnter(PSWDict dict, char *name, PSWDictValue value)
824N/A{
824N/A Entry e;
824N/A integer x = Hash(name, dict->nEntries);
824N/A e = Probe(dict, x, name);
824N/A if (e != NIL) {
824N/A e->value = value;
824N/A return -1;
824N/A }
824N/A e = (Entry)DPScalloc(sizeof(EntryRec), 1);
824N/A e->next = (dict->entries)[x]; (dict->entries)[x] = e;
824N/A e->value = value;
824N/A e->name = name; /* MakeAtom(name); */
824N/A return 0;
824N/A}
824N/A
824N/A/* -1 => not found. If found, value is returned. */
824N/APSWDictValue DPSWDictRemove(PSWDict dict, char *name)
824N/A{
824N/A Entry e, prev;
824N/A PSWDictValue value;
824N/A integer x = Hash(name, dict->nEntries);
824N/A
824N/A e = PrevProbe(&prev, dict, x, name);
824N/A if (e == NIL) return -1;
824N/A value = e->value;
824N/A if (prev == NIL) (dict->entries)[x] = e->next; else prev->next = e->next;
824N/A free(e);
824N/A return value;
824N/A}
824N/A
824N/AAtom DPSMakeAtom(char *name)
824N/A{
824N/A Entry e;
824N/A integer x = Hash(name, 511);
824N/A char *newname;
824N/A
824N/A if (atoms == NIL) atoms = DPSCreatePSWDict(511);
824N/A e = Probe(atoms, x, name);
824N/A if (e == NIL) {
824N/A e = (Entry)DPScalloc(sizeof(EntryRec), 1);
824N/A e->next = (atoms->entries)[x]; (atoms->entries)[x] = e;
824N/A e->value = 0;
824N/A newname = (char *)DPScalloc(strlen(name)+1, 1);
824N/A strcpy(newname, name);
824N/A e->name = newname;
824N/A }
824N/A return (Atom) e->name;
824N/A}