xmlparse.c

来自「ARM上的如果你对底层感兴趣」· C语言 代码 · 共 2,269 行 · 第 1/5 页

C
2,269
字号
	abort();
      }
    }
    switch (XmlTokenRole(&prologState, tok, s, next, encoding)) {
    case XML_ROLE_XML_DECL:
      {
	enum XML_Error result = processXmlDecl(parser, 0, s, next);
	if (result != XML_ERROR_NONE)
	  return result;
      }
      break;
    case XML_ROLE_DOCTYPE_SYSTEM_ID:
      hadExternalDoctype = 1;
      break;
    case XML_ROLE_DOCTYPE_PUBLIC_ID:
    case XML_ROLE_ENTITY_PUBLIC_ID:
      if (!XmlIsPublicId(encoding, s, next, &eventPtr))
	return XML_ERROR_SYNTAX;
      if (declEntity) {
	XML_Char *tem = poolStoreString(&dtd.pool,
	                                encoding,
					s + encoding->minBytesPerChar,
	  				next - encoding->minBytesPerChar);
	if (!tem)
	  return XML_ERROR_NO_MEMORY;
	normalizePublicId(tem);
	declEntity->publicId = tem;
	poolFinish(&dtd.pool);
      }
      break;
    case XML_ROLE_INSTANCE_START:
      processor = contentProcessor;
      if (hadExternalDoctype)
	dtd.complete = 0;
      return contentProcessor(parser, s, end, nextPtr);
    case XML_ROLE_ATTLIST_ELEMENT_NAME:
      {
	const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next);
	if (!name)
	  return XML_ERROR_NO_MEMORY;
	declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
	if (!declElementType)
	  return XML_ERROR_NO_MEMORY;
	if (declElementType->name != name)
	  poolDiscard(&dtd.pool);
	else {
	  poolFinish(&dtd.pool);
	  if (!setElementTypePrefix(parser, declElementType))
            return XML_ERROR_NO_MEMORY;
	}
	break;
      }
    case XML_ROLE_ATTRIBUTE_NAME:
      declAttributeId = getAttributeId(parser, encoding, s, next);
      if (!declAttributeId)
	return XML_ERROR_NO_MEMORY;
      declAttributeIsCdata = 0;
      break;
    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
      declAttributeIsCdata = 1;
      break;
    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
      if (dtd.complete
	  && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
	return XML_ERROR_NO_MEMORY;
      break;
    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
      {
	const XML_Char *attVal;
	enum XML_Error result
	  = storeAttributeValue(parser, encoding, declAttributeIsCdata,
				s + encoding->minBytesPerChar,
			        next - encoding->minBytesPerChar,
			        &dtd.pool);
	if (result)
	  return result;
	attVal = poolStart(&dtd.pool);
	poolFinish(&dtd.pool);
	if (dtd.complete
	    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
	  return XML_ERROR_NO_MEMORY;
	break;
      }
    case XML_ROLE_ENTITY_VALUE:
      {
	enum XML_Error result = storeEntityValue(parser, s, next);
	if (result != XML_ERROR_NONE)
	  return result;
      }
      break;
    case XML_ROLE_ENTITY_SYSTEM_ID:
      if (declEntity) {
	declEntity->systemId = poolStoreString(&dtd.pool, encoding,
	                                       s + encoding->minBytesPerChar,
	  				       next - encoding->minBytesPerChar);
	if (!declEntity->systemId)
	  return XML_ERROR_NO_MEMORY;
	declEntity->base = dtd.base;
	poolFinish(&dtd.pool);
      }
      break;
    case XML_ROLE_ENTITY_NOTATION_NAME:
      if (declEntity) {
	declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next);
	if (!declEntity->notation)
	  return XML_ERROR_NO_MEMORY;
	poolFinish(&dtd.pool);
	if (unparsedEntityDeclHandler) {
	  eventPtr = eventEndPtr = s;
	  unparsedEntityDeclHandler(handlerArg,
				    declEntity->name,
				    declEntity->base,
				    declEntity->systemId,
				    declEntity->publicId,
				    declEntity->notation);
	}

      }
      break;
    case XML_ROLE_GENERAL_ENTITY_NAME:
      {
	const XML_Char *name;
	if (XmlPredefinedEntityName(encoding, s, next)) {
	  declEntity = 0;
	  break;
	}
	name = poolStoreString(&dtd.pool, encoding, s, next);
	if (!name)
	  return XML_ERROR_NO_MEMORY;
	if (dtd.complete) {
	  declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
	  if (!declEntity)
	    return XML_ERROR_NO_MEMORY;
	  if (declEntity->name != name) {
	    poolDiscard(&dtd.pool);
	    declEntity = 0;
	  }
	  else
	    poolFinish(&dtd.pool);
	}
	else {
	  poolDiscard(&dtd.pool);
	  declEntity = 0;
	}
      }
      break;
    case XML_ROLE_PARAM_ENTITY_NAME:
      declEntity = 0;
      break;
    case XML_ROLE_NOTATION_NAME:
      declNotationPublicId = 0;
      declNotationName = 0;
      if (notationDeclHandler) {
	declNotationName = poolStoreString(&tempPool, encoding, s, next);
	if (!declNotationName)
	  return XML_ERROR_NO_MEMORY;
	poolFinish(&tempPool);
      }
      break;
    case XML_ROLE_NOTATION_PUBLIC_ID:
      if (!XmlIsPublicId(encoding, s, next, &eventPtr))
	return XML_ERROR_SYNTAX;
      if (declNotationName) {
	XML_Char *tem = poolStoreString(&tempPool,
	                                encoding,
					s + encoding->minBytesPerChar,
	  				next - encoding->minBytesPerChar);
	if (!tem)
	  return XML_ERROR_NO_MEMORY;
	normalizePublicId(tem);
	declNotationPublicId = tem;
	poolFinish(&tempPool);
      }
      break;
    case XML_ROLE_NOTATION_SYSTEM_ID:
      if (declNotationName && notationDeclHandler) {
	const XML_Char *systemId
	  = poolStoreString(&tempPool, encoding,
			    s + encoding->minBytesPerChar,
	  		    next - encoding->minBytesPerChar);
	if (!systemId)
	  return XML_ERROR_NO_MEMORY;
	eventPtr = eventEndPtr = s;
	notationDeclHandler(handlerArg,
			    declNotationName,
			    dtd.base,
			    systemId,
			    declNotationPublicId);
      }
      poolClear(&tempPool);
      break;
    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
      if (declNotationPublicId && notationDeclHandler) {
	eventPtr = eventEndPtr = s;
	notationDeclHandler(handlerArg,
			    declNotationName,
			    dtd.base,
			    0,
			    declNotationPublicId);
      }
      poolClear(&tempPool);
      break;
    case XML_ROLE_ERROR:
      eventPtr = s;
      switch (tok) {
      case XML_TOK_PARAM_ENTITY_REF:
	return XML_ERROR_PARAM_ENTITY_REF;
      case XML_TOK_XML_DECL:
	return XML_ERROR_MISPLACED_XML_PI;
      default:
	return XML_ERROR_SYNTAX;
      }
    case XML_ROLE_GROUP_OPEN:
      if (prologState.level >= groupSize) {
	if (groupSize)
	  groupConnector = realloc(groupConnector, groupSize *= 2);
	else
	  groupConnector = malloc(groupSize = 32);
	if (!groupConnector)
	  return XML_ERROR_NO_MEMORY;
      }
      groupConnector[prologState.level] = 0;
      break;
    case XML_ROLE_GROUP_SEQUENCE:
      if (groupConnector[prologState.level] == '|') {
	eventPtr = s;
	return XML_ERROR_SYNTAX;
      }
      groupConnector[prologState.level] = ',';
      break;
    case XML_ROLE_GROUP_CHOICE:
      if (groupConnector[prologState.level] == ',') {
	eventPtr = s;
	return XML_ERROR_SYNTAX;
      }
      groupConnector[prologState.level] = '|';
      break;
    case XML_ROLE_PARAM_ENTITY_REF:
      dtd.complete = 0;
      break;
    case XML_ROLE_NONE:
      switch (tok) {
      case XML_TOK_PI:
	eventPtr = s;
	eventEndPtr = next;
	if (!reportProcessingInstruction(parser, encoding, s, next))
	  return XML_ERROR_NO_MEMORY;
	break;
      case XML_TOK_COMMENT:
	eventPtr = s;
	eventEndPtr = next;
	if (!reportComment(parser, encoding, s, next))
	  return XML_ERROR_NO_MEMORY;
	break;
      }
      break;
    }
    if (defaultHandler) {
      switch (tok) {
      case XML_TOK_PI:
      case XML_TOK_COMMENT:
      case XML_TOK_BOM:
      case XML_TOK_XML_DECL:
	break;
      default:
	eventPtr = s;
	eventEndPtr = next;
	reportDefault(parser, encoding, s, next);
      }
    }
    s = next;
  }
  /* not reached */
}

static
enum XML_Error epilogProcessor(XML_Parser parser,
			       const char *s,
			       const char *end,
			       const char **nextPtr)
{
  processor = epilogProcessor;
  eventPtr = s;
  for (;;) {
    const char *next;
    int tok = XmlPrologTok(encoding, s, end, &next);
    eventEndPtr = next;
    switch (tok) {
    case XML_TOK_TRAILING_CR:
      if (defaultHandler) {
	eventEndPtr = end;
	reportDefault(parser, encoding, s, end);
      }
      /* fall through */
    case XML_TOK_NONE:
      if (nextPtr)
	*nextPtr = end;
      return XML_ERROR_NONE;
    case XML_TOK_PROLOG_S:
      if (defaultHandler)
	reportDefault(parser, encoding, s, next);
      break;
    case XML_TOK_PI:
      if (!reportProcessingInstruction(parser, encoding, s, next))
	return XML_ERROR_NO_MEMORY;
      break;
    case XML_TOK_COMMENT:
      if (!reportComment(parser, encoding, s, next))
	return XML_ERROR_NO_MEMORY;
      break;
    case XML_TOK_INVALID:
      eventPtr = next;
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_PARTIAL:
      if (nextPtr) {
	*nextPtr = s;
	return XML_ERROR_NONE;
      }
      return XML_ERROR_UNCLOSED_TOKEN;
    case XML_TOK_PARTIAL_CHAR:
      if (nextPtr) {
	*nextPtr = s;
	return XML_ERROR_NONE;
      }
      return XML_ERROR_PARTIAL_CHAR;
    default:
      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
    }
    eventPtr = s = next;
  }
}

static
enum XML_Error errorProcessor(XML_Parser parser,
			      const char *s,
			      const char *end,
			      const char **nextPtr)
{
  return errorCode;
}

static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
		    const char *ptr, const char *end,
		    STRING_POOL *pool)
{
  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
  if (result)
    return result;
  if (!isCdata && poolLength(pool) && poolLastChar(pool) == XML_T(' '))
    poolChop(pool);
  if (!poolAppendChar(pool, XML_T('\0')))
    return XML_ERROR_NO_MEMORY;
  return XML_ERROR_NONE;
}

static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
		     const char *ptr, const char *end,
		     STRING_POOL *pool)
{
  const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
  for (;;) {
    const char *next;
    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
    switch (tok) {
    case XML_TOK_NONE:
      return XML_ERROR_NONE;
    case XML_TOK_INVALID:
      if (enc == encoding)
	eventPtr = next;
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_PARTIAL:
      if (enc == encoding)
	eventPtr = ptr;
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_CHAR_REF:
      {
	XML_Char buf[XML_ENCODE_MAX];
	int i;
	int n = XmlCharRefNumber(enc, ptr);
	if (n < 0) {
	  if (enc == encoding)
	    eventPtr = ptr;
      	  return XML_ERROR_BAD_CHAR_REF;
	}
	if (!isCdata
	    && n == 0x20 /* space */
	    && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
	  break;
	n = XmlEncode(n, (ICHAR *)buf);
	if (!n) {
	  if (enc == encoding)
	    eventPtr = ptr;
	  return XML_ERROR_BAD_CHAR_REF;
	}
	for (i = 0; i < n; i++) {
	  if (!poolAppendChar(pool, buf[i]))
	    return XML_ERROR_NO_MEMORY;
	}
      }
      break;
    case XML_TOK_DATA_CHARS:
      if (!poolAppend(pool, enc, ptr, next))
	return XML_ERROR_NO_MEMORY;
      break;
      break;
    case XML_TOK_TRAILING_CR:
      next = ptr + enc->minBytesPerChar;
      /* fall through */
    case XML_TOK_ATTRIBUTE_VALUE_S:
    case XML_TOK_DATA_NEWLINE:
      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
	break;
      if (!poolAppendChar(pool, XML_T(' ')))
	return XML_ERROR_NO_MEMORY;
      break;
    case XML_TOK_ENTITY_REF:
      {
	const XML_Char *name;
	ENTITY *entity;
	XML_Char ch = XmlPredefinedEntityName(enc,
					      ptr + enc->minBytesPerChar,
					      next - enc->minBytesPerChar);
	if (ch) {
	  if (!poolAppendChar(pool, ch))
  	    return XML_ERROR_NO_MEMORY;
	  break;
	}
	name = poolStoreString(&temp2Pool, enc,
			       ptr + enc->minBytesPerChar,
			       next - enc->minBytesPerChar);
	if (!name)
	  return XML_ERROR_NO_MEMORY;
	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
	poolDiscard(&temp2Pool);
	if (!entity) {
	  if (dtd.complete) {
	    if (enc == encoding)
	      eventPtr = ptr;
	    return XML_ERROR_UNDEFINED_ENTITY;
	  }
	}
	else if (entity->open) {
	  if (enc == encoding)
	    eventPtr = ptr;
	  return XML_ERROR_RECURSIVE_ENTITY_REF;
	}
	else if (entity->notation) {
	  if (enc == encoding)
	    eventPtr = pt

⌨️ 快捷键说明

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