123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* Quarks.c 1.1 - Fujitsu source for CDEnext 95/11/06 20:31:17 */
- /* $XConsortium: _falQuarks.c /main/2 1996/09/09 13:20:21 rswiston $ */
- /***********************************************************
- Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard,
- All Rights Reserved
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name Digital not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- ******************************************************************/
- /*
- Copyright (c) 1987, 1988, 1990 X Consortium
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of the X Consortium shall
- not be used in advertising or otherwise to promote the sale, use or
- other dealings in this Software without prior written authorization
- from the X Consortium.
- */
- #include "_fallibint.h"
- #include <X11/Xresource.h>
- /* Not cost effective, at least for vanilla MIT clients */
- /* #define PERMQ */
- typedef unsigned long Signature;
- typedef unsigned long Entry;
- #ifdef PERMQ
- typedef unsigned char Bits;
- #endif
- static XrmQuark nextQuark = 1; /* next available quark number */
- static unsigned long quarkMask = 0;
- static Entry zero = 0;
- static Entry *quarkTable = &zero; /* crock */
- static unsigned long quarkRehash;
- static XrmString **stringTable = NULL;
- #ifdef PERMQ
- static Bits **permTable = NULL;
- #endif
- static XrmQuark nextUniq = -1; /* next quark from falrmUniqueQuark */
- #define QUANTUMSHIFT 8
- #define QUANTUMMASK ((1 << QUANTUMSHIFT) - 1)
- #define CHUNKPER 8
- #define CHUNKMASK ((CHUNKPER << QUANTUMSHIFT) - 1)
- #define LARGEQUARK ((Entry)0x80000000L)
- #define QUARKSHIFT 18
- #define QUARKMASK ((LARGEQUARK - 1) >> QUARKSHIFT)
- #define XSIGMASK ((1L << QUARKSHIFT) - 1)
- #define STRQUANTSIZE (sizeof(XrmString) * (QUANTUMMASK + 1))
- #ifdef PERMQ
- #define QUANTSIZE (STRQUANTSIZE + \
- (sizeof(Bits) * ((QUANTUMMASK + 1) >> 3))
- #else
- #define QUANTSIZE STRQUANTSIZE
- #endif
- #define HASH(sig) ((sig) & quarkMask)
- #define REHASHVAL(sig) ((((sig) % quarkRehash) + 2) | 1)
- #define REHASH(idx,rehash) ((idx + rehash) & quarkMask)
- #define NAME(q) stringTable[(q) >> QUANTUMSHIFT][(q) & QUANTUMMASK]
- #ifdef PERMQ
- #define BYTEREF(q) permTable[(q) >> QUANTUMSHIFT][((q) & QUANTUMMASK) >> 3]
- #define ISPERM(q) (BYTEREF(q) & (1 << ((q) & 7)))
- #define SETPERM(q) BYTEREF(q) |= (1 << ((q) & 7))
- #define CLEARPERM(q) BYTEREF(q) &= ~(1 << ((q) & 7))
- #endif
- /* Permanent memory allocation */
- #define WALIGN sizeof(unsigned long)
- #define DALIGN sizeof(double)
- #define NEVERFREETABLESIZE ((8192-12) & ~(DALIGN-1))
- static char *neverFreeTable = NULL;
- static int neverFreeTableSize = 0;
- static char *permalloc(unsigned int length)
- {
- char *ret;
- if (neverFreeTableSize < length) {
- if (length >= NEVERFREETABLESIZE)
- return Xmalloc(length);
- if (! (ret = Xmalloc(NEVERFREETABLESIZE)))
- return (char *) NULL;
- neverFreeTableSize = NEVERFREETABLESIZE;
- neverFreeTable = ret;
- }
- ret = neverFreeTable;
- neverFreeTable += length;
- neverFreeTableSize -= length;
- return(ret);
- }
- typedef struct {char a; double b;} TestType1;
- typedef struct {char a; unsigned long b;} TestType2;
- #ifdef XTHREADS
- static char *_falpermalloc();
- char *falpermalloc(unsigned int length)
- {
- char *p;
- _XLockMutex(_Xglobal_lock);
- p = _falpermalloc(length);
- _XUnlockMutex(_Xglobal_lock);
- return p;
- }
- #define falpermalloc _falpermalloc
- static
- #endif /* XTHREADS */
- char *falpermalloc(unsigned int length)
- {
- int i;
- if (neverFreeTableSize && length < NEVERFREETABLESIZE) {
- if ((sizeof(TestType1) !=
- (sizeof(TestType2) - sizeof(unsigned long) + sizeof(double))) &&
- !(length & (DALIGN-1)) &&
- (i = (NEVERFREETABLESIZE - neverFreeTableSize) & (DALIGN-1))) {
- neverFreeTableSize -= DALIGN - i;
- neverFreeTable += DALIGN - i;
- } else
- if (i = (NEVERFREETABLESIZE - neverFreeTableSize) & (WALIGN-1)) {
- neverFreeTableSize -= WALIGN - i;
- neverFreeTable += WALIGN - i;
- }
- }
- return permalloc(length);
- }
- static Bool
- ExpandQuarkTable(void)
- {
- unsigned long oldmask, newmask;
- char c, *s;
- Entry *oldentries, *entries;
- Entry entry;
- int oldidx, newidx, rehash;
- Signature sig;
- XrmQuark q;
- oldentries = quarkTable;
- if (oldmask = quarkMask)
- newmask = (oldmask << 1) + 1;
- else {
- if (!stringTable) {
- stringTable = (XrmString **)Xmalloc(sizeof(XrmString *) *
- CHUNKPER);
- if (!stringTable)
- return False;
- stringTable[0] = (XrmString *)NULL;
- }
- #ifdef PERMQ
- if (!permTable)
- permTable = (Bits **)Xmalloc(sizeof(Bits *) * CHUNKPER);
- if (!permTable)
- return False;
- #endif
- stringTable[0] = (XrmString *)falpermalloc(QUANTSIZE);
- if (!stringTable[0])
- return False;
- #ifdef PERMQ
- permTable[0] = (Bits *)((char *)stringTable[0] + STRQUANTSIZE);
- #endif
- newmask = 0x1ff;
- }
- entries = (Entry *)Xmalloc(sizeof(Entry) * (newmask + 1));
- if (!entries)
- return False;
- bzero((char *)entries, sizeof(Entry) * (newmask + 1));
- quarkTable = entries;
- quarkMask = newmask;
- quarkRehash = quarkMask - 2;
- for (oldidx = 0; oldidx <= oldmask; oldidx++) {
- if (entry = oldentries[oldidx]) {
- if (entry & LARGEQUARK)
- q = entry & (LARGEQUARK-1);
- else
- q = (entry >> QUARKSHIFT) & QUARKMASK;
- for (sig = 0, s = NAME(q); c = *s++; )
- sig = (sig << 1) + c;
- newidx = HASH(sig);
- if (entries[newidx]) {
- rehash = REHASHVAL(sig);
- do {
- newidx = REHASH(newidx, rehash);
- } while (entries[newidx]);
- }
- entries[newidx] = entry;
- }
- }
- if (oldmask)
- Xfree((char *)oldentries);
- return True;
- }
- XrmQuark _falrmInternalStringToQuark(
- const char *name, int len, Signature sig, Bool permstring)
- {
- XrmQuark q;
- Entry entry;
- int idx;
- int rehash = 0;
- int i;
- char *s1, *s2;
- char *new;
- idx = HASH(sig);
- _XLockMutex(_Xglobal_lock);
- while (entry = quarkTable[idx]) {
- if (entry & LARGEQUARK)
- q = entry & (LARGEQUARK-1);
- else {
- if ((entry - sig) & XSIGMASK){
- if (!rehash)
- rehash = REHASHVAL(sig);
- idx = REHASH(idx, rehash);
- continue;
- }
- q = (entry >> QUARKSHIFT) & QUARKMASK;
- }
- for (i = len, s1 = (char *)name, s2 = NAME(q); --i >= 0; ) {
- if (*s1++ != *s2++){
- if (!rehash)
- rehash = REHASHVAL(sig);
- idx = REHASH(idx, rehash);
- continue;
- }
- }
- if (*s2) {
- if (!rehash)
- rehash = REHASHVAL(sig);
- idx = REHASH(idx, rehash);
- continue;
- }
- #ifdef PERMQ
- if (permstring && !ISPERM(q)) {
- Xfree(NAME(q));
- NAME(q) = (char *)name;
- SETPERM(q);
- }
- #endif
- _XUnlockMutex(_Xglobal_lock);
- return q;
- }
- if (nextUniq == nextQuark){
- _XUnlockMutex(_Xglobal_lock);
- return NULLQUARK;
- }
- if ((nextQuark + (nextQuark >> 2)) > quarkMask) {
- if (!ExpandQuarkTable()){
- _XUnlockMutex(_Xglobal_lock);
- return NULLQUARK;
- }
- _XUnlockMutex(_Xglobal_lock);
- return _falrmInternalStringToQuark(name, len, sig, permstring);
- }
- q = nextQuark;
- if (!(q & QUANTUMMASK)) {
- if (!(q & CHUNKMASK)) {
- if (!(new = Xrealloc((char *)stringTable,
- sizeof(XrmString *) *
- ((q >> QUANTUMSHIFT) + CHUNKPER)))){
- _XUnlockMutex(_Xglobal_lock);
- return NULLQUARK;
- }
- stringTable = (XrmString **)new;
- #ifdef PERMQ
- if (!(new = Xrealloc((char *)permTable,
- sizeof(Bits *) *
- ((q >> QUANTUMSHIFT) + CHUNKPER)))){
- _XUnlockMutex(_Xglobal_lock);
- return NULLQUARK;
- }
- permTable = (Bits **)new;
- #endif
- }
- new = falpermalloc(QUANTSIZE);
- if (!new){
- _XUnlockMutex(_Xglobal_lock);
- return NULLQUARK;
- }
- stringTable[q >> QUANTUMSHIFT] = (XrmString *)new;
- #ifdef PERMQ
- permTable[q >> QUANTUMSHIFT] = (Bits *)(new + STRQUANTSIZE);
- #endif
- }
- if (!permstring) {
- s2 = (char *)name;
- #ifdef PERMQ
- name = Xmalloc(len+1);
- #else
- name = permalloc(len+1);
- #endif
- if (!name){
- _XUnlockMutex(_Xglobal_lock);
- return NULLQUARK;
- }
- for (i = len, s1 = (char *)name; --i >= 0; )
- *s1++ = *s2++;
- *s1++ = '\0';
- #ifdef PERMQ
- CLEARPERM(q);
- }
- else {
- SETPERM(q);
- #endif
- }
- NAME(q) = (char *)name;
- if (q <= QUARKMASK)
- entry = (q << QUARKSHIFT) | (sig & XSIGMASK);
- else
- entry = q | LARGEQUARK;
- quarkTable[idx] = entry;
- nextQuark++;
- _XUnlockMutex(_Xglobal_lock);
- return q;
- }
- XrmQuark falrmStringToQuark(const char *name)
- {
- char c, *tname;
- Signature sig = 0;
- if (!name)
- return (NULLQUARK);
- for (tname = (char *)name; c = *tname++; )
- sig = (sig << 1) + c;
- return _falrmInternalStringToQuark(name, tname-(char *)name-1, sig, False);
- }
- XrmQuark falrmPermStringToQuark(
- const char *name)
- {
- char c, *tname;
- Signature sig = 0;
- if (!name)
- return (NULLQUARK);
- for (tname = (char *)name; c = *tname++; )
- sig = (sig << 1) + c;
- return _falrmInternalStringToQuark(name, tname-(char *)name-1, sig, True);
- }
- XrmQuark falrmUniqueQuark(void)
- {
- XrmQuark q;
- _XLockMutex(_Xglobal_lock);
- if (nextUniq == nextQuark)
- q = NULLQUARK;
- else
- q = nextUniq--;
- _XUnlockMutex(_Xglobal_lock);
- return q;
- }
- XrmString falrmQuarkToString(XrmQuark quark)
- {
- XrmString s;
- _XLockMutex(_Xglobal_lock);
- if (quark <= 0 || quark >= nextQuark)
- s = NULLSTRING;
- else {
- #ifdef PERMQ
- /* We have to mark the quark as permanent, since the caller might hold
- * onto the string pointer forver.
- */
- SETPERM(quark);
- #endif
- s = NAME(quark);
- }
- _XUnlockMutex(_Xglobal_lock);
- return s;
- }
|