parser.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:295k
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "malloc of %d byte failedn", size);
- return(NULL);
- }
- /*
- * The content of the entity definition is copied in a buffer.
- */
- ctxt->instate = XML_PARSER_ENTITY_VALUE;
- input = ctxt->input;
- GROW;
- NEXT;
- c = CUR_CHAR(l);
- /*
- * NOTE: 4.4.5 Included in Literal
- * When a parameter entity reference appears in a literal entity
- * value, ... a single or double quote character in the replacement
- * text is always treated as a normal data character and will not
- * terminate the literal.
- * In practice it means we stop the loop only when back at parsing
- * the initial entity and the quote is found
- */
- while (IS_CHAR(c) && ((c != stop) || (ctxt->input != input))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "realloc of %d byte failedn", size);
- return(NULL);
- }
- }
- COPY_BUF(l,buf,len,c);
- NEXTL(l);
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- c = CUR_CHAR(l);
- if (c == 0) {
- GROW;
- c = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- /*
- * Raise problem w.r.t. '&' and '%' being used in non-entities
- * reference constructs. Note Charref will be handled in
- * xmlStringDecodeEntities()
- */
- cur = buf;
- while (*cur != 0) {
- if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
- xmlChar *name;
- xmlChar tmp = *cur;
- cur++;
- name = xmlParseStringName(ctxt, &cur);
- if ((name == NULL) || (*cur != ';')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "EntityValue: '%c' forbidden except for entities referencesn",
- tmp);
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_ENTITY_CHAR_ERROR;
- }
- if ((ctxt->inSubset == 1) && (tmp == '%')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "EntityValue: PEReferences forbidden in internal subsetn",
- tmp);
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_ENTITY_PE_INTERNAL;
- }
- if (name != NULL)
- xmlFree(name);
- }
- cur++;
- }
- /*
- * Then PEReference entities are substituted.
- */
- if (c != stop) {
- ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "EntityValue: " expectedn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- xmlFree(buf);
- } else {
- NEXT;
- /*
- * NOTE: 4.4.7 Bypassed
- * When a general entity reference appears in the EntityValue in
- * an entity declaration, it is bypassed and left as is.
- * so XML_SUBSTITUTE_REF is not set here.
- */
- ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
- 0, 0, 0);
- if (orig != NULL)
- *orig = buf;
- else
- xmlFree(buf);
- }
-
- return(ret);
- }
- /**
- * xmlParseAttValue:
- * @ctxt: an XML parser context
- *
- * parse a value for an attribute
- * Note: the parser won't do substitution of entities here, this
- * will be handled later in xmlStringGetNodeList
- *
- * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
- * "'" ([^<&'] | Reference)* "'"
- *
- * 3.3.3 Attribute-Value Normalization:
- * Before the value of an attribute is passed to the application or
- * checked for validity, the XML processor must normalize it as follows:
- * - a character reference is processed by appending the referenced
- * character to the attribute value
- * - an entity reference is processed by recursively processing the
- * replacement text of the entity
- * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
- * appending #x20 to the normalized value, except that only a single
- * #x20 is appended for a "#xD#xA" sequence that is part of an external
- * parsed entity or the literal entity value of an internal parsed entity
- * - other characters are processed by appending them to the normalized value
- * If the declared value is not CDATA, then the XML processor must further
- * process the normalized attribute value by discarding any leading and
- * trailing space (#x20) characters, and by replacing sequences of space
- * (#x20) characters by a single space (#x20) character.
- * All attributes for which no declaration has been read should be treated
- * by a non-validating parser as if declared CDATA.
- *
- * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
- */
- xmlChar *
- xmlParseAttValue(xmlParserCtxtPtr ctxt) {
- xmlChar limit = 0;
- xmlChar *buffer = NULL;
- int buffer_size = 0;
- xmlChar *out = NULL;
- xmlChar *current = NULL;
- xmlEntityPtr ent;
- xmlChar cur;
- SHRINK;
- if (NXT(0) == '"') {
- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
- limit = '"';
- NEXT;
- } else if (NXT(0) == ''') {
- limit = ''';
- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: " or ' expectedn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(NULL);
- }
-
- /*
- * allocate a translation buffer.
- */
- buffer_size = XML_PARSER_BUFFER_SIZE;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- perror("xmlParseAttValue: malloc failed");
- return(NULL);
- }
- out = buffer;
- /*
- * Ok loop until we reach one of the ending char or a size limit.
- */
- cur = CUR;
- while (((NXT(0) != limit) && (cur != '<')) || (ctxt->token != 0)) {
- if (cur == 0) break;
- if ((cur == '&') && (NXT(1) == '#')) {
- int val = xmlParseCharRef(ctxt);
- *out++ = val;
- } else if (cur == '&') {
- ent = xmlParseEntityRef(ctxt);
- if ((ent != NULL) &&
- (ctxt->replaceEntities != 0)) {
- xmlChar *rep;
- if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
- rep = xmlStringDecodeEntities(ctxt, ent->content,
- XML_SUBSTITUTE_REF, 0, 0, 0);
- if (rep != NULL) {
- current = rep;
- while (*current != 0) {
- *out++ = *current++;
- if (out - buffer > buffer_size - 10) {
- int index = out - buffer;
- growBuffer(buffer);
- out = &buffer[index];
- }
- }
- xmlFree(rep);
- }
- } else {
- if (ent->content != NULL)
- *out++ = ent->content[0];
- }
- } else if (ent != NULL) {
- int i = xmlStrlen(ent->name);
- const xmlChar *cur = ent->name;
- /*
- * This may look absurd but is needed to detect
- * entities problems
- */
- if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
- xmlChar *rep;
- rep = xmlStringDecodeEntities(ctxt, ent->content,
- XML_SUBSTITUTE_REF, 0, 0, 0);
- if (rep != NULL)
- xmlFree(rep);
- }
- /*
- * Just output the reference
- */
- *out++ = '&';
- if (out - buffer > buffer_size - i - 10) {
- int index = out - buffer;
- growBuffer(buffer);
- out = &buffer[index];
- }
- for (;i > 0;i--)
- *out++ = *cur++;
- *out++ = ';';
- }
- } else {
- /* invalid for UTF-8 , use COPY(out); !!! */
- if ((cur == 0x20) || (cur == 0xD) || (cur == 0xA) || (cur == 0x9)) {
- *out++ = 0x20;
- if (out - buffer > buffer_size - 10) {
- int index = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[index];
- }
- } else {
- *out++ = cur;
- if (out - buffer > buffer_size - 10) {
- int index = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[index];
- }
- }
- NEXT;
- }
- cur = CUR;
- }
- *out++ = 0;
- if (RAW == '<') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Unescaped '<' not allowed in attributes valuesn");
- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else if (RAW != limit) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: ' expectedn");
- ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else
- NEXT;
- return(buffer);
- }
- /**
- * xmlParseSystemLiteral:
- * @ctxt: an XML parser context
- *
- * parse an XML Literal
- *
- * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
- *
- * Returns the SystemLiteral parsed or NULL
- */
- xmlChar *
- xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int cur, l;
- xmlChar stop;
- int state = ctxt->instate;
- SHRINK;
- if (RAW == '"') {
- NEXT;
- stop = '"';
- } else if (RAW == ''') {
- NEXT;
- stop = ''';
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SystemLiteral " or ' expectedn");
- ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(NULL);
- }
-
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "malloc of %d byte failedn", size);
- return(NULL);
- }
- ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
- cur = CUR_CHAR(l);
- while ((IS_CHAR(cur)) && (cur != stop)) {
- if (len + 5 >= size) {
- size *= 2;
- buf = xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "realloc of %d byte failedn", size);
- ctxt->instate = state;
- return(NULL);
- }
- }
- COPY_BUF(l,buf,len,cur);
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- GROW;
- SHRINK;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- ctxt->instate = state;
- if (!IS_CHAR(cur)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteraln");
- ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- return(buf);
- }
- /**
- * xmlParsePubidLiteral:
- * @ctxt: an XML parser context
- *
- * parse an XML public literal
- *
- * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
- *
- * Returns the PubidLiteral parsed or NULL.
- */
- xmlChar *
- xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- xmlChar cur;
- xmlChar stop;
- SHRINK;
- if (RAW == '"') {
- NEXT;
- stop = '"';
- } else if (RAW == ''') {
- NEXT;
- stop = ''';
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SystemLiteral " or ' expectedn");
- ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(NULL);
- }
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "malloc of %d byte failedn", size);
- return(NULL);
- }
- cur = CUR;
- while ((IS_PUBIDCHAR(cur)) && (cur != stop)) {
- if (len + 1 >= size) {
- size *= 2;
- buf = xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "realloc of %d byte failedn", size);
- return(NULL);
- }
- }
- buf[len++] = cur;
- NEXT;
- cur = CUR;
- if (cur == 0) {
- GROW;
- SHRINK;
- cur = CUR;
- }
- }
- buf[len] = 0;
- if (cur != stop) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteraln");
- ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- return(buf);
- }
- /**
- * xmlParseCharData:
- * @ctxt: an XML parser context
- * @cdata: int indicating whether we are within a CDATA section
- *
- * parse a CharData section.
- * if we are within a CDATA section ']]>' marks an end of section.
- *
- * The right angle bracket (>) may be represented using the string ">",
- * and must, for compatibility, be escaped using ">" or a character
- * reference when it appears in the string "]]>" in content, when that
- * string is not marking the end of a CDATA section.
- *
- * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
- */
- void
- xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
- xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
- int nbchar = 0;
- int cur, l;
- SHRINK;
- cur = CUR_CHAR(l);
- while (((cur != '<') || (ctxt->token == '<')) &&
- ((cur != '&') || (ctxt->token == '&')) &&
- (IS_CHAR(cur))) {
- if ((cur == ']') && (NXT(1) == ']') &&
- (NXT(2) == '>')) {
- if (cdata) break;
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Sequence ']]>' not allowed in contentn");
- ctxt->errNo = XML_ERR_MISPLACED_CDATA_END;
- /* Should this be relaxed ??? I see a "must here */
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- }
- COPY_BUF(l,buf,nbchar,cur);
- if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
- /*
- * Ok the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData,
- buf, nbchar);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- nbchar = 0;
- }
- NEXTL(l);
- cur = CUR_CHAR(l);
- }
- if (nbchar != 0) {
- /*
- * Ok the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- }
- }
- /**
- * xmlParseExternalID:
- * @ctxt: an XML parser context
- * @publicID: a xmlChar** receiving PubidLiteral
- * @strict: indicate whether we should restrict parsing to only
- * production [75], see NOTE below
- *
- * Parse an External ID or a Public ID
- *
- * NOTE: Productions [75] and [83] interract badly since [75] can generate
- * 'PUBLIC' S PubidLiteral S SystemLiteral
- *
- * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
- * | 'PUBLIC' S PubidLiteral S SystemLiteral
- *
- * [83] PublicID ::= 'PUBLIC' S PubidLiteral
- *
- * Returns the function returns SystemLiteral and in the second
- * case publicID receives PubidLiteral, is strict is off
- * it is possible to return NULL and have publicID set.
- */
- xmlChar *
- xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
- xmlChar *URI = NULL;
- SHRINK;
- if ((RAW == 'S') && (NXT(1) == 'Y') &&
- (NXT(2) == 'S') && (NXT(3) == 'T') &&
- (NXT(4) == 'E') && (NXT(5) == 'M')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'SYSTEM'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- URI = xmlParseSystemLiteral(ctxt);
- if (URI == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseExternalID: SYSTEM, no URIn");
- ctxt->errNo = XML_ERR_URI_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- } else if ((RAW == 'P') && (NXT(1) == 'U') &&
- (NXT(2) == 'B') && (NXT(3) == 'L') &&
- (NXT(4) == 'I') && (NXT(5) == 'C')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'PUBLIC'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- *publicID = xmlParsePubidLiteral(ctxt);
- if (*publicID == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseExternalID: PUBLIC, no Public Identifiern");
- ctxt->errNo = XML_ERR_PUBID_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- if (strict) {
- /*
- * We don't handle [83] so "S SystemLiteral" is required.
- */
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the Public Identifiern");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- } else {
- /*
- * We handle [83] so we return immediately, if
- * "S SystemLiteral" is not detected. From a purely parsing
- * point of view that's a nice mess.
- */
- const xmlChar *ptr;
- GROW;
- ptr = CUR_PTR;
- if (!IS_BLANK(*ptr)) return(NULL);
-
- while (IS_BLANK(*ptr)) ptr++;
- if ((*ptr != ''') && (*ptr != '"')) return(NULL);
- }
- SKIP_BLANKS;
- URI = xmlParseSystemLiteral(ctxt);
- if (URI == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseExternalID: PUBLIC, no URIn");
- ctxt->errNo = XML_ERR_URI_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- }
- return(URI);
- }
- /**
- * xmlParseComment:
- * @ctxt: an XML parser context
- *
- * Skip an XML (SGML) comment <!-- .... -->
- * The spec says that "For compatibility, the string "--" (double-hyphen)
- * must not occur within comments. "
- *
- * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
- */
- void
- xmlParseComment(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int q, ql;
- int r, rl;
- int cur, l;
- xmlParserInputState state;
- xmlParserInputPtr input = ctxt->input;
- /*
- * Check that there is a comment right here.
- */
- if ((RAW != '<') || (NXT(1) != '!') ||
- (NXT(2) != '-') || (NXT(3) != '-')) return;
- state = ctxt->instate;
- ctxt->instate = XML_PARSER_COMMENT;
- SHRINK;
- SKIP(4);
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "malloc of %d byte failedn", size);
- ctxt->instate = state;
- return;
- }
- q = CUR_CHAR(ql);
- NEXTL(ql);
- r = CUR_CHAR(rl);
- NEXTL(rl);
- cur = CUR_CHAR(l);
- while (IS_CHAR(cur) &&
- ((cur != '>') ||
- (r != '-') || (q != '-'))) {
- if ((r == '-') && (q == '-')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Comment must not contain '--' (double-hyphen)`n");
- ctxt->errNo = XML_ERR_HYPHEN_IN_COMMENT;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- if (len + 5 >= size) {
- size *= 2;
- buf = xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "realloc of %d byte failedn", size);
- ctxt->instate = state;
- return;
- }
- }
- COPY_BUF(ql,buf,len,q);
- q = r;
- ql = rl;
- r = cur;
- rl = l;
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- if (!IS_CHAR(cur)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Comment not terminated n<!--%.50sn", buf);
- ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- xmlFree(buf);
- } else {
- if (input != ctxt->input) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Comment doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- NEXT;
- if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->comment(ctxt->userData, buf);
- xmlFree(buf);
- }
- ctxt->instate = state;
- }
- /**
- * xmlParsePITarget:
- * @ctxt: an XML parser context
- *
- * parse the name of a PI
- *
- * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
- *
- * Returns the PITarget name or NULL
- */
- xmlChar *
- xmlParsePITarget(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- name = xmlParseName(ctxt);
- if ((name != NULL) &&
- ((name[0] == 'x') || (name[0] == 'X')) &&
- ((name[1] == 'm') || (name[1] == 'M')) &&
- ((name[2] == 'l') || (name[2] == 'L'))) {
- int i;
- if ((name[0] == 'x') && (name[1] == 'm') &&
- (name[2] == 'l') && (name[3] == 0)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML declaration allowed only at the start of the documentn");
- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(name);
- } else if (name[3] == 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Invalid PI namen");
- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(name);
- }
- for (i = 0;;i++) {
- if (xmlW3CPIs[i] == NULL) break;
- if (!xmlStrcmp(name, (const xmlChar *)xmlW3CPIs[i]))
- return(name);
- }
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) {
- ctxt->sax->warning(ctxt->userData,
- "xmlParsePItarget: invalid name prefix 'xml'n");
- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
- }
- }
- return(name);
- }
- /**
- * xmlParsePI:
- * @ctxt: an XML parser context
- *
- * parse an XML Processing Instruction.
- *
- * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
- *
- * The processing is transfered to SAX once parsed.
- */
- void
- xmlParsePI(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int cur, l;
- xmlChar *target;
- xmlParserInputState state;
- if ((RAW == '<') && (NXT(1) == '?')) {
- xmlParserInputPtr input = ctxt->input;
- state = ctxt->instate;
- ctxt->instate = XML_PARSER_PI;
- /*
- * this is a Processing Instruction.
- */
- SKIP(2);
- SHRINK;
- /*
- * Parse the target name and check for special support like
- * namespace.
- */
- target = xmlParsePITarget(ctxt);
- if (target != NULL) {
- if ((RAW == '?') && (NXT(1) == '>')) {
- if (input != ctxt->input) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PI declaration doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP(2);
- /*
- * SAX: PI detected.
- */
- if ((ctxt->sax) && (!ctxt->disableSAX) &&
- (ctxt->sax->processingInstruction != NULL))
- ctxt->sax->processingInstruction(ctxt->userData,
- target, NULL);
- ctxt->instate = state;
- xmlFree(target);
- return;
- }
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "malloc of %d byte failedn", size);
- ctxt->instate = state;
- return;
- }
- cur = CUR;
- if (!IS_BLANK(cur)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePI: PI %s space expectedn", target);
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- cur = CUR_CHAR(l);
- while (IS_CHAR(cur) &&
- ((cur != '?') || (NXT(1) != '>'))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- fprintf(stderr, "realloc of %d byte failedn", size);
- ctxt->instate = state;
- return;
- }
- }
- COPY_BUF(l,buf,len,cur);
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- if (cur != '?') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePI: PI %s never end ...n", target);
- ctxt->errNo = XML_ERR_PI_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PI declaration doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP(2);
- /*
- * SAX: PI detected.
- */
- if ((ctxt->sax) && (!ctxt->disableSAX) &&
- (ctxt->sax->processingInstruction != NULL))
- ctxt->sax->processingInstruction(ctxt->userData,
- target, buf);
- }
- xmlFree(buf);
- xmlFree(target);
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePI : no target namen");
- ctxt->errNo = XML_ERR_PI_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- ctxt->instate = state;
- }
- }
- /**
- * xmlParseNotationDecl:
- * @ctxt: an XML parser context
- *
- * parse a notation declaration
- *
- * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
- *
- * Hence there is actually 3 choices:
- * 'PUBLIC' S PubidLiteral
- * 'PUBLIC' S PubidLiteral S SystemLiteral
- * and 'SYSTEM' S SystemLiteral
- *
- * See the NOTE on xmlParseExternalID().
- */
- void
- xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *Pubid;
- xmlChar *Systemid;
-
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'N') && (NXT(3) == 'O') &&
- (NXT(4) == 'T') && (NXT(5) == 'A') &&
- (NXT(6) == 'T') && (NXT(7) == 'I') &&
- (NXT(8) == 'O') && (NXT(9) == 'N')) {
- xmlParserInputPtr input = ctxt->input;
- SHRINK;
- SKIP(10);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '<!NOTATION'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- }
- SKIP_BLANKS;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "NOTATION: Name expected heren");
- ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- }
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the NOTATION name'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- }
- SKIP_BLANKS;
- /*
- * Parse the IDs.
- */
- Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
- SKIP_BLANKS;
- if (RAW == '>') {
- if (input != ctxt->input) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Notation declaration doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- NEXT;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->notationDecl != NULL))
- ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'>' required to close NOTATION declarationn");
- ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- xmlFree(name);
- if (Systemid != NULL) xmlFree(Systemid);
- if (Pubid != NULL) xmlFree(Pubid);
- }
- }
- /**
- * xmlParseEntityDecl:
- * @ctxt: an XML parser context
- *
- * parse <!ENTITY declarations
- *
- * [70] EntityDecl ::= GEDecl | PEDecl
- *
- * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
- *
- * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
- *
- * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
- *
- * [74] PEDef ::= EntityValue | ExternalID
- *
- * [76] NDataDecl ::= S 'NDATA' S Name
- *
- * [ VC: Notation Declared ]
- * The Name must match the declared name of a notation.
- */
- void
- xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name = NULL;
- xmlChar *value = NULL;
- xmlChar *URI = NULL, *literal = NULL;
- xmlChar *ndata = NULL;
- int isParameter = 0;
- xmlChar *orig = NULL;
-
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'E') && (NXT(3) == 'N') &&
- (NXT(4) == 'T') && (NXT(5) == 'I') &&
- (NXT(6) == 'T') && (NXT(7) == 'Y')) {
- xmlParserInputPtr input = ctxt->input;
- ctxt->instate = XML_PARSER_ENTITY_DECL;
- SHRINK;
- SKIP(8);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '<!ENTITY'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- if (RAW == '%') {
- NEXT;
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '%'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- isParameter = 1;
- }
- name = xmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "xmlParseEntityDecl: no namen");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- }
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the entity namen");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- /*
- * handle the various case of definitions...
- */
- if (isParameter) {
- if ((RAW == '"') || (RAW == '''))
- value = xmlParseEntityValue(ctxt, &orig);
- if (value) {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_INTERNAL_PARAMETER_ENTITY,
- NULL, NULL, value);
- }
- else {
- URI = xmlParseExternalID(ctxt, &literal, 1);
- if ((URI == NULL) && (literal == NULL)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value requiredn");
- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- if (URI) {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_EXTERNAL_PARAMETER_ENTITY,
- literal, URI, NULL);
- }
- }
- } else {
- if ((RAW == '"') || (RAW == ''')) {
- value = xmlParseEntityValue(ctxt, &orig);
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_INTERNAL_GENERAL_ENTITY,
- NULL, NULL, value);
- } else {
- URI = xmlParseExternalID(ctxt, &literal, 1);
- if ((URI == NULL) && (literal == NULL)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value requiredn");
- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- if ((RAW != '>') && (!IS_BLANK(CUR))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required before 'NDATA'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- if ((RAW == 'N') && (NXT(1) == 'D') &&
- (NXT(2) == 'A') && (NXT(3) == 'T') &&
- (NXT(4) == 'A')) {
- SKIP(5);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'NDATA'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- ndata = xmlParseName(ctxt);
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->unparsedEntityDecl != NULL))
- ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
- literal, URI, ndata);
- } else {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_EXTERNAL_GENERAL_PARSED_ENTITY,
- literal, URI, NULL);
- }
- }
- }
- SKIP_BLANKS;
- if (RAW != '>') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityDecl: entity %s not terminatedn", name);
- ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity declaration doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- NEXT;
- }
- if (orig != NULL) {
- /*
- * Ugly mechanism to save the raw entity value.
- */
- xmlEntityPtr cur = NULL;
- if (isParameter) {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getParameterEntity != NULL))
- cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
- } else {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getEntity != NULL))
- cur = ctxt->sax->getEntity(ctxt->userData, name);
- }
- if (cur != NULL) {
- if (cur->orig != NULL)
- xmlFree(orig);
- else
- cur->orig = orig;
- } else
- xmlFree(orig);
- }
- if (name != NULL) xmlFree(name);
- if (value != NULL) xmlFree(value);
- if (URI != NULL) xmlFree(URI);
- if (literal != NULL) xmlFree(literal);
- if (ndata != NULL) xmlFree(ndata);
- }
- }
- /**
- * xmlParseDefaultDecl:
- * @ctxt: an XML parser context
- * @value: Receive a possible fixed default value for the attribute
- *
- * Parse an attribute default declaration
- *
- * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
- *
- * [ VC: Required Attribute ]
- * if the default declaration is the keyword #REQUIRED, then the
- * attribute must be specified for all elements of the type in the
- * attribute-list declaration.
- *
- * [ VC: Attribute Default Legal ]
- * The declared default value must meet the lexical constraints of
- * the declared attribute type c.f. xmlValidateAttributeDecl()
- *
- * [ VC: Fixed Attribute Default ]
- * if an attribute has a default value declared with the #FIXED
- * keyword, instances of that attribute must match the default value.
- *
- * [ WFC: No < in Attribute Values ]
- * handled in xmlParseAttValue()
- *
- * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
- * or XML_ATTRIBUTE_FIXED.
- */
- int
- xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
- int val;
- xmlChar *ret;
- *value = NULL;
- if ((RAW == '#') && (NXT(1) == 'R') &&
- (NXT(2) == 'E') && (NXT(3) == 'Q') &&
- (NXT(4) == 'U') && (NXT(5) == 'I') &&
- (NXT(6) == 'R') && (NXT(7) == 'E') &&
- (NXT(8) == 'D')) {
- SKIP(9);
- return(XML_ATTRIBUTE_REQUIRED);
- }
- if ((RAW == '#') && (NXT(1) == 'I') &&
- (NXT(2) == 'M') && (NXT(3) == 'P') &&
- (NXT(4) == 'L') && (NXT(5) == 'I') &&
- (NXT(6) == 'E') && (NXT(7) == 'D')) {
- SKIP(8);
- return(XML_ATTRIBUTE_IMPLIED);
- }
- val = XML_ATTRIBUTE_NONE;
- if ((RAW == '#') && (NXT(1) == 'F') &&
- (NXT(2) == 'I') && (NXT(3) == 'X') &&
- (NXT(4) == 'E') && (NXT(5) == 'D')) {
- SKIP(6);
- val = XML_ATTRIBUTE_FIXED;
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '#FIXED'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- }
- ret = xmlParseAttValue(ctxt);
- ctxt->instate = XML_PARSER_DTD;
- if (ret == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute default value declaration errorn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else
- *value = ret;
- return(val);
- }
- /**
- * xmlParseNotationType:
- * @ctxt: an XML parser context
- *
- * parse an Notation attribute type.
- *
- * Note: the leading 'NOTATION' S part has already being parsed...
- *
- * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
- *
- * [ VC: Notation Attributes ]
- * Values of this type must match one of the notation names included
- * in the declaration; all notation names in the declaration must be declared.
- *
- * Returns: the notation attribute tree built while parsing
- */
- xmlEnumerationPtr
- xmlParseNotationType(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEnumerationPtr ret = NULL, last = NULL, cur;
- if (RAW != '(') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'(' required to start 'NOTATION'n");
- ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(NULL);
- }
- SHRINK;
- do {
- NEXT;
- SKIP_BLANKS;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Name expected in NOTATION declarationn");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(ret);
- }
- cur = xmlCreateEnumeration(name);
- xmlFree(name);
- if (cur == NULL) return(ret);
- if (last == NULL) ret = last = cur;
- else {
- last->next = cur;
- last = cur;
- }
- SKIP_BLANKS;
- } while (RAW == '|');
- if (RAW != ')') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "')' required to finish NOTATION declarationn");
- ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if ((last != NULL) && (last != ret))
- xmlFreeEnumeration(last);
- return(ret);
- }
- NEXT;
- return(ret);
- }
- /**
- * xmlParseEnumerationType:
- * @ctxt: an XML parser context
- *
- * parse an Enumeration attribute type.
- *
- * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
- *
- * [ VC: Enumeration ]
- * Values of this type must match one of the Nmtoken tokens in
- * the declaration
- *
- * Returns: the enumeration attribute tree built while parsing
- */
- xmlEnumerationPtr
- xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEnumerationPtr ret = NULL, last = NULL, cur;
- if (RAW != '(') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'(' required to start ATTLIST enumerationn");
- ctxt->errNo = XML_ERR_ATTLIST_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(NULL);
- }
- SHRINK;
- do {
- NEXT;
- SKIP_BLANKS;
- name = xmlParseNmtoken(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "NmToken expected in ATTLIST enumerationn");
- ctxt->errNo = XML_ERR_NMTOKEN_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(ret);
- }
- cur = xmlCreateEnumeration(name);
- xmlFree(name);
- if (cur == NULL) return(ret);
- if (last == NULL) ret = last = cur;
- else {
- last->next = cur;
- last = cur;
- }
- SKIP_BLANKS;
- } while (RAW == '|');
- if (RAW != ')') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "')' required to finish ATTLIST enumerationn");
- ctxt->errNo = XML_ERR_ATTLIST_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(ret);
- }
- NEXT;
- return(ret);
- }
- /**
- * xmlParseEnumeratedType:
- * @ctxt: an XML parser context
- * @tree: the enumeration tree built while parsing
- *
- * parse an Enumerated attribute type.
- *
- * [57] EnumeratedType ::= NotationType | Enumeration
- *
- * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
- *
- *
- * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
- */
- int
- xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
- if ((RAW == 'N') && (NXT(1) == 'O') &&
- (NXT(2) == 'T') && (NXT(3) == 'A') &&
- (NXT(4) == 'T') && (NXT(5) == 'I') &&
- (NXT(6) == 'O') && (NXT(7) == 'N')) {
- SKIP(8);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'NOTATION'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(0);
- }
- SKIP_BLANKS;
- *tree = xmlParseNotationType(ctxt);
- if (*tree == NULL) return(0);
- return(XML_ATTRIBUTE_NOTATION);
- }
- *tree = xmlParseEnumerationType(ctxt);
- if (*tree == NULL) return(0);
- return(XML_ATTRIBUTE_ENUMERATION);
- }
- /**
- * xmlParseAttributeType:
- * @ctxt: an XML parser context
- * @tree: the enumeration tree built while parsing
- *
- * parse the Attribute list def for an element
- *
- * [54] AttType ::= StringType | TokenizedType | EnumeratedType
- *
- * [55] StringType ::= 'CDATA'
- *
- * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
- * 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
- *
- * Validity constraints for attribute values syntax are checked in
- * xmlValidateAttributeValue()
- *
- * [ VC: ID ]
- * Values of type ID must match the Name production. A name must not
- * appear more than once in an XML document as a value of this type;
- * i.e., ID values must uniquely identify the elements which bear them.
- *
- * [ VC: One ID per Element Type ]
- * No element type may have more than one ID attribute specified.
- *
- * [ VC: ID Attribute Default ]
- * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
- *
- * [ VC: IDREF ]
- * Values of type IDREF must match the Name production, and values
- * of type IDREFS must match Names; each IDREF Name must match the value
- * of an ID attribute on some element in the XML document; i.e. IDREF
- * values must match the value of some ID attribute.
- *
- * [ VC: Entity Name ]
- * Values of type ENTITY must match the Name production, values
- * of type ENTITIES must match Names; each Entity Name must match the
- * name of an unparsed entity declared in the DTD.
- *
- * [ VC: Name Token ]
- * Values of type NMTOKEN must match the Nmtoken production; values
- * of type NMTOKENS must match Nmtokens.
- *
- * Returns the attribute type
- */
- int
- xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
- SHRINK;
- if ((RAW == 'C') && (NXT(1) == 'D') &&
- (NXT(2) == 'A') && (NXT(3) == 'T') &&
- (NXT(4) == 'A')) {
- SKIP(5);
- return(XML_ATTRIBUTE_CDATA);
- } else if ((RAW == 'I') && (NXT(1) == 'D') &&
- (NXT(2) == 'R') && (NXT(3) == 'E') &&
- (NXT(4) == 'F') && (NXT(5) == 'S')) {
- SKIP(6);
- return(XML_ATTRIBUTE_IDREFS);
- } else if ((RAW == 'I') && (NXT(1) == 'D') &&
- (NXT(2) == 'R') && (NXT(3) == 'E') &&
- (NXT(4) == 'F')) {
- SKIP(5);
- return(XML_ATTRIBUTE_IDREF);
- } else if ((RAW == 'I') && (NXT(1) == 'D')) {
- SKIP(2);
- return(XML_ATTRIBUTE_ID);
- } else if ((RAW == 'E') && (NXT(1) == 'N') &&
- (NXT(2) == 'T') && (NXT(3) == 'I') &&
- (NXT(4) == 'T') && (NXT(5) == 'Y')) {
- SKIP(6);
- return(XML_ATTRIBUTE_ENTITY);
- } else if ((RAW == 'E') && (NXT(1) == 'N') &&
- (NXT(2) == 'T') && (NXT(3) == 'I') &&
- (NXT(4) == 'T') && (NXT(5) == 'I') &&
- (NXT(6) == 'E') && (NXT(7) == 'S')) {
- SKIP(8);
- return(XML_ATTRIBUTE_ENTITIES);
- } else if ((RAW == 'N') && (NXT(1) == 'M') &&
- (NXT(2) == 'T') && (NXT(3) == 'O') &&
- (NXT(4) == 'K') && (NXT(5) == 'E') &&
- (NXT(6) == 'N') && (NXT(7) == 'S')) {
- SKIP(8);
- return(XML_ATTRIBUTE_NMTOKENS);
- } else if ((RAW == 'N') && (NXT(1) == 'M') &&
- (NXT(2) == 'T') && (NXT(3) == 'O') &&
- (NXT(4) == 'K') && (NXT(5) == 'E') &&
- (NXT(6) == 'N')) {
- SKIP(7);
- return(XML_ATTRIBUTE_NMTOKEN);
- }
- return(xmlParseEnumeratedType(ctxt, tree));
- }
- /**
- * xmlParseAttributeListDecl:
- * @ctxt: an XML parser context
- *
- * : parse the Attribute list def for an element
- *
- * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
- *
- * [53] AttDef ::= S Name S AttType S DefaultDecl
- *
- */
- void
- xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *elemName;
- xmlChar *attrName;
- xmlEnumerationPtr tree;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'A') && (NXT(3) == 'T') &&
- (NXT(4) == 'T') && (NXT(5) == 'L') &&
- (NXT(6) == 'I') && (NXT(7) == 'S') &&
- (NXT(8) == 'T')) {
- xmlParserInputPtr input = ctxt->input;
- SKIP(9);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '<!ATTLIST'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- elemName = xmlParseName(ctxt);
- if (elemName == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "ATTLIST: no name for Elementn");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- }
- SKIP_BLANKS;
- while (RAW != '>') {
- const xmlChar *check = CUR_PTR;
- int type;
- int def;
- xmlChar *defaultValue = NULL;
- tree = NULL;
- attrName = xmlParseName(ctxt);
- if (attrName == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "ATTLIST: no name for Attributen");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- break;
- }
- GROW;
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the attribute namen");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- break;
- }
- SKIP_BLANKS;
- type = xmlParseAttributeType(ctxt, &tree);
- if (type <= 0) {
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- break;
- }
- GROW;
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the attribute typen");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
- SKIP_BLANKS;
- def = xmlParseDefaultDecl(ctxt, &defaultValue);
- if (def <= 0) {
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
- GROW;
- if (RAW != '>') {
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the attribute default valuen");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
- SKIP_BLANKS;
- }
- if (check == CUR_PTR) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseAttributeListDecl: detected internal errorn");
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->attributeDecl != NULL))
- ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
- type, def, defaultValue, tree);
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- GROW;
- }
- if (RAW == '>') {
- if (input != ctxt->input) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute list declaration doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- NEXT;
- }
- xmlFree(elemName);
- }
- }
- /**
- * xmlParseElementMixedContentDecl:
- * @ctxt: an XML parser context
- *
- * parse the declaration for a Mixed Element content
- * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
- *
- * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
- * '(' S? '#PCDATA' S? ')'
- *
- * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
- *
- * [ VC: No Duplicate Types ]
- * The same name must not appear more than once in a single
- * mixed-content declaration.
- *
- * returns: the list of the xmlElementContentPtr describing the element choices
- */
- xmlElementContentPtr
- xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt) {
- xmlElementContentPtr ret = NULL, cur = NULL, n;
- xmlChar *elem = NULL;
- GROW;
- if ((RAW == '#') && (NXT(1) == 'P') &&
- (NXT(2) == 'C') && (NXT(3) == 'D') &&
- (NXT(4) == 'A') && (NXT(5) == 'T') &&
- (NXT(6) == 'A')) {
- SKIP(7);
- SKIP_BLANKS;
- SHRINK;
- if (RAW == ')') {
- ctxt->entity = ctxt->input;
- NEXT;
- ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
- if (RAW == '*') {
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
- NEXT;
- }
- return(ret);
- }
- if ((RAW == '(') || (RAW == '|')) {
- ret = cur = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
- if (ret == NULL) return(NULL);
- }
- while (RAW == '|') {
- NEXT;
- if (elem == NULL) {
- ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
- if (ret == NULL) return(NULL);
- ret->c1 = cur;
- cur = ret;
- } else {
- n = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
- if (n == NULL) return(NULL);
- n->c1 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
- cur->c2 = n;
- cur = n;
- xmlFree(elem);
- }
- SKIP_BLANKS;
- elem = xmlParseName(ctxt);
- if (elem == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementMixedContentDecl : Name expectedn");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- xmlFreeElementContent(cur);
- return(NULL);
- }
- SKIP_BLANKS;
- GROW;
- }
- if ((RAW == ')') && (NXT(1) == '*')) {
- if (elem != NULL) {
- cur->c2 = xmlNewElementContent(elem,
- XML_ELEMENT_CONTENT_ELEMENT);
- xmlFree(elem);
- }
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
- ctxt->entity = ctxt->input;
- SKIP(2);
- } else {
- if (elem != NULL) xmlFree(elem);
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementMixedContentDecl : '|' or ')*' expectedn");
- ctxt->errNo = XML_ERR_MIXED_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- xmlFreeElementContent(ret);
- return(NULL);
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementMixedContentDecl : '#PCDATA' expectedn");
- ctxt->errNo = XML_ERR_PCDATA_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- return(ret);
- }
- /**
- * xmlParseElementChildrenContentDecl:
- * @ctxt: an XML parser context
- *
- * parse the declaration for a Mixed Element content
- * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
- *
- *
- * [47] children ::= (choice | seq) ('?' | '*' | '+')?
- *
- * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
- *
- * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
- *
- * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
- *
- * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
- * TODO Parameter-entity replacement text must be properly nested
- * with parenthetized groups. That is to say, if either of the
- * opening or closing parentheses in a choice, seq, or Mixed
- * construct is contained in the replacement text for a parameter
- * entity, both must be contained in the same replacement text. For
- * interoperability, if a parameter-entity reference appears in a
- * choice, seq, or Mixed construct, its replacement text should not
- * be empty, and neither the first nor last non-blank character of
- * the replacement text should be a connector (| or ,).
- *
- * returns: the tree of xmlElementContentPtr describing the element
- * hierarchy.
- */
- xmlElementContentPtr
- xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) {
- xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
- xmlChar *elem;
- xmlChar type = 0;
- SKIP_BLANKS;
- GROW;
- if (RAW == '(') {
- /* Recurse on first child */
- NEXT;
- SKIP_BLANKS;
- cur = ret = xmlParseElementChildrenContentDecl(ctxt);
- SKIP_BLANKS;
- GROW;
- } else {
- elem = xmlParseName(ctxt);
- if (elem == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : Name or '(' expectedn");
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(NULL);
- }
- cur = ret = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
- GROW;
- if (RAW == '?') {
- cur->ocur = XML_ELEMENT_CONTENT_OPT;
- NEXT;
- } else if (RAW == '*') {
- cur->ocur = XML_ELEMENT_CONTENT_MULT;
- NEXT;
- } else if (RAW == '+') {
- cur->ocur = XML_ELEMENT_CONTENT_PLUS;
- NEXT;
- } else {
- cur->ocur = XML_ELEMENT_CONTENT_ONCE;
- }
- xmlFree(elem);
- GROW;
- }
- SKIP_BLANKS;
- SHRINK;
- while (RAW != ')') {
- /*
- * Each loop we parse one separator and one element.
- */
- if (RAW == ',') {
- if (type == 0) type = CUR;
- /*
- * Detect "Name | Name , Name" error
- */
- else if (type != CUR) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : '%c' expectedn",
- type);
- ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if ((op != NULL) && (op != ret))
- xmlFreeElementContent(op);
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- NEXT;
- op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_SEQ);
- if (op == NULL) {
- xmlFreeElementContent(ret);
- return(NULL);
- }
- if (last == NULL) {
- op->c1 = ret;
- ret = cur = op;
- } else {
- cur->c2 = op;
- op->c1 = last;
- cur =op;
- last = NULL;
- }
- } else if (RAW == '|') {
- if (type == 0) type = CUR;
- /*
- * Detect "Name , Name | Name" error
- */
- else if (type != CUR) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : '%c' expectedn",
- type);
- ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if ((op != NULL) && (op != ret))
- xmlFreeElementContent(op);
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- NEXT;
- op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
- if (op == NULL) {
- if ((op != NULL) && (op != ret))
- xmlFreeElementContent(op);
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- if (last == NULL) {
- op->c1 = ret;
- ret = cur = op;
- } else {
- cur->c2 = op;
- op->c1 = last;
- cur =op;
- last = NULL;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : ',' '|' or ')' expectedn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_FINISHED;
- if ((op != NULL) && (op != ret))
- xmlFreeElementContent(op);
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- GROW;
- SKIP_BLANKS;
- GROW;
- if (RAW == '(') {
- /* Recurse on second child */
- NEXT;
- SKIP_BLANKS;
- last = xmlParseElementChildrenContentDecl(ctxt);
- SKIP_BLANKS;
- } else {
- elem = xmlParseName(ctxt);
- if (elem == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : Name or '(' expectedn");
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if ((op != NULL) && (op != ret))
- xmlFreeElementContent(op);
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- last = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
- xmlFree(elem);
- if (RAW == '?') {
- last->ocur = XML_ELEMENT_CONTENT_OPT;
- NEXT;
- } else if (RAW == '*') {
- last->ocur = XML_ELEMENT_CONTENT_MULT;
- NEXT;
- } else if (RAW == '+') {
- last->ocur = XML_ELEMENT_CONTENT_PLUS;
- NEXT;
- } else {
- last->ocur = XML_ELEMENT_CONTENT_ONCE;
- }
- }
- SKIP_BLANKS;
- GROW;
- }
- if ((cur != NULL) && (last != NULL)) {
- cur->c2 = last;
- }
- ctxt->entity = ctxt->input;
- NEXT;
- if (RAW == '?') {
- ret->ocur = XML_ELEMENT_CONTENT_OPT;
- NEXT;
- } else if (RAW == '*') {
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
- NEXT;
- } else if (RAW == '+') {
- ret->ocur = XML_ELEMENT_CONTENT_PLUS;
- NEXT;
- }
- return(ret);
- }
- /**
- * xmlParseElementContentDecl:
- * @ctxt: an XML parser context
- * @name: the name of the element being defined.
- * @result: the Element Content pointer will be stored here if any
- *
- * parse the declaration for an Element content either Mixed or Children,
- * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
- *
- * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
- *
- * returns: the type of element content XML_ELEMENT_TYPE_xxx
- */
- int
- xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, xmlChar *name,
- xmlElementContentPtr *result) {
- xmlElementContentPtr tree = NULL;
- xmlParserInputPtr input = ctxt->input;
- int res;
- *result = NULL;
- if (RAW != '(') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementContentDecl : '(' expectedn");
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(-1);
- }
- NEXT;
- GROW;
- SKIP_BLANKS;
- if ((RAW == '#') && (NXT(1) == 'P') &&
- (NXT(2) == 'C') && (NXT(3) == 'D') &&
- (NXT(4) == 'A') && (NXT(5) == 'T') &&
- (NXT(6) == 'A')) {
- tree = xmlParseElementMixedContentDecl(ctxt);
- res = XML_ELEMENT_TYPE_MIXED;
- } else {
- tree = xmlParseElementChildrenContentDecl(ctxt);
- res = XML_ELEMENT_TYPE_ELEMENT;
- }
- if ((ctxt->entity != NULL) && (input != ctxt->entity)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Element content declaration doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- /****************************
- if (RAW != ')') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementContentDecl : ')' expectedn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(-1);
- }
- ****************************/
- *result = tree;
- return(res);
- }
- /**
- * xmlParseElementDecl:
- * @ctxt: an XML parser context
- *
- * parse an Element declaration.
- *
- * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
- *
- * [ VC: Unique Element Type Declaration ]
- * No element type may be declared more than once
- *
- * Returns the type of the element, or -1 in case of error
- */
- int
- xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- int ret = -1;
- xmlElementContentPtr content = NULL;
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'E') && (NXT(3) == 'L') &&
- (NXT(4) == 'E') && (NXT(5) == 'M') &&
- (NXT(6) == 'E') && (NXT(7) == 'N') &&
- (NXT(8) == 'T')) {
- xmlParserInputPtr input = ctxt->input;
- SKIP(9);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'ELEMENT'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementDecl: no name for Elementn");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return(-1);
- }
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the element namen");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- if ((RAW == 'E') && (NXT(1) == 'M') &&
- (NXT(2) == 'P') && (NXT(3) == 'T') &&
- (NXT(4) == 'Y')) {
- SKIP(5);
- /*
- * Element must always be empty.
- */
- ret = XML_ELEMENT_TYPE_EMPTY;
- } else if ((RAW == 'A') && (NXT(1) == 'N') &&
- (NXT(2) == 'Y')) {
- SKIP(3);
- /*
- * Element is a generic container.
- */
- ret = XML_ELEMENT_TYPE_ANY;
- } else if (RAW == '(') {
- ret = xmlParseElementContentDecl(ctxt, name, &content);
- } else {
- /*
- * [ WFC: PEs in Internal Subset ] error handling.
- */
- if ((RAW == '%') && (ctxt->external == 0) &&
- (ctxt->inputNr == 1)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PEReference: forbidden within markup decl in internal subsetn");
- ctxt->errNo = XML_ERR_PEREF_IN_INT_SUBSET;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expectedn");
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- }
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- if (name != NULL) xmlFree(name);
- return(-1);
- }
- SKIP_BLANKS;
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- SKIP_BLANKS;
- if (RAW != '>') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementDecl: expected '>' at the endn");
- ctxt->errNo = XML_ERR_GT_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Element declaration doesn't start and stop in the same entityn");
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
-
- NEXT;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->elementDecl != NULL))
- ctxt->sax->elementDecl(ctxt->userData, name, ret,
- content);
- }
- if (content != NULL) {
- xmlFreeElementContent(content);
- }
- if (name != NULL) {
- xmlFree(name);
- }
- }
- return(ret);
- }
- /**
- * xmlParseMarkupDecl:
- * @ctxt: an XML parser context
- *
- * parse Markup declarations
- *
- * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
- * NotationDecl | PI | Comment
- *
- * [ VC: Proper Declaration/PE Nesting ]
- * TODO Parameter-entity replacement text must be properly nested with
- * markup declarations. That is to say, if either the first character
- * or the last character of a markup declaration (markupdecl above) is
- * contained in the replacement text for a parameter-entity reference,
- * both must be contained in the same replacement text.
- *
- * [ WFC: PEs in Internal Subset ]
- * In the internal DTD subset, parameter-entity references can occur
- * only where markup declarations can occur, not within markup declarations.
- * (This does not apply to references that occur in external parameter
- * entities or to the external subset.)
- */
- void
- xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
- GROW;
- xmlParseElementDecl(ctxt);
- xmlParseAttributeListDecl(ctxt);
- xmlParseEntityDecl(ctxt);
- xmlParseNotationDecl(ctxt);
- xmlParsePI(ctxt);
- xmlParseComment(ctxt);
- /*
- * This is only for internal subset. On external entities,
- * the replacement is done before parsing stage
- */
- if ((ctxt->external == 0) && (ctxt->inputNr == 1))
- xmlParsePEReference(ctxt);
- ctxt->instate = XML_PARSER_DTD;
- }
- /**
- * xmlParseTextDecl:
- * @ctxt: an XML parser context
- *
- * parse an XML declaration header for external entities
- *
- * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
- *
- * Question: Seems that EncodingDecl is mandatory ? Is that a typo ?
- */
- void
- xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *version;
- /*
- * We know that '<?xml' is here.
- */
- SKIP(5);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space needed after '<?xml'n");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- /*
- * We may have the VersionInfo here.
- */
- version = xmlParseVersionInfo(ctxt);
- if (version == NULL)
- version = xmlCharStrdup(XML_DEFAULT_VERSION);
- ctxt->input->version = version;
- /*
- * We must have the encoding declaration
- */
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Space needed heren");
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- ctxt->input->encoding = xmlParseEncodingDecl(ctxt);
- SKIP_BLANKS;
- if ((RAW == '?') && (NXT(1) == '>')) {
- SKIP(2);
- } else if (RAW == '>') {
- /* Deprecated old WD ... */
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML declaration must end-up with '?>'n");
- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "parsing XML declaration: '?>' expectedn");
- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- MOVETO_ENDTAG(CUR_PTR);
- NEXT;
- }
- }
- /*
- * xmlParseConditionalSections
- * @ctxt: an XML parser context
- *
- * TODO : Conditionnal section are not yet supported !
- *
- * [61] conditionalSect ::= includeSect | ignoreSect
- * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
- * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
- * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
- * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
- */
- void
- xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
- SKIP(3);
- SKIP_BLANKS;
- if ((RAW == 'I') && (NXT(1) == 'N') && (NXT(2) == 'C') &&
- (NXT(3) == 'L') && (NXT(4) == 'U') && (NXT(5) == 'D') &&
- (NXT(6) == 'E')) {
- SKIP(7);
- SKIP_BLANKS;
- if (RAW != '[') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section '[' expectedn");
- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
- (NXT(2) != '>'))) {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
- int tok = ctxt->token;
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
- xmlParseConditionalSections(ctxt);
- } else if (IS_BLANK(CUR)) {
- NEXT;
- } else if (RAW == '%') {
- xmlParsePEReference(ctxt);
- } else
- xmlParseMarkupDecl(ctxt);
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
- (tok == ctxt->token)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Content error in the external subsetn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
- break;
- }
- }
- } else if ((RAW == 'I') && (NXT(1) == 'G') && (NXT(2) == 'N') &&
- (NXT(3) == 'O') && (NXT(4) == 'R') && (NXT(5) == 'E')) {
- int state;
- SKIP(6);
- SKIP_BLANKS;
- if (RAW != '[') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section '[' expectedn");
- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- /*
- * Parse up to the end of the conditionnal section
- * But disable SAX event generating DTD building in the meantime
- */
- state = ctxt->disableSAX;
- while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
- (NXT(2) != '>'))) {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
- int tok = ctxt->token;
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
- xmlParseConditionalSections(ctxt);
- } else if (IS_BLANK(CUR)) {
- NEXT;
- } else if (RAW == '%') {
- xmlParsePEReference(ctxt);
- } else
- xmlParseMarkupDecl(ctxt);
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
- (tok == ctxt->token)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Content error in the external subsetn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
- break;
- }
- }
- ctxt->disableSAX = state;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section INCLUDE or IGNORE keyword expectedn");
- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- if (RAW == 0)
- SHRINK;
- if (RAW == 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section not closedn");
- ctxt->errNo = XML_ERR_CONDSEC_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- SKIP(3);
- }
- }
- /**
- * xmlParseExternalSubset:
- * @ctxt: an XML parser context
- * @ExternalID: the external identifier
- * @SystemID: the system identifier (or URL)
- *
- * parse Markup declarations from an external subset
- *
- * [30] extSubset ::= textDecl? extSubsetDecl
- *
- * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
- */
- void
- xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
- const xmlChar *SystemID) {
- GROW;
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l')) {
- xmlParseTextDecl(ctxt);
- }
- if (ctxt->myDoc == NULL) {
- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
- }
- if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
- xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
- ctxt->instate = XML_PARSER_DTD;
- ctxt->external = 1;
- while (((RAW == '<') && (NXT(1) == '?')) ||
- ((RAW == '<') && (NXT(1) == '!')) ||
- IS_BLANK(CUR)) {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
- int tok = ctxt->token;
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
- xmlParseConditionalSections(ctxt);
- } else if (IS_BLANK(CUR)) {
- NEXT;
- } else if (RAW == '%') {
- xmlParsePEReference(ctxt);
- } else
- xmlParseMarkupDecl(ctxt);
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
- (tok == ctxt->token)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Content error in the external subsetn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
- break;
- }
- }
-
- if (RAW != 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the documentn");
- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- }
- /**
- * xmlParseReference:
- * @ctxt: an XML parser context
- *
- * parse and handle entity references in content, depending on the SAX
- * interface, this may end-up in a call to character() if this is a
- * CharRef, a predefined entity, if there is no reference() callback.
- * or if the parser was asked to switch to that mode.
- *
- * [67] Reference ::= EntityRef | CharRef
- */
- void
- xmlParseReference(xmlParserCtxtPtr ctxt) {
- xmlEntityPtr ent;
- xmlChar *val;
- if (RAW != '&') return;
- if (ctxt->inputNr > 1) {
- xmlChar cur[2] = { '&' , 0 } ;
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->characters(ctxt->userData, cur, 1);
- if (ctxt->token == '&')
- ctxt->token = 0;
- else {
- SKIP(1);
- }
- return;
- }
- if (NXT(1) == '#') {
- int i = 0;
- xmlChar out[10];
- int hex = NXT(2);
- int val = xmlParseCharRef(ctxt);
-
- if (ctxt->encoding != NULL) {
- /*
- * So we are using non-UTF-8 buffers
- * Check that the char fit on 8bits, if not
- * generate a CharRef.
- */
- if (val <= 0xFF) {
- out[0] = val;
- out[1] = 0;
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->characters(ctxt->userData, out, 1);
- } else {
- if ((hex == 'x') || (hex == 'X'))
- sprintf((char *)out, "#x%X", val);
- else
- sprintf((char *)out, "#%d", val);
- if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->reference(ctxt->userData, out);
- }
- } else {
- /*
- * Just encode the value in UTF-8
- */
- COPY_BUF(0 ,out, i, val);
- out[i] = 0;
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->characters(ctxt->userData, out, i);
- }
- } else {
- ent = xmlParseEntityRef(ctxt);
- if (ent == NULL) return;
- if ((ent->name != NULL) &&
- (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
- xmlNodePtr list = NULL;
- int ret;
- /*
- * The first reference to the entity trigger a parsing phase
- * where the ent->children is filled with the result from
- * the parsing.
- */
- if (ent->children == NULL) {
- xmlChar *value;
- value = ent->content;
- /*
- * Check that this entity is well formed
- */
- if ((value != NULL) &&
- (value[1] == 0) && (value[0] == '<') &&
- (!xmlStrcmp(ent->name, BAD_CAST "lt"))) {
- /*
- * TODO: get definite answer on this !!!
- * Lots of entity decls are used to declare a single
- * char
- * <!ENTITY lt "<">
- * Which seems to be valid since
- * 2.4: The ampersand character (&) and the left angle
- * bracket (<) may appear in their literal form only
- * when used ... They are also legal within the literal
- * entity value of an internal entity declaration;i
- * see "4.3.2 Well-Formed Parsed Entities".
- * IMHO 2.4 and 4.3.2 are directly in contradiction.
- * Looking at the OASIS test suite and James Clark
- * tests, this is broken. However the XML REC uses
- * it. Is the XML REC not well-formed ????
- * This is a hack to avoid this problem
- */
- list = xmlNewDocText(ctxt->myDoc, value);
- if (list != NULL) {
- if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
- (ent->children == NULL)) {
- ent->children = list;
- ent->last = list;
- list->parent = (xmlNodePtr) ent;
- } else {
- xmlFreeNodeList(list);
- }
- } else if (list != NULL) {
- xmlFreeNodeList(list);
- }
- } else {
- /*
- * 4.3.2: An internal general parsed entity is well-formed
- * if its replacement text matches the production labeled
- * content.
- */
- if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
- ctxt->depth++;
- ret = xmlParseBalancedChunkMemory(ctxt->myDoc,
- ctxt->sax, NULL, ctxt->depth,
- value, &list);
- ctxt->depth--;
- } else if (ent->etype ==
- XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
- ctxt->depth++;
- ret = xmlParseExternalEntity(ctxt->myDoc,
- ctxt->sax, NULL, ctxt->depth,
- ent->SystemID, ent->ExternalID, &list);
- ctxt->depth--;
- } else {
- ret = -1;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Internal: invalid entity typen");
- }
- if (ret == XML_ERR_ENTITY_LOOP) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Detected entity reference loopn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_ENTITY_LOOP;
- } else if ((ret == 0) && (list != NULL)) {
- if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
- (ent->children == NULL)) {
- ent->children = list;
- while (list != NULL) {
- list->parent = (xmlNodePtr) ent;
- if (list->next == NULL)
- ent->last = list;
- list = list->next;
- }
- } else {
- xmlFreeNodeList(list);
- }
- } else if (ret > 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value requiredn");
- ctxt->errNo = ret;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else if (list != NULL) {
- xmlFreeNodeList(list);
- }
- }
- }
- if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
- (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
- /*
- * Create a node.
- */
- ctxt->sax->reference(ctxt->userData, ent->name);
- return;
- } else if (ctxt->replaceEntities) {
- xmlParserInputPtr input;
- input = xmlNewEntityInputStream(ctxt, ent);
- xmlPushInput(ctxt, input);
- if ((ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) &&
- (RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- if (input->standalone) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "external parsed entities cannot be standalonen");
- ctxt->errNo = XML_ERR_EXT_ENTITY_STANDALONE;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- }
- /*
- * !!! TODO: build the tree under the entity first
- * 1234
- */
- return;
- }
- }
- val = ent->content;
- if (val == NULL) return;
- /*
- * inline the entity.
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
- }
- }
- /**
- * xmlParseEntityRef:
- * @ctxt: an XML parser context
- *
- * parse ENTITY references declarations
- *
- * [68] EntityRef ::= '&' Name ';'
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", the Name given in the entity reference
- * must match that in an entity declaration, except that well-formed
- * documents need not declare any of the following entities: amp, lt,
- * gt, apos, quot. The declaration of a parameter entity must precede
- * any reference to it. Similarly, the declaration of a general entity
- * must precede any reference to it which appears in a default value in an
- * attribute-list declaration. Note that if entities are declared in the
- * external subset or in external parameter entities, a non-validating
- * processor is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be declared is a
- * well-formedness constraint only if standalone='yes'.
- *
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an unparsed entity
- *
- * Returns the xmlEntityPtr if found, or NULL otherwise.
- */
- xmlEntityPtr
- xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEntityPtr ent = NULL;
- GROW;
-
- if (RAW == '&') {
- NEXT;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityRef: no namen");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if (RAW == ';') {
- NEXT;
- /*
- * Ask first SAX for entity resolution, otherwise try the
- * predefined set.
- */
- if (ctxt->sax != NULL) {
- if (ctxt->sax->getEntity != NULL)
- ent = ctxt->sax->getEntity(ctxt->userData, name);
- if (ent == NULL)
- ent = xmlGetPredefinedEntity(name);
- }
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", the
- * Name given in the entity reference must match that in an
- * entity declaration, except that well-formed documents
- * need not declare any of the following entities: amp, lt,
- * gt, apos, quot.
- * The declaration of a parameter entity must precede any
- * reference to it.
- * Similarly, the declaration of a general entity must
- * precede any reference to it which appears in a default
- * value in an attribute-list declaration. Note that if
- * entities are declared in the external subset or in
- * external parameter entities, a non-validating processor
- * is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be
- * declared is a well-formedness constraint only if
- * standalone='yes'.
- */
- if (ent == NULL) {
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity '%s' not definedn", name);
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Entity '%s' not definedn", name);
- ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
- }
- }
- /*
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an
- * unparsed entity
- */
- else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity reference to unparsed entity %sn", name);
- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- /*
- * [ WFC: No External Entity References ]
- * Attribute values cannot contain direct or indirect
- * entity references to external entities.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute references external entity '%s'n", name);
- ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- /*
- * [ WFC: No < in Attribute Values ]
- * The replacement text of any entity referred to directly or
- * indirectly in an attribute value (other than "<") must
- * not contain a <.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent != NULL) &&
- (xmlStrcmp(ent->name, BAD_CAST "lt")) &&
- (ent->content != NULL) &&
- (xmlStrchr(ent->content, '<'))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'<' in entity '%s' is not allowed in attributes valuesn", name);
- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- /*
- * Internal check, no parameter entities here ...
- */
- else {
- switch (ent->etype) {
- case XML_INTERNAL_PARAMETER_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attempt to reference the parameter entity '%s'n", name);
- ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- break;
- default:
- break;
- }
- }
- /*
- * [ WFC: No Recursion ]
- * TODO A parsed entity must not contain a recursive reference
- * to itself, either directly or indirectly.
- */
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityRef: expecting ';'n");
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
- return(ent);
- }
- /**
- * xmlParseStringEntityRef:
- * @ctxt: an XML parser context
- * @str: a pointer to an index in the string
- *
- * parse ENTITY references declarations, but this version parses it from
- * a string value.
- *
- * [68] EntityRef ::= '&' Name ';'
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", the Name given in the entity reference
- * must match that in an entity declaration, except that well-formed
- * documents need not declare any of the following entities: amp, lt,
- * gt, apos, quot. The declaration of a parameter entity must precede
- * any reference to it. Similarly, the declaration of a general entity
- * must precede any reference to it which appears in a default value in an
- * attribute-list declaration. Note that if entities are declared in the
- * external subset or in external parameter entities, a non-validating
- * processor is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be declared is a
- * well-formedness constraint only if standalone='yes'.
- *
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an unparsed entity
- *
- * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
- * is updated to the current location in the string.
- */
- xmlEntityPtr
- xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
- xmlChar *name;
- const xmlChar *ptr;
- xmlChar cur;
- xmlEntityPtr ent = NULL;
- if ((str == NULL) || (*str == NULL))
- return(NULL);
- ptr = *str;
- cur = *ptr;
- if (cur == '&') {
- ptr++;
- cur = *ptr;
- name = xmlParseStringName(ctxt, &ptr);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityRef: no namen");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if (*ptr == ';') {
- ptr++;
- /*
- * Ask first SAX for entity resolution, otherwise try the
- * predefined set.
- */
- if (ctxt->sax != NULL) {
- if (ctxt->sax->getEntity != NULL)
- ent = ctxt->sax->getEntity(ctxt->userData, name);
- if (ent == NULL)
- ent = xmlGetPredefinedEntity(name);
- }
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", the
- * Name given in the entity reference must match that in an
- * entity declaration, except that well-formed documents
- * need not declare any of the following entities: amp, lt,
- * gt, apos, quot.
- * The declaration of a parameter entity must precede any
- * reference to it.
- * Similarly, the declaration of a general entity must
- * precede any reference to it which appears in a default
- * value in an attribute-list declaration. Note that if
- * entities are declared in the external subset or in
- * external parameter entities, a non-validating processor
- * is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be
- * declared is a well-formedness constraint only if
- * standalone='yes'.
- */
- if (ent == NULL) {
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity '%s' not definedn", name);
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Entity '%s' not definedn", name);
- ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
- }
- }
- /*
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an
- * unparsed entity
- */
- else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity reference to unparsed entity %sn", name);
- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- /*
- * [ WFC: No External Entity References ]
- * Attribute values cannot contain direct or indirect
- * entity references to external entities.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute references external entity '%s'n", name);
- ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- /*
- * [ WFC: No < in Attribute Values ]
- * The replacement text of any entity referred to directly or
- * indirectly in an attribute value (other than "<") must
- * not contain a <.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent != NULL) &&
- (xmlStrcmp(ent->name, BAD_CAST "lt")) &&
- (ent->content != NULL) &&
- (xmlStrchr(ent->content, '<'))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'<' in entity '%s' is not allowed in attributes valuesn", name);
- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- /*
- * Internal check, no parameter entities here ...
- */
- else {
- switch (ent->etype) {
- case XML_INTERNAL_PARAMETER_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attempt to reference the parameter entity '%s'n", name);
- ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- break;
- default:
- break;
- }
- }
- /*
- * [ WFC: No Recursion ]
- * TODO A parsed entity must not contain a recursive reference
- * to itself, either directly or indirectly.
- */
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityRef: expecting ';'n");
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
- *str = ptr;
- return(ent);
- }
- /**
- * xmlParsePEReference:
- * @ctxt: an XML parser context
- *
- * parse PEReference declarations
- * The entity content is handled directly by pushing it's content as
- * a new input stream.
- *
- * [69] PEReference ::= '%' Name ';'
- *
- * [ WFC: No Recursion ]
- * TODO A parsed entity must not contain a recursive
- * reference to itself, either directly or indirectly.
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", ... ... The declaration of a parameter
- * entity must precede any reference to it...
- *
- * [ VC: Entity Declared ]
- * In a document with an external subset or external parameter entities
- * with "standalone='no'", ... ... The declaration of a parameter entity
- * must precede any reference to it...
- *
- * [ WFC: In DTD ]
- * Parameter-entity references may only appear in the DTD.
- * NOTE: misleading but this is handled.
- */
- void
- xmlParsePEReference(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEntityPtr entity = NULL;
- xmlParserInputPtr input;
- if (RAW == '%') {
- NEXT;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePEReference: no namen");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- if (RAW == ';') {
- NEXT;
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getParameterEntity != NULL))
- entity = ctxt->sax->getParameterEntity(ctxt->userData,
- name);
- if (entity == NULL) {
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PEReference: %%%s; not foundn", name);
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- /*
- * [ VC: Entity Declared ]
- * In a document with an external subset or external
- * parameter entities with "standalone='no'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "PEReference: %%%s; not foundn", name);
- ctxt->valid = 0;
- }
- } else {
- /*
- * Internal checking in case the entity quest barfed
- */
- if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
- (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Internal: %%%s; is not a parameter entityn", name);
- } else {
- /*
- * TODO !!!
- * handle the extra spaces added before and after
- * c.f. http://www.w3.org/TR/REC-xml#as-PE
- */
- input = xmlNewEntityInputStream(ctxt, entity);
- xmlPushInput(ctxt, input);
- if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
- (RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- }
- if (ctxt->token == 0)
- ctxt->token = ' ';
- }
- }
- ctxt->hasPErefs = 1;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePEReference: expecting ';'n");
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
- }
- /**
- * xmlParseStringPEReference:
- * @ctxt: an XML parser context
- * @str: a pointer to an index in the string
- *
- * parse PEReference declarations
- *
- * [69] PEReference ::= '%' Name ';'
- *
- * [ WFC: No Recursion ]
- * TODO A parsed entity must not contain a recursive
- * reference to itself, either directly or indirectly.
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", ... ... The declaration of a parameter
- * entity must precede any reference to it...
- *
- * [ VC: Entity Declared ]
- * In a document with an external subset or external parameter entities
- * with "standalone='no'", ... ... The declaration of a parameter entity
- * must precede any reference to it...
- *
- * [ WFC: In DTD ]
- * Parameter-entity references may only appear in the DTD.
- * NOTE: misleading but this is handled.
- *
- * Returns the string of the entity content.
- * str is updated to the current value of the index
- */
- xmlEntityPtr
- xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
- const xmlChar *ptr;
- xmlChar cur;
- xmlChar *name;
- xmlEntityPtr entity = NULL;
- if ((str == NULL) || (*str == NULL)) return(NULL);
- ptr = *str;
- cur = *ptr;
- if (cur == '%') {
- ptr++;
- cur = *ptr;
- name = xmlParseStringName(ctxt, &ptr);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringPEReference: no namen");
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- cur = *ptr;
- if (cur == ';') {
- ptr++;
- cur = *ptr;
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getParameterEntity != NULL))
- entity = ctxt->sax->getParameterEntity(ctxt->userData,
- name);
- if (entity == NULL) {
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PEReference: %%%s; not foundn", name);
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- } else {
- /*
- * [ VC: Entity Declared ]
- * In a document with an external subset or external
- * parameter entities with "standalone='no'", ...
- * ... The declaration of a parameter entity must
- * precede any reference to it...
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "PEReference: %%%s; not foundn", name);
- ctxt->valid = 0;
- }
- } else {
- /*
- * Internal checking in case the entity quest barfed
- */
- if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
- (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Internal: %%%s; is not a parameter entityn", name);
- }
- }
- ctxt->hasPErefs = 1;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringPEReference: expecting ';'n");
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
- *str = ptr;
- return(entity);
- }
- /**
- * xmlParseDocTypeDecl:
- * @ctxt: an XML parser context
- *
- * parse a DOCTYPE declaration
- *
- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
- * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
- *
- * [ VC: Root Element Type ]
- * The Name in the document type declaration must match the element
- * type of the root element.
- */
- void
- xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name = NULL;
- xmlChar *ExternalID = NULL;
- xmlChar *URI = NULL;
- /*
- * We know that '<!DOCTYPE' has been detected.
- */
- SKIP(9);
- SKIP_BLANKS;
- /*
- * Parse the DOCTYPE name.
- */
- name = xmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseDocTypeDecl : no DOCTYPE name !n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- }
- ctxt->intSubName = name;
- SKIP_BLANKS;
- /*
- * Check for SystemID and ExternalID
- */
- URI = xmlParseExternalID(ctxt, &ExternalID, 1);
- if ((URI != NULL) || (ExternalID != NULL)) {
- ctxt->hasExternalSubset = 1;
- }
- ctxt->extSubURI = URI;
- ctxt->extSubSystem = ExternalID;
- SKIP_BLANKS;
- /*
- * Create and update the internal subset.
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
- /*
- * Is there any internal subset declarations ?
- * they are handled separately in xmlParseInternalSubset()
- */
- if (RAW == '[')
- return;
- /*
- * We should be at the end of the DOCTYPE declaration.
- */
- if (RAW != '>') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminatedn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
- }
- NEXT;
- }
- /**
- * xmlParseInternalsubset:
- * @ctxt: an XML parser context
- *
- * parse the internal subset declaration
- *
- * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
- */
- void
- xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
- /*
- * Is there any DTD definition ?
- */
- if (RAW == '[') {
- ctxt->instate = XML_PARSER_DTD;
- NEXT;
- /*
- * Parse the succession of Markup declarations and
- * PEReferences.
- * Subsequence (markupdecl | PEReference | S)*
- */
- while (RAW != ']') {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
- SKIP_BLANKS;
- xmlParseMarkupDecl(ctxt);
- xmlParsePEReference(ctxt);
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseInternalSubset: error detected in Markup declarationn");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- break;
- }
- }
- if (RAW == ']') NEXT;
- }