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

📄 xrm.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
 *                 doall - whether to do all lines or just one *//* * This function is highly optimized to inline as much as possible.  * Be very careful with modifications, or simplifications, as they  * may adversely affect the performance. * * Chris Peterson, MIT X Consortium		5/17/90. */#define LIST_SIZE 101#define BUFFER_SIZE 100static void GetIncludeFile();static void GetDatabase(db, str, filename, doall)    XrmDatabase db;    register char *str;    char *filename;    Bool doall;{    register char *ptr;    register XrmBits bits = 0;    register char c;    int len;    register Signature sig;    register char *ptr_max;    register XrmQuarkList t_quarks;    register XrmBindingList t_bindings;    int alloc_chars = BUFSIZ;    char buffer[BUFSIZ], *value_str;    XrmQuark quarks[LIST_SIZE];    XrmBinding bindings[LIST_SIZE];    XrmValue value;    Bool only_pcs;    Bool dolines;    if (!db)	return;    if (!(value_str = Xmalloc(sizeof(char) * alloc_chars)))	return;    (*db->methods->mbinit)(db->mbstate);    str--;    dolines = True;    while (!is_EOF(bits) && dolines) {	dolines = doall;	/*	 * First: Remove extra whitespace. 	 */	do {	    bits = next_char(c, str);	} while is_space(bits);	/*	 * Ignore empty lines.	 */	if (is_EOL(bits))	    continue;		/* start a new line. */	/*	 * Second: check the first character in a line to see if it is	 * "!" signifying a comment, or "#" signifying a directive.	 */	if (c == '!') { /* Comment, spin to next newline */	    while (is_simple(bits = next_char(c, str))) {}	    if (is_EOL(bits))		continue;	    while (!is_EOL(bits = next_mbchar(c, len, str))) {}	    str--;	    continue;		/* start a new line. */	}	if (c == '#') { /* Directive */	    /* remove extra whitespace */	    only_pcs = True;	    while (is_space(bits = next_char(c, str))) {};	    /* only "include" directive is currently defined */	    if (!strncmp(str, "include", 7)) {		str += (7-1);		/* remove extra whitespace */		while (is_space(bits = next_char(c, str))) {};		/* must have a starting " */		if (c == '"') {		    char *fname = str+1;		    len = 0;		    do {			if (only_pcs) {			    bits = next_char(c, str);			    if (is_nonpcs(bits))				only_pcs = False;			}			if (!only_pcs)			    bits = next_mbchar(c, len, str);		    } while (c != '"' && !is_EOL(bits));		    /* must have an ending " */		    if (c == '"')			GetIncludeFile(db, filename, fname, str - len - fname);		}	    }	    /* spin to next newline */	    if (only_pcs) {		while (is_simple(bits))		    bits = next_char(c, str);		if (is_EOL(bits))		    continue;	    }	    while (!is_EOL(bits))		bits = next_mbchar(c, len, str);	    str--;	    continue;		/* start a new line. */	}	/*	 * Third: loop through the LHS of the resource specification	 * storing characters and converting this to a Quark.	 *	 * If the number of quarks is greater than LIST_SIZE - 1.  This	 * function will trash your memory.	 *	 * If the length of any quark is larger than BUFSIZ this function	 * will also trash memory.	 */		t_bindings = bindings;	t_quarks = quarks;	sig = 0;	ptr = buffer;	*t_bindings = XrmBindTightly;		for(;;) {	    if (!is_binding(bits)) {		while (!is_EOQ(bits)) {		    *ptr++ = c;		    sig = (sig << 1) + c; /* Compute the signature. */		    bits = next_char(c, str);		}		*t_quarks++ = _XrmInternalStringToQuark(buffer, ptr - buffer,							sig, False);		if (is_separator(bits))  {		    if (!is_space(bits))			break;		    /* Remove white space */		    do {			*ptr++ = c;			sig = (sig << 1) + c; /* Compute the signature. */		    } while (is_space(bits = next_char(c, str)));		    /* 		     * The spec doesn't permit it, but support spaces		     * internal to resource name/class 		     */		    if (is_separator(bits))			break;		    t_quarks--;		    continue;		}		if (c == '.')		    *(++t_bindings) = XrmBindTightly;		else		    *(++t_bindings) = XrmBindLoosely;		sig = 0;		ptr = buffer;	    }	    else {		/*		 * Magic unspecified feature #254.		 *		 * If two separators appear with no Text between them then		 * ignore them.		 *		 * If anyone of those separators is a '*' then the binding 		 * will be loose, otherwise it will be tight.		 */		if (c == '*')		    *t_bindings = XrmBindLoosely;	    }	    bits = next_char(c, str);	}	*t_quarks = NULLQUARK;	/*	 * Make sure that there is a ':' in this line.	 */	if (c != ':') {	    char oldc;	    /*	     * A parsing error has occured, toss everything on the line	     * a new_line can still be escaped with a '\'.	     */	    while (is_normal(bits))		bits = next_char(c, str);	    if (is_EOL(bits))		continue;	    bits = next_mbchar(c, len, str);	    do {		oldc = c;		bits = next_mbchar(c, len, str);	    } while (c && (c != '\n' || oldc == '\\'));	    str--;	    continue;	}	/*	 * I now have a quark and binding list for the entire left hand	 * side.  "c" currently points to the ":" separating the left hand	 * side for the right hand side.  It is time to begin processing	 * the right hand side.	 */	/* 	 * Fourth: Remove more whitespace	 */	for(;;) {	    if (is_space(bits = next_char(c, str)))		continue;	    if (c != '\\')		break;	    bits = next_char(c, str);	    if (c == '\n')		continue;	    str--;	    bits = BSLASH;	    c = '\\';	    break;	}	/* 	 * Fifth: Process the right hand side.	 */	ptr = value_str;	ptr_max = ptr + alloc_chars - 4;	only_pcs = True;	len = 1;	for(;;) {	    /*	     * Tight loop for the normal case:  Non backslash, non-end of value	     * character that will fit into the allocated buffer.	     */	    if (only_pcs) {		while (is_normal(bits) && ptr < ptr_max) {		    *ptr++ = c;		    bits = next_char(c, str);		}		if (is_EOL(bits))		    break;		if (is_nonpcs(bits)) {		    only_pcs = False;		    bits = next_mbchar(c, len, str);		}	    }	    while (!is_special(bits) && ptr + len <= ptr_max) {		len = -len;		while (len)		    *ptr++ = str[len++];		bits = next_mbchar(c, len, str);	    }	    if (is_EOL(bits)) {		str--;		break;	    }	    if (c == '\\') {		/*		 * We need to do some magic after a backslash.		 */		if (only_pcs) {		    bits = next_char(c, str);		    if (is_nonpcs(bits))			only_pcs = False;		}		if (!only_pcs)		    bits = next_mbchar(c, len, str);		if (is_EOL(bits)) {		    if (is_EOF(bits))			continue;		} else if (c == 'n') {		    /*		     * "\n" means insert a newline.		     */		    *ptr++ = '\n';		} else if (c == '\\') {		    /*		     * "\\" completes to just one backslash.		     */		    *ptr++ = '\\';		} else {		    /*		     * pick up to three octal digits after the '\'.		     */		    char temp[3];		    int count = 0;		    while (is_odigit(bits) && count < 3) {			temp[count++] = c;			if (only_pcs) {			    bits = next_char(c, str);			    if (is_nonpcs(bits))				only_pcs = False;			}			if (!only_pcs)			    bits = next_mbchar(c, len, str);		    }		    /*		     * If we found three digits then insert that octal code		     * into the value string as a character.		     */		    if (count == 3) {			*ptr++ = (unsigned char) ((temp[0] - '0') * 0100 +						  (temp[1] - '0') * 010 +						  (temp[2] - '0'));		    }		    else {			int tcount;			/* 			 * Otherwise just insert those characters into the 			 * string, since no special processing is needed on			 * numerics we can skip the special processing.			 */			for (tcount = 0; tcount < count; tcount++) {			    *ptr++ = temp[tcount]; /* print them in						      the correct order */			}		    }		    continue;		}		if (only_pcs) {		    bits = next_char(c, str);		    if (is_nonpcs(bits))			only_pcs = False;		}		if (!only_pcs)		    bits = next_mbchar(c, len, str);	    }	    /* 	     * It is important to make sure that there is room for at least	     * four more characters in the buffer, since I can add that	     * many characters into the buffer after a backslash has occured.	     */	    if (ptr + len > ptr_max) {		char * temp_str;		alloc_chars += BUFSIZ/10;				temp_str = Xrealloc(value_str, sizeof(char) * alloc_chars);		if (!temp_str) {		    Xfree(value_str);		    (*db->methods->mbfinish)(db->mbstate);		    return;		}		ptr = temp_str + (ptr - value_str); /* reset pointer. */		value_str = temp_str;		ptr_max = value_str + alloc_chars - 4;	    }	}	/*	 * Lastly: Terminate the value string, and store this entry 	 * 	   into the database.	 */	*ptr++ = '\0';	/* Store it in database */	value.size = ptr - value_str;	value.addr = (XPointer) value_str;		PutEntry(db, bindings, quarks, XrmQString, &value);    }    Xfree(value_str);    (*db->methods->mbfinish)(db->mbstate);}#if NeedFunctionPrototypesvoid XrmPutStringResource(    XrmDatabase *pdb,    _Xconst char*specifier,    _Xconst char*str)#elsevoid XrmPutStringResource(pdb, specifier, str)    XrmDatabase *pdb;    char	*specifier;    char	*str;#endif{    XrmValue	value;    XrmBinding	bindings[MAXDBDEPTH+1];    XrmQuark	quarks[MAXDBDEPTH+1];    if (!*pdb) *pdb = NewDatabase();    XrmStringToBindingQuarkList(specifier, bindings, quarks);    value.addr = (XPointer) str;    value.size = strlen(str)+1;    PutEntry(*pdb, bindings, quarks, XrmQString, &value);}#if NeedFunctionPrototypesvoid XrmPutLineResource(    XrmDatabase *pdb,    _Xconst char*line)#elsevoid XrmPutLineResource(pdb, line)    XrmDatabase *pdb;    char	*line;#endif{    if (!*pdb) *pdb = NewDatabase();    GetDatabase(*pdb, line, (char *)NULL, False);}#if NeedFunctionPrototypesXrmDatabase XrmGetStringDatabase(    _Xconst char    *data)#elseXrmDatabase XrmGetStringDatabase(data)    char	    *data;#endif{    XrmDatabase     db;    db = NewDatabase();    GetDatabase(db, data, (char *)NULL, True);    return db;}/*	Function Name: ReadInFile *	Description: Reads the file into a buffer. *	Arguments: filename - the name of the file. *	Returns: An allocated string containing the contents of the file. */static char *ReadInFile(filename)char * filename;{    register int fd, size;    char * filebuf;    if ( (fd = OpenFile(filename)) == -1 )	return (char *)NULL;    GetSizeOfFile(filename, size);	    if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */	close(fd);	return (char *)NULL;    }    if (ReadFile(fd, filebuf, size) != size) { /* If we didn't read the						  correct number of bytes. */	CloseFile(fd);	Xfree(filebuf);	return (char *)NULL;    }    CloseFile(fd);    filebuf[size] = '\0';	/* NULL terminate it. */    return filebuf;}static voidGetIncludeFile(db, base, fname, fnamelen)    XrmDatabase db;    char *base;    char *fname;    int fnamelen;{    int len;

⌨️ 快捷键说明

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