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

📄 exmlparser.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	mprAssert(state >= 0);	if ((c = getNextChar(xp)) < 0) {		return TOKEN_EOF;	}	mprFlushBuf(tokBuf);	/*	 *	Special case parsing for names and for element data. We do this for	 *	performance so we can return to the caller the largest token possible	 */	if (state == EXML_ELT_DATA) {		/*		 *	Read all the data up to the start of the closing element "<" or the		 *	start of a sub-element. 		 */#if UNUSED		while (isspace(c)) {			if ((c = getNextChar(xp)) < 0) {				return TOKEN_EOF;			}		}#endif		if (c == '<') {			if ((c = getNextChar(xp)) < 0) {				return TOKEN_EOF;			}			if (c == '/') {				return TOKEN_LS_SLASH;			}			putLastChar(xp, c);			return TOKEN_LS;		}		do {			if (mprPutCharToBuf(tokBuf, c) < 0) {				return TOKEN_TOO_BIG;			}			if ((c = getNextChar(xp)) < 0) {				return TOKEN_EOF;			}		} while (c != '<');		/*		 *	Put back the last look-ahead character		 */		putLastChar(xp, c);		/*		 *	If all white space, then zero the token buffer		 */		for (cp = tokBuf->start; *cp; cp++) {			if (!isspace(*cp)) {				return TOKEN_TEXT;			}		}		mprFlushBuf(tokBuf);		return TOKEN_TEXT;	}	while (1) {		switch (c) {		case ' ':		case '\n':		case '\t':		case '\r':			break;		case '<':			if ((c = getNextChar(xp)) < 0) {				return TOKEN_EOF;			}			if (c == '/') {				return TOKEN_LS_SLASH;			}			putLastChar(xp, c);			return TOKEN_LS;			case '=':			return TOKEN_EQ;		case '>':			return TOKEN_GR;		case '/':			if ((c = getNextChar(xp)) < 0) {				return TOKEN_EOF;			}			if (c == '>') {				return TOKEN_SLASH_GR;			}			return TOKEN_ERR;				case '\"':		case '\'':			xp->quoteChar = c;			/* Fall through */		default:			/* 			 *	We handle element names, attribute names and attribute values 			 *	here. We do NOT handle data between elements here. Read the 			 *	token.  Stop on white space or a closing element ">"			 */			if (xp->quoteChar) {				if ((c = getNextChar(xp)) < 0) {					return TOKEN_EOF;				}				while (c != xp->quoteChar) {					if (mprPutCharToBuf(tokBuf, c) < 0) {						return TOKEN_TOO_BIG;					}					if ((c = getNextChar(xp)) < 0) {						return TOKEN_EOF;					}				}				xp->quoteChar = 0;			} else {				while (!isspace(c) && c != '>' && c != '/' && c != '=') {					if (mprPutCharToBuf(tokBuf, c) < 0) {						return TOKEN_TOO_BIG;					}					if ((c = getNextChar(xp)) < 0) {						return TOKEN_EOF;					}				}				putLastChar(xp, c);			}			if (mprGetBufLength(tokBuf) <= 0) {				return TOKEN_ERR;			}			mprAddNullToBuf(tokBuf);			if (state == EXML_AFTER_LS) {				/*				 *	If we are just inside an element "<", then analyze what we				 *	have to see if we have an element name, instruction or 				 *	comment. Tokbuf will hold "?" for instructions or "!--"				 *	for comments.				 */				if (mprLookAtNextCharInBuf(tokBuf) == '?') {					/*	Just ignore processing instructions */					rc = scanFor(xp, "?>");					if (rc < 0) {						return TOKEN_TOO_BIG;					} else if (rc == 0) {						return TOKEN_ERR;					}					return TOKEN_INSTRUCTIONS;				} else if (mprLookAtNextCharInBuf(tokBuf) == '!') {					/*					 *	First discard the comment leadin "!--" and eat leading 					 *	white space.					 */					if (strcmp((char*) tokBuf->start, "![CDATA[") == 0) {						mprFlushBuf(tokBuf);#if UNUSED						c = mprLookAtNextCharInBuf(inBuf);						while (isspace(c)) {							if ((c = getNextChar(xp)) < 0) {								return TOKEN_EOF;							}							c = mprLookAtNextCharInBuf(inBuf);						}#endif						rc = scanFor(xp, "]]>");						if (rc < 0) {							return TOKEN_TOO_BIG;						} else if (rc == 0) {							return TOKEN_ERR;						}						return TOKEN_CDATA;					} else {						mprFlushBuf(tokBuf);#if UNUSED						c = mprLookAtNextCharInBuf(inBuf);						while (isspace(c)) {							if ((c = getNextChar(xp)) < 0) {								return TOKEN_EOF;							}							c = mprLookAtNextCharInBuf(inBuf);						}#endif						rc = scanFor(xp, "-->");						if (rc < 0) {							return TOKEN_TOO_BIG;						} else if (rc == 0) {							return TOKEN_ERR;						}						return TOKEN_COMMENT;					}				}			}			trimToken(xp);			return TOKEN_TEXT;		}		if ((c = getNextChar(xp)) < 0) {			return TOKEN_EOF;		}	}	/* Should never get here */	mprAssert(0);	return TOKEN_ERR;}/******************************************************************************//* *	Scan for a pattern. Eat and discard input up to the pattern. Return 1 if *	the pattern was found, return 0 if not found. Return < 0 on errors. */static int scanFor(Exml *xp, char *str){	MprBuf	*tokBuf;	char	*cp;	int		c;	mprAssert(str);	tokBuf = xp->tokBuf;	while (1) {		for (cp = str; *cp; cp++) {			if ((c = getNextChar(xp)) < 0) {				return 0;			}			if (tokBuf) {				if (mprPutCharToBuf(tokBuf, c) < 0) {					return -1;				}			}			if (c != *cp) {				break;			}		}		if (*cp == '\0') {			/*			 *	Remove the pattern from the tokBuf			 */			if (tokBuf) {				mprAdjustBufEnd(tokBuf, -(int) strlen(str));				trimToken(xp);			}			return 1;		}	}}/******************************************************************************//* *	Get another character. We read and buffer blocks of data if we need more *	data to parse. */static int getNextChar(Exml *xp){	MprBuf	*inBuf;	char	c;	int		l;	inBuf = xp->inBuf;	if (mprGetBufLength(inBuf) <= 0) {		/* 		 *	Flush to reset the servp/endp pointers to the start of the buffer		 *	so we can do a maximal read 		 */		mprFlushBuf(inBuf);		l = (xp->readFn)(xp, xp->inputArg, mprGetBufStart(inBuf), 			mprGetBufLinearSpace(inBuf));		if (l <= 0) {			return -1;		}		mprAdjustBufEnd(inBuf, l);	}	c = mprGetCharFromBuf(inBuf);	if (c == '\n') {		xp->lineNumber++;	}	return c;}/******************************************************************************//* *	Put back a character in the input buffer */static int putLastChar(Exml *xp, int c){	if (mprInsertCharToBuf(xp->inBuf, (char) c) < 0) {		mprAssert(0);		return -1;	}	if (c == '\n') {		xp->lineNumber--;	}	return 0;}/******************************************************************************//* *	Output a parse message */ static void error(Exml *xp, char *fmt, ...){	va_list		args;	char		*buf;	mprAssert(fmt);	va_start(args, fmt);	mprAllocVsprintf(MPR_LOC_ARGS(xp), &buf, MPR_MAX_STRING, fmt, args);	va_end(args);	/*	 *	MOB need to add the failing line text and a pointer to which column	 */	mprFree(xp->errMsg);	mprAllocSprintf(MPR_LOC_ARGS(xp), &xp->errMsg, MPR_MAX_STRING, 		"XML error: %s\nAt line %d\n", buf, xp->lineNumber);	mprFree(buf);}/******************************************************************************//* *	Remove trailing whitespace in a token and ensure it is terminated with *	a NULL for easy parsing */static void trimToken(Exml *xp){	while (isspace(mprLookAtLastCharInBuf(xp->tokBuf))) {		mprAdjustBufEnd(xp->tokBuf, -1);	}	mprAddNullToBuf(xp->tokBuf);}/******************************************************************************/const char *exmlGetErrorMsg(Exml *xp){	if (xp->errMsg == 0) {		return "";	}	return xp->errMsg;}/******************************************************************************/int exmlGetLineNumber(Exml *xp){	return xp->lineNumber;}/******************************************************************************/#elsevoid exmlParserDummy() {}#endif /* BLD_FEATURE_EXML *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim:tw=78 * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */

⌨️ 快捷键说明

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