⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xrm.c

📁 Nxlib,一个模拟xlib的程序。使用microwindows的库来运行需要xlib支持的程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Xorg: Xrm.c,v 1.6 2000/08/17 19:45:08 cpqbld Exp $ *//***********************************************************Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard                        All Rights ReservedPermission 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 thatboth that copyright notice and this permission notice appear in supporting documentation, and that the name Digital not beused in advertising or publicity pertaining to distribution of thesoftware without specific, written prior permission.  DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDINGALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALLDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ORANY 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 THISSOFTWARE.******************************************************************//*Copyright 1987, 1988, 1990, 1998  The Open GroupAll Rights Reserved.The above copyright notice and this permission notice shall be includedin all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OROTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of The Open Group shallnot be used in advertising or otherwise to promote the sale, use orother dealings in this Software without prior written authorizationfrom The Open Group.*//* $XFree86: xc/lib/X11/Xrm.c,v 3.15 2001/01/17 19:41:50 dawes Exp $ */#include	<stdio.h>#include	<ctype.h>//#include	"Xlibint.h"#include	"nxlib.h"#include	<X11/Xresource.h>#include	"Xlcint.h"#ifdef XTHREADS#include	"locking.h"#endif#include 	"XrmI.h"#include	<X11/Xos.h>#ifdef __STDC__#define Const const#else#define Const /**/#endif#if defined(__STDC__) && !defined(NORCONST)#define RConst const#else#define RConst /**/#endifextern XrmQuark _XrmInternalStringToQuark();/*These Xrm routines allow very fast lookup of resources in the resourcedatabase.  Several usage patterns are exploited:(1) Widgets get a lot of resources at one time.  Rather than look up each fromscratch, we can precompute the prioritized list of database levels once, thensearch for each resource starting at the beginning of the list.(2) Many database levels don't contain any leaf resource nodes.  There is nopoint in looking for resources on a level that doesn't contain any.  Thisinformation is kept on a per-level basis.(3) Sometimes the widget instance tree is structured such that you get the sameclass name repeated on the fully qualified widget name.  This can result in thesame database level occuring multiple times on the search list.  The code belowonly checks to see if you get two identical search lists in a row, rather thanlook back through all database levels, but in practice this removes allduplicates I've ever observed.Joel McCormack*//*The Xrm representation has been completely redesigned to substantially reducememory and hopefully improve performance.The database is structured into two kinds of tables: LTables that containonly values, and NTables that contain only other tables.Some invariants:The next pointer of the top-level node table points to the top-level leaftable, if any.Within an LTable, for a given name, the tight value always precedes theloose value, and if both are present the loose value is always right afterthe tight value.Within an NTable, all of the entries for a given name are contiguous,in the order tight NTable, loose NTable, tight LTable, loose LTable.Bob Scheifler*/typedef unsigned long Signature;static XrmQuark XrmQString, XrmQANY;typedef	Bool (*DBEnumProc)(#if NeedNestedPrototypes    /* this is Nested on purpose, to match Xlib.h */    XrmDatabase*	/* db */,    XrmBindingList	/* bindings */,    XrmQuarkList	/* quarks */,    XrmRepresentation*	/* type */,    XrmValue*		/* value */,    XPointer		/* closure */#endif);typedef struct _VEntry {    struct _VEntry	*next;		/* next in chain */    XrmQuark		name;		/* name of this entry */    unsigned int	tight:1;	/* 1 if it is a tight binding */    unsigned int	string:1;	/* 1 if type is String */    unsigned int	size:30;	/* size of value */} VEntryRec, *VEntry;typedef struct _DEntry {    VEntryRec		entry;		/* entry */    XrmRepresentation	type;		/* representation type */} DEntryRec, *DEntry;/* the value is right after the structure */#define StringValue(ve) (XPointer)((ve) + 1)#define RepType(ve) ((DEntry)(ve))->type/* the value is right after the structure */#define DataValue(ve) (XPointer)(((DEntry)(ve)) + 1)#define RawValue(ve) (char *)((ve)->string ? StringValue(ve) : DataValue(ve))typedef struct _NTable {    struct _NTable	*next;		/* next in chain */    XrmQuark		name;		/* name of this entry */    unsigned int	tight:1;	/* 1 if it is a tight binding */    unsigned int	leaf:1;		/* 1 if children are values */    unsigned int	hasloose:1;	/* 1 if has loose children */    unsigned int	hasany:1;	/* 1 if has ANY entry */    unsigned int	pad:4;		/* unused */    unsigned int	mask:8;		/* hash size - 1 */    unsigned int	entries:16;	/* number of children */} NTableRec, *NTable;/* the buckets are right after the structure */#define NodeBuckets(ne) ((NTable *)((ne) + 1))#define NodeHash(ne,q) NodeBuckets(ne)[(q) & (ne)->mask]/* leaf tables have an extra level of indirection for the buckets, * so that resizing can be done without invalidating a search list. * This is completely ugly, and wastes some memory, but the Xlib * spec doesn't really specify whether invalidation is OK, and the * old implementation did not invalidate. */typedef struct _LTable {    NTableRec		table;    VEntry		*buckets;} LTableRec, *LTable;#define LeafHash(le,q) (le)->buckets[(q) & (le)->table.mask]/* An XrmDatabase just holds a pointer to the first top-level table. * The type name is no longer descriptive, but better to not change * the Xresource.h header file.  This type also gets used to define * XrmSearchList, which is a complete crock, but we'll just leave it * and caste types as required. */typedef struct _XrmHashBucketRec {    NTable table;    XPointer mbstate;    XrmMethods methods;#ifdef XTHREADS    LockInfoRec linfo;#endif} XrmHashBucketRec;/* closure used in get/put resource */typedef struct _VClosure {    XrmRepresentation	*type;		/* type of value */    XrmValuePtr		value;		/* value itself */} VClosureRec, *VClosure;/* closure used in get search list */typedef struct _SClosure {    LTable		*list;		/* search list */    int			idx;		/* index of last filled element */    int			limit;		/* maximum index */} SClosureRec, *SClosure;/* placed in XrmSearchList to indicate next table is loose only */#define LOOSESEARCH ((LTable)1)/* closure used in enumerate database */typedef struct _EClosure {    XrmDatabase db;			/* the database */    DBEnumProc proc;			/* the user proc */    XPointer closure;			/* the user closure */    XrmBindingList bindings;		/* binding list */    XrmQuarkList quarks;		/* quark list */    int mode;				/* XrmEnum<kind> */} EClosureRec, *EClosure;/* predicate to determine when to resize a hash table */#define GrowthPred(n,m) ((unsigned)(n) > (((m) + 1) << 2))#define GROW(prev) \    if (GrowthPred((*prev)->entries, (*prev)->mask)) \	GrowTable(prev)/* pick a reasonable value for maximum depth of resource database */#define MAXDBDEPTH 100/* macro used in get/search functions *//* find an entry named ename, with leafness given by leaf */#define NFIND(ename) \    q = ename; \    entry = NodeHash(table, q); \    while (entry && entry->name != q) \	entry = entry->next; \    if (leaf && entry && !entry->leaf) { \	entry = entry->next; \	if (entry && !entry->leaf) \	    entry = entry->next; \	if (entry && entry->name != q) \	    entry = (NTable)NULL; \    }/* resourceQuarks keeps track of what quarks have been associated with values * in all LTables.  If a quark has never been used in an LTable, we don't need * to bother looking for it. */static unsigned char *resourceQuarks = (unsigned char *)NULL;static XrmQuark maxResourceQuark = -1;/* determines if a quark has been used for a value in any database */#define IsResourceQuark(q)  ((q) > 0 && (q) <= maxResourceQuark && \			     resourceQuarks[(q) >> 3] & (1 << ((q) & 7)))typedef unsigned char XrmBits;#define BSLASH  ((XrmBits) (1 << 5))#define NORMAL	((XrmBits) (1 << 4))#define EOQ	((XrmBits) (1 << 3))#define SEP	((XrmBits) (1 << 2))#define ENDOF	((XrmBits) (1 << 1))#define SPACE	(NORMAL|EOQ|SEP|(XrmBits)0)#define RSEP	(NORMAL|EOQ|SEP|(XrmBits)1)#define EOS	(EOQ|SEP|ENDOF|(XrmBits)0)#define EOL	(EOQ|SEP|ENDOF|(XrmBits)1)#define BINDING	(NORMAL|EOQ)#define ODIGIT	(NORMAL|(XrmBits)1)#define next_char(ch,str) xrmtypes[(unsigned char)((ch) = *(++(str)))]#define next_mbchar(ch,len,str) xrmtypes[(unsigned char)(ch = (*db->methods->mbchar)(db->mbstate, str, &len), str += len, ch)]#define is_space(bits)		((bits) == SPACE)#define is_EOQ(bits)		((bits) & EOQ)#define is_EOF(bits)		((bits) == EOS)#define is_EOL(bits)		((bits) & ENDOF)#define is_binding(bits)	((bits) == BINDING)#define is_odigit(bits)		((bits) == ODIGIT)#define is_separator(bits)	((bits) & SEP)#define is_nonpcs(bits)		(!(bits))#define is_normal(bits)		((bits) & NORMAL)#define is_simple(bits)		((bits) & (NORMAL|BSLASH))#define is_special(bits)	((bits) & (ENDOF|BSLASH))/* parsing types */static XrmBits Const xrmtypes[256] = {    EOS,0,0,0,0,0,0,0,    0,SPACE,EOL,0,0,#if defined(WIN32) || defined(__EMX__) /* || defined(OS2) */                    EOL,	/* treat CR the same as LF, just in case */#else                    0,#endif                      0,0,    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,    SPACE,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,BINDING,NORMAL,NORMAL,NORMAL,BINDING,NORMAL,    ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,    NORMAL,NORMAL,RSEP,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,BSLASH,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,    NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,0    /* The rest will be automatically initialized to zero. */};void XrmInitialize(){    XrmQString = XrmPermStringToQuark("String");    XrmQANY = XrmPermStringToQuark("?");}XrmDatabase XrmGetDatabase(display)    Display *display;{    XrmDatabase retval;    LockDisplay(display);    retval = display->db;    UnlockDisplay(display);    return retval;}void XrmSetDatabase(display, database)    Display *display;    XrmDatabase database;{    LockDisplay(display);    display->db = database;    UnlockDisplay(display);}#if NeedFunctionPrototypesvoid XrmStringToQuarkList(    register _Xconst char  *name,    register XrmQuarkList quarks)   /* RETURN */#elsevoid XrmStringToQuarkList(name, quarks)    register char 	 *name;    register XrmQuarkList quarks;   /* RETURN */#endif{    register XrmBits		bits;    register Signature  	sig = 0;    register char       	ch, *tname;    register int 		i = 0;    if ((tname = (char *)name)) {	tname--;	while (!is_EOF(bits = next_char(ch, tname))) {	    if (is_binding (bits)) {		if (i) {		    /* Found a complete name */		    *quarks++ = _XrmInternalStringToQuark(name,tname - name,							  sig, False);		    i = 0;		    sig = 0;		}		name = tname+1;	    }	    else {		sig = (sig << 1) + ch; /* Compute the signature. */		i++;	    }	}	*quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);    }    *quarks = NULLQUARK;}#if NeedFunctionPrototypesvoid XrmStringToBindingQuarkList(    register _Xconst char   *name,    register XrmBindingList bindings,   /* RETURN */    register XrmQuarkList   quarks)     /* RETURN */#elsevoid XrmStringToBindingQuarkList(name, bindings, quarks)    register char	    *name;    register XrmBindingList bindings;   /* RETURN */    register XrmQuarkList   quarks;     /* RETURN */#endif{    register XrmBits		bits;    register Signature  	sig = 0;    register char       	ch, *tname;    register XrmBinding 	binding;    register int 		i = 0;    if ((tname = (char *)name)) {	tname--;	binding = XrmBindTightly;	while (!is_EOF(bits = next_char(ch, tname))) {	    if (is_binding (bits)) {		if (i) {		    /* Found a complete name */		    *bindings++ = binding;		    *quarks++ = _XrmInternalStringToQuark(name, tname - name,							  sig, False);		    i = 0;		    sig = 0;		    binding = XrmBindTightly;		}		name = tname+1;		if (ch == '*')		    binding = XrmBindLoosely;	    }	    else {		sig = (sig << 1) + ch; /* Compute the signature. */		i++;	    }	}	*bindings = binding;	*quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);    }    *quarks = NULLQUARK;}#ifdef DEBUGstatic void PrintQuarkList(quarks, stream)    XrmQuarkList    quarks;    FILE	    *stream;{    Bool	    firstNameSeen;    for (firstNameSeen = False; *quarks; quarks++) {	if (firstNameSeen) {	    (void) fprintf(stream, ".");	}	firstNameSeen = True;	(void) fputs(XrmQuarkToString(*quarks), stream);    }} /* PrintQuarkList */#endif /* DEBUG *//* * Fallback methods for Xrm parsing. * Simulate a C locale. No state needed here. */static voidc_mbnoop(    XPointer state){}static charc_mbchar(    XPointer state,    const char *str,    int *lenp){    *lenp = 1;    return *str;}static const char *c_lcname(    XPointer state){    return "C";}static const XrmMethodsRec mb_methods = {    c_mbnoop,	/* mbinit */    c_mbchar,	/* mbchar */    c_mbnoop,	/* mbfinish */    c_lcname,	/* lcname */    c_mbnoop	/* destroy */};static XrmDatabase NewDatabase(){    register XrmDatabase db;    db = (XrmDatabase) Xmalloc(sizeof(XrmHashBucketRec));    if (db) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -