diff --git a/ChangeLog b/ChangeLog index 4a318573..4d341987 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Thu Jun 7 06:44:01 CEST 2001 Daniel Veillard + + * DOCBparser.c: implemented the + hack + * tree.[ch]: added xmlHasNsProp as suggested in bug report #55653 + * uri.c: fixed a warning + Tue Jun 5 22:54:21 CEST 2001 Daniel Veillard * HTMLtree.c: trying to close bug #55772 escaping in script diff --git a/DOCBparser.c b/DOCBparser.c index fe498d1e..a1a8bbf5 100644 --- a/DOCBparser.c +++ b/DOCBparser.c @@ -1,6 +1,10 @@ /* * DOCBparser.c : an attempt to parse SGML Docbook documents * + * This is extremely hackish. It also adds one extension + * + * allowing to store the encoding of the document within the instance. + * * See Copyright for the status of this software. * * Daniel.Veillard@w3.org @@ -3176,6 +3180,173 @@ docbParseExternalID(docbParserCtxtPtr ctxt, xmlChar **publicID) { return(URI); } +/** + * docbParsePI: + * @ctxt: an XML parser context + * + * parse an XML Processing Instruction. + * + * [16] PI ::= '' Char*)))? '?>' + * + * The processing is transfered to SAX once parsed. + */ + +static void +docbParsePI(xmlParserCtxtPtr ctxt) { + xmlChar *buf = NULL; + int len = 0; + int size = DOCB_PARSER_BUFFER_SIZE; + int cur, l; + xmlChar *target; + xmlParserInputState state; + int count = 0; + + 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 = xmlParseName(ctxt); + if (target != NULL) { + xmlChar *encoding = NULL; + + if ((RAW == '?') && (NXT(1) == '>')) { + if (input != ctxt->input) { + ctxt->errNo = XML_ERR_ENTITY_BOUNDARY; + if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) + ctxt->sax->error(ctxt->userData, + "PI declaration doesn't start and stop in the same entity\n"); + 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; + } + if (xmlStrEqual(target, BAD_CAST "sgml-declaration")) { + + encoding = xmlParseEncodingDecl(ctxt); + if (encoding == NULL) { + xmlGenericError(xmlGenericErrorContext, + "sgml-declaration: failed to find/handle encoding\n"); +#ifdef DEBUG + } else { + xmlGenericError(xmlGenericErrorContext, + "switched to encoding %s\n", encoding); +#endif + } + + } + buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + if (buf == NULL) { + xmlGenericError(xmlGenericErrorContext, + "malloc of %d byte failed\n", size); + ctxt->instate = state; + return; + } + cur = CUR; + if (encoding != NULL) { + len = snprintf((char *) buf, size - 1, + " encoding = \"%s\"", encoding); + if (len < 0) + len = size; + } else { + if (!IS_BLANK(cur)) { + ctxt->errNo = XML_ERR_SPACE_REQUIRED; + if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) + ctxt->sax->error(ctxt->userData, + "docbParsePI: PI %s space expected\n", target); + ctxt->wellFormed = 0; + ctxt->disableSAX = 1; + } + SKIP_BLANKS; + } + cur = CUR_CHAR(l); + while (IS_CHAR(cur) && /* checked */ + ((cur != '?') || (NXT(1) != '>'))) { + if (len + 5 >= size) { + size *= 2; + buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar)); + if (buf == NULL) { + xmlGenericError(xmlGenericErrorContext, + "realloc of %d byte failed\n", size); + ctxt->instate = state; + return; + } + } + count++; + if (count > 50) { + GROW; + count = 0; + } + 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 != '?') { + ctxt->errNo = XML_ERR_PI_NOT_FINISHED; + if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) + ctxt->sax->error(ctxt->userData, + "docbParsePI: PI %s never end ...\n", target); + ctxt->wellFormed = 0; + ctxt->disableSAX = 1; + } else { + if (input != ctxt->input) { + ctxt->errNo = XML_ERR_ENTITY_BOUNDARY; + if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) + ctxt->sax->error(ctxt->userData, + "PI declaration doesn't start and stop in the same entity\n"); + 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 { + ctxt->errNo = XML_ERR_PI_NOT_STARTED; + if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) + ctxt->sax->error(ctxt->userData, + "docbParsePI : no target name\n"); + ctxt->wellFormed = 0; + ctxt->disableSAX = 1; + } + ctxt->instate = state; + } +} + /** * docbParseComment: * @ctxt: an SGML parser context @@ -4559,7 +4730,7 @@ docbParseMarkupDecl(xmlParserCtxtPtr ctxt) { xmlParseAttributeListDecl(ctxt); docbParseEntityDecl(ctxt); xmlParseNotationDecl(ctxt); - xmlParsePI(ctxt); + docbParsePI(ctxt); xmlParseComment(ctxt); /* * This is only for internal subset. On external entities, @@ -4651,7 +4822,7 @@ docbParseMisc(xmlParserCtxtPtr ctxt) { (NXT(2) == '-') && (NXT(3) == '-')) || IS_BLANK(CUR)) { if ((RAW == '<') && (NXT(1) == '?')) { - xmlParsePI(ctxt); /* TODO: SGML PIs differs */ + docbParsePI(ctxt); /* TODO: SGML PIs differs */ } else if (IS_BLANK(CUR)) { NEXT; } else @@ -4773,6 +4944,7 @@ docbParseDocument(docbParserCtxtPtr ctxt) { if (ctxt->myDoc != NULL) { dtd = ctxt->myDoc->intSubset; + ctxt->myDoc->standalone = -1; if (dtd == NULL) ctxt->myDoc->intSubset = xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "SGML", diff --git a/include/libxml/tree.h b/include/libxml/tree.h index f272b999..b13b0bc8 100644 --- a/include/libxml/tree.h +++ b/include/libxml/tree.h @@ -677,6 +677,9 @@ xmlChar * xmlGetProp (xmlNodePtr node, const xmlChar *name); xmlAttrPtr xmlHasProp (xmlNodePtr node, const xmlChar *name); +xmlAttrPtr xmlHasNsProp (xmlNodePtr node, + const xmlChar *name, + const xmlChar *namespace); xmlAttrPtr xmlSetNsProp (xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, diff --git a/tree.c b/tree.c index 99afb61f..d5286871 100644 --- a/tree.c +++ b/tree.c @@ -4218,6 +4218,78 @@ xmlHasProp(xmlNodePtr node, const xmlChar *name) { return(NULL); } +/** + * xmlHasNsProp: + * @node: the node + * @name: the attribute name + * @namespace: the URI of the namespace + * + * Search for an attribute associated to a node + * This attribute has to be anchored in the namespace specified. + * This does the entity substitution. + * This function looks in DTD attribute declaration for #FIXED or + * default declaration values unless DTD use has been turned off. + * + * Returns the attribute or the attribute declaration or NULL + * if neither was found. + */ +xmlAttrPtr +xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *namespace) { + xmlAttrPtr prop; + xmlDocPtr doc; + xmlNsPtr ns; + + if (node == NULL) + return(NULL); + + prop = node->properties; + if (namespace == NULL) + return(xmlHasProp(node, name)); + while (prop != NULL) { + /* + * One need to have + * - same attribute names + * - and the attribute carrying that namespace + * or + * no namespace on the attribute and the element carrying it + */ + if ((xmlStrEqual(prop->name, name)) && + (((prop->ns == NULL) && (node->ns != NULL) && + (xmlStrEqual(node->ns->href, namespace))) || + ((prop->ns != NULL) && + (xmlStrEqual(prop->ns->href, namespace))))) { + return(prop); + } + prop = prop->next; + } + if (!xmlCheckDTD) return(NULL); + + /* + * Check if there is a default declaration in the internal + * or external subsets + */ + doc = node->doc; + if (doc != NULL) { + if (doc->intSubset != NULL) { + xmlAttributePtr attrDecl; + + attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name); + if ((attrDecl == NULL) && (doc->extSubset != NULL)) + attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name); + + if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) { + /* + * The DTD declaration only allows a prefix search + */ + ns = xmlSearchNs(doc, node, attrDecl->prefix); + if ((ns != NULL) && (xmlStrEqual(ns->href, namespace))) + return((xmlAttrPtr) attrDecl); + } + } + } + return(NULL); +} + /** * xmlGetProp: * @node: the node diff --git a/tree.h b/tree.h index f272b999..b13b0bc8 100644 --- a/tree.h +++ b/tree.h @@ -677,6 +677,9 @@ xmlChar * xmlGetProp (xmlNodePtr node, const xmlChar *name); xmlAttrPtr xmlHasProp (xmlNodePtr node, const xmlChar *name); +xmlAttrPtr xmlHasNsProp (xmlNodePtr node, + const xmlChar *name, + const xmlChar *namespace); xmlAttrPtr xmlSetNsProp (xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, diff --git a/uri.c b/uri.c index b4554606..b59ef035 100644 --- a/uri.c +++ b/uri.c @@ -1109,7 +1109,7 @@ xmlURIEscape(const xmlChar *str) { if(uri->port) { xmlChar port[10]; - snprintf(segment, 10, "%d", uri->port); + snprintf((char *) segment, 10, "%d", uri->port); xmlStrcat(ret, BAD_CAST ":"); xmlStrcat(ret, port); xmlFree(segment);